下载演示项目- 18kb下载源文件- 2kbintroduction 这个示例演示了如何在模态对话框中显示工具提示。 此外,还阐明了代码重用的一些基本原则和MFC编程的精神。 示例是使用Visual c++ 6.0创建的,但是应该从4.2开始工作。 如何在应用程序中集成示例 在应用程序中包含文件ToolTipDialog.cpp。 在stdafx。h,加上这条线 隐藏,复制代码# include“ToolTipDialog.h” 从CToolTipDialog派生对话框,而不是CDialog。 确保调用CToolTipDialog::OnInitDialog而不是CDialog::OnInitDialog。 在资源文件中添加与对话框中的控件具有相同id的字符串。 如果你有一个选项对话框,包括选项“在对话框中显示工具提示”。当这个设置改变时,调用CToolTipDialog::EnableToolTips()。 它是如何工作的 示例使用MFC CToolTipCtrl,它是围绕一个Windows通用控件构建的。这个通用控件为我们做所有的工作。 唯一要做的是创建控件,为窗口分配工具提示,并传递鼠标消息。 函数CToolTipDialog::OnInitDialog()查找所有ID匹配控件ID的字符串。 隐藏,复制Code
BOOL CToolTipDialog::OnInitDialog() { BOOL bResult = CDialog::OnInitDialog(); m_wndToolTip.Create(this); m_wndToolTip.Activate(c_bShowToolTips); CWnd *pWndChild = GetWindow(GW_CHILD); CString strToolTip; while (pWndChild) { int nID = pWndChild->GetDlgCtrlID(); if (strToolTip.LoadString(nID)) { m_wndToolTip.AddTool(pWndChild, strToolTip); } pWndChild = pWndChild->GetWindow(GW_HWNDNEXT); } return bResult; }
标准windows程序有一个主循环,该循环连续调用GetMessage()、TranslateMessage()和DispatchMessage()。 MFC主循环和模态循环包含一些额外的。其中之一是在TranslateMessage()之前调用PreTranslateMessage()。 这使我们有机会查看每条消息或在发送消息之前过滤消息。 这是我们可以拦截所有鼠标消息并将其转发给工具提示控件的地方。 隐藏,复制Code
BOOL CToolTipDialog::PreTranslateMessage(MSG *pMsg) { if (c_bShowToolTips && pMsg->message >= WM_MOUSEFIRST && pMsg->message <= WM_MOUSELAST) { MSG msg; ::CopyMemory(&msg, pMsg, sizeof(MSG)); HWND hWndParent = ::GetParent(msg.hwnd); while (hWndParent && hWndParent != m_hWnd) { msg.hwnd = hWndParent; hWndParent = ::GetParent(hWndParent); } if (msg.hwnd) { ListBoxTextExpand(&msg); m_wndToolTip.RelayEvent(&msg); } } return CDialog::PreTranslateMessage(pMsg); }
正如Richard Collins指出的,仅仅将鼠标事件传递到工具提示控件是不够的。对于具有子窗口的控件,这将不起作用。例如,组合框有一个编辑控件作为子控件。当鼠标消息被发送到这个编辑控件时,hWndParent将是组合框,而不是对话框。调整消息,使工具提示控件相信它确实被发送到组合框。当然,原始消息被传递给基类函数。 列表框字符串的自动扩展 Murali Soundararajan添加了在工具提示中显示列表框字符串的代码。要做到这一点,你只需给你的列表框字符串TOOLTIPEXPAND。其余的都为你做了。工具提示将在鼠标下方显示列表框项目的文本。这不适用于所有者绘制的列表框。这就是调用ListBoxTextExpand(msg)所需要的。 代码重用 CodeGuru网站已经包含了Dave Bixler的一篇文章,它也做了同样的工作。 然而,Dave告诉我们为每个对话一遍又一遍地写同样的代码。 你应该避免这样做的原因有两个: 我的高中数学老师过去常说,数学家应该尽可能地懒惰。对于程序员来说更是如此。您应该总是尽可能少地编写代码。 您可能希望稍后更改此代码。也许你想在椭圆窗口中显示你的工具提示。此时,您将希望在某个位置更改代码。 MFC扩展 这个示例只包含一小段代码。您可能想知道,创建一个通用基类并从中派生是否值得。 不过,你可以稍后在这个类中添加其他内容,你所有的对话框都会免费获得这些新内容。 这是一个应该坚持的普遍原则。当从一个MFC类派生一个类时,您应该始终创建一个像这样的中产阶级。 凡是通用的都放在基类中,凡是应用程序特定的都放在派生类中。 结果是:当您完成创建应用程序时,您将拥有自己的MFC扩展库。所有的功能都将在一个新的应用程序中使用。 在资源文件中放置字符串 美国人可能不清楚这一点,但欧洲人知道这一点:您应该将所有字符串放在一个资源文件中。微软已经警告我们够多了。 为什么?因为总有一天,人们会开始问他们能不能弄到法语、德语……你的软件版本。 当您的应用程序开始为全世界所熟知时,您可能会遇到这种情况。 让事情自动进行 MFC的精神是让事情自动进行。为了让向导能够使用框架,人们发明了各种可怕的宏,并且在您不知情的情况下加载了各种资源。 例如,工具栏的工具提示自动加载。这并不总是增强MFC源代码的可读性,但确实使程序员的工作更轻松。 在扩展MFC(或简单地使用它)时,您应该遵循相同的原则。 这就是资源字符串与控件具有相同ID的原因。你应该经常尝试像这样的花招。 有时甚至可以是be有用消息中创建新的宏符合地图或其他地图。 本文转载于:http://www.diyabc.com/frontweb/news8153.html