[ATL/WTL]_[初级]_[窗口如何实现WM_MOUSELEAVE和WM_MOUSEHOVER]

场景:

1.  WTL的控件默认不支持进入和移出的 WM_MOUSEHOVER ,WM_MOUSELEAVE 事件, 即使写了映射也没用, 必须要使用函数

_TrackMouseEvent  添加监听.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms645615(v=vs.85).aspx

2. 默认的Window窗口如果有子窗口时, 当进入子窗口时, 会对父窗口调用WM_MOUSELEAVE, 因为子窗口默认会拦截消息, 因为子窗口也得处理自己的MOUSEMOVE事件.

如果想全权处理子窗口的消息, 那么需要自己处理所有鼠标事件,这里没找到方法. 如果想自己处理子窗口的进入移除事件, 可以在父窗口绘制子窗口的按钮.

my_button.h

#ifndef __MY_BUTTON_H
#define __MY_BUTTON_H

#include <Windows.h>
#include <string>
#include "atlframe.h"

class MyButton : public CWindowImpl<MyButton>
{
public:
	MyButton(){}
	~MyButton(){}

	BEGIN_MSG_MAP_EX(MyButton)
		MESSAGE_HANDLER(WM_PAINT,OnPaint)
		MESSAGE_HANDLER(WM_CREATE,OnCreate)
		MESSAGE_HANDLER(WM_LBUTTONDOWN,OnLButtonDown)
		MESSAGE_HANDLER(WM_MOUSEMOVE,OnMouseMove)
		MESSAGE_HANDLER(WM_MOUSEHOVER,OnMouseHover)
		MESSAGE_HANDLER(WM_MOUSELEAVE,OnMouseLeave)
		REFLECT_NOTIFICATIONS()
	END_MSG_MAP()

protected:

	LRESULT OnEraseBkgnd(UINT uMsg,WPARAM wparam,LPARAM lparam,BOOL& bHandled);

	LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

	LRESULT OnPaint(UINT uMsg,WPARAM nnwparam,LPARAM lparam,BOOL& bHandled);

	LRESULT OnCreate(UINT uMsg,WPARAM nnwparam,LPARAM lparam,BOOL& bHandled);

	LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

	LRESULT OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

	LRESULT OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

private:
	CToolTipCtrl tooltip_;
	CButton button_;
	bool m_bTracking_;

	HBRUSH bg_color_brush_;
	HBRUSH bg_white_brush_;
	HBRUSH bg_brush_;
	CRect button_rect_;

};

#endif

my_button.cpp

#include "stdafx.h"

#include "my_button.h"

LRESULT MyButton::OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	POINT pt = { LOWORD(lParam), HIWORD(lParam) };
	if (PtInRect(&button_rect_, pt))
 	{
 	}
	return 0;
}

LRESULT MyButton::OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	bg_brush_ = bg_color_brush_;
	Invalidate(0);
	return 0;
}

LRESULT MyButton::OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	bg_brush_ = bg_white_brush_;
	Invalidate(0);
	m_bTracking_ = false;
	return 0;
}

LRESULT MyButton::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	MSG msg;
	msg.message = WM_MOUSEMOVE;
	msg.hwnd = m_hWnd;
	msg.lParam = lParam;
	msg.wParam = wParam;
	tooltip_.RelayEvent(&msg);

	if (!m_bTracking_)
    {
        TRACKMOUSEEVENT tme;
        tme.cbSize = sizeof(TRACKMOUSEEVENT);
        tme.dwFlags = TME_LEAVE | TME_HOVER;//要触发的消息类型
        tme.hwndTrack = m_hWnd;
        tme.dwHoverTime = 10;// 如果不设此参数,无法触发mouseHover

        if (::_TrackMouseEvent(&tme)) //MOUSELEAVE|MOUSEHOVER消息由此函数触发.
        {
            m_bTracking_ = true;
        }
    }
	return 0;
}

LRESULT MyButton::OnCreate(UINT uMsg,WPARAM nnwparam,LPARAM lparam,BOOL& bHandled)
{
	m_bTracking_ = false;
	bg_white_brush_ = AtlGetStockBrush(BLACK_BRUSH);
	bg_color_brush_ = AtlGetStockBrush(GRAY_BRUSH);

	tooltip_.Create(m_hWnd,NULL,NULL,TTS_NOPREFIX);
	tooltip_.AddTool(m_hWnd,L"tooltip");

	bg_brush_ = bg_white_brush_;

	button_.Create(m_hWnd,CRect(20,20,120,40),L"Open",WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON);

	return 0;
}

LRESULT MyButton::OnEraseBkgnd(UINT uMsg,WPARAM wparam,LPARAM lparam,BOOL& bHandled)
{
	return (LRESULT)1;
}

LRESULT MyButton::OnPaint(UINT uMsg,WPARAM nnwparam,LPARAM lparam,BOOL& bHandled)
{
	CPaintDC hdc(m_hWnd);

	CRect client_rect;
	GetClientRect(&client_rect);

	CMemoryDC mdc(hdc,client_rect);
	mdc.SetBkMode(TRANSPARENT);
	Gdiplus::Graphics graphics(mdc);

	mdc.FillRect(client_rect,bg_brush_);
	return 0;
}

未进入:

进入:

完整项目下载地址:

http://download.csdn.net/detail/infoworld/9252273

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-21 05:53:29

[ATL/WTL]_[初级]_[窗口如何实现WM_MOUSELEAVE和WM_MOUSEHOVER]的相关文章

[ATL/WTL]_[初级]_[Win32窗口自定义消息处理过程]

场景 有时候我们需要单独对某个窗口消息进行拦截,比如CEdit响应回车, 这时候就需要拦截窗口处理过程了. 当然MFC的界面可以重载: BOOL CXXXDlg::PreTranslateMessage(MSG* pMsg){ 但是WTL的CEdit并不支持这种方式,WTL如果想在 PreTranslateMessage 里拦截消息,必须继承 CMessageFilter 后还要把这个控件注册到消息循环里才行,也就是必须写子类 或者从父窗口拦截这个CEdit的消息. CMessageLoop*

[ATL/WTL]_[初级]_[拖放文件到窗口]

场景: 1. 软件需要支持从桌面拖动文件到软件里,避免从文件打开窗口选择文件,这样效率快很多,这时就需要窗口支持拖放技术. drag and drop. 2. 软件需要复制文件到远程或设备里,支持拖放的话就很方便. 两种方案: 1. 如果是Windows 窗口程序, 可以使用监听WM_DROPFILES 消息来实现, 这里讲解第一种, 比较方便. http://blog.csdn.net/laogaoav/article/details/9152181 2. 如果不想监听 WM_DROPFILE

[WTL/ATL]_[初级]_[如何使用GetOpenFileName多选文件-根据文件名长度计算lpstrFile长度]

场景: 1. 使用GetOpenFileName 时, 需要预先自定义lpstrFile的长度比如,buf[1024], 但是如果选择的文件过多怎么办?总不能创建一个超大的内存空间吧, 如果选择少时又浪费内存. 2. 微软的MSDN的坏处就是不提供实际的例子,而在别的地方提供,难道他们没遇到这类普通的问题? 3. 这里stackoverflow提供了一个微软使用lpfnHook 的例子来解决这个问题,这个例子对于unicode是有问题的,计算长度没有x2. 这个bug困扰了我半天. 找这个解决方

[ATL/WTL]_[初级]_[转发消息让CStatic支持点击消息操作]

场景: 1. CStatic支持不定长的字符串长度,还可以支持图片背景,当然要父控件响应 WM_CTLCOLORSTATIC 消息. 2. 可以响应点击事件的Cstatic可以当作简单按钮来使用,不需要自定义绘制操作. 3. 普通创建的CStatic不能响应点击时间,需要加上 SS_NOTIFY的 style才可以, 注意AA_STATIC_CLICK是自定义事件ID. #ifndef __DH_STATIC #define __DH_STATIC #include "window/common

[ATL/WTL]_[初级]_[常用的界面对象操作]

1. 获取指定大小字体 HFONT AppUtil::GetFont(int pixel,bool bold,const wchar_t* font_name) { LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); // zero out structure lf.lfHeight = pixel; // request a 8-pixel-height font if(bold) { lf.lfWeight = FW_BOLD; } lstrcpy(lf

[Cocoa]_[初级]_[NSTableView--数据操作和表格操作要注意的问题]

1.首先在MainMenu.lib文件里面创建一个NSTableView,在界面上显示一个表格出来,并对表格进行设置. 2.创建文件TableViewDelegate.h和TableViewDelegate.m(文件内容如下文件所示).并在MainMenu.lib文件中创建一个Object(从窗口右边选中Object,拉到在Window中的对话框中),命名:TableViewDelegate. 3.设置代理:tableView 进行设置,和图片中的Table View进行连接. staticFi

[libcurl]_[初级]_[使用libcurl下载大文件]

场景: 1. 在Windows编程时, 下载http页面(html,xml)可以使用winhttp库,但是并不是很下载文件,因为会失败. 由此引出了WinINet库,无奈这个库的稳定性比较低,使用例子又少, 下载大文件时经常是不完整,可查找的资料很少或者是没有特殊情况的解决办法. 2. 我的原则是如果系统有自带的就用系统的,但是 WinINet 要掌握需要花不少时间. 时间因素考虑到了libcurl. 3. libcurl支持ftp,http等协议的文件读取,还能自动获取文件大小, 最重要的是不

[wxWidgets]_[初级]_[配置codeblock+wxWidgets3.0.1开发环境]

配置Codeblock+wxWidgets-3.0.1开发环境 作者: Sai 1. 下载codeblock,进官网,首先提醒下,下载工具一定要进官网,最新,没木马. http://www.codeblocks.org/downloads/binaries 选在SourceForge.net下载吧. codeblocks-13.12mingw-setup-TDM-GCC-481.exe 2. 下载最新wxWidgets版本 3.0.1稳定版. http://www.wxwidgets.org/d

[项目管理]_[初级]_[TortoiseSVN的使用入门]

Svn 概述: svn是版本控制工具,简单来说它的功能就是通过差异算法来记录你每次提交的文件差异来存储的,版本控制工具的好处是你可以代码出问题时回退到某个时间点的代码,或对比最新和本机代码看有哪些变化等,对排除程序bug,代码审查,保存稳定版本程序是作用很大的. 1. Svn主要有几个操作需要会用,客户端 Windows: TortoiseSVN MacOSX:   SvnX 命令行:     svn(通用) 创建资源库(Create respository) 1.资源库是存放源代码的地方,sv