Phinecos(洞庭散人)
光荣在于平淡,艰巨因为漫长
XBalloonMsg - a non-MFC balloon-shaped message box
原文链接:
XBalloonMsg - a non-MFC balloon-shaped message box
只需要调用下面两个函数:
Function
Description
void
Show
()
显示气泡状信息
void
Destroy
()
从屏幕上删除气泡状信息
//
=============================================================================
//
special symbol for title string - replaced with module name
#define
LPCTSTR_DEFAULT_TITLE ((LPCTSTR)-1L)
//
=============================================================================
class
CXBalloonMsg
//
=============================================================================
{
//
Construction
public
:
CXBalloonMsg();
virtual
~
CXBalloonMsg();
//
Attributes
public
:
static
HWND m_hWndBalloon;
//
Operations
public
:
static
void
Show(LPCTSTR lpszTitle,
LPCTSTR lpszMsg,
HWND hCtrl,
HWND hParent,
HINSTANCE hInstance,
UINT nIcon
=
TTI_INFO,
BOOL bUseBalloonTips
=
TRUE,
UINT nTimeOutSeconds
=
0
,
LPRECT pRect
=
NULL);
static
void
Destroy();
//
Implementation
protected
:
static
LRESULT CALLBACK KeyboardProc(
int
nCode, WPARAM wParam, LPARAM lParam);
static
LRESULT CALLBACK MouseProc(
int
nCode, WPARAM wParam, LPARAM lParam);
static
LRESULT __stdcall DefWindowProcX(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
static
void
CALLBACK TimerProcX(HWND hwnd,
UINT message,
UINT_PTR nIdEvent,
DWORD dwTime);
static
BOOL GetEnableBalloonTips();
static
void
GetStrings(LPCTSTR lpszTitle, LPCTSTR lpszMsg, HINSTANCE hInstance);
static
TCHAR
*
GetModuleName(HINSTANCE hInstance);
static
void
PositionBalloon(LPRECT pRect, LPRECT pNewRect, BOOL bBalloon);
static
BOOL m_bInit;
//
TRUE = initialization finished
static
BOOL m_bUseBalloonTips;
//
TRUE = use balloon tips if possible
static
BOOL m_bBalloon;
//
TRUE = balloon tips not disallowed in
//
registry
static
HINSTANCE m_hInstance;
//
app instance
static
UINT m_nIcon;
//
icon to use
static
UINT m_nLastMessage;
//
last message received
static
UINT m_nTimeOutSeconds;
//
message timeout in seconds;
//
0 = no timeout
static
UINT m_nTimerId;
//
timer id returned by SetTimer()
static
LPRECT m_pRect;
//
NULL = use control rect
static
HWND m_hWnd;
//
hwnd of CXBalloonMsg
static
HWND m_hParent;
//
parent hwnd
static
HWND m_hCtrl;
//
control hwnd
static
WNDPROC m_wndProc;
//
window proc for parent subclassing
static
HHOOK m_hKeyboardHook;
//
keyboard hook
static
HHOOK m_hMouseHook;
//
mouse hook
static
TCHAR m_szTitle[
500
];
//
title string
static
TCHAR m_szMsg[
4000
];
//
message string
}
;
实现代码
//
=============================================================================
//
class variables
//
=============================================================================
BOOL CXBalloonMsg::m_bInit
=
FALSE;
//
未初始化
BOOL CXBalloonMsg::m_bUseBalloonTips
=
TRUE;
//
默认使用气泡效果
BOOL CXBalloonMsg::m_bBalloon
=
TRUE;
HINSTANCE CXBalloonMsg::m_hInstance
=
0
;
UINT CXBalloonMsg::m_nIcon
=
TTI_INFO;
UINT CXBalloonMsg::m_nLastMessage
=
0
;
UINT CXBalloonMsg::m_nTimeOutSeconds
=
0
;
UINT CXBalloonMsg::m_nTimerId
=
0
;
LPRECT CXBalloonMsg::m_pRect
=
0
;
HWND CXBalloonMsg::m_hWnd
=
0
;
HWND CXBalloonMsg::m_hParent
=
0
;
HWND CXBalloonMsg::m_hCtrl
=
0
;
HWND CXBalloonMsg::m_hWndBalloon
=
0
;
WNDPROC CXBalloonMsg::m_wndProc
=
0
;
HHOOK CXBalloonMsg::m_hKeyboardHook
=
0
;
HHOOK CXBalloonMsg::m_hMouseHook
=
0
;
TCHAR CXBalloonMsg::m_szTitle[]
=
{
0
}
;
TCHAR CXBalloonMsg::m_szMsg[]
=
{
0
}
;
//
=============================================================================
CXBalloonMsg::CXBalloonMsg()
//
=============================================================================
{
}
//
=============================================================================
CXBalloonMsg::
~
CXBalloonMsg()
//
=============================================================================
{
if
(m_wndProc
&&
IsWindow(m_hParent))
::SetWindowLong(m_hParent, GWL_WNDPROC, (LONG)m_wndProc);
//
保存窗口处理过程
m_wndProc
=
0
;
}
//
=============================================================================
//
//
Show()
//
//
Purpose: The Show() function creates, displays, and operates a
//
balloon message box. The message box contains an
//
application-defined message and title, a close button,
//
and an optional icon.
//
//
Parameters: lpszTitle - [in] Pointer to a null-terminated string
//
that contains the balloon message title.
//
If this parameter is NULL, no title and
//
no icon will be displayed. The special
//
symbol LPCTSTR_DEFAULT_TITLE may be used;
//
it will cause the executable module name
//
to be displayed.
//
lpszMsg - [in] Pointer to a null-terminated string
//
that contains the balloon message to be
//
displayed. Must not be null.
//
hCtrl - [in] Handle to the control that the
//
message is being displayed for. Must not
//
be null.
//
hParent - [in] Handle to the parent window of the
//
control. Must not be null.
//
hInstance - [in] Handle to the instance of the module
//
that contains the string resource. May
//
be null if string resource is not used.
//
nIcon - [in] Specifies the icon to associate with
//
the balloon message.
//
bUseBalloonTips - [in] Specifies whether balloon tips are
//
to be used to display the message. If
//
this parameter is TRUE, balloon tips will
//
be used unless disabled in the registry.
//
If this parameter is FALSE, regular
//
tooltips will be used, regardless of value
//
of registry key. If not present, this
//
parameter defaults to TRUE.
//
nTimeOutSeconds - [in] Specifies number of seconds before the
//
balloon message is automatically closed. If
//
this parameter is zero, the balloon message
//
will not be automatically closed. If not
//
present, this parameter defaults to zero.
//
pRect - [in] Pointer to a RECT struct that contains
//
position where balloon message is to be
//
displayed. May be null if default position
//
should be used. If not present, this
//
parameter defaults to null.
//
//
Returns: None
//
void
CXBalloonMsg::Show(LPCTSTR lpszTitle,
LPCTSTR lpszMsg,
HWND hCtrl,
HWND hParent,
HINSTANCE hInstance,
UINT nIcon
/**/
/*
= TTI_INFO
*/
,
BOOL bUseBalloonTips
/**/
/*
= TRUE
*/
,
UINT nTimeOutSeconds
/**/
/*
= 0
*/
,
LPRECT pRect
/**/
/*
= NULL
*/
)
{
_ASSERTE(lpszMsg);
_ASSERTE(hCtrl);
_ASSERTE(hParent);
if
(
!
lpszMsg
||
!
hCtrl
||
!
hParent)
{
TRACE(_T(
"
ERROR - bad parameter\n
"
));
return
;
}
if
(
!
IsWindow(hCtrl)
||
!
IsWindow(hParent))
{
TRACE(_T(
"
ERROR - not a valid window handle\n
"
));
return
;
}
Destroy();
//
销毁以前的
m_hParent
=
hParent;
m_hCtrl
=
hCtrl;
m_hInstance
=
hInstance;
m_nIcon
=
nIcon;
m_pRect
=
pRect;
m_bUseBalloonTips
=
bUseBalloonTips;
m_nTimeOutSeconds
=
nTimeOutSeconds;
m_nTimerId
=
0
;
GetStrings(lpszTitle, lpszMsg, hInstance);
//
加载字符串
//
make sure there's a message
_ASSERTE(m_szMsg[
0
]
!=
_T(
'
\0
'
));
if
(m_szMsg[
0
]
==
_T(
'
\0
'
))
return
;
m_bInit
=
FALSE;
//
初始化还未完成
m_nLastMessage
=
0
;
TCHAR
*
pszClassName
=
_T(
"
XBalloonMsg
"
);
WNDCLASS wc
=
{
CS_DBLCLKS,
//
class style - want WM_LBUTTONDBLCLK
DefWindowProcX,
//
window proc
0
,
//
class extra bytes
0
,
//
window extra bytes
hInstance,
//
instance handle
0
,
//
icon
::LoadCursor(
0
, IDC_ARROW),
//
cursor
0
,
//
background brush
0
,
//
menu name
pszClassName
//
class name
}
;
if
(
!
::RegisterClass(
&
wc))
{
//
注册窗口类
DWORD dwLastError
=
GetLastError();
if
(dwLastError
!=
ERROR_CLASS_ALREADY_EXISTS)
{
TRACE(_T(
"
ERROR - RegisterClass failed, GetLastError() returned %u\n
"
), dwLastError);
_ASSERTE(FALSE);
return
;
}
}
m_hWnd
=
::CreateWindowEx(
0
, pszClassName, _T(
""
), WS_POPUP
|
WS_VISIBLE,
30000
,
30000
,
10
,
10
,
m_hParent, (HMENU)
0
, hInstance,
0
);
if
(
!
m_hWnd)
{
TRACE(_T(
"
ERROR - CreateWindowEx failed\n
"
));
_ASSERTE(m_hWnd);
}
else
{
::SetWindowPos(m_hParent, m_hWnd,
0
,
0
,
0
,
0
,
SWP_NOMOVE
|
SWP_NOSIZE);
}
}
//
=============================================================================
//
//
Destroy()
//
//
Purpose: The Destroy() function removes the balloon tip from the
//
screen and destroys the tooltip window.
//
//
Parameters: None
//
//
Returns: None
//
void
CXBalloonMsg::Destroy()
{
TRACE(_T(
"
in CXBalloonMsg::Destroy\n
"
));
if
(m_nTimerId)
::KillTimer(
0
, m_nTimerId);
m_nTimerId
=
0
;
if
(m_wndProc
&&
IsWindow(m_hParent))
::SetWindowLong(m_hParent, GWL_WNDPROC, (LONG)m_wndProc);
m_wndProc
=
0
;
if
(IsWindow(m_hWndBalloon))
{
::SendMessage(m_hWndBalloon, TTM_POP,
0
,
0
);
::PostMessage(m_hWndBalloon, WM_CLOSE,
0
,
0
);
}
m_hWndBalloon
=
0
;
if
(IsWindow(m_hWnd))
::DestroyWindow(m_hWnd);
}
//
=============================================================================
//
//
KeyboardProc()
//
//
Purpose: Callback function set by the SetWindowsHookEx() function.
//
The system calls this function whenever an application
//
calls the GetMessage or PeekMessage function and there is a
//
keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.
//
//
Parameters: nCode - hook code
//
wParam - virtual-key code
//
lParam - keystroke-message information
//
//
Returns: LRESULT - 1 to prevent the system from passing the message on;
//
or the return value from CallNextHookEx().
//
LRESULT CALLBACK CXBalloonMsg::KeyboardProc(
int
nCode,
WPARAM wParam,
LPARAM lParam)
{
if
((nCode
>=
0
)
&&
((lParam
&
0x80000000
)
==
0
)
&&
//
ignore key releases
(wParam
!=
VK_CONTROL)
&&
(wParam
!=
VK_SHIFT)
&&
(wParam
!=
VK_MENU))
{
LRESULT rc
=
1
;
if
(wParam
==
VK_ESCAPE
||
wParam
==
VK_RETURN
||
wParam
==
VK_TAB
||
wParam
==
VK_LEFT
||
wParam
==
VK_UP
||
wParam
==
VK_RIGHT
||
wParam
==
VK_DOWN
||
((wParam
>=
VK_F1)
&&
(wParam
<=
VK_F24))
)
{
//
don't forward these keystrokes
}
else
{
rc
=
CallNextHookEx(m_hKeyboardHook, nCode, wParam, lParam);