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.

253 lines
7.8 KiB

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. class CCompPreview
  4. {
  5. public:
  6. protected:
  7. HWND _hwnd;
  8. HBITMAP _hbmMonitor;
  9. HDC _hdcCompMemory;
  10. int _iScreenWidth;
  11. int _iScreenHeight;
  12. int _iXBorders;
  13. int _iYBorders;
  14. static LRESULT CALLBACK CompPreviewWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
  15. friend BOOL RegisterCompPreviewClass(void);
  16. LONG _OnCreate(HWND hwnd);
  17. void _OnDestroy(void);
  18. void _OnPaint(void);
  19. void _RecalcMetrics(void);
  20. };
  21. void CCompPreview::_RecalcMetrics(void)
  22. {
  23. RECT rect;
  24. SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE);
  25. _iScreenWidth = rect.right - rect.left;
  26. _iScreenHeight = rect.bottom - rect.top;
  27. _iXBorders = (2 * GET_CXSIZE);
  28. _iYBorders = (GET_CYSIZE + GET_CYCAPTION);
  29. }
  30. LONG CCompPreview::_OnCreate(HWND hwnd)
  31. {
  32. LONG lRet = 0;
  33. _hwnd = hwnd;
  34. SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
  35. HDC hdc = GetDC(NULL);
  36. _hdcCompMemory = CreateCompatibleDC(hdc);
  37. ReleaseDC(NULL, hdc);
  38. _hbmMonitor = LoadMonitorBitmap();
  39. if (_hbmMonitor == NULL)
  40. {
  41. lRet = -1;
  42. }
  43. _RecalcMetrics(); //Initialize the screen width and height etc.,
  44. return lRet;
  45. }
  46. void CCompPreview::_OnDestroy()
  47. {
  48. if (_hbmMonitor)
  49. {
  50. DeleteObject(_hbmMonitor);
  51. }
  52. if (_hdcCompMemory)
  53. {
  54. DeleteDC(_hdcCompMemory);
  55. }
  56. delete this;
  57. }
  58. void CCompPreview::_OnPaint()
  59. {
  60. PAINTSTRUCT ps;
  61. BITMAP bm;
  62. RECT rc;
  63. BeginPaint(_hwnd,&ps);
  64. if (_hbmMonitor)
  65. {
  66. DWORD dwDefWidth = (_iScreenWidth / (COMPONENT_PER_ROW + 1)) - _iXBorders;
  67. DWORD dwDefHeight = (_iScreenHeight / (COMPONENT_PER_COL + 1)) - _iYBorders;
  68. //
  69. // Select the monitor bitmap into an hdc.
  70. //
  71. HBITMAP hbmOld = (HBITMAP)SelectObject(_hdcCompMemory, _hbmMonitor);
  72. //
  73. // Get the size of the bitmap and of our window.
  74. //
  75. GetClientRect(_hwnd, &rc);
  76. GetObject(_hbmMonitor, sizeof(bm), &bm);
  77. //
  78. // Center the bitmap in the window.
  79. //
  80. rc.left = ( rc.right - bm.bmWidth ) / 2;
  81. rc.top = ( rc.bottom - bm.bmHeight ) / 2;
  82. BitBlt(ps.hdc, rc.left, rc.top, bm.bmWidth, bm.bmHeight, _hdcCompMemory,
  83. 0, 0, SRCCOPY);
  84. SelectObject(_hdcCompMemory, hbmOld);
  85. //
  86. // From now on, only paint in the "monitor" area of the bitmap.
  87. //
  88. IntersectClipRect(ps.hdc, rc.left + MON_X, rc.top + MON_Y, rc.left + MON_X + MON_DX, rc.top + MON_Y + MON_DY);
  89. //
  90. // Determine who the selected component is.
  91. //
  92. int iSelectedComponent;
  93. SendMessage(GetParent(_hwnd), WM_COMP_GETCURSEL, 0, (LPARAM)&iSelectedComponent);
  94. //
  95. // Create two new brush/pen combos, and remember the original
  96. // brush & pen.
  97. //
  98. HBRUSH hbrushActComp = CreateSolidBrush(GetSysColor(COLOR_ACTIVECAPTION));
  99. HPEN hpenActComp = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_CAPTIONTEXT));
  100. HBRUSH hbrushComp = CreateSolidBrush(GetSysColor(COLOR_INACTIVECAPTION));
  101. HPEN hpenComp = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_INACTIVECAPTIONTEXT));
  102. HBRUSH hbrushOld = (HBRUSH)SelectObject(ps.hdc, hbrushComp);
  103. HPEN hpenOld = (HPEN)SelectObject(ps.hdc, hpenComp);
  104. int iPrimaryMonitorX = -GetSystemMetrics(SM_XVIRTUALSCREEN);
  105. int iPrimaryMonitorY = -GetSystemMetrics(SM_YVIRTUALSCREEN);
  106. int iPrimaryMonitorCX = GetSystemMetrics(SM_CXSCREEN);
  107. int iPrimaryMonitorCY = GetSystemMetrics(SM_CYSCREEN);
  108. //
  109. // Draw each component in the "monitor" area of the bitmap.
  110. //
  111. int i, cComp;
  112. g_pActiveDeskAdv->GetDesktopItemCount(&cComp, 0);
  113. for (i=0; i < cComp; i++)
  114. {
  115. COMPONENT comp;
  116. comp.dwSize = sizeof(COMPONENT);
  117. if (SUCCEEDED(g_pActiveDeskAdv->GetDesktopItem(i, &comp, 0)) && (comp.fChecked))
  118. {
  119. // FEATURE: We show only components in the primary monitor in IE v4.01
  120. if (comp.cpPos.iLeft < iPrimaryMonitorX
  121. || comp.cpPos.iLeft > iPrimaryMonitorX + iPrimaryMonitorCX
  122. || comp.cpPos.iTop < iPrimaryMonitorY
  123. || comp.cpPos.iTop > iPrimaryMonitorY + iPrimaryMonitorCY)
  124. {
  125. continue;
  126. }
  127. // If the width or Height is -1, then we don't know what the actual
  128. // size is going to be. So, we try to give a default size here for comp
  129. // in the preview bitmap.
  130. DWORD dwCompWidth = (comp.cpPos.dwWidth == COMPONENT_DEFAULT_WIDTH)? dwDefWidth : comp.cpPos.dwWidth;
  131. DWORD dwCompHeight = (comp.cpPos.dwHeight == COMPONENT_DEFAULT_HEIGHT)? dwDefHeight : comp.cpPos.dwHeight;
  132. if (i == iSelectedComponent)
  133. {
  134. SelectObject(ps.hdc, hbrushActComp);
  135. SelectObject(ps.hdc, hpenActComp);
  136. }
  137. int nLeft = rc.left + MON_X + MulDiv(comp.cpPos.iLeft - iPrimaryMonitorX, MON_DX, GetDeviceCaps(_hdcCompMemory, HORZRES));
  138. int nTop = rc.top + MON_Y + MulDiv(comp.cpPos.iTop - iPrimaryMonitorY, MON_DY, GetDeviceCaps(_hdcCompMemory, VERTRES));
  139. int nRight = rc.left + MON_X + MulDiv((comp.cpPos.iLeft - iPrimaryMonitorX) + dwCompWidth, MON_DX, GetDeviceCaps(_hdcCompMemory, HORZRES));
  140. int nBottom = rc.top + MON_Y + MulDiv((comp.cpPos.iTop - iPrimaryMonitorY)+ dwCompHeight, MON_DY, GetDeviceCaps(_hdcCompMemory, VERTRES));
  141. Rectangle(ps.hdc, nLeft, nTop, nRight, nBottom);
  142. if (i == iSelectedComponent)
  143. {
  144. SelectObject(ps.hdc, hbrushComp);
  145. SelectObject(ps.hdc, hpenComp);
  146. }
  147. }
  148. }
  149. SelectObject(ps.hdc, hpenOld);
  150. SelectObject(ps.hdc, hbrushOld);
  151. DeleteObject(hpenComp);
  152. DeleteObject(hbrushComp);
  153. DeleteObject(hpenActComp);
  154. DeleteObject(hbrushActComp);
  155. }
  156. EndPaint(_hwnd,&ps);
  157. }
  158. LRESULT CALLBACK CCompPreview::CompPreviewWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  159. {
  160. CCompPreview *pcp = (CCompPreview *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  161. switch(message)
  162. {
  163. case WM_CREATE:
  164. pcp = new CCompPreview();
  165. return pcp ? pcp->_OnCreate(hwnd) : -1;
  166. case WM_DESTROY:
  167. pcp->_OnDestroy();
  168. break;
  169. case WM_PAINT:
  170. pcp->_OnPaint();
  171. return 0;
  172. case WM_DISPLAYCHANGE:
  173. case WM_WININICHANGE:
  174. pcp->_RecalcMetrics();
  175. break;
  176. // 98/09/01 vtan #190588: WM_SYSCOLORCHANGE is passed when the desktop
  177. // background color is changed. This message is passed to the property
  178. // sheet common control which sends the message through to all the
  179. // children. The message is now processed here. The old monitor background
  180. // bitmap is discarded and a new one created with the current (new)
  181. // setting.
  182. case WM_SYSCOLORCHANGE:
  183. if (pcp->_hbmMonitor != NULL)
  184. {
  185. DeleteObject(pcp->_hbmMonitor);
  186. pcp->_hbmMonitor = LoadMonitorBitmap();
  187. }
  188. break;
  189. }
  190. return DefWindowProc(hwnd,message,wParam,lParam);
  191. }
  192. BOOL RegisterCompPreviewClass(void)
  193. {
  194. WNDCLASS wc;
  195. if (!GetClassInfo(HINST_THISDLL, c_szComponentPreview, &wc)) {
  196. wc.style = 0;
  197. wc.lpfnWndProc = CCompPreview::CompPreviewWndProc;
  198. wc.cbClsExtra = 0;
  199. wc.cbWndExtra = 0;
  200. wc.hInstance = HINST_THISDLL;
  201. wc.hIcon = NULL;
  202. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  203. wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1);
  204. wc.lpszMenuName = NULL;
  205. wc.lpszClassName = c_szComponentPreview;
  206. if (!RegisterClass(&wc))
  207. return FALSE;
  208. }
  209. return TRUE;
  210. }