从资源生成的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
。
上一篇: C++/Win32 dialog generated from resource not behaving normally