精通
英语
和
开源
,
擅长
开发
与
培训
,
胸怀四海
第一信赖
1.本软件实现了桌面自动隐藏侧边栏,栏内显示动态图形。
2.使用的技术有鼠标钩子,钩子实现框架封装成类,主框架窗口和钩子结合,简单图形控制。
3.钩子实现框架,接口简单,灵活易用。
核心代码如下:
/////////////////////////////////////////////////////////////////////////////
// CAppBarMngr message handlers
//------------------------------------------------------------------------------------
// Function: Init - Loads DLL functions and initilize mouse hook
// Arguments: _hWnd - Handler of window to manage
// _width - Desired width of managed window
// _left - True if window is left side docked, false if not
// Returns: APPBARHOOK_DLLERROR - An error has ocurred while loading DLL functions
// APPBARHOOK_ALREADYHOOKED - Another instance has hooked mouse
// APPBARHOOK_SUCCESS - All is OK
//------------------------------------------------------------------------------------
int CAppBarMngr::Init(HWND _hWnd, int _width, bool _left)
{
m_Module = ::LoadLibrary("AppBarHook.dll"); // Load DLL
if (!m_Module)
return APPBARHOOK_DLLERROR;
m_fpSetHook = (TFSetHook)::GetProcAddress(m_Module, "SetHook"); // Load function
if (m_fpSetHook) // If function has been loaded sucessfully
{
m_pWindow = CWnd::FromHandle(_hWnd);
m_Left = _left; // Set orientation and width
m_Width = _width;
// Get the Display area for multi-monitor usage
HDC hdc = ::GetDC(NULL);
::GetClipBox(hdc, &m_Screen);
::ReleaseDC(NULL, hdc);
// Make a first slide
if (m_Left)
SlideWindow(m_Screen.left, false);
else
SlideWindow(m_Screen.right-m_Width, true);
if (!(*m_fpSetHook)(this->m_nThreadID, m_Width, m_Left)) // Invoke SetHook function
{
::FreeLibrary(m_Module); // Clean DLL reference
m_Module = NULL;
return APPBARHOOK_ALREADYHOOKED; // Already hooked, maybe second instance
}
return APPBARHOOK_SUCCESS; // All is OK
} else {
::FreeLibrary(m_Module); // Clean DLL reference
m_Module = NULL;
return APPBARHOOK_DLLERROR;
}
}
//-----------------------------------------------------------------------------------------------
// Function: PreTranslateMessage - Receive messages from hook module
// Arguments: pMsg - Pointer to message
// Messages: WM_USER+2 - Border of screen has been touched - possibly must make window to appear
// WM_USER+3 - Mouse cursor is outside window area - possibly must make window to hide
//-----------------------------------------------------------------------------------------------
BOOL CAppBarMngr::PreTranslateMessage(MSG* pMsg)
{
static CRect rect;
switch (pMsg->message) {
case WM_USER+2: // Activate (border touched)
m_pWindow->GetWindowRect(&rect);
if (m_Left) { // If window is left sided
if (rect.left<m_Screen.left) // Evaluate if window must appear
{
SlideWindow(m_Screen.left-m_Width, true); // Slide it from left to right
}
} else { // If window is right sided
if (rect.right>m_Screen.right) // Evaluate if window must appear
SlideWindow(m_Screen.right, false); // Slide it from right to left
}
break;
case WM_USER+3: // Deactivate (hide)
m_pWindow->GetWindowRect(&rect);
if (m_Left) { // If window is left sided
if (rect.left>=m_Screen.left) // Evaluate if window must disappear
{
SlideWindow(m_Screen.left, false); // Slide it from right to left
}
} else { // If window is right sided
if (rect.left<m_Screen.right) // Evaluate if window must disappear
SlideWindow(m_Screen.right-m_Width, true);// Slide it from left to right
}
break;
}
return CWinThread::PreTranslateMessage(pMsg);
}
//-----------------------------------------------------------------------------------------------
// Function: SlideWindow - Slide window in any orientation smoothly
// Arguments: xStart - Starting horizontal screen coordinate
// left2right - Sliding orientation, true for left to right, false for countersense
//-----------------------------------------------------------------------------------------------
void CAppBarMngr::SlideWindow(int xStart, bool left2right)
{
int maxdelay = 5; // delay between steps (miliseconds)
int h = ::GetSystemMetrics(SM_CYSCREEN); // Screen height (pixels)
int x; // instantaneous left side position (screen coords)
unsigned int t; // time for next step
float step = (float)m_Width / 10.0f; // step size (pixels)
for (int i=0, delay=maxdelay; i<=10; i++, delay+=2) {
t = ::GetTickCount() + delay; // Calculate next next time
x = xStart + (int)(i*step) * (left2right?1:-1); // Step window pos
m_pWindow->SetWindowPos(&CWnd::wndTopMost, x, 0, m_Width, 500, SWP_SHOWWINDOW); // Do move
while (::GetTickCount()<t) // Wait for next step
::Sleep(1);
}
}