Windows NT 4.0 source code leak
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.

355 lines
11 KiB

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