NT4/private/windows/win4help/winhelp/sgl.c
2020-09-30 17:12:29 +02:00

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);
}