65.9K
CodeProject 正在变化。 阅读更多。
Home

如何更改 MessageBox 窗口(添加控件并更改文本)?

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.52/5 (20投票s)

2005年4月6日

CPOL

4分钟阅读

viewsIcon

122230

downloadIcon

5768

本文描述了如何更改 MessageBox 窗口(添加控件和更改文本)。

Sample Image - dMsgBox.jpg

引言

在本文中,我们将学习如何向 MessageBox 添加控件或更改其按钮文本。您可以使用此方法创建(完整的)多语言程序(只是一个建议!)。有几种方法可以做到这一点,我选择了钩子方法。

钩子 MessageBox 的步骤

钩子 MessageBox

  • 使用 SetWindowsHookEx () 函数,参数为 WH_CALLWND,并将其传递给 hookproc。
  • 声明一个钩子过程。
  • 在 hookproc 中,使用 SetWindowLong () 函数来处理 MessageBox 窗口创建过程(也许这是一个好名字)。
  • 声明一个 CALLBACK 函数来处理 MessageBox 窗口创建过程。
  • CALLBACK 函数作为 SetWindowLong () 函数的 new long 参数传递。
  • 最后,将您的代码放在 CALLBACK 函数中(用于窗口创建的代码)。

SetWindowsHookEx() 函数

此函数安装一个钩子过程。使用此函数,您可以钩住窗口事件。换句话说,当您安装钩子过程时,您就是在告诉系统在调用所需事件时通知您。

根据 MSDN 的说法: SetWindowsHookEx 函数将应用程序定义的钩子过程安装到钩子链中。您会安装一个钩子过程来监视系统中的某些类型的事件。这些事件与特定线程或与调用线程的同一个桌面中的所有线程相关。

如何使用 SetWindowsHookEx() 函数安装钩子过程?

g_hHook = SetWindowsHookEx (WH_CALLWNDPROC,
                               (HOOKPROC)SetHook,
                               NULL,
                               GetCurrentThreadId ());

其中 g_hHook 是一个全局变量,SetHook 是我的 HookProc;

什么是 WH_CALLWNDPROC?

使用此参数安装一个钩子过程,该过程在系统将消息发送到目标窗口过程之前监视消息(MSDN)。

声明 HookProcedure

在您的头文件中使用以下声明

LRESULT CALLBACK SetHook(int nCode,WPARAM wParam,LPARAM lParam);

这将声明一个名为 SetHook 的钩子过程。请参阅此代码片段

LRESULT CALLBACK SetHook(int nCode,WPARAM wParam,LPARAM lParam)
{
if (nCode==HC_ACTION)
{
    CWPSTRUCT* pwp = (CWPSTRUCT*)lParam;
    
    if (pwp->message==WM_INITDIALOG)
        
    oldProc=(WNDPROC)SetWindowLong(pwp>hwnd,
GWL_WNDPROC,(LONG)HookWndProc); 
}
return CallNextHookEx(g_hHook,nCode,wParam,lParam);
}

此代码片段是我的 SetHook 过程。

什么是 GWL_WNDPROC?

此参数为窗口过程设置新的地址。(我认为这足够了)。

什么是 CWPSTRUCT?

这是一个结构,包含有关窗口消息的信息,例如窗口的句柄(hwnd)。我们传递该结构的指针以在回调函数中使用 hwnd 成员。

HookWndProc 是一个处理窗口创建代码的函数。

处理窗口创建过程

为此,您必须声明一个 CALLBACK 函数。

LRESULT CALLBACK HookWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);

这是我的 HookWndProc 过程。

LRESULT CALLBACK HookWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    //Let OS to perform basic operation
    LRESULT rc = CallWindowProc( oldProc, hWnd, uMsg, wParam, lParam );

    //If MessageBox wanted to initialized, do something
    if (uMsg==WM_INITDIALOG)
    {
        if (m_hIcon)
            SetIcon(hWnd,m_hIcon);
            CreateButton(hWnd);    

        if (m_strCaption)
            SetCaption(hWnd);
    }
    if (uMsg==WM_COMMAND&&wParam==IDC_CHECKBOX)
        //If user clicked the check box handle it!
        SetOut(wParam);
    if (uMsg==WM_NCDESTROY)
        //On exit Uninstall the hook procedure
        //If we don't do that every message box will have 
        //A check box on it!
        UnInstallHook(g_hHook);
return rc;
}

主要操作已完成。我的意思是 hwnd。在获得此 hwnd 后,我们可以对 MessageBox 窗口执行任何操作。但别忘了调用 CallWindowProc 函数。

CallWindowProc 是做什么的?

根据 MSDN: CallWindowProc 函数将消息信息传递给指定的窗口过程。

我使用此函数是因为我不想自己绘制 MessageBox 窗口,而只想更改一些文本。如果您想绘制主窗口,我认为您不应该调用此函数!

有关 SetWindowsHookExSetWindowLongCallWindowProc 的更多信息,请使用 MSDN Library。(我认为这是最好的参考资料)。

最后,我想提醒您:调用 CallNextHookEx () 函数,因为如果您不这样做,其他可能已安装钩子链的应用程序将不会收到钩子信息,我知道您不希望这样。

像往常一样,根据 MSDN 的说法:调用 CallNextHookEx 函数链接到下一个钩子过程是可选的,但强烈推荐;否则,已安装钩子的其他应用程序将收不到钩子通知,并可能因此行为不当。您应该调用 CallNextHookEx,除非您绝对需要阻止其他应用程序看到通知。

最后的话

首先,我要感谢 Nicolas Bonamy 先生。他的文章对我帮助很大。

有一个演示应用程序,如果您愿意,可以下载。在该项目中,我有一个类,其中包含一些用于向 MessageBox 添加 CheckBox、更改按钮文本以及用于将控件放置在正确且良好位置的一些函数。

我想说我的英语不太好,这也是我写一些函数 MSDN Library 定义的原因(请原谅我的糟糕语法)。

最后,我建议您使用 Visual Assist X,因为它是一个非常有用的 Visual Studio 插件。

如果您觉得本文有趣且信息丰富,请投我一票。欢迎提出意见和评论。

G.K.Z - King Zoser。

© . All rights reserved.