从资源生成的C ++ / Win32对话框不正常运行

我为(无模式)对话框编写了一个资源脚本,该对话框应包含一个编辑控件(用于显示非编辑日志报告):

IDD_LOG DIALOGEX 10, 10, 300, 200, 0
STYLE WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_BORDER | WS_SYSMENU | DS_CENTER
CAPTION "Last Log Report"
{
    EDITTEXT 301, 0, 0, 250, 180, WS_VISIBLE | WS_CHILD | WS_VSCROLL | ES_MULTILINE | ES_READONLY
}   

当我通过使用菜单调用对话框时

hwndLogDlg = CreateDialog(NULL, MAKEINTRESOURCE(IDD_LOG), hwnd, (DLGPROC)LogDlgProc)

以下的事情是不正确的:

  • 对话框窗口包含一个编辑控件,但是还有另一个编辑控件,其大小相同。 该编辑控件似乎是非子窗口。 另外,当我在编辑控件中设置调用SetDlgItemText(hwndLogDlg, IDDE_LOGTXT, "<Could not load log data>");的文本时SetDlgItemText(hwndLogDlg, IDDE_LOGTXT, "<Could not load log data>"); ,他们都被设置。
    尽管设置了WS_CHILD,但我怀疑资源编译器会将该脚本中的编辑控件看作对话框的子对象,并将其作为单独的窗口再次查看。
  • 当创建对话框时主窗口被阻止,尽管对话框是无模式的。
  • 即使我调用DestroyWindow(hwndDlg);单击对话窗口的关闭按钮也不会导致它关闭DestroyWindow(hwndDlg); 在WM_QUIT和WM_DESTROY上。 再加上主窗口被阻塞的问题,我关闭所有内容的唯一方法是关闭任务栏或任务管理器的窗口。
  • 消息循环:

    while(GetMessage(&Msg, NULL, 0, 0) > 0) {
        if (!IsDialogMessage(hwndDlg, &Msg)){
            TranslateMessage(&Msg); 
            DispatchMessage(&Msg);
        }
    }
    

    对话窗口程序:

    INT_PTR CALLBACK LogDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam){
    switch (message){
        case WM_INITDIALOG:{
            hwndLogTxt = GetDlgItem(hwndDlg, IDDE_LOGTXT);
    
            fileHandler fH;
            if (!fH.init("report.log")){
                SetDlgItemText(hwndLogTxt, IDDE_LOGTXT, "<Could not load log data>");
                err(ERR_CUSTOM,"Failed to extract log file!","Extraction Error!");
            }
            else SetDlgItemText(hwndLogTxt, IDDE_LOGTXT, fH.getStr());
            break;
        }
        case WM_DESTROY:{
            DestroyWindow(hwndDlg);
            break;
        }
    }
    return true;
    }
    

    所以我最终想得到的是一个无模式的对话框,它包含一个(只读)编辑控件(占用对话窗口的所有客户区)。 这个问题是关于我的资源语法还是关于我称之为的方式? 我是否可能错过了WM_INITDIALOG上的必要步骤?


    一些评论:

    a)我想你在调用CreateDialog()实际使用了LogDlgProc ? 你也有ShowWindow(hwndDlg, SW_SHOW); CreateDialog()

    b)你的EDITTEXT控件是在资源文件中用一个数字作为id声明的,你的逻辑使用IDDE_TXT - 将你的对话资源改为EDITTEXT IDDE_TXT...

    c)更改代码以将您的编辑控件设置为SetDlgItemText(hwndDlg, IDDE_TXT, ...); ; 确保fH.getStr()返回正确的字符串值

    d)必要时从它读取后关闭fH (取决于fileHandler的实现方式)

    e)未处理的消息返回FALSE

    f)在调用DestroyWindow之前,您不会得到WM_DESTROY ,我认为处理IDCANCEL应该足够了

    你的对话过程应该看起来像

    INT_PTR CALLBACK LogDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {   switch (message)
        {   case WM_INITDIALOG:
            {   fileHandler fH;
                if (fH.init("report.log"))
                {   SetDlgItemText(hwndDlg, IDDE_TXT, fH.getStr());
                    // close fH
                }
                else
                {   SetDlgItemText(hwndDlg, IDDE_TXT, "<Could not load log data>");
                    err(ERR_CUSTOM,"Failed to extract log file!","Extraction Error!");
                }
                return TRUE;
            }
    
            case WM_COMMAND: 
                if (LOWORD(wParam) == IDCANCEL) 
                {   DestroyWindow(hwndDlg);
                    return TRUE;
                }
    //EDIT start
                if (HIWORD(wParam) == EN_SETFOCUS && LOWORD(wParam) == IDDE_TXT)
                {   SendDlgItemMessage(hwndDlg, IDDE_TXT, EM_SETSEL, -1, -1);
                    return TRUE;
                }
    //EDIT end
    
        }
        return FALSE;
    }
    

    通常,从对话框proc返回FALSE以获得默认处理。

    逻辑上返回值的一些消息是特殊的。 您可以使用<windowsx.h>SetDlgMsgResult宏来正确处理这些特殊情况。 或者你现在可以忽略它们。

    另外,我怀疑你不应该调用DestroyWindow

    链接地址: http://www.djcxy.com/p/39263.html

    上一篇: C++/Win32 dialog generated from resource not behaving normally

    下一篇: CRichEditCtrl selects all text when it gets focus