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
10 KiB
364 lines
10 KiB
/*
|
|
* 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 TransparantBlt 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);
|
|
|
|
TransparantBlt(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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* TransparantBlt
|
|
*
|
|
* Purpose:
|
|
* Given a DC, a bitmap, and a color to assume as transparant in that
|
|
* bitmap, BitBlts the bitmap to the DC letting the existing background
|
|
* show in place of the transparant 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 transparant.
|
|
*
|
|
* Return Value:
|
|
* None
|
|
*/
|
|
|
|
void TransparantBlt(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;
|
|
}
|
|
|