【问题标题】:Why can't my program display this dialog box, while another program can?为什么我的程序不能显示这个对话框,而另一个程序可以?
【发布时间】:2011-01-30 04:59:11
【问题描述】:

我正在尝试为 Winamp 输入插件编写一个包装器,但遇到了一些问题。我希望我的包装器能够显示插件的配置对话框,这是(或应该)通过调用插件的 Config(HWND hwndParent) 函数来实现的。

对于大多数插件,这工作正常,我的程序能够显示插件的配置对话框。但是,64th Note(播放 USF 文件的插件)给我带来了问题。 Winamp 可以很好地显示它的配置对话框,但是每当我尝试从我的包装器中显示它时,对话框在它出现之前就被破坏了。值得庆幸的是,64th Note 是开源的,所以我查看了它的内部结构,试图了解出了什么问题。我已经剪掉了不相关的部分,剩下的就是这个:

插件中的配置功能(应显示配置对话框):

void Config(HWND hwndParent) {
    DialogBox(slave, (const char *) IDD_CONFIG_WINDOW, NULL, configDlgProc);
}

(Slave 是插件 DLL 的 HINSTANCE 句柄。)对话框的 proc 如下(我已经剥离了所有功能,因为它似乎对这个问题没有影响):

BOOL CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
 return 0;
}

IDD_CONFIG_WINDOW 的模板如下:

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

当然,proc 函数中没有任何内容,对话框没有任何功能,但在调用 Config 函数时,它仍然显示在 Winamp 中。但是,当我从包装程序调用它时,它不会出现。当我在其 proc 函数中监视发送到对话框的消息时,我看到 WM_DESTROY 和 WM_NCDESTROY 是在前几条消息中发送的,但我不知道为什么。

如果我更改 Config 函数以显示插件的 About 对话框而不是其配置对话框,Winamp 我的包装器 都会显示 About 对话框,这表明导致问题的配置对话框模板有一些独特的东西。修改后的 Config 函数如下所示:

void Config(HWND hwndParent) {
    DialogBox(slave, (const char *) IDD_ABOUTBOX, NULL, configDlgProc);
}

关于对话框的模板如下:

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

就像我说的,我的包装器可以很好地显示“关于”对话框,Winamp 也是如此。为什么 Winamp 可以显示 Config 对话框,而我的 wrapper 不能?

【问题讨论】:

    标签: c++ c windows dialog


    【解决方案1】:

    也许您还没有注册 Trackbar 控件的 WNDCLASS?您必须先加载公共控件 DLL,然后才能对其进行实例化。

    我专门看这一行:

     CONTROL         "Slider2",IDC_PRISLIDER,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,74,90,108,11
    

    编辑:您需要在程序启动期间与 comctl32.lib 链接并调用 InitCommonControlsEx

    【讨论】:

    • 耶!!!使用 Code::Blocks 它一直说 InitCommonControlsEx 没有被声明(即使在与 comctl32 链接并包括 commctrl.h 时)但我尝试了普通的旧 InitCommonControls 并且它有效!如果有人偶然知道如何解决 InitCommonControlsEx 未声明的问题,那也很好,但至少修复了显示停止器,我终于可以继续我的包装器了!
    • 是否取决于“#include ”是在“#include ”之前还是之后?
    • 如果 出现在 之后,我只会得到一个未声明的错误。如果 包含在 之前,我会收到 50 多个错误。 (诸如“DWORD 未命名类型”或“HINSTANCE 未命名类型”之类的内容。)
    • 我在这里找到了解决问题的方法:invisionfree.com/forums/CPPlearningcommunity/ar/t2899.htm 这些说明适用于 Dev-C++,但它们也适用于 Code::Blocks。
    • 是的,您需要将 WINVER 定义为至少 0x0500,因为 MSDN 说该功能是在 Win2000 中引入的。我对使用 InitCommonControls 非常谨慎,因为 MSDN 说从 Common Controls 6.0 开始,它什么都不做,您必须使用 InitCommonControlsEx。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    相关资源
    最近更新 更多