flyfish
OnOK OnCancel EndDialog的关系
VC\atlmfc\src\mfc\dlgcore.cpp文件中
void CDialog::OnOK() { if (!UpdateData(TRUE)) { TRACE(traceAppMsg, 0, "UpdateData failed during dialog termination.\n"); // the UpdateData routine will set focus to correct item return; } EndDialog(IDOK); } void CDialog::OnCancel() { EndDialog(IDCANCEL); } void CDialog::EndDialog(int nResult) { ASSERT(::IsWindow(m_hWnd)); if (m_nFlags & (WF_MODALLOOP|WF_CONTINUEMODAL)) EndModalLoop(nResult); ::EndDialog(m_hWnd, nResult); }
消息路由是
OnOK-》EndDialog
OnCancel-》EndDialog
用户点击确定或者取消按钮时收到两个消息IDOK或IDCANCEL,执行OnOK或者OnCancel,然后调用函数EndDialog来结束对话框。
win32应用程序的退出
// 主消息循环: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 分析菜单选择: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: 在此添加任意绘图代码... EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }
1 程序运行的过程中,不断以GetMessage从消息队列中抓取消息。如果这个消息是WM_QUIT,GetMessage会传回0而结束while循环,进而结束整个程序。
2 DestroyWindow 发送 WM_DESTROY消息
3 程序对WM_DESTROY的标准反应是调用PostQuitMessage。
4 PostQuitMessage发送WM_QUIT消息,准备让消息循环中的GetMessage取得这消息,结束消息循环。
消息路由是
DestroyWindow-》WM_DESTROY-》PostQuitMessage-》WM_QUIT
点击标题栏关闭按钮时发送WM_CLOSE 消息,WM_CLOSE 消息调用 DestroyWindow 函数.
消息路由是
WM_CLOSE-》DestroyWindow
在线程中退出应用程序
在基于对话框程序中,创建一个线程 AfxBeginThread(ProcessThread,this); 线程函数 UINT CXDlg::ProcessThread(LPVOID pParam) { CXDlg *pDlg=static_cast<CXDlg*>(pParam); if (NULL==pDlg)return 1; //这里调用退出函数 }
退出函数无论执行OnOK(),OnOK()或者PostQuitMessage(0); 应用程序都没有退出
在线程中传递的是窗口指针,而不是窗口句柄
while (GetMessage( lpMsg, hWnd, 0, 0)) 相当于hWnd是无效的
PostQuitMessage函数发送一个WM_QUIT消息到线程消息队列并且立即返回.该函数简单的通知系统线程请求马上退出
GetMessage中的参数hWnd是无效的窗口句柄或lpMsg是空指针时。GetMessage返回值是-1。
所以需要获取句柄,调用AfxGetMainWnd()->SendMessage(WM_CLOSE);