Plugin configuration

Does DOpus have some helper methods to store plugin configuration or do I have to use GetConfigPath to get plugin config dir and manage XML there using DOpusPluginHelperXML (which I actually don't have because I'm writing plugin in Delphi :slight_smile:)?

I also need font/color choosers in my config, there is DOpusChooseFont, but I didn't find DOpus-styled color picker.

The plugin API provides two config helpers, one simple and one more advanced. You should be able to use any of the APIs from Delphi. There's a sample here:

What are the names of the helpers exactly? DOpusPluginHelperConfig and DOpusPluginHelperXML?
Delphi wrappers don't have them, and they don't have any methods from Support SDK, I guess I'll have to add them :slight_smile:

The helper functions are all loaded from dopus.exe via GetProcAddress, the same way you'd load functions out of a normal DLL. (EXEs can export functions as well, although it's not done as often. So your plugin DLL can use functions in dopus.exe the same as Opus uses functions in your DLL.)

Have a look at the Plugin Support.h file in the plugin SDK and you can see how it loads all the functions, and get their names and arguments/types from there.

Support SDK only has font selector, not the color one? Default plugins like Text are using own dialogs from their DLLs then?

You can use the Opus color picker from plugins, although it's not documented (mainly due to lack of interest from anyone writing plugins, rather than because we don't want people to know!).

Here are the details:

Function name for GetProcAddress is: DOpusColorPicker

Signature is:

COLORREF DOpusColorPicker(HWND hWndButton,
                          int iID,
                          COLORREF crColor,
                          DWORD dwFlags,
                          HWND hwndNotify,
                          UINT uiNotifyMsg)
  • hWndButton: Window handle of the button that caused the color picker to open. Used to position the picker.
  • iID: Control ID of the same button (usually; can be whatever you want really). Sent back to you with notifications (see below).
  • crColor: The initial value for the color being edited.
  • dwFlags:
    // DOpusColorPicker flags
    #define DOCOLPICKF_TRANSPARENT		(1<<0)	// Enable the Transparent "color".
    #define DOCOLPICKF_TRANSISDEFAULT	(1<<1)	// Lable the Transparent color as "Use Default".
    #define DOCOLPICKF_CLOSEONF4		(1<<2)	// The color picker should close if F4 is pushed
                                                // (e.g. if opened in response to F4 on a drop-down button).
  • hwndNotify: Window to send notification messages to (usually the dialog).
  • uiNotifyMsg: The notification message to send, or 0 (zero) if you don't want notifications.

Returns: The new chosen color. If "Default" or "Transparent" is enabled and chosen, the result is COLOR_TRANSPARENT i.e. 0xffffffff.

Notifications are optional, but let you reflect color changes as they happen instead of waiting until the final choice is made. Each time the color changes in the picker, Opus will do:

SendMessage(hwndNotifyWnd, uiNotifyMsg, iID, crNewColor)

One more holiday question :opussanta:
If LoadOrSaveConfigW with OPUSCFG_LOAD is used, will it assign values to all items provided by pCfgItemArray? What if I want items that are not yet in oxc to have some default values?
I tried to store COLORREF as DPCITYPE_DWORD and LoadOrSaveConfigW sets its value to 0, which is black and is not the color I want as default one.

There's a way to do that, but it was added fairly recently for the internal Text plugin and is undocumented. (All the published plugin code uses the more complex config API for anything with optional values.)

This only works in Opus 12.7 and above, so make sure you test the Opus version number:

#define MAKE64BITVERSIONNUMBER(a,b,c,d) ((((DWORD64)(a))<<48) + (((DWORD64)(b))<<32) + (((DWORD64)(c))<<16) + (((DWORD64)(d))<<00))

	DWORD64 opusVersion = pInitExData->dwOpusVerMajor;
	opusVersion <<= 32;
	opusVersion += pInitExData->dwOpusVerMinor;

	if (opusVersion < MAKE64BITVERSIONNUMBER(12,7,0,0))
		return FALSE;

The published DOpusPluginConfigItemW structure is defined like this (// comments added for clarity):

typedef struct DOpusPluginConfigItemW
	LPCWSTR			pszName;
	int				iType;  // 32-bit
	LPVOID			pData;
	DWORD			dwDataSize;

In 12.7 and above, that 32-bit iType field is interpreted as a 16-bit iValType and a 16-bit wFlags:

typedef struct DOpusPluginConfigItemW
	LPCWSTR			pszName;
	short			iValType;  // 16-bit
	WORD			wFlags;    // 16-bit
	LPVOID			pData;
	DWORD			dwDataSize;

(Since the defined type values max out at 8 currently, wFlags is effectively zero in all code that uses the original structure.)

The new wFlags field has one possible flag:

#define DPCIF_LeaveDefault		(1 << 0)

If that is set, whatever value you put in pData will be left as-is if nothing exists in the XML for that item. So you can set it to the default you want before calling LoadOrSaveConfigW and the default will be left as-is if the config file doesn't mention it.

Edit: Actually, you can probably ignore everything below, unless you're making a plugin that works with both Opus 12 and earlier versions. If it's Opus 12 and above, the new and old LOGFONT types should both do the same thing. (It only matters when Opus 12 loads configs saved by earlier versions.)

Speaking of the type values, there's also an undocumented type which lets you load font settings that include a height. This was added in 12.0 as part of the high DPI support:

// Current version - define PLUGINSUPPORTVERSION when including this file to use an older version
// Verison 1 is Opus 9
// Version 2 is Opus 10
// Version 3 is Opus 11
// Version 12000 is Opus 12.0 (first version using this easier to understand numbering format)
	DPCITYPE_LOGFONT,			// In Opus 12, when loading configs saved by earlier versions, this will always load a fixed size font. (Typically 8pt or 9pt.)
	DPCITYPE_LOGFONTWITHHEIGHT, // Same as DPCITYPE_LOGFONT but: If doing a Load, lfHeight must be filled in by the caller and will be used when loading configs saved before Opus 12.