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