Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
4.2 KiB

  1. // IconCtrl.cpp : Implementation of CIconControl
  2. #include "stdafx.h"
  3. #include "ndmgr.h"
  4. #include "IconControl.h"
  5. #include "findview.h"
  6. #include "util.h"
  7. /////////////////////////////////////////////////////////////////////////////
  8. // CIconControl
  9. const CLSID CLSID_IconControl = {0xB0395DA5, 0x06A15, 0x4E44, {0x9F, 0x36, 0x9A, 0x9D, 0xC7, 0xA2, 0xF3, 0x41}};
  10. //+-------------------------------------------------------------------
  11. //
  12. // Member: CIconControl::ScConnectToAMCViewForImageInfo
  13. //
  14. // Synopsis: Find the CAMCView that hosts this control and ask
  15. // for the icon information.
  16. //
  17. // Arguments:
  18. //
  19. // Returns: SC
  20. //
  21. //--------------------------------------------------------------------
  22. SC CIconControl::ScConnectToAMCViewForImageInfo ()
  23. {
  24. DECLARE_SC(sc, _T("CIconControl::ScGetAMCView"));
  25. HWND hWnd = FindMMCView((*dynamic_cast<CComControlBase*>(this)));
  26. if (!hWnd)
  27. return (sc = E_FAIL);
  28. // check if we need the notch on the right side
  29. m_fLayoutRTL = (::GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL);
  30. m_fAskedForImageInfo = true;
  31. sc = SendMessage(hWnd, MMC_MSG_GET_ICON_INFO, (WPARAM)&m_hIcon, 0);
  32. if (!m_hIcon)
  33. return (sc = E_FAIL);
  34. m_fImageInfoValid = true;
  35. return (sc);
  36. }
  37. //+-------------------------------------------------------------------
  38. //
  39. // Member: CIconControl::OnDraw
  40. //
  41. // Synopsis: Called by the host to draw.
  42. //
  43. // Arguments:
  44. //
  45. // Returns: HRESULT
  46. //
  47. //--------------------------------------------------------------------
  48. HRESULT CIconControl::OnDraw(ATL_DRAWINFO& di)
  49. {
  50. DECLARE_SC(sc, _T("CIconControl::OnDraw"));
  51. RECT& rc = *(RECT*)di.prcBounds;
  52. // If never got the icon, ask CAMCView.
  53. if (!m_fAskedForImageInfo)
  54. {
  55. sc = ScConnectToAMCViewForImageInfo();
  56. if (sc)
  57. return sc.ToHr();
  58. }
  59. // Our attempt to get icon failed, so just return.
  60. if (!m_fImageInfoValid)
  61. {
  62. sc.TraceAndClear();
  63. return sc.ToHr();
  64. }
  65. // Draw the outline. Looks like:
  66. // xxxxxxxxxxxxxxxxxxxxxx
  67. // x x
  68. // x x
  69. // x xx
  70. // x x
  71. // xxxxxxxxxxxxxxxxxxxx <------- "Notch"
  72. // color the complete area
  73. COLORREF bgColor = GetSysColor(COLOR_ACTIVECAPTION);
  74. WTL::CBrush brush;
  75. brush.CreateSolidBrush(bgColor); // background brush
  76. WTL::CDC dc(di.hdcDraw);
  77. // clear the DC
  78. dc.FillRect(&rc, brush);
  79. if(m_bDisplayNotch) //Draw the notch if needed
  80. {
  81. WTL::CRgn rgn;
  82. int roundHeight = 10; // hack
  83. // clear out a quarter circle
  84. int left = (m_fLayoutRTL==false ? rc.right : rc.left) - roundHeight;
  85. int right = (m_fLayoutRTL==false ? rc.right : rc.left) + roundHeight;
  86. int bottom= rc.bottom + roundHeight;
  87. int top = rc.bottom - roundHeight;
  88. rgn.CreateRoundRectRgn(left, top, right, bottom, roundHeight*2, roundHeight*2);
  89. {
  90. COLORREF bgColor = GetSysColor(COLOR_WINDOW);
  91. WTL::CBrush brush;
  92. brush.CreateSolidBrush(bgColor); // background brush
  93. dc.FillRgn(rgn, brush);
  94. }
  95. }
  96. dc.Detach(); // release the DC before exiting!!
  97. const int LEFT_MARGIN = 10;
  98. const int TOP_MARGIN = 5;
  99. POINT ptIconPos = { (m_fLayoutRTL==false ? rc.left + LEFT_MARGIN : rc.right - LEFT_MARGIN -1 ), rc.top + TOP_MARGIN };
  100. // if we are on rtl mode - need to make dc behave that way as well
  101. // For a time we draw an icon ( to appear in place and be flipped correctly )
  102. // (IE does not have RTL dc by default)
  103. DWORD dwLayout=0L;
  104. if ( m_fLayoutRTL && !( (dwLayout=GetLayout(di.hdcDraw)) & LAYOUT_RTL) )
  105. {
  106. LPtoDP( di.hdcDraw, &ptIconPos, 1/*nPoint*/);
  107. SetLayout(di.hdcDraw, dwLayout|LAYOUT_RTL);
  108. DPtoLP( di.hdcDraw, &ptIconPos, 1/*nPoint*/);
  109. }
  110. if (! DrawIconEx(di.hdcDraw, ptIconPos.x, ptIconPos.y, m_hIcon, 0, 0, 0, NULL, DI_NORMAL))
  111. {
  112. sc.FromLastError();
  113. sc.TraceAndClear();
  114. return sc.ToHr();
  115. }
  116. // Restore the DC to its previous layout state.
  117. if ( m_fLayoutRTL && !( dwLayout & LAYOUT_RTL ) )
  118. {
  119. SetLayout(di.hdcDraw, dwLayout);
  120. }
  121. return sc.ToHr();
  122. }