diff options
Diffstat (limited to 'private/oleutest/letest/ole2ui/resimage.c')
-rw-r--r-- | private/oleutest/letest/ole2ui/resimage.c | 363 |
1 files changed, 363 insertions, 0 deletions
diff --git a/private/oleutest/letest/ole2ui/resimage.c b/private/oleutest/letest/ole2ui/resimage.c new file mode 100644 index 000000000..8a95f4c71 --- /dev/null +++ b/private/oleutest/letest/ole2ui/resimage.c @@ -0,0 +1,363 @@ +/* + * RESIMAGE.C + * + * Implementation of the Results Image control for OLE 2.0 UI dialogs. + * We need a separate control for dialogs in order to control the repaints + * properly and to provide a clean message interface for the dialog + * implementations. + * + * Copyright (c)1992 Microsoft Corporation, All Right Reserved + */ + + +#define STRICT 1 +#include "ole2ui.h" +#include "resimage.h" + +OLEDBGDATA + +//Flag indicating if we've registered the class +static BOOL fRegistered=FALSE; + +//Bitmap and image dimensions for result images. +static HBITMAP hBmpResults=NULL; +static UINT cxBmpResult=0; +static UINT cyBmpResult=0; + +/* + * FResultImageInitialize + * + * Purpose: + * Attempts to load result bitmaps for the current display driver + * for use in OLE 2.0 UI dialogs. Also registers the ResultImage + * control class. + * + * Parameters: + * hInst HINSTANCE instance of the DLL. + * + * hPrevInst HINSTANCE of the previous instance. Used to + * determine whether to register window classes or not. + * + * lpszClassName LPSTR containing the class name to register the + * ResultImage control class with. + * + * Return Value: + * BOOL TRUE if all initialization succeeded, FALSE otherwise. + */ + +BOOL FResultImageInitialize(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpszClassName) + { + int cx, iBmp; + HDC hDC; + BITMAP bm; + + WNDCLASS wc; + + + /* + * Determine the aspect ratio of the display we're currently + * running on and load the appropriate bitmap into the global + * hBmpResults (used from the ResultImage control only). + * + * By retrieving the logical Y extent of the display driver, you + * only have limited possibilities: + * LOGPIXELSY Display + * ---------------------------------------- + * 48 CGA (unsupported) + * 72 EGA + * 96 VGA + * 120 8514/a (i.e. HiRes VGA) + */ + + hDC=GetDC(NULL); + + if (NULL==hDC) + return FALSE; + + cx=GetDeviceCaps(hDC, LOGPIXELSY); + ReleaseDC(NULL, hDC); + + /* + * Instead of single comparisons, check ranges instead, so in case + * we get something funky, we'll act reasonable. + */ + if (72 >=cx) iBmp=IDB_RESULTSEGA; + if (72 < cx && 120 > cx) iBmp=IDB_RESULTSVGA; + if (120 <=cx) iBmp=IDB_RESULTSHIRESVGA; + + hBmpResults=LoadBitmap(hInst, MAKEINTRESOURCE(iBmp)); + + if (NULL==hBmpResults) + { + //On error, fail loading the DLL + OleDbgOut1(TEXT("FResultImageInitialize: Failed LoadBitmap.\r\n")); + return FALSE; + } + + OleDbgOut4(TEXT("FResultImageInitialize: Loaded hBmpResults\r\n")); + + //Now that we have the bitmap, calculate image dimensions + GetObject(hBmpResults, sizeof(BITMAP), &bm); + cxBmpResult=bm.bmWidth; + cyBmpResult=bm.bmHeight/CIMAGESY; + + + // Only register class if we're the first instance + if (hPrevInst) + fRegistered = TRUE; + else + { + // Static flag fRegistered guards against calling this function more + // than once in the same instance + + if (!fRegistered) + { + wc.lpfnWndProc =ResultImageWndProc; + wc.cbClsExtra =0; + wc.cbWndExtra =CBRESULTIMAGEWNDEXTRA; + wc.hInstance =hInst; + wc.hIcon =NULL; + wc.hCursor =LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground =NULL; + wc.lpszMenuName =NULL; + wc.lpszClassName =lpszClassName; + wc.style =CS_GLOBALCLASS | CS_VREDRAW | CS_HREDRAW; + + fRegistered = RegisterClass(&wc); + } + } + + return fRegistered; +} + + + + + +/* + * ResultImageUninitialize + * + * Purpose: + * Cleans up anything done in FResultImageInitialize, such as freeing + * the bitmaps. Call from WEP. + * + * Parameters: + * None + * + * Return Value: + * None + */ + +void ResultImageUninitialize(void) + { + if (NULL!=hBmpResults) + { + DeleteObject(hBmpResults); + } + + return; + } + + + + + + +/* + * ResultImageWndProc + * + * Purpose: + * Window Procedure for the ResultImage custom control. Only handles + * WM_CREATE, WM_PAINT, and private messages to manipulate the bitmap. + * + * Parameters: + * Standard + * + * Return Value: + * Standard + */ + +LONG CALLBACK EXPORT ResultImageWndProc(HWND hWnd, UINT iMsg + , WPARAM wParam, LPARAM lParam) + { + UINT iBmp; + PAINTSTRUCT ps; + HDC hDC; + + //Handle standard Windows messages. + switch (iMsg) + { + case WM_CREATE: + SetWindowWord(hWnd, RIWW_IMAGEINDEX, RESULTIMAGE_NONE); + return 0L; + + case WM_PAINT: + iBmp=GetWindowWord(hWnd, RIWW_IMAGEINDEX); + + hDC=BeginPaint(hWnd, &ps); + + if (RESULTIMAGE_NONE!=iBmp) + { + RECT rc; + UINT x, y; + HDC hDCDlg; + HBRUSH hBr; + LOGBRUSH lb; + HWND hDlg; + + /* + * Our job before using TransparentBlt is to figure out + * where to position the result image. We place it centered + * on this control, so get our rect's center and subtract + * half of the image dimensions. + */ + GetClientRect(hWnd, &rc); + x=(rc.right+rc.left-cxBmpResult)/2; + y=(rc.bottom+rc.top-cyBmpResult)/2; + + //Get the backgroup color the dialog is using. + hDlg=GetParent(hWnd); + hDCDlg=GetDC(hDlg); +#if defined( WIN32 ) + hBr = (HBRUSH)SendMessage(hDlg, + WM_CTLCOLORDLG, + (WPARAM)hDCDlg, + (LPARAM)hDlg); +#else + hBr = (HBRUSH)SendMessage(hDlg, + WM_CTLCOLOR, + (WPARAM)hDCDlg, + MAKELPARAM(hDlg, CTLCOLOR_DLG)); +#endif + ReleaseDC(hDlg, hDCDlg); + + GetObject(hBr, sizeof(LOGBRUSH), &lb); + SetBkColor(hDC, lb.lbColor); + + TransparentBlt(hDC, x, y, hBmpResults, 0, iBmp*cyBmpResult + , cxBmpResult, cyBmpResult, RGBTRANSPARENT); + } + + EndPaint(hWnd, &ps); + break; + + case RIM_IMAGESET: + //wParam contains the new index. + iBmp=GetWindowWord(hWnd, RIWW_IMAGEINDEX); + + //Validate the index before changing it and repainting + if (RESULTIMAGE_NONE==wParam || + ((RESULTIMAGE_MIN <= wParam) && (RESULTIMAGE_MAX >= wParam))) + { + SetWindowWord(hWnd, RIWW_IMAGEINDEX, (WORD)wParam); + InvalidateRect(hWnd, NULL, FALSE); + UpdateWindow(hWnd); + } + + //Return the previous index. + return iBmp; + + case RIM_IMAGEGET: + //Return the current index. + iBmp=GetWindowWord(hWnd, RIWW_IMAGEINDEX); + return (LONG)iBmp; + + default: + return DefWindowProc(hWnd, iMsg, wParam, lParam); + } + + return 0L; + } + + + + + + +/* + * TransparentBlt + * + * Purpose: + * Given a DC, a bitmap, and a color to assume as transparent in that + * bitmap, BitBlts the bitmap to the DC letting the existing background + * show in place of the transparent color. + * + * Parameters: + * hDC HDC on which to draw. + * x, y UINT location at which to draw the bitmap + * hBmp HBITMIP to draw from + * xOrg, yOrg UINT coordinates from which to draw the bitamp + * cx, cy UINT dimensions of the bitmap to Blt. + * cr COLORREF to consider as transparent. + * + * Return Value: + * None + */ + +void TransparentBlt(HDC hDC, UINT x, UINT y, HBITMAP hBmp, UINT xOrg, UINT yOrg + , UINT cx, UINT cy, COLORREF cr) + { + HDC hDCSrc, hDCMid, hMemDC; + HBITMAP hBmpMono, hBmpT; + HBRUSH hBr, hBrT; + COLORREF crBack, crText; + + if (NULL==hBmp) + return; + + //Get three intermediate DC's + hDCSrc=CreateCompatibleDC(hDC); + hDCMid=CreateCompatibleDC(hDC); + hMemDC=CreateCompatibleDC(hDC); + + SelectObject(hDCSrc, hBmp); + + //Create a monochrome bitmap for masking + hBmpMono=CreateCompatibleBitmap(hDCMid, cx, cy); + SelectObject(hDCMid, hBmpMono); + + //Create a middle bitmap + hBmpT=CreateCompatibleBitmap(hDC, cx, cy); + SelectObject(hMemDC, hBmpT); + + + //Create a monochrome mask where we have 0's in the image, 1's elsewhere. + crBack=SetBkColor(hDCSrc, cr); + BitBlt(hDCMid, 0, 0, cx, cy, hDCSrc, xOrg, yOrg, SRCCOPY); + SetBkColor(hDCSrc, crBack); + + //Put the unmodified image in the temporary bitmap + BitBlt(hMemDC, 0, 0, cx, cy, hDCSrc, xOrg, yOrg, SRCCOPY); + + //Create an select a brush of the background color + hBr=CreateSolidBrush(GetBkColor(hDC)); + hBrT=SelectObject(hMemDC, hBr); + + //Force conversion of the monochrome to stay black and white. + crText=SetTextColor(hMemDC, 0L); + crBack=SetBkColor(hMemDC, RGB(255, 255, 255)); + + /* + * Where the monochrome mask is 1, Blt the brush; where the mono mask + * is 0, leave the destination untouches. This results in painting + * around the image with the background brush. We do this first + * in the temporary bitmap, then put the whole thing to the screen. + */ + BitBlt(hMemDC, 0, 0, cx, cy, hDCMid, 0, 0, ROP_DSPDxax); + BitBlt(hDC, x, y, cx, cy, hMemDC, 0, 0, SRCCOPY); + + + SetTextColor(hMemDC, crText); + SetBkColor(hMemDC, crBack); + + SelectObject(hMemDC, hBrT); + DeleteObject(hBr); + + DeleteDC(hMemDC); + DeleteDC(hDCSrc); + DeleteDC(hDCMid); + DeleteObject(hBmpT); + DeleteObject(hBmpMono); + + return; + } |