定制MessageBox
来源:互联网 发布:linux ssh目录 编辑:程序博客网 时间:2024/05/17 07:07
定制MessageBox
大家都知道MessageBox()函数的用法: int MessageBox( HWND hWnd, // handle to owner window LPCTSTR lpText, // text in message box LPCTSTR lpCaption, // message box title UINT uType // message box style ); 虽然在参数uType中可以指定一些样式,但你在程序中对MessageBox的外观能定义 的不多。原因是当调用MessageBox()函数后,它在内部有自己的消息循环(所有的 模式对话框都有自己的消息循环),返回时MessageBox对话框窗口已经被Destroy, 所以你没有办法得到MessageBox对话框的窗口句柄。但你可以根据自己的不同需 求用下面的方法中去定制你的MessageBox: 如果你只是想用自己的icon去代替系统MessageBox提供的那几种有限的icon, 用MessageBoxIndirect()函数就可以了: int MessageBoxIndirect( CONST LPMSGBOXPARAMS lpMsgBoxParams // message box parameters ); typedef struct { UINT cbSize; HWND hwndOwner; HINSTANCE hInstance; LPCTSTR lpszText; LPCTSTR lpszCaption; DWORD dwStyle; LPCTSTR lpszIcon; DWORD_PTR dwContextHelpId; MSGBOXCALLBACK lpfnMsgBoxCallback; DWORD dwLanguageId; } MSGBOXPARAMS, *PMSGBOXPARAMS; 看到MSGBOXPARAMS结构中的lpszIcon吧,在使用过程中你应当准备一个合适的 MSGBOXPARAMS结构,如果你要用自己的icon,你一定要用MB_USERICON这个flag。 上面我们也讲到不能定制MessageBox对话框的原因是没有办法得到它的窗口句柄 ,但我们真的没有办法了吗?当然有办法,那就是使用HOOK(钩子)机制。 在windows系统中有多种HOOK,但在这里我们只用到HK_CBT类型的钩子。 HK_CBT钩子过程在WM_MOVE、WM_SIZE、WM_ACTIVE、WM_CREATE、WM_DESTROY时被 系统调用,所以HK_CBT钩子可以在这里用。下面让我们看如何实现MessageBox的 定制过程。 1,安装HK_CBT钩子; 2,调用MessageBox()函数; 3,移除HK_CBT钩子。 整个过程很简单吧?我将介绍第一步和第三步。 安装HK_CBT钩子: HHOOK hMsgBoxHook = SetWindowsHookEx( WH_CBT, // Type of hook CBTProc, // Hook procedure (see below) NULL, // Module handle. Must be NULL (see docs) GetCurrentThreadId() // Only install for THIS thread!!! ); 重要的是SetWindowHookEx()函数的后边两个参数,用它可以区别安装是一个全局 钩子还是一个线程钩子,在这里我们只要安装一个线程钩子。所以我们将Module handle 设置为NULL,同时将thread ID设为本线程的ID。 在SetWindowHookEx()函数中有一个hook procedure,这是window调用的一个回调 函数,在windows系统中有一个HOOK链,我们在编写hook procedure时要注意保证 此链的完整,所以我们的hook procedure要调用CallNextHookEx()函数。下面就 是我们的hook procedure: LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam) { HWND hwnd; if(nCode < 0) return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam); switch(nCode) { case HCBT_ACTIVATE: // 现在wParam中就是message box的句柄 hwnd = (HWND)wParam; // 我们已经有了message box的句柄,在这里我们就可以定制message box了! return 0; } // Call the next hook, if there is one return CallNextHookEx(hMsgBoxHook, nCode, wParam, lParam); } 移除HK_CBT钩子: 只要调用UnhookWindowsHookEx()函数就可以了 好了,我们将在上面的三步写成一个函数,如下: int MsgBoxEx(HWND hwnd, TCHAR *szText, TCHAR *szCaption, UINT uType) { int ret; // Install a thread hook, so we can customize it hMsgBoxHook = SetWindowsHookEx( WH_CBT, CBTProc, NULL, GetCurrentThreadId() ); // Display a standard message box ret = MessageBox(hwnd, szText, szCaption, uType); // remove the window hook UnhookWindowsHookEx(hMsgBoxHook); return ret; } 其实你也可以钩住WM_CREATE消息,不过那样处理要复杂一些。我记得在早期的 windows platform SDK中有这样一个例子。 你可能说,定制一个MessageBox有什么用处,我想有下面的用途: 1.你可以用CreateWindowEx()给MessageBox添加一个check box控件,并子 类化MessageBox来处理check box的消息 2.通过子类化改变messagebox、button或icon,以便和你整个程序的界面风 格相一致 只要有了MessageBox对话框的句柄,你能做的很多,很多... 另外,如果你对模式对话框的机理很了解,你可以自己写出一个 "MessageBox"来代替系统MessageBox用在你的程序中。 你可以参考Jeffrey Richter的《Windows 95程式设计指南》,在书中给出 了模式对话框的伪码。这本书的繁体电子版可以在候捷的个人网站上下载。 这种方法也比较简单(添加一个消息循环,Enable/Disable Owner窗口), 我就在示例代码中不实现了。由于我工作较忙,在写示例代码时没有多少 注释和防错,请读者谅解 |
- 定制MessageBox
- 定制MessageBox
- 定制MessageBox
- 定制MessageBox
- 在silverlight中定制自己的MessageBox(消息框)
- MessageBox
- MessageBox()
- MessageBox
- MessageBox
- messageBox
- MessageBox
- MessageBox
- MessageBox()
- MessageBox
- MessageBox
- messagebox
- MessageBox
- MessageBox
- C语言二分法
- C++怎么做
- C++每个系统标识符的意思是什么
- c++数组题 求救
- 然后程序输出它对应的2进制数 c语言程序:任意输入一个10进制数(小于255)
- 定制MessageBox
- 用JCreator编写java程序时遇到的问题
- C语言编程软件名字叫什么
- 理解不了C语言增1、减1
- 用c#把一个字符串写到记事本中
- 下面c程序的结果
- 我的SQL server和Visual Studio出了问题 在控制面板 安装不了 说有问题 在360里面提示的是安装 老是提示不能删除 结果卸到最后一个程序的时候 要给卸了重来装 怎么样强行删除文件
- C#和C语言
- 《开源合辑-互联网->Wiki》 第2部分