Mfc获取模态对话框列表 [英] Mfc get modal dialog list

查看:123
本文介绍了Mfc获取模态对话框列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我正在使用MFC进行单元测试。我的软件是SDI。



我有2个线程:第一个是图形线程,第二个是重现用户行为的单元测试程序。当没有模态对话框时,它运行良好,我使用SendMessage(模拟点击按钮,或更改文本等),直到消息被处理为止,因此我没有任何同步问题。



但是当按钮打开Modal CDialog时,我无法使用SendMessage,因为只要打开模态对话框,单元测试线程就会被阻止。所以我使用PostMessage和Sleep。现在我的问题是得到当前打开的CDialog的指针。



我尝试过:



这是单元测试的代码



Hi,

I am working on unit test with MFC. My software is a SDI.

I have 2 threads : the first one is the graphic thread and the second one a unit test procedure which reproduce a user behavior. It is working well when there isn't modal dialog, I use SendMessage (to simulate click on button, or change text, etc.) which is blocking until the message has been treated so I haven't any sync issue.

But when the button opens a Modal CDialog I can't use SendMessage because the unit test thread is going to be blocked as long as the modal dialog is opened. So I use PostMessage and Sleep. And now my problem is to get the pointer of the current opened CDialog.

What I have tried:

Here is the code of the unit test

bool UnitTestBoite()
{
   // Here I am in unit test thread
   CFrameWnd *pMainFrame = (CFrameWnd *)AfxGetMainWnd();
   // Post Message to notify the button ID_INSERER_BOITE is clicked
   pMainFrame->PostMessageW(WM_COMMAND, MAKELONG(ID_INSERER_BOITE, 0), 0);
   // In the handler of ID_INSERER_BOITE
   // there is something like CDialog dlg(pMainFrame, IDD_BASE_BOITE); dlg.DoModal();
   Sleep(1000);
   UINT myModalTemplateId = IDD_BASE_BOITE;
   ...





要获得模态对话框指针我试过:



To get modal dialog pointer I tried :

CWnd* pChild = pMainFrame->GetWindow(GW_CHILD);
while (pChild != nullptr)
{
    // Retrieve template ID
    UINT nResourceId = GetWindowLong(pChild->GetSafeHwnd(), GWL_ID);
    if (nResourceId == myModalTemplateId )
        break;
    pChild = pChild->GetWindow(GW_HWNDNEXT);
}
if (pChild == nullptr)
    return false;






or

HWND hwndForeGround = ::GetForegroundWindow();
// Retrieve template ID
UINT nResourceId = GetWindowLong(hwndForeGround, GWL_ID);
if (nResourceId != myModalTemplateId )
   return false;






or

CWnd *pModal = pMainFrame_->GetForegroundWindow();
  // Retrieve template ID
  UINT nResourceId = GetWindowLong(pModal->GetSafeHwnd(), GWL_ID);
  if (nResourceId != myModalTemplateId )
     return false;



这些代码片段都没有工作......我想到的最后一个解决方案是让我的所有CDialog类继承自自定义类和注册所有打开的CDialog,但它有点侵入...是否有优雅意味着这样做?



感谢阅读,卢卡斯。


None of these code snippet worked... The last solution I have thought was to make all my CDialog classes inherits from a custom class and register all opened CDialog, but it is a bit invasive... Is there an "elegant" means to do that ?

Thank for reading, Lucas.

推荐答案

您的第一次尝试将无效,因为您正在寻找一个模式对话框,其样式为 WS_POPUP

弹出窗口不能包含样式 WS_CHILD



Folowing code不会返回对话框模板ID(对于弹出窗口),它返回子窗口的控件ID(包括子对话框的对话框模板ID)

该字段用于弹出窗口的菜单资源ID,所以如果你的模态对话框有没有任何菜单,那么该功能将返回0



Your first attempt will not work because , you looking for a modal dialog , which has a style of WS_POPUP
A popup window can not contain a style of WS_CHILD

Folowing code will not return dialog template ID (for popup windows), it returns control ID for child windows (including dialog template ID of child dialogs)
That field is used for menu resource ID for popup windows , so if your modal dialog has not got any menu then that function will return 0

GetWindowLong(hwndForeGround, GWL_ID);





GetLastActivePopup函数(Windows) [ ^ ]可以用来获取最后一个弹出窗口,但你仍然无法通过模板ID来识别该对话框,即使你会找到一个CDialog类



您已经将它用于测试目的,您可以比较窗口标题以确保找到您要查找的对话框



以下代码应该有帮助





GetLastActivePopup function (Windows)[^] can be used to get last popup window but you still can not idetify that dialog by Template ID , even if you will find a CDialog class

you will already use this for testing purpose ,you can compare window title to ensure that you found the dialog you looking for

following code should help

CFrameWnd *pMainFrame = (CFrameWnd *)AfxGetMainWnd();
if(pMainFrame)
{
	CWnd *pWnd = pMainFrame->GetLastActivePopup();
	if(pWnd)
	{
		if(pWnd->IsKindOf(RUNTIME_CLASS(CDialog)))
		{
			CDialog *pDialog = reinterpret_cast<cdialog*>(pWnd);
			if(pDialog)
			{
				CString strTitle;
				pDialog->GetWindowText(strTitle);
				
				if(strTitle.CompareNoCase(_T("My Dialog")) == 0)
				{
					//we found dialog ,dismiss it
					pDialog->EndDialog(0);	
				}
			}
		}
	}
}


这篇关于Mfc获取模态对话框列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆