I'm trying to write a wrapper for Winamp input plugins and have hit a bit of a snag. I'd like my wrapper to be able to display a plugin's configuration dialog, which is (or should be) achieved by calling the plugin's Config(HWND hwndParent) function.
For most plugins, this works fine and my program is able to display the plugin's configuration dialog. However, 64th Note (a plugin for playing USF files) is giving me problems. Winamp can display its configuration dialog just fine, but whenever I try to display it from my wrapper, the dialog gets destroyed before it ever shows itself. Thankfully, 64th Note is open source, so I took a look at its innards to try and get an idea of what's going wrong. I've trimmed off the irrelevant bits and am left with this:
Config function in the plugin (should show configuration dialog):
void Config(HWND hwndParent) {
DialogBox(slave, (const char *) IDD_CONFIG_WINDOW, NULL, configDlgProc);
}
(Slave is the plugin DLL's HINSTANCE handle.) The proc for the dialog is as follows (I have stripped out all the functionality, since it doesn't appear to have an influence on this problem):
BOOL CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return 0;
}
The template for IDD_CONFIG_WINDOW is as follows:
IDD_CONFIG_WINDOW DIALOGEX 0, 0, 269, 149
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "64th Note configuration"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
DEFPUSHBUTTON "OK",IDOK,212,38,50,14
CONTROL "Play Forever",IDC_NOLENGTH,"Button",BS_AUTORADIOBUTTON,7,7,55,8
CONTROL "Always Use Default Length",IDC_SETLEN,"Button",BS_AUTORADIOBUTTON,7,17,101,8
CONTROL "Default Length",IDC_DEFLEN,"Button",BS_AUTORADIOBUTTON,7,29,63,8
EDITTEXT IDC_DEFLENVAL,71,28,38,12,ES_AUTOHSCROLL
EDITTEXT IDC_DEFFADEVAL,71,42,38,12,ES_AUTOHSCROLL
CONTROL "Detect Silence",IDC_DETSIL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,56,63,8
EDITTEXT IDC_DETSILVAL,71,56,38,12,ES_AUTOHSCROLL
CONTROL "Slider2",IDC_PRISLIDER,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,74,90,108,11
EDITTEXT IDC_TITLEFMT,7,127,255,15,ES_AUTOHSCROLL
CONTROL "Default to file name on missing field",IDC_FNONMISSINGTAG,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,50,114,124,8
CONTROL "Use Recompiler CPU",IDC_RECOMPILER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,7,83,8
CONTROL "Round Frequency",IDC_ROUNDFREQ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,16,73,8
CONTROL "Seek Backwards",IDC_BACKWARDS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,26,70,8
CONTROL "Fast Seek",IDC_FASTSEEK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,35,48,8
CONTROL "RSP Sections",IDC_SECTIONS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,45,60,8
CONTROL "Soft Amplify",IDC_SOFTAMP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,54,53,8
CONTROL "Audio HLE",IDC_AUDIOHLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,63,50,8
CONTROL "Auto Audio HLE",IDC_AUTOAUDIOHLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,72,64,8
CONTROL "Display Errors",IDC_DISPERROR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,145,81,58,8
EDITTEXT IDC_RELVOL,211,104,28,12,ES_AUTOHSCROLL
PUSHBUTTON "Cancel",IDCANCEL,212,54,50,14
PUSHBUTTON "Help",IDHELPBUTTON,212,71,50,14
LTEXT "Title format:",IDC_STATIC,7,113,38,8
LTEXT "seconds",IDC_STATIC,112,29,28,8
LTEXT "Default Fade",IDC_STATIC,19,43,42,8
LTEXT "seconds",IDC_STATIC,112,43,28,8
LTEXT "seconds",IDC_STATIC,112,57,28,8
CTEXT "CPU Thread Priority",IDC_STATIC,7,91,63,8
CTEXT "Look ma, I'm data!",IDC_CPUPRI,75,104,108,8
LTEXT "Relative Volume",IDC_STATIC,199,94,52,8
LTEXT "Fade Type",IDC_STATIC,7,75,35,8
COMBOBOX IDC_FADETYPE,45,72,87,74,CBS_DROPDOWNLIST | WS_TABSTOP
END
Naturally, without any substance in the proc function, the dialog doesn't have any functionality, but it still displays in Winamp when the Config function is invoked. However, it does not appear when I invoke it from my wrapper program. When I monitored the messages sent to the dialog in its proc function, I saw that WM_DESTROY and WM_NCDESTROY were sent within the first few messages, though I have no clue as to why.
If I change the Config function so that it dis开发者_如何学编程plays the plugin's About dialog instead of its configuration dialog, both Winamp and my wrapper will display the About dialog, which suggests that there is something unique to the configuration dialog template that's causing the problem. The modified Config function reads like so:
void Config(HWND hwndParent) {
DialogBox(slave, (const char *) IDD_ABOUTBOX, NULL, configDlgProc);
}
The template for the About dialog is as follows:
IDD_ABOUTBOX DIALOGEX 0, 0, 152, 151
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About 64th Note"
FONT 8, "MS Sans Serif", 0, 0, 0x1
BEGIN
LTEXT "64th Note v1.2 beta 3\nBased on Project 64 1.6 by Zilmar and Jabo\nAudio HLE by Azimer\nPSF concept and tagging by Neill Corlett\nPlayer by hcs, Josh W, dr0\nhttp://hcs64.com/usf",IDC_STATIC,7,94,138,50
CONTROL 110,IDC_STATIC,"Static",SS_BITMAP,26,7,95,86,WS_EX_DLGMODALFRAME
END
Like I said, my wrapper displays the About dialog just fine, as does Winamp. Why can Winamp display the Config dialog, while my wrapper cannot?
Perhaps you haven't registered the Trackbar control's WNDCLASS? You have to load the common control DLL before you can instantiate it.
I'm specifically looking at this line:
CONTROL "Slider2",IDC_PRISLIDER,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,74,90,108,11
EDIT: You'll need to link with comctl32.lib and call InitCommonControlsEx during your program startup.
精彩评论