C++/Win32 dialog generated from resource not behaving normally

I wrote a resource script for a (modeless) dialog that should contain an edit control (used to show a non-edit log report):

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
}   

When I call up the dialog via the menu using

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

the following things are not right with it:

  • The dialog window contains an edit control, but there's another edit control with the same size above it all. That edit control seems to be a non-child window. Also, when I set the text in the edit control calling SetDlgItemText(hwndLogDlg, IDDE_LOGTXT, "<Could not load log data>"); , both of them are set.
    I suspect the resource compiler to see the edit control in the script as both a child of the dialog box and a second time as a separate window, although WS_CHILD is set.
  • The main window is blocked when the dialog is created, although the dialog is modeless.
  • Clicking the closing button of the dialog window won't cause it to close, even though I call DestroyWindow(hwndDlg); on WM_QUIT and WM_DESTROY. Together with the problem of the main window being blocked, the only ways for me to close everything is to close the window from the taskbar or taskmanager.
  • Message loop:

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

    Dialog window procedure:

    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;
    }
    

    So what I would like to get in the end, is a modeless dialog box containing a (read-only) edit control (that takes up all of the client-area of the dialog window). Is this problem about my resource syntax or about the way I call it? May I even have been missing necessary steps on WM_INITDIALOG?


    Some comments:

    a) I suppose you actually used LogDlgProc in your call to CreateDialog() ? do you also have ShowWindow(hwndDlg, SW_SHOW); after CreateDialog() ?

    b) your EDITTEXT control is declared in the resource file with a number as the id, your logic uses IDDE_TXT -- change your dialog resource to have EDITTEXT IDDE_TXT...

    c) change the code to set your edit control to SetDlgItemText(hwndDlg, IDDE_TXT, ...); ; make sure that fH.getStr() returns the correct string value

    d) close fH after reading from it if necessary (depending on how fileHandler is implemented)

    e) return FALSE for unhandled messages

    f) you won't get a WM_DESTROY until you call DestroyWindow , I think handling IDCANCEL should be enough

    Your dialog proc should look like

    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;
    }
    

    In general, return FALSE from the dialog proc to get default processing.

    Some messages that logically return a value are however special-cased. You can use the SetDlgMsgResult macro from <windowsx.h> to handle those special cases correctly. Or you can just ignore them for now.

    Also, I suspect you should not call DestroyWindow .

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

    上一篇: 如何在MFC中的对话框中阻止鼠标输入

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