一种在注入进程中使用WTL创建无焦点不在任务栏出现“吸附”窗口的方法和思路(三)

2014-11-24 11:21:31 · 作者: · 浏览: 1
ARAM lParam, BOOL& bHandled )
{
return MA_NOACTIVATE; // MA_NOACTIVATEANDEAT亦可
}
最后要特别注意下窗口显示和移动对焦点的影响。在窗口显示时,如果我们使用ShowWindow和MoveWindow这类的函数,会导致我们我们窗口还可以获得焦点。我们要使用SetWindowPos,最后一个参数要带上SWP_NOACTIVATE。
[cpp]
VOID CWTLTitleWindow::ShowWindow()
{
if ( FALSE == IsBaseWindow( m_hAttachHWnd ) ) {
return;
}
int x = 0;
int y = 0;
ECalcResult eResult = CalcTitleWindowXY( x, y );
if ( EError == eResult ) {
::SetWindowPos( m_hWnd, NULL, x, y, TIPWINDTH, TIPHEIGHT, SWP_NOACTIVATE | SWP_HIDEWINDOW );
return;
}
else if ( ENoChange == eResult ) {
return;
}

::SetWindowPos( m_hWnd, NULL, x, y, TIPWINDTH, TIPHEIGHT, SWP_NOACTIVATE | SWP_SHOWWINDOW);
}
最后说一下业务相关的消息传递。在被注入进程的顶层窗口接受到一些消息后,我们会将这些消息传递给我们的窗口,让其做一些处理。为了区分消息来源于顶层窗口还是自己,我将顶层窗口消息处理为一个用户自定义消息。
[cpp]
VOID CWTLTitleWindow::DealMsg( UINT uMsg )
{
::PostMessage( m_hWnd, WM_USER + uMsg, NULL, NULL );
}
消息映射是这么写的,用于处理整个用户自定义消息(而不会处理顶层窗口传来的其用户自定义消息)
[cpp]
MESSAGE_RANGE_HANDLER( WM_USER, WM_USER + WM_USER, OnDealUserMsg )
[cpp] view plaincopy
LRESULT CWTLTitleWindow::OnDealUserMsg( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
UINT uAttachedWindowMsg = uMsg - WM_USER;
if ( IsNeedShowMsg(uAttachedWindowMsg) ) {
ShowWindow();
}
else {
::PostMessage( m_hWnd, uAttachedWindowMsg, wParam, lParam );
}
return 1;
}
外框窗口和标题窗口基本类似,但是其背景是使用画笔画的,而不是通过贴图。另一个很大的区别就是外框窗口是一个空心的异形窗口。这些区别的主要体现是在DoPaint函数中
[cpp]
void CWTLOutSideWindow::DoPaint( HDC dc )
{
CRect rc; www.2cto.com
GetClientRect(&rc);
CMemoryDC MemDc( dc, rc );

HRGN RgnInside = CreateRectRgn( rc.left + WIDTHHEIGHTADD, rc.top + WIDTHHEIGHTADD,
rc.right - WIDTHHEIGHTADD, rc.bottom - WIDTHHEIGHTADD );

HRGN RgnOut = CreateRectRgn( rc.left, rc.top, rc.right, rc.bottom );

CombineRgn( RgnOut, RgnOut, RgnInside, RGN_DIFF );

MemDc.FillRgn( RgnOut, m_brush );
SetWindowRgn( RgnOut, TRUE ); // 设置异形窗口

DeleteObject( RgnInside );
DeleteObject( RgnOut );
}


作者:breaksoftware