分享
 
 
 

基于 CDialog 的应用程序一开始便被隐藏的方法

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

基于 CDialog 的应用程序一开始便被隐藏的方法

作者: Solomon (lsong@kali.com.cn)

日期: 2001/12/29

相关文章: http://www.csdn.net/develop/article/11/11634.shtm

要使一个基于 CDialog 的应用程序一开始便被隐藏的方法有好多种。大多数方法在相关文章(http://www.csdn.net/develop/article/11/11634.shtm)中已经提及。本人之所以要写这篇文章,主要是通过分析MFC 调用模式对话框的方法向大家展示一种简单,合理,完满的解决方案。

首先,用MFC 生成的一个基于对话框的应用程序框架,然后修改对话框资源的Visible属性使之成为不可见(在属性页的MoreStyle中),接着按下F5 来运行这个程序,我们会发现,它并不象我们期望的那样一开始就被隐藏。而是被显示了出来。那么为什么会这样呢?特别是精通SDK的朋友们,会对此百思不得其解。

其实,MFC框架为了显示对话框很多工作,它并不简简单单地调用DialogBox显示对话框,而是使用了相对复杂的方法。现在,我就来引导大家对此探个究竟。

在生成的应用程序框架中(名称为Test),你会看到CTestApp和CTestDlg 两个类,在CTestApp的InitInstance方法中有如下语句:

CTestDlg dlg;

m_pMainWnd = &dlg;

int nResponse = dlg.DoModal(); // 此处将创建并显示对话框

DoModal 是一个虚函数,MFC允许用户编写自己的调用对话框方式来替代原来的方式。但是,MS实在令人失望。如果,你打开 DlgCore.Cpp (MFC Source 目录下)并复制DoModal 的代码到你自己的类中,你会发现无法编译成功。原因在于MS在DoModal中使用了两个非输出函数AfxHookWindowCreate 和AfxUnhookWindowCreate。(这两个函数的作用超出了本文所讨论的范围,因此不作详细论述。)由于无法编译,所以MS 要求用户的 DoModal 必须调用CDialog的DoModal来显示对话框。这样,控制隐藏就无法通过重载DoModal实现了。那么MS在DoModal中干了什么呢?下面就是一部分代码。

int CDialog::DoModal()

{

...... 读入资源,并作一些设置

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);//进入消息循环

}

.......

}

}

...... 释放资源等

}

原来,DoModal 并不使用 DialogBox 直接调出对话框,而是通过创建无模式对话框并维护消息循环的方式(RunModalLoop)来模拟模式对话框的效果。(看起来好像有点像DialogBox 的内部作业方式)MLF_SHOWONIDLE 是什么?看英文的意思是在Idle 的时候ShowWindow。那么是不是这样呢?好吧,为了探个究竟,让我们进入RunModalLoop。RunModalLoop在WinCore.CPP中定义。打开WinCore.CPP 并找到 RunModalLoop, 会看到以下的语句

BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);

条件dwFlags & MLF_SHOWONIDLE 始终为TRUE。 而!(GetStyle() & WS_VISIBLE)只有在WS_VISIBLE属性没有设置的时候才会为 TRUE。这样,当我们去掉Visible 属性后bShowIdle就为 TRUE 了。再往下,就会看到以下的调用

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;//指示下一次Idle 时不用显示对话框了

}

While 里的条件是消息队列里再也没有任何消息了。此时,由于bShowIdle为TRUE,就会调用ShowWindow来显示对话框。由于ShowWindow只执行一次,所以如果能截获第一次WM_SHOWWINDOW消息, 就能控制了隐藏了。

是的。在CTestDlg处理 WM_SHOWWINDOW并添上以下代码

void CTestDlg::OnShowWindow(BOOL bShow, UINT nStatus)

{

if( GetStyle() & WS_VISIBLE ) {

CDialog::OnShowWindow(bShow, nStatus);

} else {

long Style = ::GetWindowLong(*this, GWL_STYLE);

::SetWindowLong(*this, GWL_STYLE, Style | WS_VISIBLE);

CDialog::OnShowWindow(SW_HIDE, nStatus);

}

}

再运行一下,哈哈,对话框不见了,连闪都不闪一下。细心的读者也许会问为什么使用SetWindowLong,而不是 ModifyStyle, 其实是为了加快速度,因为ModifyStyle内部还要调用GetWindowLong和SetWindowPos。到此为止,一个简单,完满的解决方法已经展现在大家面前了。

其实,本来MS可以做的更好,比如把GetStyle()声明为虚函数,使得我们能返回WS_VISIBLE 来控制bShowIdle成为 FALSE, 或者把

DWORD dwFlags = MLF_SHOWONIDLE;

改成

DWORD dwFlags = ShowOnIdle(); // 声明为虚函数

希望MS能在以后的版本中考虑这个问题。

这是本人在CSDN上的第一个作品,希望大家能多提宝贵意见。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有