在工具提示控件中使用对话框

【勇芳软件工作室】汉化HomePreviousNext

以下示例包括一组应用程序定义的函数,用于实现对话框的工具提示控件。DoCreateDialogTooltip函数创建一个工具提示控件,并使用EnumChildWindows函数枚举对话框中的控件。枚举程序EnumChildProc使用工具提示控件注册每个控件。该过程将对话框指定为每个工具提示控件的父窗口,并为每个工具提示控件包含LPSTR_TEXTCALLBACK值。因此,每当工具提示控件需要控件的文本时,对话框将收到包含TTN_NEEDTEXT通知消息的WM_NOTIFY消息。对话框过程调用OnWMNotify函数来处理TTN_NEEDTEXT通知。OnWMNotify根据工具提示控件的标识符提供适当的字符串。

工具提示控件需要接收系统发送到控制窗口的鼠标消息。要访问消息,DoCreateDialogTooltip函数安装WH_GETMESSAGE类型的挂接过程。挂钩过程GetMsgProc监视针对其中一个控制窗口的鼠标消息的消息流,并将消息中继到工具提示控件。

// DoCreateDialogTooltip - 为对话框创建一个工具提示控件,

//枚举子控件窗口,并安装一个钩子

//监视发布的鼠标消息的消息流的过程

//到控制窗口。

//如果成功返回TRUE,否则返回FALSE。

//

//全局变量

// g_hinst __应用程序实例的句柄

// g_hwndTT __工具提示控件的句柄

// g_hwndDlg __对话框的句柄

// g_hhk __挂??钩过程的句柄

BOOL DoCreateDialogTooltip(void)

{

//确保加载公共控件DLL并创建

//一个工具提示控件。

InitCommonControls();

g_hwndTT = CreateWindowEx(0, TOOLTIPS_CLASS, (LPSTR) NULL,

TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, g_hwndDlg, (HMENU) NULL, g_hinst, NULL);

if (g_hwndTT == NULL)

return FALSE;

//枚举子窗口,使用工具提示注册它们
// 控制。

if(!EnumChildWindows(g_hwndDlg,(WNDENUMPROC)EnumChildProc,0))

return FALSE;

//安装一个挂钩程序来监视鼠标的消息流

//用于对话框中控件的消息。

g_hhk = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc,

(HINSTANCE) NULL, GetCurrentThreadId());

if (g_hhk == (HHOOK) NULL)

return FALSE;

return TRUE;

}

// EmumChildProc - 通过工具提示控制寄存器控制窗口
//使用TTM_ADDTOOL消息传递a的地址

// TOOLINFO结构。

//如果成功返回TRUE,否则返回FALSE。

// hwndCtrl - 控制窗口的句柄

// lParam - 应用程序定义的值(未使用)

BOOL EnumChildProc(HWND hwndCtrl, LPARAM lParam)

{

TOOLINFO ti;

char szClass[64];

//跳过静态控件。

GetClassName(hwndCtrl, szClass, sizeof(szClass));

if(lstrcmp(szClass,“STATIC”){

ti.cbSize = sizeof(TOOLINFO);

ti.uFlags = TTF_IDISHWND;

ti.hwnd = g_hwndDlg;

ti.uId = (UINT) hwndCtrl;

ti.hinst = 0;

ti.lpszText = LPSTR_TEXTCALLBACK;

SendMessage(g_hwndTT,TTM_ADDTOOL,0,

(LPARAM) (LPTOOLINFO) &ti);

}

return TRUE;

}

// GetMsgProc - 监视预期的鼠标消息的消息流

//在对话框中的控制窗口。

//返回与消息相关的值。

// nCode - 钩子代码

// wParam - message flag(not used)

// lParam - MSG结构的地址

LRESULT CALLBACK GetMsgProc(int nCode,WPARAM wParam,LPARAM lParam)

{

MSG *lpmsg;

lpmsg = (MSG *) lParam;

if(nCode < 0 ||!(IsChild(g_hwndDlg,lpmsg- > hwnd)))

return (CallNextHookEx(g_hhk, nCode, wParam, lParam));

switch(lpmsg- > message){

case WM_MOUSEMOVE:

case WM_LBUTTONDOWN:

case WM_LBUTTONUP:

case WM_RBUTTONDOWN:

case WM_RBUTTONUP:

if (g_hwndTT != NULL) {

MSG msg;

msg.lParam = lpmsg->lParam;

msg.wParam = lpmsg->wParam;

msg.message = lpmsg->message;

msg.hwnd = hwnd;

SendMessage(g_hwndTT,TTM_RELAYEVENT,0,

(LPARAM) (LPMSG) &msg);

}

break;

默认:

break;

}

return (CallNextHookEx(g_hhk, nCode, wParam, lParam));

}

// OnWMNotify - 提供具有相应文本的工具提示控件

//显示控制窗口。这个函数被调用

//响应WM_NOTIFY消息的对话框过程。

// lParam - WM_NOTIFY消息的第二个消息参数

VOID OnWMNotify(LPARAM lParam)

{

LPTOOLTIPTEXT lpttt;

int idCtrl;

if ((((LPNMHDR) lParam)->code) == TTN_NEEDTEXT) {

idCtrl = GetDlgCtrlID((HWND) ((LPNMHDR) lParam)->idFrom);

lpttt = (LPTOOLTIPTEXT) lParam;

switch(idCtrl){

case ID_HORZSCROLL:

lpttt->lpszText = "A horizontal scroll bar.";

return;

case ID_CHECK:

lpttt->lpszText = "A check box.";

return;

case ID_EDIT:

lpttt->lpszText = "An edit control.";

return;

}

}

return;

}