Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 拦截创建对话录_Windows_User Interface_Mfc_Cdialog - Fatal编程技术网

Windows 拦截创建对话录

Windows 拦截创建对话录,windows,user-interface,mfc,cdialog,Windows,User Interface,Mfc,Cdialog,我有一个相当大的应用程序,可以显示许多不同的MFC CDialog派生的对话框窗口。所有对话框均通过与以下类似的中心功能显示: void ShowDialog(CDialog& dlg) { dlg.DoModal(); } 现在我需要在每个对话框的OnInitDialog方法中调用一个函数。从技术上讲,它不需要在OnInitDialog中,但最好是在对话框可见之前 蛮力方法将遍历代码,找到最后的每个对话框,并将函数调用添加到OnInitDialog方法(如果有,如果没有,则添加一

我有一个相当大的应用程序,可以显示许多不同的MFC CDialog派生的对话框窗口。所有对话框均通过与以下类似的中心功能显示:

void ShowDialog(CDialog& dlg)
{
  dlg.DoModal();
}
现在我需要在每个对话框的OnInitDialog方法中调用一个函数。从技术上讲,它不需要在OnInitDialog中,但最好是在对话框可见之前

蛮力方法将遍历代码,找到最后的每个对话框,并将函数调用添加到OnInitDialog方法(如果有,如果没有,则添加一个)。但似乎有一种更优雅的方式

请注意,dlg实际上不是一个CDialog,而是从中派生出来的东西


有什么想法、技巧或技巧吗?我并不想修补消息映射,但希望找到更干净/更安全的东西。

如果您的所有对话框都有一个共同的祖先,这似乎意味着您有,那么您可以简单地将代码放在您选择的适当位置的该共同祖先中。例如,
OnInitDialog()
是虚拟的。

事实证明,这很容易做到:

HHOOK gPrevHook = SetWindowsHookEx(WH_CALLWNDPROCRET, HookProc, NULL, myGUIThreadID);


LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if(NULL != wParam)
    {
         CWPRETSTRUCT* pS = (CWPRETSTRUCT*)lParam;
         if(WM_INITDIALOG == pS->message)
             CallFuncOnWindow(pS->hwnd);
    }

    return CallNextHookEx(gPrevHook, nCode, wParam, lParam);
}

对于一个高性能的应用程序来说,这可能不是一件需要做的事情,但是对于一个简单的GUI来说,它可以完美地工作。不需要其他代码更改。

CDialog是唯一的共同祖先:(@Doug在其中加入了一个共同祖先。这与强力“find all OnInitDialog”方法没有太大区别。我希望能将WM_INITDIALOG重定向到单独的函数(挂钩)或者其他一些技巧,这样我就不必更改所有其他代码。@Doug切换到一个共同祖先是很简单的。无论你从CDialog下到哪里,你都会插入你的共同祖先。我可以向你保证,在未来很长一段时间内,好处是显而易见的!我同意David的观点。也许添加一个共同祖先(CMyDialog)的工作量会很大类似于在每个对话框中添加方法调用。但它在将来会给您带来很多好处。官方术语是“技术债务”。这简直令人震惊。如果用正确的方法来做,会更快!你所要做的就是在课堂上使用正则表达式。*CDialog并用cmycomonanceStor替换CDialog。1小时绝对上限。从那以后,你将受益匪浅。只不过这不会处理所有没有实现OnInitDialog的对话框。而且它也不会处理没有实现OnInitDialog的对话框我还没有一个基类,在他们的OnInitDialog中调用base::OnInitDialog。任何遗漏的情况都是bug。这是7行不会遗漏任何内容的代码,不依赖于人类记住从基类派生未来的代码,等等。如果这是一个“拦截框架”,将会有关于它的文章:)CDialog引入了OnInitDialog。不调用base OnInitDialog已经是一个错误。你的设计很差。复杂、不透明、不必要。你已经放弃了亲吻,让它变得复杂。OnInitDialog是虚拟的,而不是纯粹的虚拟。如果它只调用基类,那么调用它是不必要的,也是愚蠢的。我看不出7行代码比将一个新类引入现有类继承权并需要数百行更改更复杂,其中大多数更改是编译器无法验证的。