StaticMenuGrabber.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:5k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // StaticMenuGrabber.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "commandbarsdesigner.h"
  5. #include "StaticMenuGrabber.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CStaticMenuGrabber
  13. CStaticMenuGrabber::CStaticMenuGrabber()
  14. {
  15. m_hCursor = AfxGetApp()->LoadCursor(IDC_GRABBER);
  16. m_bGrabbing = FALSE;
  17. m_pMenuBar = NULL;
  18. }
  19. CStaticMenuGrabber::~CStaticMenuGrabber()
  20. {
  21. }
  22. BEGIN_MESSAGE_MAP(CStaticMenuGrabber, CStatic)
  23. //{{AFX_MSG_MAP(CStaticMenuGrabber)
  24. ON_WM_PAINT()
  25. ON_WM_LBUTTONDOWN()
  26. //}}AFX_MSG_MAP
  27. END_MESSAGE_MAP()
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CStaticMenuGrabber message handlers
  30. void CStaticMenuGrabber::OnPaint() 
  31. {
  32. CPaintDC dcPaint(this); // device context for painting
  33. CXTPBufferDC dc(dcPaint);
  34. CXTPClientRect rc(this);
  35. dc.FillSolidRect(rc, GetXtremeColor(COLOR_WINDOW));
  36. dc.Draw3dRect(rc, GetXtremeColor(COLOR_BTNSHADOW), GetXtremeColor(COLOR_BTNSHADOW));
  37. CString str;
  38. GetWindowText(str);
  39. CXTPFontDC font(&dc, GetFont());
  40. dc.SetBkMode(TRANSPARENT);
  41. dc.SetTextColor(GetXtremeColor(COLOR_WINDOWTEXT));
  42. if (m_bGrabbing)
  43. {
  44. rc.left += 5 + 32 + 5;
  45. dc.DrawText(_T("Now drag the mouse to select a menu"), rc, DT_VCENTER | DT_LEFT| DT_SINGLELINE);
  46. }
  47. else
  48. {
  49. ::DrawIconEx(dc, rc.left + 5, rc.CenterPoint().y - 16, m_hCursor, 32, 32, 0, 0, DI_NORMAL);
  50. rc.left += 5 + 32 + 5;
  51. dc.DrawText(str, rc, DT_VCENTER | DT_LEFT| DT_SINGLELINE);
  52. }
  53. }
  54. struct XTP_MENUBARINFO
  55. {
  56.     DWORD cbSize;
  57.     RECT  rcBar;          // rect of bar, popup, item
  58.     HMENU hMenu;          // real menu handle of bar, popup
  59.     HWND  hwndMenu;       // hwnd of item submenu if one
  60.     BOOL  fBarFocused:1;  // bar, popup has the focus
  61.     BOOL  fFocused:1;     // item has the focus
  62. };
  63. #ifndef OBJID_MENU
  64. #define OBJID_MENU 0xFFFFFFFD
  65. #endif
  66. void CStaticMenuGrabber::HighlightWindow(HWND hwnd, BOOL fDraw)
  67. {
  68. #define DINV                3
  69. HDC hdc;
  70.     RECT rcWindow;
  71.     RECT rc;
  72. BOOL bBorderOn;
  73.     bBorderOn = fDraw;
  74.     if (hwnd == NULL || !IsWindow(hwnd))
  75.         return;
  76. typedef BOOL (WINAPI* PFNGETMENUBARINFO)( HWND hwnd, LONG idObject, LONG idItem, XTP_MENUBARINFO* pmbi);
  77. HINSTANCE hInst = ::GetModuleHandleA("USER32.DLL");
  78. PFNGETMENUBARINFO pfnGetMenuBarInfo = (PFNGETMENUBARINFO)GetProcAddress(hInst, "GetMenuBarInfo");
  79. if (!pfnGetMenuBarInfo)
  80. return;
  81. XTP_MENUBARINFO mbInfo = {sizeof(mbInfo)};
  82. if (!(*pfnGetMenuBarInfo)(hwnd, OBJID_MENU, 0, &mbInfo))
  83. return;
  84.     hdc = ::GetWindowDC(hwnd);
  85.     ::GetWindowRect(hwnd, &rcWindow);
  86.     rc = mbInfo.rcBar;
  87.     ::OffsetRect(&rc, -rcWindow.left, -rcWindow.top);
  88.     if (!IsRectEmpty(&rc))
  89.     {
  90.         PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, DINV,  DSTINVERT);
  91.         PatBlt(hdc, rc.left, rc.bottom - DINV, DINV,
  92.             -(rc.bottom - rc.top - 2 * DINV), DSTINVERT);
  93.         PatBlt(hdc, rc.right - DINV, rc.top + DINV, DINV,
  94.             rc.bottom - rc.top - 2 * DINV, DSTINVERT);
  95.         PatBlt(hdc, rc.right, rc.bottom - DINV, -(rc.right - rc.left),
  96.             DINV, DSTINVERT);
  97.     }
  98.     ::ReleaseDC(hwnd, hdc);
  99. }
  100. void CStaticMenuGrabber::ConvertMenu(HWND hWnd)
  101. {
  102. if (!m_pMenuBar)
  103. return;
  104. m_pMenuBar->GetControls()->RemoveAll();
  105. HMENU hMenu = ::GetMenu(hWnd);
  106. if (!hMenu)
  107. return;
  108. m_pMenuBar->LoadMenu(CMenu::FromHandle(hMenu));
  109. CXTPClientRect rc(m_pMenuBar->GetParent());
  110. CSize sz = m_pMenuBar->CalcDockingLayout(rc.Width(), /*LM_HIDEWRAP|*/ LM_HORZDOCK|LM_HORZ | LM_COMMIT);
  111. m_pMenuBar->MoveWindow(0, 0, rc.Width(), sz.cy);
  112. m_pMenuBar->Invalidate(FALSE);
  113. }
  114. void CStaticMenuGrabber::OnLButtonDown(UINT /*nFlags*/, CPoint point) 
  115. {
  116. m_bGrabbing = TRUE;
  117. Invalidate(FALSE);
  118. SetCapture();
  119. ::SetCursor(m_hCursor);
  120. HWND hPrevSpyWnd = 0;
  121. BOOL bAccept = FALSE;
  122. for (;;)
  123. {
  124. MSG msg;
  125. VERIFY(::GetMessage(&msg, NULL, 0, 0));
  126. if (msg.message == WM_LBUTTONUP)
  127. {
  128. bAccept = TRUE;
  129. break;
  130. }
  131. else if (msg.message == WM_KEYDOWN)
  132. {
  133. if (msg.wParam == VK_ESCAPE)
  134. break;
  135. }
  136. else if (msg.message == WM_MOUSEMOVE)
  137. {
  138. GetCursorPos(&point);
  139. HWND hWnd = ::WindowFromPoint(point);
  140. CRect rc;
  141. GetWindowRect(rc);
  142. if (rc.PtInRect(point))
  143. hWnd = 0;
  144. HMENU hMenu = hWnd ? ::GetMenu(hWnd) : NULL;
  145. if (!hMenu)
  146. hWnd = NULL;
  147. if(hWnd != hPrevSpyWnd)
  148. {
  149. if(hPrevSpyWnd) HighlightWindow(hPrevSpyWnd, FALSE);
  150. if(hWnd) HighlightWindow(hWnd,TRUE);
  151. hPrevSpyWnd = hWnd;
  152. }
  153. //continue;
  154. }
  155. DispatchMessage (&msg);
  156. if (::GetCapture() != m_hWnd)
  157. break;
  158. }
  159. if (hPrevSpyWnd)
  160. {
  161. HighlightWindow(hPrevSpyWnd, FALSE);
  162. }
  163. ReleaseCapture();
  164. if (bAccept && hPrevSpyWnd)
  165. {
  166. ConvertMenu(hPrevSpyWnd);
  167. }
  168. hPrevSpyWnd = 0;
  169. m_bGrabbing = FALSE;
  170. Invalidate(FALSE);
  171. }