327 lines
8.2 KiB
C
327 lines
8.2 KiB
C
/*****************************************************************************
|
|
* *
|
|
* SGL.C *
|
|
* *
|
|
* Copyright (C) Microsoft Corporation 1989-1994. *
|
|
* All Rights reserved. *
|
|
* *
|
|
******************************************************************************
|
|
* *
|
|
* Module Intent *
|
|
* *
|
|
* This file provides a simple graphics layer that should be platform *
|
|
* independent. *
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "help.h"
|
|
#pragma hdrstop
|
|
|
|
#include "inc\fontlyr.h"
|
|
|
|
// Globals used to display the "Unable to display picture" string.
|
|
|
|
static char rgchOOMPicture[50]; // Comment at end of line
|
|
static int cchOOMPicture = -1;
|
|
|
|
static VOID STDCALL InitSGL(void);
|
|
|
|
/*******************
|
|
**
|
|
** Name: HsgcFromQde
|
|
**
|
|
** Purpose: Makes qde->hdc into a Simple Graphics Context, by selecting
|
|
** the standard pen and brush, and setting foreground and
|
|
** background colors. Qde->hdc will be restored in the call
|
|
** FreeHsgc().
|
|
**
|
|
** Arguments: de - Display environment for the window to be accessed
|
|
**
|
|
** Returns: A handle to a simpel graphics context. NULL indicates an error.
|
|
**
|
|
** Notes: Qde->hdc should not be used between calls to HsgcFromQde() and
|
|
** FreeHsgc().
|
|
**
|
|
*******************/
|
|
|
|
HSGC STDCALL HsgcFromQde(const QDE qde)
|
|
{
|
|
HPEN hPen;
|
|
HBRUSH hBrush;
|
|
|
|
ASSERT(qde->hdc);
|
|
SaveDC(qde->hdc);
|
|
|
|
if ((hPen = CreatePen(PS_SOLID, 0, qde->coFore)))
|
|
SelectObject(qde->hdc, hPen);
|
|
|
|
if ((hBrush = CreateSolidBrush(qde->coBack)))
|
|
SelectObject(qde->hdc, hBrush);
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
| Russp-j thinks we can deal with the failure of the pen and brush. They |
|
|
| seem to be duplicating the defaults in the DC anyway. |
|
|
\*--------------------------------------------------------------------------*/
|
|
|
|
SetBkMode(qde->hdc, OPAQUE);
|
|
SetBkColor(qde->hdc, qde->coBack);
|
|
|
|
// (kevynct) Fix for Help 3.5 bug 569
|
|
|
|
SetTextColor(qde->hdc, qde->coFore);
|
|
|
|
return qde->hdc;
|
|
}
|
|
|
|
/*******************
|
|
**
|
|
** Name: FSetPen
|
|
**
|
|
** Purpose: Sets the pen and the drawing mode. The default is a pen of
|
|
** size 1, coWHITE background, coBLACK foreground, opaque background
|
|
** and a roCopy raster op.
|
|
**
|
|
** Arguments: hsgc - Handle to simple graphics context
|
|
** wSize - Pen size (both height and width)
|
|
** coBack - Color index for the background and brush
|
|
** coFore - Color index for the foreground and pen
|
|
** wBkMode - Background mode (wOPAQUE or wTRANSPARENT)
|
|
** If wTRANSPARENT, the background color is not used
|
|
** for the brush.
|
|
** ro - Raster operation
|
|
**
|
|
** Returns: Nothing.
|
|
**
|
|
** Note:
|
|
** This routine uses hsgc as a HDC to some Windows calls
|
|
** for default color support.
|
|
**
|
|
*******************/
|
|
|
|
void STDCALL FSetPen(HSGC hsgc, UINT size, COLORREF coBack, COLORREF coFore,
|
|
UINT BkMode, UINT ro, UINT stylePen)
|
|
{
|
|
HPEN hPen;
|
|
HBRUSH hBrush;
|
|
|
|
ASSERT(hsgc != NULL);
|
|
|
|
if (coFore == coDEFAULT || cntFlags.fOverColor || fDisableAuthorColors)
|
|
coFore = GetTextColor(hsgc);
|
|
if (coBack == coDEFAULT || cntFlags.fOverColor || fDisableAuthorColors)
|
|
coBack = GetBkColor( hsgc );
|
|
|
|
if (hPen = CreatePen(stylePen, size, coFore))
|
|
SafeDeleteObject(SelectObject(hsgc, hPen));
|
|
|
|
if (BkMode == wTRANSPARENT)
|
|
hBrush = GetStockObject(NULL_BRUSH);
|
|
else
|
|
hBrush = CreateSolidBrush(coBack);
|
|
if (hBrush && (hBrush = SelectObject(hsgc, hBrush)))
|
|
DeleteObject(hBrush);
|
|
|
|
SetBkColor(hsgc, coBack);
|
|
SetBkMode(hsgc, BkMode);
|
|
SetROP2(hsgc, ro);
|
|
}
|
|
|
|
/*******************
|
|
-
|
|
- Name: FreeHsgc
|
|
*
|
|
* Purpose: Restores the display context to what it was before the last
|
|
* call to HsgcFromQde.
|
|
*
|
|
* Arguments: hsgc - Handle to simple graphics context
|
|
*
|
|
* Returns: Nothing.
|
|
*
|
|
******************/
|
|
|
|
void STDCALL FreeHsgc(HSGC hsgc)
|
|
{
|
|
ASSERT(hsgc != NULL);
|
|
|
|
// Remove GDI objects:
|
|
|
|
SafeDeleteObject(SelectObject(hsgc, GetStockObject(BLACK_PEN)));
|
|
SafeDeleteObject(SelectObject(hsgc, GetStockObject(WHITE_BRUSH)));
|
|
|
|
// Restore old background mode and color:
|
|
|
|
RestoreDC(hsgc, -1);
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name InitSGL
|
|
-
|
|
* Purpose
|
|
* Initializes the "Unable to display picture" string.
|
|
*
|
|
* Arguments
|
|
* The current instance handle.
|
|
*
|
|
* Returns
|
|
* Nothing.
|
|
*
|
|
* +++
|
|
*
|
|
* Notes
|
|
* This function initializes the globals rgchOOMPicture and cchOOMPicture.
|
|
*
|
|
***************************************************************************/
|
|
|
|
static VOID STDCALL InitSGL(void)
|
|
{
|
|
LoadString(hInsNow, wERRS_OOMBITMAP, rgchOOMPicture, sizeof(rgchOOMPicture));
|
|
cchOOMPicture = lstrlen(rgchOOMPicture);
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: LGetOOMPictureExtent
|
|
-
|
|
* Purpose: returns the size of a reasonable box to display this
|
|
* error message.
|
|
*
|
|
* Arguments: hdc The target ds
|
|
*
|
|
* Returns: The reasonable size in pixels, as returned by
|
|
* GetTextExtent()
|
|
*
|
|
* Globals Used: rgchOOMPicture The error message
|
|
* cchOOMPicture its size
|
|
*
|
|
* +++
|
|
*
|
|
* Notes:
|
|
*
|
|
|
|
21-Nov-1992 [ralphw] While extremely unlikely, if GetStockObject() failed,
|
|
this code would have tried to select random data in as the "old"
|
|
font, since it checked for non-NULL without having first initialized
|
|
it to NULL.
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
LONG STDCALL LGetOOMPictureExtent(HDC hdc, int idResource)
|
|
{
|
|
DWORD lExtent;
|
|
HFONT hfont, hfontOld;
|
|
POINT pt;
|
|
|
|
ASSERT(hdc);
|
|
|
|
if (cchOOMPicture == -1)
|
|
InitSGL();
|
|
hfont = GetStockObject(ANSI_VAR_FONT);
|
|
if (hfont != NULL)
|
|
hfontOld = SelectObject(hdc, hfont);
|
|
|
|
if (fHelpAuthor && idResource) {
|
|
PSTR pszText = GetStringResource(idResource);
|
|
pt = GetTextSize(hdc, pszText, strlen(pszText));
|
|
}
|
|
else
|
|
pt = GetTextSize(hdc, rgchOOMPicture, cchOOMPicture);
|
|
lExtent = MAKELONG(pt.x, pt.y);
|
|
pt = GetTextSize(hdc, "M", 1);
|
|
lExtent += 2 * MAKELONG(pt.x, pt.y);
|
|
if (hfont) {
|
|
SelectObject(hdc, hfontOld);
|
|
DeleteObject(hfont);
|
|
}
|
|
return lExtent;
|
|
}
|
|
|
|
/***************************************************************************
|
|
*
|
|
- Name: RenderOOMPicture
|
|
-
|
|
* Purpose: Something to do when the actual picture is unavailable
|
|
*
|
|
* Arguments: hdc The target display surface
|
|
* rc The target rectangle
|
|
* fHighlight Reverse video?
|
|
*
|
|
* Returns: nothing
|
|
*
|
|
* Globals Used: rgchOOMPicture The message
|
|
* cchOOMPicture Its size
|
|
*
|
|
* +++
|
|
*
|
|
* Notes:
|
|
*
|
|
***************************************************************************/
|
|
|
|
void STDCALL RenderOOMPicture(HDC hdc, const LPRECT lprc, BOOL fHighlight,
|
|
int idResource)
|
|
{
|
|
HBRUSH hbrushBack, hbrushFore;
|
|
HANDLE hOld;
|
|
WORD wAlign;
|
|
DWORD rgbBack, rgbFore;
|
|
POINT pt;
|
|
POINT ptTmp;
|
|
PSTR pszText;
|
|
|
|
if (fHighlight) {
|
|
rgbBack = GetTextColor(hdc);
|
|
rgbFore = GetBkColor(hdc);
|
|
}
|
|
else {
|
|
rgbFore = GetTextColor(hdc);
|
|
rgbBack = GetBkColor(hdc);
|
|
}
|
|
|
|
if ((hbrushBack = CreateSolidBrush(rgbBack)) == NULL)
|
|
hbrushBack = GetStockObject(WHITE_BRUSH);
|
|
if ((hbrushFore = CreateSolidBrush(rgbFore)) == NULL)
|
|
hbrushFore = GetStockObject(BLACK_BRUSH);
|
|
|
|
FillRect(hdc, lprc, hbrushBack);
|
|
FrameRect(hdc, lprc, hbrushFore);
|
|
DeleteObject(hbrushBack);
|
|
DeleteObject(hbrushFore);
|
|
|
|
rgbBack = SetBkColor(hdc, rgbBack);
|
|
rgbFore = SetTextColor(hdc, rgbFore);
|
|
|
|
if (cchOOMPicture == -1)
|
|
InitSGL();
|
|
|
|
// Draw the text
|
|
|
|
hOld = SelectObject(hdc, hfontSmallSys);
|
|
if (fHelpAuthor && idResource != -1) {
|
|
pszText = GetStringResource(idResource);
|
|
ptTmp = GetTextSize(hdc, pszText, strlen(pszText));
|
|
}
|
|
else {
|
|
pszText = NULL;
|
|
ptTmp = GetTextSize(hdc, rgchOOMPicture, cchOOMPicture);
|
|
}
|
|
pt.x = (lprc->right - lprc->left - ptTmp.x) / 2;
|
|
pt.y = (lprc->bottom - lprc->top - ptTmp.y) / 2;
|
|
|
|
if (pt.x > 0 && pt.y > 0) {
|
|
wAlign = GetTextAlign(hdc);
|
|
SetTextAlign(hdc, TA_LEFT | TA_TOP | TA_NOUPDATECP);
|
|
if (pszText)
|
|
TextOut(hdc, lprc->left + pt.x, lprc->top + pt.y,
|
|
pszText, strlen(pszText));
|
|
else
|
|
TextOut(hdc, lprc->left + pt.x, lprc->top + pt.y,
|
|
rgchOOMPicture, cchOOMPicture);
|
|
SetTextAlign(hdc, wAlign);
|
|
}
|
|
if (hOld) // REVIEW: And if not?
|
|
SelectObject(hdc, hOld);
|
|
SetBkColor(hdc, rgbBack);
|
|
SetTextColor(hdc, rgbFore);
|
|
}
|