#include "StdAfx.h" #include "..\include\skinmenu.h" #include "..\include\PopupMenuSkin.h" CPopupMenuSkin *CSkinMenu::m_pPopupMenuSkin = GetSkin().GetPopupMenuSkin(); ////////////////////////////////////////////////////////////////////// HHOOK CSkinMenu::m_hMsgHook = NULL; LPCTSTR CSkinMenu::wpnOldProc = _T("RAZA_MenuOldWndProc"); BOOL CSkinMenu::m_bPrinted = TRUE; int CSkinMenu::m_nEdgeLeft = 1; int CSkinMenu::m_nEdgeTop = 1; int CSkinMenu::m_nEdgeSize = 1; ////////////////////////////////////////////////////////////////////// // CCoolMenu modern version check CSkinMenu::CSkinMenu(void) { } CSkinMenu::~CSkinMenu(void) { } BOOL CSkinMenu::IsModernVersion() { OSVERSIONINFO pVersion; pVersion.dwOSVersionInfoSize = sizeof(pVersion); GetVersionEx( &pVersion ); return TRUE; } void CSkinMenu::EnableHook() { m_pPopupMenuSkin = GetSkin().GetPopupMenuSkin(); ASSERT( m_hMsgHook == NULL ); ASSERT( m_bUnhook == FALSE ); m_bEnable = IsModernVersion(); if ( ! m_bEnable ) return; m_bUnhook = TRUE; EnableHook( TRUE ); } void CSkinMenu::EnableHook(BOOL bEnable) { m_pPopupMenuSkin = GetSkin().GetPopupMenuSkin(); if ( bEnable == ( m_hMsgHook != NULL ) ) return; if ( bEnable ) { m_hMsgHook = SetWindowsHookEx( WH_CALLWNDPROC, MsgHook, AfxGetInstanceHandle(), GetCurrentThreadId() ); } else { UnhookWindowsHookEx( m_hMsgHook ); m_hMsgHook = NULL; } } void CSkinMenu::RegisterEdge(int nLeft, int nTop, int nLength) { m_nEdgeLeft = nLeft; m_nEdgeTop = nTop; m_nEdgeSize = nLength; } LRESULT CALLBACK CSkinMenu::MsgHook(int nCode, WPARAM wParam, LPARAM lParam) { CWPSTRUCT* pCWP = (CWPSTRUCT*)lParam; while ( nCode == HC_ACTION ) { if ( pCWP->message != WM_CREATE && pCWP->message != 0x01E2 ) break; TCHAR szClassName[16]; int nClassName = GetClassName( pCWP->hwnd, szClassName, 16 ); if ( nClassName != 6 || _tcscmp( szClassName, _T("#32768") ) != 0 ) break; if ( ::GetProp( pCWP->hwnd, wpnOldProc ) != NULL ) break; /*HWND hWndFore = GetForegroundWindow(); if ( hWndFore != NULL && CWnd::FromHandlePermanent( hWndFore ) == NULL ) break;*/ WNDPROC pWndProc = (WNDPROC)(LONG_PTR)::GetWindowLong( pCWP->hwnd, GWL_WNDPROC ); if ( pWndProc == NULL ) break; ASSERT( pWndProc != MenuProc ); if ( ! SetProp( pCWP->hwnd, wpnOldProc, pWndProc ) ) break; if ( ! SetWindowLong( pCWP->hwnd, GWL_WNDPROC, (DWORD)(DWORD_PTR)MenuProc ) ) { ::RemoveProp( pCWP->hwnd, wpnOldProc ); break; } break; } return CallNextHookEx( CSkinMenu::m_hMsgHook, nCode, wParam, lParam ); } LRESULT CALLBACK CSkinMenu::MenuProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { WNDPROC pWndProc = (WNDPROC)::GetProp( hWnd, wpnOldProc ); switch ( uMsg ) { case WM_NCCALCSIZE: { NCCALCSIZE_PARAMS* pCalc = (NCCALCSIZE_PARAMS*)lParam; pCalc->rgrc[0].left ++; pCalc->rgrc[0].top ++; pCalc->rgrc[0].right --; pCalc->rgrc[0].bottom --; pCalc->rgrc[0].bottom --; } return 0; case WM_WINDOWPOSCHANGING: if ( WINDOWPOS* pWndPos = (WINDOWPOS*)lParam ) { DWORD nStyle = GetWindowLong( hWnd, GWL_STYLE ); DWORD nExStyle = GetWindowLong( hWnd, GWL_EXSTYLE ); CRect rc( 0, 0, 32, 32 ); AdjustWindowRectEx( &rc, nStyle, FALSE, nExStyle ); pWndPos->cx -= ( rc.Width() - 34 ); pWndPos->cy -= ( rc.Height() - 34 ) - 1; if ( pWndPos->x != m_nEdgeLeft || pWndPos->y != m_nEdgeTop ) pWndPos->x ++; } break; case WM_PRINT: if ( ( lParam & PRF_CHECKVISIBLE ) && ! IsWindowVisible( hWnd ) ) return 0; if ( lParam & PRF_NONCLIENT ) { CWnd* pWnd = CWnd::FromHandle( hWnd ); CDC* pDC = CDC::FromHandle( (HDC)wParam ); CRect rc; pWnd->GetWindowRect( &rc ); BOOL bEdge = ( rc.left == m_nEdgeLeft && rc.top == m_nEdgeTop ); rc.OffsetRect( -rc.left, -rc.top ); pDC->Draw3dRect( &rc, m_pPopupMenuSkin->m_colorBackground,m_pPopupMenuSkin->m_colorBackground ); if ( bEdge ) pDC->FillSolidRect( rc.left + 1, rc.top, min( rc.Width(), m_nEdgeSize ) - 2, 1, m_pPopupMenuSkin->m_colorBackground); } if ( lParam & PRF_CLIENT ) { CWnd* pWnd = CWnd::FromHandle( hWnd ); CDC* pDC = CDC::FromHandle( (HDC)wParam ); CBitmap bmBuf, *pbmOld; CDC dcBuf; CRect rc; pWnd->GetClientRect( &rc ); dcBuf.CreateCompatibleDC( pDC ); bmBuf.CreateCompatibleBitmap( pDC, rc.Width(), rc.Height() ); pbmOld = (CBitmap*)dcBuf.SelectObject( &bmBuf ); m_bPrinted = TRUE; dcBuf.FillSolidRect( &rc, GetSysColor( COLOR_MENU ) ); SendMessage( hWnd, WM_PRINTCLIENT, (WPARAM)dcBuf.GetSafeHdc(), 0 ); pDC->BitBlt( 1, 1, rc.Width(), rc.Height(), &dcBuf, 0, 0, SRCCOPY ); dcBuf.SelectObject( pbmOld ); } return 0; case WM_NCPAINT: { CWnd* pWnd = CWnd::FromHandle( hWnd ); CWindowDC dc( pWnd ); CRect rc; pWnd->GetWindowRect( &rc ); BOOL bEdge = ( rc.left == m_nEdgeLeft && rc.top == m_nEdgeTop ); rc.OffsetRect( -rc.left, -rc.top ); dc.Draw3dRect( &rc, m_pPopupMenuSkin->m_colorBackground, m_pPopupMenuSkin->m_colorBackground ); if ( bEdge ) dc.FillSolidRect( rc.left + 1, rc.top, min( rc.Width(), m_nEdgeSize ) - 2, 1, m_pPopupMenuSkin->m_colorBackground ); } return 0; case WM_PAINT: m_bPrinted = FALSE; break; case WM_NCDESTROY: ::RemoveProp( hWnd, wpnOldProc ); break; } return CallWindowProc( pWndProc, hWnd, uMsg, wParam, lParam ); }