【问题标题】:winapi dialogbox doesn't showwinapi 对话框不显示
【发布时间】:2014-06-04 12:02:09
【问题描述】:

我的对话框有问题,当我调用函数“DialogBoxA”时,对话框没有出现。我只得到“忙碌光标”,光标也被困在一个小矩形(对话框的大小)内。按下(几乎)任何按钮后,它就会神奇地出现。

对话框调用

DialogBoxA(hInstance,MAKEINTRESOURCEA(IDD_ORACLE_DIALOG),0,reinterpret_cast<DLGPROC>(DlgProc));

对话框资源代码

IDD_ORACLE_DIALOG DIALOGEX 0, 0, 155, 71
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,43,50,50,14
    PUSHBUTTON      "Cancel",IDCANCEL,98,50,50,14
    COMBOBOX        IDC_COMBOSERVER,53,6,94,30,CBS_DROPDOWN | CBS_SORT | CBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
    EDITTEXT        IDC_EDITLOG,54,25,94,14,ES_AUTOHSCROLL
    LTEXT           "Server",IDC_STATIC,7,7,47,13
    LTEXT           "Log",IDC_STATIC,7,25,47,13
END

DialogProc

LRESULT CALLBACK DlgProc(HWND hWndDlg, UINT Msg, WPARAM wParam,LPARAM lParam){
    switch(Msg){
    case WM_INITDIALOG:
        for(auto it = vServerList.begin();it!=vServerList.end();++it){
            SendMessageA(GetDlgItem(hWndDlg,IDC_COMBOSERVER),CB_ADDSTRING,0,reinterpret_cast<LPARAM>(it->c_str()));
        }
        if(vServerList.size()>0){
            SendMessage(GetDlgItem(hWndDlg,IDC_COMBOSERVER),CB_SETCURSEL,0,0);
            SendMessage(GetDlgItem(hWndDlg,IDC_EDITLOG),WM_NCLBUTTONDOWN,HTCAPTION,0);
        }else{
            SendMessage(GetDlgItem(hWndDlg,IDC_COMBOSERVER),WM_NCLBUTTONDOWN,HTCAPTION,0);
        }
#ifdef _DEBUG
        SendMessageA(GetDlgItem(hWndDlg,IDC_EDITLOG),WM_SETTEXT,0,reinterpret_cast<LPARAM>("q40log"));
#endif
        return TRUE;
    case WM_COMMAND:
        switch(wParam){
        case IDOK:
            size_t tServer,tLog;
            tServer = GetWindowTextLength(GetDlgItem(hWndDlg,IDC_COMBOSERVER))+1;
            tLog = GetWindowTextLength(GetDlgItem(hWndDlg,IDC_EDITLOG))+1;
            char *pszServer,*pszLog;
            pszServer = static_cast<char*>(calloc(tServer,sizeof(char)));
            pszLog = static_cast<char*>(calloc(tLog,sizeof(char)));
            GetDlgItemTextA(hWndDlg,IDC_COMBOSERVER,pszServer,tServer);
            GetDlgItemTextA(hWndDlg,IDC_EDITLOG,pszLog,tLog);
            szServer = pszServer;
            szUser = pszLog;
            free(pszServer);
            free(pszLog);
            EndDialog(hWndDlg,0);
            return TRUE;
        case IDCLOSE:
        case IDCANCEL:
            EndDialog(hWndDlg,0);
            return FALSE;
        }
        break;
    }
    return FALSE;
}

【问题讨论】:

  • .RC 摘录看起来不错,您的DlgProc 可能是原因。

标签: visual-studio-2010 winapi visual-c++ dialog


【解决方案1】:

明显的故障模式是:

  1. 对话过程有问题。
  2. 对话框资源无效。
  3. 对话框资源链接错误,无法加载。
  4. 实例句柄不正确。

在这些选项中,您在对话过程参数中使用的强制转换,似乎很可能是对话过程有问题。

我希望您添加演员表,因为代码无法编译。而且它不会编译,因为对话过程的签名不正确。演员并没有改变这个事实。这只是您压制编译器并告诉它您比它更了解的一种方式。一般来说,编译器往往是正确的。如果您的对话过程有错误的签名,您需要更正它。参考documentation找出正确的签名。

您的代码的另一个大问题是您忽略了DialogBox 的返回值。如果函数失败,那么文档会告诉您值为 0 或 -1。在这种情况下,您可以调用GetLastError 来获取扩展的错误信息。使用 Win32 API 函数时必须养成检查错误的习惯。

【讨论】:

  • 我刚查了一下,Dialogbox函数调用后没有报错。当然我会用我的 dialogproc 更新我的问题,这样你就可以更清楚我做了什么
  • 这不会使我的建议无效,即您必须始终检查错误。您在 Q 中的代码没有。你必须纠正它。您不会检查代码中任何地方的错误。你只需要这样做。选项 1 看起来像是问题的原因。您似乎也遇到了一些 Unicode 问题。您正在为 UNICODE 进行编译,对吗?在这种情况下,你为什么要调用 ANSI API?
  • 侮辱帮助你和给你建议的人很少可能产生结果。祝你好运。
  • 我很抱歉,这个“看似”普通的简单代码因为无法正常工作而让我感到不安。感谢您的输入,我发现了错误。
  • 你的猜测是正确的,但它与函数签名无关。我将焦点设置到组合框或编辑控件的部分导致了这种“奇怪”的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多