读书人

再次探讨消息循环共存的有关问题(望高

发布时间: 2012-12-16 12:02:32 作者: rapoo

再次探讨消息循环共存的问题(望高手出手)

主窗口--------------------模式对话框,三个按钮,idok, idcancel, idc_button1


前2个按钮点击后,关闭对话框; 后一个按钮,点击后产生一个about对话框(注意,有意用非模式对话框)


目标 :

(1)

当主窗口是模式对话框的时候, 可以验证 文本框可以随意编辑,并做出一些列动作。

证明: 当主窗口是模式的时候, 文本框和主窗口共用一个消息循环!

(2)

当主窗口是模式对话框的时候, 弹出一个非模式about对话框,想看这个非模式对话框是否和主窗口共用一个消息循环。

于是有了这样的代码:


INT_PTR CALLBACK DialogProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{

switch(uMsg)
{
case WM_INITDIALOG:
oldWndProc=SetWindowLong(GetDlgItem(hwndDlg,IDC_EDIT1),GWL_WNDPROC,(LONG)EditProc);

return TRUE;
break;
case WM_CLOSE:
EndDialog(hwndDlg,0);
// DestroyWindow(hwndDlg);
return TRUE;
break;
case WM_COMMAND:
{
WORDnId=LOWORD(wParam);
switch(nId)
{
case IDOK:
case IDCANCEL:
// DestroyWindow(hwndDlg);
EndDialog(hwndDlg,0);
return TRUE;
break;

case IDC_BUTTON1://定位这段代码了, 原因嘛,呵呵,很可能是没有消息循环才不出现这个子窗口的

CreateDialog(hInst,MAKEINTRESOURCE(IDD_ABOUTBOX),hwndDlg,About);
ShowWindow(hwndDlg,SW_SHOW);

return TRUE;

break;

default:
return FALSE;
break;
}
}
break;

case WM_DESTROY:
PostQuitMessage(0);
return TRUE;
default:
return FALSE;
}

return FALSE;
}



整个程序里没有任何getmessage之类的函数, 或许这个原因导致。

我点击按钮,并不会产生我们要看到的about对话框!



是否是以为 主窗口和about对话框没有共用同一个消息循环才导致的?



问题2: 对主对话框的wm_destroy是否需要修改,这个case里进行 destroywindow(about);

然后才是postquitmessage(0); ?



[最优解释]
WM_DESTROY先送到parent,然后送到child,收到这个信息意味着资源正在被释放,一般要做的也就是PostQuitMessage(0);来结束进程,进程结束,一切资源被操作系统回收. 如果主窗口不在了,child窗口也不会存在,所以也就不需要call了,当然有什么资源在手的除外.
[其他解释]
引用:
多谢老师,却是你说的这个问题。

不过一直有个小问题困惑我。

主窗口是一个模式对话框,对吧。

添加资源后,一般来说,对话框资源风格,根本不需要你去修改它,然后你就可以 dialogbox了。

就会弹出,不可能程序执行……


注意看DialogBox和CreateDialog的Remarks部分:

DialogBox:
The function displays the dialog box (regardless of whether the template specifies the WS_VISIBLE style)

CreateDialog:
The function displays the dialog box if the template specifies the WS_VISIBLE style.
[其他解释]
1.
在GetMessage()后面,加上IsDialogMessage()

while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
{
if (!TranslateAccelerator (hwnd, hAccel, &msg))


{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
}

2.
不需要特别摧毁,主线程死了它也死了
[其他解释]
表达有些问题,纠正一下:
问题1:这个非模式对话框和模式对话框主窗口当然是共用一个消息循环
[其他解释]
打开模式对话框最特别的一点是:它内部启动了另一个消息循环,直接取代了原始消息循环(如果有的话)。
[其他解释]
问题1:这个非模式对话框是否和模式对话框的主窗口当然是共用一个消息循环
你那个ShowWindow有问题吧,都不是显示刚创建的非模式对话框


case IDC_BUTTON1:
ShowWindow(CreateDialog(hInst,MAKEINTRESOURCE(IDD_ABOUTBOX),hwndDlg,About),SW_SHOW);


问题2:同楼上
[其他解释]
引用:
表达有些问题,纠正一下:
问题1:这个非模式对话框和模式对话框主窗口当然是共用一个消息循环


多谢老师,却是你说的这个问题。

不过一直有个小问题困惑我。

主窗口是一个模式对话框,对吧。

添加资源后,一般来说,对话框资源风格,根本不需要你去修改它,然后你就可以 dialogbox了。

就会弹出,不可能程序执行后,对话框是最小化状态。

让我很费解。

不知道是不是机子的故障导致的。


[其他解释]
引用:
1.
在GetMessage()后面,加上IsDialogMessage()

while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlgModeless == 0 || !IsDialogMessage (hDlgModeless, &msg))
{
if (!T……



老师很明显你用错了,主窗口是模式对话框。 呵呵 不过这不是大问题,因为楼下的网友已经帮我解决了。


翻过一些资料了,对sdk,非mfc的子控件,采用createwindow的方式创建的,

那么是否需要处理wm_destroy?

在什么地方处理, 肯定不是在自己的处理函数处理,

可能会在父窗口的处理函数里处理。

如果不destroywindow(子窗口),

到底会不会有什么问题?

这个问题, 请教过好多高手, 似乎都说,不需要程序员处理, 只需要处理主窗口即可。


如果是mfc的,似乎也不需要处理,要处理的是记得别内存泄露即可。
比如一个文本框,是dynamic create出来的,可以在父窗口中释放内存即可,

不需要再destroywindow(文本框)



读书人网 >VC/MFC

热点推荐