MSN Messenger 类型状态栏弹出消息框






4.35/5 (27投票s)
MSN Messenger 类型状态栏弹出消息框
引言
最近,我发现 Windows 编程中一个有趣的事情是,当有人登录 MSN Messenger 时,状态栏会弹出消息窗口。 我想与大家分享这段代码,如果您也想使用它,但因为没有直接的 API 帮助而无法实现,那么这段代码可以帮助您。
如何使用源代码
在您的项目中包含以下文件
- StatusBarMsgWnd.h
- StatusBarMsgWnd.cpp
以下代码展示了如何创建 CStatusBarMsgWnd
对象并使用它来弹出窗口。我们使用一个伪构造函数 CreateObject()
,因为我们想强制在堆上创建对象。 为了使普通构造函数不可用,我们将其设为 "private
"。我们想在堆上创建对象,因为 PopMsg()
函数会触发定时器,并在函数返回后继续动画显示窗口的弹出和折叠。 因此,消息窗口应该保留在内存中,直到所有定时器都停止并且窗口折叠。 这样,父应用程序的响应速度比我之前使用的 Sleep()
API 更快。 使用 Sleep()
会导致应用程序阻塞,直到窗口被销毁。
CStatusBarMsgWnd* t_MsgWnd = CStatusBarMsgWnd::CreateObject(
_T("Some idiot has signed in !!"), // the message to be displayed
180, // width of the window
150, // height of window
4000, // time for the message to be displayed
10, // delay for animation, how fast the window opens and closes
CRect(30, 30, 130, 110), // rectangle in the window where the
// message will be displayed
this // parent of the message window
);
t_MsgWndMsg.PopMsg();
详细说明
PopMsg()
函数首先检查状态栏在桌面上的位置。只有四种情况:
- 状态栏在屏幕底部
- 状态栏在屏幕顶部
- 状态栏在屏幕左侧
- 状态栏在屏幕右侧
下面显示了 PopMsg()
函数的代码
void CStatusBarMsgWnd::PopMsg()
{
if (CheckIfStatusBarBottom())
// Most frequent case is status bar at bottom
{
PopWndForBottomStatusBar();
}
else
{
if (CheckIfStatusBarTop())
{
PopWndForTopStatusBar();
}
else
{
if (CheckIfStatusBarLeft())
{
PopWndForLeftStatusBar();
}
else
{
PopWndForRightStatusBar();
}
}
}
}
CheckIfStatusBarBottom()
(或 CheckIfStatusBarTop()
,CheckIfStatusBarLeft()
)函数使用 GetSystemMetrics()
和 SystemParatmeterInfo()
API 来计算全屏区域以及屏幕上减去状态栏的区域。 然后,通过一些基本的中学数学知识,我们计算出状态栏的确切位置(底部、顶部、左侧或右侧),并以动画方式显示消息窗口。
真正的操作发生在 OnTimer()
函数中,该函数由 WM_TIMER
消息触发。有三个定时器:
IDT_POP_WINDOW_TIMER
-> 用于动画弹出窗口IDT_SHOW_WINDOW_TIMER
-> 用于显示窗口并保持其位置一段时间IDT_COLLAPSE_WINDOW_TIMER
-> 用于动画窗口折叠
还有三个常量,分别是 STP_BOTTOM
、STP_TOP
、STP_RIGHT
和 STP_LEFT
,它们表示状态栏的位置。这些在 OnTimer()
中用于进行相应的动画计算。
窗口在使用 delete this
在 OnTimer()
函数中折叠后会自动删除。 这就是我们强制在堆上创建此窗口的原因。
类详细信息
类 CStatusBarMsgWnd
派生自 CFrameWnd
。 标题栏在 OnCreate()
成员函数中删除。 创建了两个 CFont
对象,一个带有下划线,另一个没有下划线。 当鼠标位于窗口上方时,我们使用 OnMouseHover()
函数(针对 WM_MOUSEHOVER
消息)显示带有下划线的字体。 类似地,当鼠标离开窗口时,我们使用 OnMouseLeave()
函数(针对 WM_MOUSELEAVE
消息)显示不带下划线的字体。 初始化一个“手”型光标 m_hCursor
,以便在鼠标悬停在窗口上时显示。
重写 OnLButtonDown()
函数,以适应您想要做的任何事情,以处理 WM_LBUTTONDOWN
消息。 目前,OnLButtonDown()
仅显示一个消息框。 您可以更改并执行任何操作以满足您的需求。
int CStatusBarMsgWnd::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
ModifyStyle(WS_CAPTION, 0,
SWP_FRAMECHANGED); // removes title bar
// Start creating two fonts, one underlined ,
// other non underlined
// LOGFONT structure for font properties
LOGFONT lf;
::ZeroMemory (&lf, sizeof (lf));
lf.lfHeight = 100;
lf.lfWeight = FW_BOLD;
lf.lfUnderline = TRUE;
::strcpy (lf.lfFaceName, _T("Arial"));
// Prepare for an underlined font
m_fontMessageUnderline.CreatePointFontIndirect(&lf);
// Prepare an non underlined font
lf.lfUnderline = FALSE;
m_fontMessageNoUnderline.CreatePointFontIndirect(&lf);
// Initialize the cursor.
m_hCursor = ::LoadCursor(NULL, IDC_HAND);
return 0;
}
如何使用演示项目 EXE
双击 popwnd.exe 并使用“消息菜单”来弹出消息窗口。
未来的工作,进行中...
- MSN Messenger 在消息框中使用颜色方案,该颜色取自活动标题栏。