Skip to content

videofilt_vdxframe_addingconfigurability

shekh edited this page Apr 15, 2018 · 1 revision

VirtualDub Plugin SDK 1.2

Adding configurability

Once the basic structure is in place, interesting filters need some sort of configurability. VDXFrame also has wrappers to make this easier. As usual, these are optional and you can use another UI library with the filter base class.

Splitting off the configuration class

One of the side effects of making it easier to add instance data to a filter is that the filter class itself is likely to contain fields that are not related to configuration parameters. To make writing the configuration UI easier, it's recommended that the configuration data be split off into a separate structure:

struct MyFilterConfig {
    int mBrightness;
    int mContrast;
    
    MyFilterConfig()
        : mBrightness(0)
        , mContrast(100)
    {
    }
};

Doing this makes it more likely that either the structure can be copied as-is, or that it is easier to write the copy constructor and assignment operators.

Writing the configuration dialog

Once the configuration structure is lifted out into a separate class, the dialog class can be created. This is done by deriving from VDXVideoFilterDialog:

class MyFilterDialog : public VDXVideoFilterDialog {
public:
    MyFilterDialog(MyFilterConfig& config, IVDXFilterPreview *ifp) : mConfig(config), mpPreview(ifp) {}

    bool Show(VDXHWND parent) {
        return 0 != VDXVideoFilterDialog::Show(NULL, MAKEINTRESOURCE(IDD_FILTER_CONFIG), (HWND)parent);
    }

    virtual INT_PTR DlgProc(UINT msg, WPARAM wParam, LPARAM lParam);
    
protected:
    MyFilterConfig& mConfig;
    IVDXFilterPreview *mpPreview;
};

INT_PTR MyFilterDialog::DlgProc(UINT msg, WPARAM wParam, LPARAM lParam) {
    return FALSE;
}

Sadly, this is as much as VDXVideoFilterDialog will for you, as you will still have to write Win32 dialog code. However, the base class takes care of wrapping and unwrapping the this pointer, making the rest easier. You can extend the base class with additional methods to add common message handlers.

Hooking up the dialog

Now that the dialog is created, the Configure() method can be added to the filter class:

bool MyFilter::Configure(VDXHWND hwnd) {
    MyFilterConfig oldConfig(mConfig);
    MyFilterDialog dlg(mConfig, fa->ifp);

    if (dlg.Show(hwnd))
        return true;
        
    mConfig = oldConfig;
    return false;
}

The copying of the configuration object in and out may seem unnecessary, but this allows the dialog and the filter to share the same configuration structure so that the dialog can update the filter for live previews. It also means that the dialog class doesn't have to worry about rolling back the changes to the configuration object.

An additional advantage of this split structure between the filter, dialog, and configuration objects is that it allows the platform-dependent dialog code to be isolated in a different module, if desired. The VDXHWND type makes this easier.

Note that there is a gotcha involved with the VDXFrame implementation of the Configure() method: the VDXVideoFilterDefinition template uses an overload trick to determine if the filter class overloads Configure(). Therefore, a filter cannot "unimplement" the Configure() method by calling the base VDXVideoFilter::Configure() method.

Summarizing settings in the filter list

The stringProc and stringProc2 methods of a filter generate a short blurb for filter list UI. VDXVideoFilter consolidates both of these into one method and provides a SafePrintf() helper to simplify its implementation:

void EmptyFilter::GetSettingString(char *buf, int maxlen) {
    SafePrintf(buf, maxlen, " (%d)", mConfig.mBrightness);
}

Copyright (C) 2007-2012 Avery Lee.

Clone this wiki locally