MFC对话框
1分类
模式和非模式
2相关类
CDialog --父类 CWnd
CCommonDialog 通用对话框--父类CDialog
CPropertypage 属性页对话框 --父类CDialog
CpropertySheet类,与CPropertypage一起完成属性页的创建.
3创建基于对话框的应用程序。
1.模式对话框
添加对话框资源,定义相关联的对话框类。
调用CDialog::DoModal函数创建和显示对话框。
通过调用CDialog::OnOk和CDialog::OnCancel关闭对话框。
virtual BOOL OnInitDialog( ); //初始化
2非模式对话框
添加资源,定义相关联的对话框类
创建和显示与一般框架窗口类似。
处理对话框的关闭。 点击关闭按钮与cancel处理函数相同
virtual void OnOK( );
virtual void OnCancel( );
先调用父类的函数再销毁。
DestroyWindow
virtual void PostNcDestroy( ); //最后执行的函数
CWnd::PostNcDestroy
先删除子类再删除父类。
DoModal函数调用
查找对话框资源。
hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);
HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);
hDialogTemplate = LoadResource(hInst, hResource);
将父窗口设置为不可用状态。
HWND hWndParent = PreModal();
AfxUnhookWindowCreate();
BOOL bEnableParent = FALSE;
if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
{
::EnableWindow(hWndParent, FALSE);
bEnableParent = TRUE;
}
创建非模式对话框,进入对话框消息循环。(父窗口不可用)
AfxHookWindowCreate(this);
if (CreateDlgIndirect(lpDialogTemplate,
CWnd::FromHandle(hWndParent), hInst))
{
if (m_nFlags & WF_CONTINUEMODAL)
{
// enter modal loop
DWORD dwFlags = MLF_SHOWONIDLE;
if (GetStyle() & DS_NOIDLEMSG)
dwFlags |= MLF_NOIDLEMSG;
VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
}
// hide the window before enabling the parent, etc.
if (m_hWnd != NULL)
SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|
SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
}
消息循环
int CWnd::RunModalLoop(DWORD dwFlags)
{
ASSERT(::IsWindow(m_hWnd)); // window must be created
ASSERT(!(m_nFlags & WF_MODALLOOP)); // window must not already be in modal state
// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);
HWND hWndParent = ::GetParent(m_hWnd);
m_nFlags |= (WF_MODALLOOP|WF_CONTINUEMODAL);
MSG* pMsg = &AfxGetThread()->m_msgCur;
// acquire and dispatch messages until the modal state is done
for (;;)
{
ASSERT(ContinueModal());
// phase1: check to see if we can do idle work
while (bIdle &&
!::PeekMessage(pMsg, NULL, NULL, NULL, PM_NOREMOVE))
{
ASSERT(ContinueModal());
// show the dialog when the message queue goes idle
if (bShowIdle)
{
ShowWindow(SW_SHOWNORMAL);
UpdateWindow();
bShowIdle = FALSE;
}
// call OnIdle while in bIdle state
if (!(dwFlags & MLF_NOIDLEMSG) && hWndParent != NULL && lIdleCount == 0)
{
// send WM_ENTERIDLE to the parent
::SendMessage(hWndParent, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)m_hWnd);
}
if ((dwFlags & MLF_NOKICKIDLE) ||
!SendMessage(WM_KICKIDLE, MSGF_DIALOGBOX, lIdleCount++))
{
// stop idle processing next time
bIdle = FALSE;
}
}
// phase2: pump messages while available
do
{
ASSERT(ContinueModal());
// pump message, but quit on WM_QUIT
if (!AfxGetThread()->PumpMessage())
{
AfxPostQuitMessage(0);
MFC第十天
最新推荐文章于 2022-02-12 22:12:25 发布