}
return TRUE;
}
如果是原程序创建的窗口,则判断该句柄是否已经存在一个管理“吸附”窗口的线程(该信息保存在一个Map中)。如果不存在,就创建一个管理两个“吸附”窗口的线程,并将
[cpp]
typedef struct _WindowThreadColloction_{
LPCWindowThread lpTitleWindowThread;
}WindowThreadColloction, *pWindowThreadColloction;
typedef std::map
typedef MapHwndThread::iterator MapHwndThreadIter;
[cpp]
LPCWindowThread lpWindowThread = NULL;
lpWindowThread = GetTitleWindowThread( hAttachedWnd );
if ( NULL == lpWindowThread ) {
if ( WM_SHOWWINDOW == uMsg ) {
lpWindowThread = new CWindowThread(hAttachedWnd);
if ( NULL == lpWindowThread ) {
_ASSERT(FALSE);
return;
}
UpdateHwndTitleWindowThread( hAttachedWnd, lpWindowThread );
}
else {
return;
}
}
lpWindowThread->NotifyMsg( uMsg );
}
现在我们将看一下我们管理两个“吸附”窗口的线程类。
[cpp]
class CWindowThread:
public CMessageLoop,
public CMessageFilter
{
public:
CWindowThread(void);
~CWindowThread(void);
public:
CWindowThread(HWND hAttachWindow);
public:
VOID NotifyMsg(UINT uMsg);
VOID ExitThread();
BOOL PreTranslateMessage(MSG* pMsg);
private:
static DWORD WINAPI ThreadRoutine(LPVOID lpParam);
private:
HWND m_hAttachWindow;
HANDLE m_hThread;
CWTLTitleWindow* m_pCWTLTitleWindow;
CWTLOutSideWindow* m_pCWTLOutSideWindow;
};
typedef CWindowThread* LPCWindowThread;
[cpp]
BOOL CWindowThread::PreTranslateMessage( MSG* pMsg )
{
if ( WM_SYSKEYDOWN == pMsg->message ) {
return TRUE;
}
return FALSE;
}
[cpp]
DWORD WINAPI CWindowThread::ThreadRoutine( LPVOID lpParam )
{
CWindowThread* pThis = (CWindowThread*) lpParam;
if ( NULL == pThis ){
return 0xFFFFFFFF;
}
if ( NULL == pThis->m_pCWTLTitleWindow ) {
pThis->m_pCWTLTitleWindow = new CWTLTitleWindow( pThis->m_hAttachWindow );
pThis->m_pCWTLTitleWindow->Create( pThis->m_hAttachWindow ); // 注意这儿要设置为父窗口
pThis->m_pCWTLTitleWindow->RunWindowMsgLoop();
}
if ( NULL == pThis->m_pCWTLOutSideWindow ) {
pThis->m_pCWTLOutSideWindow = new CWTLOutSideWindow( pThis->m_hAttachWindow );
pThis->m_pCWTLOutSideWindow->Create( pThis->m_hAttachWindow ); // 注意这儿要设置为父窗口
pThis->m_pCWTLOutSideWindow->RunWindowMsgLoop();
}
pThis->Run(); // 启动消息循环
return 0;
}
[cpp]
VOID CWindowThread::NotifyMsg( UINT uMsg )
{
if ( m_pCWTLTitleWindow ){
m_pCWTLTitleWindow->DealMsg( uMsg );
}
if ( m_pCWTLOutSideWindow ) {
m_pCWTLOutSideWindow->DealMsg( uMsg );
}
}
下面再来看看窗口的实现。因为我们要做的是“吸附”窗口,该窗口应该不能影响原窗口正常的行为(比如不应该抢焦点,不在任务栏出现),同时考虑到刷新问题,我们要让该窗口具有双缓存。以“标题”窗口为例
[cpp]
class CWTLTitleWindow:
public CDoubleBufferWindowImpl< CWTLTitleWindow, CWindow, CWinTraits
{
public:
typedef CWTLTitleWindow _thisClass;
typedef CDoubleBufferImpl<_thisClass> _baseDblBufImpl;
DECLARE_WND_CLASS_EX(TITILEWINDOWCLASS, CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS, COLOR_WINDOW);
CWTLTitleWindow(void);
~CWTLTitleWindow(void);
public:
CWTLTitleWindow(HWND hA