如果我们想让程序弹出一个msgbox窗口,我们应该用MessageBox函数,这个函数原型是这样的:
int WINAPI MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
第一个参数是拥有消息的窗口,第二个参数是msgbox的消息,第三个参数是标题,第四个是控制符集
我们应该这样写
#include <Windows.h> //该函数包含在Windows.h头文件中
int main()
{
MessageBox(0, "hello world", "test", MB_ABORTRETRYIGNORE | MB_SYSTEMMODAL);
return 0;
}
效果如图:
但是有时候我们希望它的按钮控件也能有所不同,这就需要钩子的帮助了
这是我连连看项目的一个控件,我们写了一个hook函数,然后再在我们封装的msgbox中安装钩子,再调用MessageBox函数,最后卸载钩子。
代码如下,注释已经写的很详细了
LRESULT CALLBACK CBTHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
//可以监听窗口的返回值 在win32APP中,WPARAM与LPARAM都表示32位整型变量
HWND hwnd = (HWND)wParam; //HWND 窗口句柄
if (nCode == HCBT_ACTIVATE)
{
if (nCode == HCBT_ACTIVATE)
{
SetDlgItemText((HWND)wParam, IDYES, "&直接开始");//设置标题或对话框控件的文字
SetDlgItemText((HWND)wParam, IDNO, "&读档开始");
SetDlgItemText((HWND)wParam, IDOK, "&OK");
SetDlgItemText((HWND)wParam, IDCANCEL, "&Cancel");
SetDlgItemText((HWND)wParam, IDABORT, "&简单");
SetDlgItemText((HWND)wParam, IDRETRY, "&一般");
SetDlgItemText((HWND)wParam, IDIGNORE, "&困难");
}
}
return 0;
}
int Msg(HWND hwnd, TCHAR *szText, TCHAR *szCaption, UINT uType)
{
//res = Msg(0, "请选择模式", "连连看", MB_YESNO | MB_SYSTEMMODAL);
int ret;
HHOOK hHook = SetWindowsHookEx( //钩子,监控windows消息框
WH_CBT, //钩子类型
//WH_CBT 当Windows激活、产生、释放(关闭)、最小化、最大化或改变窗口时都将触发此事件
CBTHookProc, //回调函数地址
//CBTHookProc自定义函数,用来改变控件的文字
NULL,// 应用程序实例的句柄。
// 如果dwThreadId 标识当前进程创建的一个线程,而且子程代码位于当前进程,hMod必须为NULL。
GetCurrentThreadId()//与安装的钩子子程相关联的线程的标识符。
//获取当前线程ID
);
ret = MessageBox(hwnd, szText, szCaption, uType);
//参数1代表消息框拥有的窗口
//2.消息框的内容
//3.消息框的标题
//4.指定一个决定对话框的内容和行为的位标志集
UnhookWindowsHookEx(hHook);//卸载钩子
//这个参数是上一个函数SetWindowsHookEx的返回值.
return ret;
}
调用时的用法如下
int res = Msg(0, "请选择难度", "连连看", MB_ABORTRETRYIGNORE | MB_SYSTEMMODAL);
效果: