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.

364 lines
9.8 KiB

  1. /*
  2. * RESIMAGE.C
  3. *
  4. * Implementation of the Results Image control for OLE 2.0 UI dialogs.
  5. * We need a separate control for dialogs in order to control the repaints
  6. * properly and to provide a clean message interface for the dialog
  7. * implementations.
  8. *
  9. * Copyright (c)1992 Microsoft Corporation, All Right Reserved
  10. */
  11. #define STRICT 1
  12. #include "ole2ui.h"
  13. #include "resimage.h"
  14. OLEDBGDATA
  15. //Flag indicating if we've registered the class
  16. static BOOL fRegistered=FALSE;
  17. //Bitmap and image dimensions for result images.
  18. static HBITMAP hBmpResults=NULL;
  19. static UINT cxBmpResult=0;
  20. static UINT cyBmpResult=0;
  21. /*
  22. * FResultImageInitialize
  23. *
  24. * Purpose:
  25. * Attempts to load result bitmaps for the current display driver
  26. * for use in OLE 2.0 UI dialogs. Also registers the ResultImage
  27. * control class.
  28. *
  29. * Parameters:
  30. * hInst HINSTANCE instance of the DLL.
  31. *
  32. * hPrevInst HINSTANCE of the previous instance. Used to
  33. * determine whether to register window classes or not.
  34. *
  35. * lpszClassName LPSTR containing the class name to register the
  36. * ResultImage control class with.
  37. *
  38. * Return Value:
  39. * BOOL TRUE if all initialization succeeded, FALSE otherwise.
  40. */
  41. BOOL FResultImageInitialize(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpszClassName)
  42. {
  43. int cx, iBmp;
  44. HDC hDC;
  45. BITMAP bm;
  46. WNDCLASS wc;
  47. /*
  48. * Determine the aspect ratio of the display we're currently
  49. * running on and load the appropriate bitmap into the global
  50. * hBmpResults (used from the ResultImage control only).
  51. *
  52. * By retrieving the logical Y extent of the display driver, you
  53. * only have limited possibilities:
  54. * LOGPIXELSY Display
  55. * ----------------------------------------
  56. * 48 CGA (unsupported)
  57. * 72 EGA
  58. * 96 VGA
  59. * 120 8514/a (i.e. HiRes VGA)
  60. */
  61. hDC=GetDC(NULL);
  62. if (NULL==hDC)
  63. return FALSE;
  64. cx=GetDeviceCaps(hDC, LOGPIXELSY);
  65. ReleaseDC(NULL, hDC);
  66. /*
  67. * Instead of single comparisons, check ranges instead, so in case
  68. * we get something funky, we'll act reasonable.
  69. */
  70. if (72 >=cx) iBmp=IDB_RESULTSEGA;
  71. if (72 < cx && 120 > cx) iBmp=IDB_RESULTSVGA;
  72. if (120 <=cx) iBmp=IDB_RESULTSHIRESVGA;
  73. hBmpResults=LoadBitmap(hInst, MAKEINTRESOURCE(iBmp));
  74. if (NULL==hBmpResults)
  75. {
  76. //On error, fail loading the DLL
  77. OleDbgOut1(TEXT("FResultImageInitialize: Failed LoadBitmap.\r\n"));
  78. return FALSE;
  79. }
  80. OleDbgOut4(TEXT("FResultImageInitialize: Loaded hBmpResults\r\n"));
  81. //Now that we have the bitmap, calculate image dimensions
  82. GetObject(hBmpResults, sizeof(BITMAP), &bm);
  83. cxBmpResult=bm.bmWidth;
  84. cyBmpResult=bm.bmHeight/CIMAGESY;
  85. // Only register class if we're the first instance
  86. if (hPrevInst)
  87. fRegistered = TRUE;
  88. else
  89. {
  90. // Static flag fRegistered guards against calling this function more
  91. // than once in the same instance
  92. if (!fRegistered)
  93. {
  94. wc.lpfnWndProc =ResultImageWndProc;
  95. wc.cbClsExtra =0;
  96. wc.cbWndExtra =CBRESULTIMAGEWNDEXTRA;
  97. wc.hInstance =hInst;
  98. wc.hIcon =NULL;
  99. wc.hCursor =LoadCursor(NULL, IDC_ARROW);
  100. wc.hbrBackground =NULL;
  101. wc.lpszMenuName =NULL;
  102. wc.lpszClassName =lpszClassName;
  103. wc.style =CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW;
  104. fRegistered = RegisterClass(&wc);
  105. }
  106. }
  107. return fRegistered;
  108. }
  109. /*
  110. * ResultImageUninitialize
  111. *
  112. * Purpose:
  113. * Cleans up anything done in FResultImageInitialize, such as freeing
  114. * the bitmaps. Call from WEP.
  115. *
  116. * Parameters:
  117. * None
  118. *
  119. * Return Value:
  120. * None
  121. */
  122. void ResultImageUninitialize(void)
  123. {
  124. if (NULL!=hBmpResults)
  125. {
  126. DeleteObject(hBmpResults);
  127. }
  128. return;
  129. }
  130. /*
  131. * ResultImageWndProc
  132. *
  133. * Purpose:
  134. * Window Procedure for the ResultImage custom control. Only handles
  135. * WM_CREATE, WM_PAINT, and private messages to manipulate the bitmap.
  136. *
  137. * Parameters:
  138. * Standard
  139. *
  140. * Return Value:
  141. * Standard
  142. */
  143. LONG CALLBACK EXPORT ResultImageWndProc(HWND hWnd, UINT iMsg
  144. , WPARAM wParam, LPARAM lParam)
  145. {
  146. UINT iBmp;
  147. PAINTSTRUCT ps;
  148. HDC hDC;
  149. //Handle standard Windows messages.
  150. switch (iMsg)
  151. {
  152. case WM_CREATE:
  153. SetWindowWord(hWnd, RIWW_IMAGEINDEX, RESULTIMAGE_NONE);
  154. return 0L;
  155. case WM_PAINT:
  156. iBmp=GetWindowWord(hWnd, RIWW_IMAGEINDEX);
  157. hDC=BeginPaint(hWnd, &ps);
  158. if (RESULTIMAGE_NONE!=iBmp)
  159. {
  160. RECT rc;
  161. UINT x, y;
  162. HDC hDCDlg;
  163. HBRUSH hBr;
  164. LOGBRUSH lb;
  165. HWND hDlg;
  166. /*
  167. * Our job before using TransparantBlt is to figure out
  168. * where to position the result image. We place it centered
  169. * on this control, so get our rect's center and subtract
  170. * half of the image dimensions.
  171. */
  172. GetClientRect(hWnd, &rc);
  173. x=(rc.right+rc.left-cxBmpResult)/2;
  174. y=(rc.bottom+rc.top-cyBmpResult)/2;
  175. //Get the backgroup color the dialog is using.
  176. hDlg=GetParent(hWnd);
  177. hDCDlg=GetDC(hDlg);
  178. #if defined( WIN32 )
  179. hBr = (HBRUSH)SendMessage(hDlg,
  180. WM_CTLCOLORDLG,
  181. (WPARAM)hDCDlg,
  182. (LPARAM)hDlg);
  183. #else
  184. hBr = (HBRUSH)SendMessage(hDlg,
  185. WM_CTLCOLOR,
  186. (WPARAM)hDCDlg,
  187. MAKELPARAM(hDlg, CTLCOLOR_DLG));
  188. #endif
  189. ReleaseDC(hDlg, hDCDlg);
  190. GetObject(hBr, sizeof(LOGBRUSH), &lb);
  191. SetBkColor(hDC, lb.lbColor);
  192. TransparantBlt(hDC, x, y, hBmpResults, 0, iBmp*cyBmpResult
  193. , cxBmpResult, cyBmpResult, RGBTRANSPARENT);
  194. }
  195. EndPaint(hWnd, &ps);
  196. break;
  197. case RIM_IMAGESET:
  198. //wParam contains the new index.
  199. iBmp=GetWindowWord(hWnd, RIWW_IMAGEINDEX);
  200. //Validate the index before changing it and repainting
  201. if (RESULTIMAGE_NONE==wParam ||
  202. ((RESULTIMAGE_MIN <= wParam) && (RESULTIMAGE_MAX >= wParam)))
  203. {
  204. SetWindowWord(hWnd, RIWW_IMAGEINDEX, (WORD)wParam);
  205. InvalidateRect(hWnd, NULL, FALSE);
  206. UpdateWindow(hWnd);
  207. }
  208. //Return the previous index.
  209. return iBmp;
  210. case RIM_IMAGEGET:
  211. //Return the current index.
  212. iBmp=GetWindowWord(hWnd, RIWW_IMAGEINDEX);
  213. return (LONG)iBmp;
  214. default:
  215. return DefWindowProc(hWnd, iMsg, wParam, lParam);
  216. }
  217. return 0L;
  218. }
  219. /*
  220. * TransparantBlt
  221. *
  222. * Purpose:
  223. * Given a DC, a bitmap, and a color to assume as transparant in that
  224. * bitmap, BitBlts the bitmap to the DC letting the existing background
  225. * show in place of the transparant color.
  226. *
  227. * Parameters:
  228. * hDC HDC on which to draw.
  229. * x, y UINT location at which to draw the bitmap
  230. * hBmp HBITMIP to draw from
  231. * xOrg, yOrg UINT coordinates from which to draw the bitamp
  232. * cx, cy UINT dimensions of the bitmap to Blt.
  233. * cr COLORREF to consider as transparant.
  234. *
  235. * Return Value:
  236. * None
  237. */
  238. void TransparantBlt(HDC hDC, UINT x, UINT y, HBITMAP hBmp, UINT xOrg, UINT yOrg
  239. , UINT cx, UINT cy, COLORREF cr)
  240. {
  241. HDC hDCSrc, hDCMid, hMemDC;
  242. HBITMAP hBmpMono, hBmpT;
  243. HBRUSH hBr, hBrT;
  244. COLORREF crBack, crText;
  245. if (NULL==hBmp)
  246. return;
  247. //Get three intermediate DC's
  248. hDCSrc=CreateCompatibleDC(hDC);
  249. hDCMid=CreateCompatibleDC(hDC);
  250. hMemDC=CreateCompatibleDC(hDC);
  251. SelectObject(hDCSrc, hBmp);
  252. //Create a monochrome bitmap for masking
  253. hBmpMono=CreateCompatibleBitmap(hDCMid, cx, cy);
  254. SelectObject(hDCMid, hBmpMono);
  255. //Create a middle bitmap
  256. hBmpT=CreateCompatibleBitmap(hDC, cx, cy);
  257. SelectObject(hMemDC, hBmpT);
  258. //Create a monochrome mask where we have 0's in the image, 1's elsewhere.
  259. crBack=SetBkColor(hDCSrc, cr);
  260. BitBlt(hDCMid, 0, 0, cx, cy, hDCSrc, xOrg, yOrg, SRCCOPY);
  261. SetBkColor(hDCSrc, crBack);
  262. //Put the unmodified image in the temporary bitmap
  263. BitBlt(hMemDC, 0, 0, cx, cy, hDCSrc, xOrg, yOrg, SRCCOPY);
  264. //Create an select a brush of the background color
  265. hBr=CreateSolidBrush(GetBkColor(hDC));
  266. hBrT=SelectObject(hMemDC, hBr);
  267. //Force conversion of the monochrome to stay black and white.
  268. crText=SetTextColor(hMemDC, 0L);
  269. crBack=SetBkColor(hMemDC, RGB(255, 255, 255));
  270. /*
  271. * Where the monochrome mask is 1, Blt the brush; where the mono mask
  272. * is 0, leave the destination untouches. This results in painting
  273. * around the image with the background brush. We do this first
  274. * in the temporary bitmap, then put the whole thing to the screen.
  275. */
  276. BitBlt(hMemDC, 0, 0, cx, cy, hDCMid, 0, 0, ROP_DSPDxax);
  277. BitBlt(hDC, x, y, cx, cy, hMemDC, 0, 0, SRCCOPY);
  278. SetTextColor(hMemDC, crText);
  279. SetBkColor(hMemDC, crBack);
  280. SelectObject(hMemDC, hBrT);
  281. DeleteObject(hBr);
  282. DeleteDC(hMemDC);
  283. DeleteDC(hDCSrc);
  284. DeleteDC(hDCMid);
  285. DeleteObject(hBmpT);
  286. DeleteObject(hBmpMono);
  287. return;
  288. }
  289.