12.对话框和对话框类CDialog(2)

2019-02-15 22:03

UINT message, PARAM, LPARAM) {

if (message == WM_INITDIALOG) {

//处理WM_INITDIALOG消息

CDialog* pDlg = DYNAMIC_DOWNCAST(CDialog, CWnd::FromHandlePermanent(hWnd)); if (pDlg != NULL)

return pDlg->OnInitDialog(); else return 1; }

return 0; }

由上可以看出,MFC的对话框函数AfxDlgProc仅处理消息WM_INITDIALOG,其他都留给对话框窗口过程处理。因此,它不同于SDK编程的对话框过程。程序员在SDK的对话框过程处理消息和事件,实现自己的对话框功能。

AfxDlgProc处理WM_INITDIALOG消息时调用虚拟函数OnInitDialog,给程序员一个机会处理对话框的初始化。

2. 模式对话框窗口过程

本小节讨论对话框的窗口过程。

AfxWndProc是所有的MFC窗口类使用的窗口过程,它取代了模式对话框原来的窗口过程(Windows提供),那么,MFC如何完成Win32下对话框窗口的功能呢?

考查模式对话框的创建过程。CDialog::DoModal用来创建模式对话框窗口并执行有关任务,和DoModal相关的是MFC内部使用的成员函数

CDialog::PreModal和CDialog::PostModal。下面分别讨论它们的实现。 HWND CDialog::PreModal() {

// cannot call DoModal on a dialog already constructed as modeless ASSERT(m_hWnd == NULL);

// allow OLE servers to disable themselves AfxGetApp()->EnableModeless(FALSE); // 得到父窗口

CWnd* pWnd = CWnd::GetSafeOwner(m_pParentWnd, &m_hWndTop);

// 如同CWnd处理其他窗口的创建,设置一个窗口创建HOOK

AfxHookWindowCreate(this); //返回父窗口的句柄

return pWnd->GetSafeHwnd(); }

void CDialog::PostModal() {

//取消窗口创建前链接的HOOK

AfxUnhookWindowCreate(); // just in case //MFC对话框对象和对应的Windows对话框窗口分离 Detach(); // just in case

// m_hWndTop是当前对话框的父窗口或所属窗口,则恢复它

if (::IsWindow(m_hWndTop)) ::EnableWindow(m_hWndTop, TRUE); m_hWndTop = NULL;

AfxGetApp()->EnableModeless(TRUE); }

int CDialog::DoModal() {

// can be constructed with a resource template or InitModalIndirect

ASSERT(m_lpszTemplateName != NULL || m_hDialogTemplate != NULL || m_lpDialogTemplate != NULL); //加载对话框资源

LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate;

HGLOBAL hDialogTemplate = m_hDialogTemplate; HINSTANCE hInst = AfxGetResourceHandle(); //查找资源(见9.5.2节),找到了就加载它 if (m_lpszTemplateName != NULL) {

hInst =

AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG); HRSRC hResource =

::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);

hDialogTemplate = LoadResource(hInst, hResource); }

//锁定加载的资源

if (hDialogTemplate != NULL)

lpDialogTemplate =

(LPCDLGTEMPLATE)LockResource(hDialogTemplate);

// return -1 in case of failure to load the dialog template resource

if (lpDialogTemplate == NULL) return -1;

//创建对话框前禁止父窗口,为此要调用PreModal得到父窗口句柄

HWND hWndParent = PreModal(); AfxUnhookWindowCreate(); CWnd* pParentWnd =

CWnd::FromHandle(hWndParent); BOOL bEnableParent = FALSE; if (hWndParent != NULL

&& ::IsWindowEnabled(hWndParent)) {

::EnableWindow(hWndParent, FALSE); bEnableParent = TRUE; }

//创建对话框,注意是无模式对话框 TRY {

//链接一个HOOK到HOOK链以处理窗口创建, //如同4.4.1节描述的CWnd类窗口创建一样 AfxHookWindowCreate(this); //CreateDlgIndirect间接调用::CreateDlgIndirect,

//最终调用了::CreateWindowEX来创建对话框窗口。

//HOOK过程_AfxCbtFilterHook用子类化的方法 //取代原来的窗口过程为AfxWndProc。 if (CreateDlgIndirect(lpDialogTemplate, CWnd::FromHandle(hWndParent), hInst)) {

if (m_nFlags & WF_CONTINUEMODAL) {

// enter modal loop

DWORD dwFlags = MLF_SHOWONIDLE;

//RunModalLoop接管整个应用程序的消息处理 if (GetStyle() & DS_NOIDLEMSG) dwFlags |= MLF_NOIDLEMSG; VERIFY(RunModalLoop(dwFlags) == m_nModalResult); }


12.对话框和对话框类CDialog(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:开放性试题测试

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: