Duilib 实现右下角弹出像QQ新闻窗口,3秒后自动关闭(一)
转载:https://blog.twofei.com/667/
自绘或子类化控件时,有时需要处理鼠标进入(MouseEnter)/鼠标离开(MouseLeave)/鼠标停留(MouseHover)消息,虽然有定义这两个消息常量(WM_MOUSEHOVER 与 WM_MOUSELEAVE),但默认情况下 Windows 的窗口消息是不会产生这三个消息的。但提供了一个 API 函数_TrackMouseEvent 可以使用,这个函数可以使 Windows 产生 鼠标停留(WM_MOUSEHOVER)与 鼠标离开(WM_MOUSELEAVE)消息,至于鼠标进入消息(Windows 没有定义 WM_MOUSEENTER 宏),直接手动在第一次鼠标移动的时候模拟产生就行了。不过不爽的是 鼠标离开消息 Windows 没有传递离开时的坐标过来,所以这个也得手动模拟:每次鼠标移动的时候记录下坐标,在收到鼠标离开消息时,采用此值即可。下面的代码没有作此处理,如有需要可手动加上。
效果:
.h文件
#ifndef _POPUPWND_H_
#define _POPUPWND_H_ #include "WndShadow.h" #define WIN_VISITWIDTH 280
#define WIN_VISITHEIGHT 186 #define ID_VISITPOP_WINDOW 20
#define ID_TIMER_DISPLAY_DELAY 30
#define ID_TIMER_CLOSE_WINDOW 40 class CPopUpWnd :public WindowImplBase
{
public:
CPopUpWnd(); ~CPopUpWnd(); public:
virtual LPCTSTR GetWindowClassName() const; virtual void OnFinalMessage(HWND hWnd); virtual CDuiString GetSkinFile(); virtual CDuiString GetSkinFolder(); virtual UILIB_RESOURCETYPE GetResourceType() const; virtual CControlUI* CreateControl(LPCTSTR pstrClassName); virtual LRESULT ResponseDefaultKeyEvent(WPARAM wParam); virtual LRESULT HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam); virtual void Notify(TNotifyUI& msg); virtual void OnClick(TNotifyUI& msg); virtual void InitWindow(); void OnPrepare(); public: void InitControl(); void StartTrack(); void MoveSelfWindow(); LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam,BOOL& bHandled); LRESULT OnMouseMove(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); LRESULT OnMouseEnter(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); public:
CWndShadow m_WndShadow; CLabelUI* m_pMousePos; UINT m_uTime;//移动窗口时器 protected:
bool m_bMouseTracking; // 是否正在跟踪鼠标
bool m_bMouseWithin; // 鼠标是否在窗口内
}; #endif//_POPUPWND_H
.cpp文件
#include "..\..\stdafx.h"
#include "PopUpWnd.h"
#pragma comment(lib, "comctl32.lib") CPopUpWnd::CPopUpWnd()
:m_uTime()
,m_bMouseTracking(false)
,m_bMouseWithin(false)
,m_pMousePos(NULL)
{ } CPopUpWnd::~CPopUpWnd()
{
if (m_uTime)
{
KillTimer(this->GetHWND(),ID_VISITPOP_WINDOW);
m_uTime = ;
}
} LPCTSTR CPopUpWnd::GetWindowClassName() const
{
return _T("PopUpWnd");
} void CPopUpWnd::OnFinalMessage(HWND hWnd)
{
CWindowWnd::OnFinalMessage(hWnd);
} CDuiString CPopUpWnd::GetSkinFile()
{
return _T("xml//PopUpDlg.xml");
} CDuiString CPopUpWnd::GetSkinFolder()
{
return _T("");
} UILIB_RESOURCETYPE CPopUpWnd::GetResourceType() const
{
return UILIB_FILE;
} LRESULT CPopUpWnd::ResponseDefaultKeyEvent(WPARAM wParam)
{
if (wParam == VK_RETURN)
{
return FALSE;
}
else if (wParam == VK_ESCAPE)
{
Close();
return TRUE;
}
return FALSE;
} CControlUI* CPopUpWnd::CreateControl(LPCTSTR pstrClassName)
{ return NULL;
} void CPopUpWnd::InitWindow()
{
//窗体增加阴影
CWndShadow::Initialize(m_PaintManager.GetInstance());
m_WndShadow.Create(m_hWnd , true);
m_WndShadow.SetSize();
m_WndShadow.SetPosition(, ); //修改窗口风格
//SetWindowLong(m_hWnd,GWL_STYLE,GetWindowLong(m_hWnd,GWL_STYLE) & ~WS_MAXIMIZEBOX & ~WS_THICKFRAME ); //加入WS_EX_LAYERED扩展属性
LONG styleValue = ::GetWindowLong(m_hWnd, GWL_EXSTYLE); styleValue &= ~(WS_EX_APPWINDOW);//当窗口可见时将一个顶层窗口放置在任务栏上
styleValue |= WS_EX_TOOLWINDOW; //工具条窗口样式 SetWindowLong(m_hWnd,GWL_EXSTYLE,styleValue); InitControl(); //右下角慢慢弹出
//m_uTime = SetTimer(m_hWnd,ID_VISITPOP_WINDOW,20,NULL); //在此调用MoveSelfWindow()方法 窗口不会显示在右下角,因为InitWindow在WM_CREATE 消息响应函数里调用,窗口还没创建出来
} void CPopUpWnd::InitControl()
{
m_pMousePos = static_cast<CLabelUI*>(m_PaintManager.FindControl(TEXT("mouse")));
} void CPopUpWnd::OnPrepare()
{
//直接显示在右下角
MoveSelfWindow(); //3秒后窗口自动关闭
SetTimer(m_hWnd,ID_TIMER_DISPLAY_DELAY,,NULL);
} void CPopUpWnd::Notify(TNotifyUI& msg)
{
if( msg.sType == _T("windowinit") ) OnPrepare(); if ( msg.sType == _T("click") )
{ }
WindowImplBase::Notify(msg);
} void CPopUpWnd::OnClick(TNotifyUI& msg)
{
__super::OnClick(msg);
} void CPopUpWnd::MoveSelfWindow()
{
RECT rect;
SystemParametersInfo(SPI_GETWORKAREA,,&rect,);
int y=rect.bottom-rect.top;
int x=rect.right-rect.left;
x=x-WIN_VISITWIDTH;
y=y-WIN_VISITHEIGHT; MoveWindow(m_hWnd,x,y,WIN_VISITWIDTH,WIN_VISITHEIGHT,TRUE);
} LRESULT CPopUpWnd::OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam,BOOL& bHandled)
{
static int nHeight=;
int cy=GetSystemMetrics(SM_CYSCREEN);
int cx=GetSystemMetrics(SM_CXSCREEN);
RECT rect;
SystemParametersInfo(SPI_GETWORKAREA,,&rect,);
int y=rect.bottom-rect.top;
int x=rect.right-rect.left;
x=x-WIN_VISITWIDTH; switch(wParam)
{//多个定时器
case ID_VISITPOP_WINDOW:
if(nHeight<=WIN_VISITHEIGHT)
{
++nHeight;
MoveWindow(m_hWnd,x,y-WIN_VISITHEIGHT,WIN_VISITWIDTH,WIN_VISITHEIGHT,TRUE);
}
else
{
//nHeight = 0;
KillTimer(m_hWnd,ID_VISITPOP_WINDOW); SetTimer(m_hWnd,ID_TIMER_DISPLAY_DELAY,,NULL);
}
break;
case ID_TIMER_DISPLAY_DELAY:
KillTimer(m_hWnd,ID_TIMER_DISPLAY_DELAY);
Close(IDCLOSE);
break;
}
return ;
} //LRESULT CPopUpWnd::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
//{
// POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
// //::ScreenToClient(m_hWnd,&pt);//转换成屏幕坐标
// //POINT pt1 ;/*= { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };*/
// //GetCursorPos(&pt1);
// RECT rect;
// ::GetWindowRect (m_hWnd,&rect);
// //::ClientToScreen(m_hWnd,&pt);//转换成屏幕坐标
// if (PtInRect(&rect,pt))//判断point是否在rect内部
// {
// KillTimer(m_hWnd,ID_TIMER_DISPLAY_DELAY);
// }
//
// return 0;
//} void CPopUpWnd::StartTrack()
{
TRACKMOUSEEVENT tme = {};
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_HOVER | TME_LEAVE;
tme.dwHoverTime = HOVER_DEFAULT;
_TrackMouseEvent(&tme);
} LRESULT CPopUpWnd::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// 如果鼠标不在客户区内,就产生一个鼠标进入事件
if(!m_bMouseWithin) {
OnMouseEnter(uMsg /* WM_MOUSEMOVE */, wParam, lParam, bHandled);
} // 开始跟踪鼠标停留/离开事件
if(!m_bMouseTracking) {
StartTrack();
m_bMouseTracking = true;
return ;
} TCHAR text[MAX_PATH];
wsprintf(text,_T("鼠标移动: %d,%d"),GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); m_pMousePos->SetText(text); return ;
} LRESULT CPopUpWnd::OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_bMouseTracking = false; TCHAR text[MAX_PATH];
wsprintf(text,_T("鼠标停留: %d,%d"),GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
m_pMousePos->SetText(text); return ;
} LRESULT CPopUpWnd::OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_bMouseTracking = false;
m_bMouseWithin = false; SetTimer(m_hWnd,ID_TIMER_DISPLAY_DELAY,,NULL); TCHAR text[MAX_PATH];
wsprintf(text,_T("鼠标离开: %d,%d"),GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
m_pMousePos->SetText(text); return ;
} LRESULT CPopUpWnd::OnMouseEnter(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_bMouseWithin = true; KillTimer(m_hWnd,ID_TIMER_DISPLAY_DELAY); TCHAR text[MAX_PATH];
wsprintf(text,_T("鼠标进入:%d,%d"),GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
m_pMousePos->SetText(text);
return ;
} LRESULT CPopUpWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lRes = ;
BOOL bHandled = TRUE; switch( uMsg )
{
case WM_NCLBUTTONDBLCLK:
//不做处理
{
return ;
}
break;
case WM_TIMER:
lRes = OnTimer(uMsg,wParam,lParam,bHandled);
break;
case WM_MOUSELEAVE:
lRes = OnMouseLeave(uMsg,wParam,lParam,bHandled);
break;
default:
bHandled = FALSE;
}
return WindowImplBase::HandleMessage(uMsg,wParam,lParam);
}
Duilib 实现右下角弹出像QQ新闻窗口,3秒后自动关闭(一)的更多相关文章
- Duilib 实现右下角弹出像QQ新闻窗口,3秒后窗口透明度渐变最后关闭,若在渐变过程中鼠标放到窗口上,窗口恢复最初状态(二)
效果: 1.定义两个个定时器ID #define ID_TIMER_DISPLAY_DELAY 30 #define ID_TIMER_DISPLAY_CLOSE 40 2.添加一个成员函数和成员变量 ...
- 三、临时弹出一个QQ对话窗口
第一种:需要添加好友才可以访问 <a href="http://wpa.qq.com/msgrd?v=3&uin=317985559&site=qq&menu= ...
- C#利用API制作类似QQ一样的右下角弹出窗体
C#利用API制作类似QQ一样的右下角弹出窗体 (2009-03-21 15:02:49) 转载▼ 标签: 杂谈 分类: .NET using System;using System.Collecti ...
- 搜狗输入法弹出搜狐新闻的解决办法(sohunews.exe)
狗输入法弹出搜狐新闻的解决办法(sohunews.exe) 1.找到搜狗输入法的安装目录(一般是C:\program files\sougou input\版本号\)2.右键点击sohunews.ex ...
- 右下角弹出"Windows-延缓写入失败"或者"xxx-损坏文件 请运行Chkdsk工具"
知识点分析: 任务栏右下角弹出“Windows-延缓写入失败”或者“xxx-损坏文件 请运行Chkdsk工具”. 操作步骤: 方法一:Chkdsk工具 在开始---运行中输入cmd,然后输入chkds ...
- Jquery--仿制360右下角弹出窗口
原文:Jquery--仿制360右下角弹出窗口 先发浏览器效果图,给大家看. 要实现这样的效果,按照思路,第一步,写好CSS布局,将图片放到浏览器右下角的位置 CSS代码很灵活,我写的只是简单的一种而 ...
- C# Winform在win10里弹出无焦点的窗口
原文:C# Winform在win10里弹出无焦点的窗口 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/wangmy1988/article/det ...
- 点击文字弹出一个DIV层窗口代码
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- [转]C# 安装时弹出设置服务登录窗口
本文转自:http://blog.csdn.net/prince_jun/article/details/38435887 安装服务时系统不要弹出设置服务登录窗口:在程序中将serviceProces ...
随机推荐
- 网络层 运输层 NAT路由器 NATP路由器 一根光纤 多个固定ip
长城宽带想要公网和固定ip的来看看吧.[迅雷赚钱宝吧]_百度贴吧 https://tieba.baidu.com/p/4035318158?red_tag=0898389066 连续电话投诉加咨询一周 ...
- php之setcookie
注意在任何发送请求头之前不能有输出,不然会获取不到header头 setcookie(key,value, expires, 'path', domain); 在发送cookie时,会自动把cooki ...
- 邮件的DNS设置
为了反垃圾,在发件人使用的域名下面最好配置两条DNS记录:SPF和DKIM,他们都是用来反垃圾的,邮件接受服务器会检查这两项,只有符合要求才会进入用户的邮箱. 一般来说,大批量发送邮件时,我们会使用第 ...
- 算法抽象及用Python实现具体算法
一.算法抽象 它们一般是在具体算法的基础上总结.提炼.分析出来的,再反过来用于指导解决其它问题.它们适用于某一类问题的解决,用辩 证法的观点看,抽象的算法和具体的算法就是抽象与具体.普遍性与特殊性.共 ...
- MySQL多线程备份工具:mydumper
MySQL多线程备份工具:mydumper http://www.orczhou.com/index.php/2011/12/how-to-split-mysqldump-file/ Mydumper ...
- quic协议实时视频直播
扫盲 https://www.jianshu.com/p/b7546ff9b683 demo https://github.com/felix-001/QuicRtmp https://github. ...
- Py-apply用法学习【转载】
转自:https://blog.csdn.net/anshuai_aw1/article/details/82347016 1.Apply Python中apply函数的格式为:apply(func, ...
- 机器学习理论基础学习17---贝叶斯线性回归(Bayesian Linear Regression)
本文顺序 一.回忆线性回归 线性回归用最小二乘法,转换为极大似然估计求解参数W,但这很容易导致过拟合,由此引入了带正则化的最小二乘法(可证明等价于最大后验概率) 二.什么是贝叶斯回归? 基于上面的讨论 ...
- VS2010/MFC编程入门之三十七(工具栏:工具栏的创建、停靠与使用)
鸡啄米在上一节教程中讲了工具栏资源及CToolBar类,本节继续讲解工具栏的相关知识,主要内容包括工具栏的创建.停靠与使用. 工具栏的使用 上一节中鸡啄米提到过,一般情况下工具栏中的按钮在菜单栏中都有 ...
- minicom的安装和tftp的安装
1.minicom 的安装 在弹出的窗口中选择“Serial port setup”进行配置.配置完之后选择“Save setup as dfl”保存.最后选择“Exit from Minicom”退 ...