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:
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.
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
.
上一篇: 如何在MFC中的对话框中阻止鼠标输入