Leaked source code of windows server 2003
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.
 
 
 
 
 
 

942 lines
24 KiB

/////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
//
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
//
// Other brand and product names used herein are trademarks of their respective owners.
//
// The entire program and user interface including the structure, sequence, selection,
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
// by "1" and "2," and each dialog message are protected by copyrights registered in
// the United States and by international treaties.
//
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
//
// Active Voice Corporation
// Seattle, Washington
// USA
//
/////////////////////////////////////////////////////////////////////////////////////////
////
// icobutt.c - icon button functions
////
#include "winlocal.h"
#include "icobutt.h"
#include "gfx.h"
#include "mem.h"
#include "str.h"
#include "sys.h"
#include "trace.h"
////
// private definitions
////
// dimensions of standard Windows icon
//
#define ICONWIDTH 32
#define ICONHEIGHT 32
// icobutt control struct
//
typedef struct ICOBUTT
{
DWORD dwVersion;
HINSTANCE hInst;
HTASK hTask;
DWORD dwFlags;
HICON hIconMono;
HICON hIconColor;
HICON hIconGreyed;
HFONT hFont;
HWND hwndButton;
} ICOBUTT, FAR *LPICOBUTT;
// helper functions
//
static int IcoButtDrawFace(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem);
static int IcoButtDrawEdges(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem);
static int IcoButtDrawIcon(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem);
static int IcoButtDrawText(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem);
static int IcoButtDrawLine(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem,
LPTSTR lpszLine, int nLine);
static LPICOBUTT IcoButtGetPropPtr(HWND hwndButton);
static int IcoButtSetPropPtr(HWND hwndButton, LPICOBUTT lpIcoButt);
static LPICOBUTT IcoButtRemovePropPtr(HWND hwndButton);
static LPICOBUTT IcoButtGetPtr(HICOBUTT hIcoButt);
static HICOBUTT IcoButtGetHandle(LPICOBUTT lpIcoButt);
////
// public functions
////
// IcoButtInit - initialize icon button
// <hwndButton> (i) button window handle
// NULL create new button
// <dwVersion> (i) must be ICOBUTT_VERSION
// <hInst> (i) instance handle of calling module
// <id> (i) id of button
// <hIconMono> (i) icon to display on mono displays
// <hIconColor> (i) icon to display on color displays
// 0 use mono icon
// <hIconGreyed> (i) icon to display when button disabled
// 0 use mono icon
// <hFont> (i) font to use for text
// NULL use variable-pitch system font (ANSI_VAR_FONT)
// <lpszText> (i) button text string
// <x> (i) button horizontal position
// <y> (i) button vertical position
// <cx> (i) button width
// <cy> (i) button height
// <hwndParent> (i) button parent
// <dwFlags> (i) control flags
// ICOBUTT_ICONCENTER draw icon centered above text (default)
// ICOBUTT_ICONLEFT draw icon on the left side of text
// ICOBUTT_ICONRIGHT draw icon on the right side of text
// ICOBUTT_NOFOCUS do not draw control showing focus
// ICOBUTT_NOTEXT do not draw any button text
// ICOBUTT_SPLITTEXT split long text onto two rows if necessary
// ICOBUTT_NOSIZE ignore <cx> and <cy> param
// ICOBUTT_NOMOVE ignore <x> and <y> param
// return handle (NULL if error)
//
// NOTE: if <hwndButton> is set to an existing button,
// a new button is not created. Rather, only the icon button
// control structure <hIcoButt> is created. This allows
// existing buttons to be turned into an icon button.
//
HICOBUTT DLLEXPORT WINAPI IcoButtInit(HWND hwndButton,
DWORD dwVersion, HINSTANCE hInst, UINT id,
HICON hIconMono, HICON hIconColor, HICON hIconGreyed,
HFONT hFont, LPTSTR lpszText, int x, int y, int cx, int cy,
HWND hwndParent, DWORD dwFlags)
{
BOOL fSuccess = TRUE;
LPICOBUTT lpIcoButt = NULL;
DWORD dwStyle;
if (hwndButton != NULL &&
(lpIcoButt = IcoButtGetPropPtr(hwndButton)) != NULL)
{
// IcoButtInit() has already been used to initialize this button
// so we need to call IcoButtTerm before continuing
//
if (IcoButtTerm(hwndButton, IcoButtGetHandle(lpIcoButt)) != 0)
fSuccess = TraceFALSE(NULL);
else
lpIcoButt = NULL;
}
if (!fSuccess)
;
else if (dwVersion != ICOBUTT_VERSION)
fSuccess = TraceFALSE(NULL);
else if (hInst == NULL)
fSuccess = TraceFALSE(NULL);
// at least this icon must be specified
//
else if (hIconMono == NULL)
fSuccess = TraceFALSE(NULL);
// memory is allocated such that the client app owns it
//
else if (lpIcoButt == NULL &&
(lpIcoButt = (LPICOBUTT) MemAlloc(NULL, sizeof(ICOBUTT), 0)) == NULL)
{
fSuccess = TraceFALSE(NULL);
}
else
{
lpIcoButt->hwndButton = hwndButton;
lpIcoButt->dwVersion = dwVersion;
lpIcoButt->hInst = hInst;
lpIcoButt->hTask = GetCurrentTask();
lpIcoButt->dwFlags = dwFlags;
lpIcoButt->hFont =
(hFont == NULL ? GetStockObject(ANSI_VAR_FONT) : hFont);
lpIcoButt->hIconMono = hIconMono;
lpIcoButt->hIconColor = hIconColor;
lpIcoButt->hIconGreyed = hIconGreyed;
}
// if icon button does not yet exist...
//
if (fSuccess && hwndButton == NULL)
{
// create an icon button window
//
if ((lpIcoButt->hwndButton = CreateWindowEx(
0L,
TEXT("Button"),
lpszText,
BS_OWNERDRAW | WS_POPUP,
x, y, cx, cy,
hwndParent,
(HMENU)IntToPtr(id),
lpIcoButt->hInst,
NULL)) == NULL)
{
fSuccess = TraceFALSE(NULL);
}
// store icobutt pointer as window property
//
else if (IcoButtSetPropPtr(lpIcoButt->hwndButton, lpIcoButt) != 0)
fSuccess = TraceFALSE(NULL);
// show the window AFTER setting window property because
// lpIcoButt is needed by IconButtDraw() to draw the button
//
else
ShowWindow(lpIcoButt->hwndButton, SW_SHOW);
}
// else if icon button already exists...
//
else if (fSuccess && hwndButton != NULL)
{
// make sure the button style is owner drawn
//
if ((dwStyle = (DWORD)
GetWindowLongPtr(lpIcoButt->hwndButton, GWL_STYLE)) == 0L)
fSuccess = TraceFALSE(NULL);
else if (SetWindowLongPtr(lpIcoButt->hwndButton,
GWL_STYLE, BS_OWNERDRAW | dwStyle) == 0L)
fSuccess = TraceFALSE(NULL);
// set window id
//
#ifdef _WIN32
else if (SetWindowLongPtr(lpIcoButt->hwndButton, GWLP_ID, id) == 0)
#else
else if (SetWindowWordPtr(lpIcoButt->hwndButton, GWWP_ID, id) == 0)
#endif
fSuccess = TraceFALSE(NULL);
// set window size
//
else if (!(dwFlags & ICOBUTT_NOSIZE) &&
!SetWindowPos(lpIcoButt->hwndButton, NULL, 0, 0, cx, cy,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER))
fSuccess = TraceFALSE(NULL);
// set window position
//
else if (!(dwFlags & ICOBUTT_NOMOVE) &&
!SetWindowPos(lpIcoButt->hwndButton, NULL, x, y, 0, 0,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOZORDER))
fSuccess = TraceFALSE(NULL);
// store icobutt pointer as window property
//
else if (IcoButtSetPropPtr(lpIcoButt->hwndButton, lpIcoButt) != 0)
fSuccess = TraceFALSE(NULL);
else
{
// set window parent
//
SetParent(lpIcoButt->hwndButton, hwndParent);
// set window text AFTER setting window property because
// lpIcoButt is needed by IconButtDraw() to draw the button
//
SetWindowText(lpIcoButt->hwndButton, lpszText);
}
}
if (!fSuccess)
{
IcoButtTerm(hwndButton, IcoButtGetHandle(lpIcoButt));
lpIcoButt = NULL;
}
return fSuccess ? IcoButtGetHandle(lpIcoButt) : NULL;
}
// IcoButtTerm - terminate icon button
// <hwndButton> (i) button window handle
// NULL destroy window
// <hIcoButt> (i) handle returned from IcoButtCreate
// return 0 if success
//
// NOTE: if <hwndButton> is set to an existing button,
// the button is not destroyed. Rather, only the icon button
// control structure <hIcoButt> is destroyed. This allows
// IcoButtInit() to be called again for the same button.
//
int DLLEXPORT WINAPI IcoButtTerm(HWND hwndButton, HICOBUTT hIcoButt)
{
BOOL fSuccess = TRUE;
LPICOBUTT lpIcoButt;
if ((lpIcoButt = IcoButtGetPtr(hIcoButt)) == NULL)
fSuccess = TraceFALSE(NULL);
else
{
if (IcoButtRemovePropPtr(lpIcoButt->hwndButton) == NULL)
fSuccess = TraceFALSE(NULL);
if (hwndButton == NULL &&
lpIcoButt->hwndButton != NULL &&
!DestroyWindow(lpIcoButt->hwndButton))
fSuccess = TraceFALSE(NULL);
else
lpIcoButt->hwndButton = NULL;
if ((lpIcoButt = MemFree(NULL, lpIcoButt)) != NULL)
fSuccess = TraceFALSE(NULL);
}
return fSuccess ? 0 : -1;
}
// IcoButtDraw - draw icon button
// <lpDrawItem> (i) structure describing how to draw control
// return 0 if success
//
int DLLEXPORT WINAPI IcoButtDraw(const LPDRAWITEMSTRUCT lpDrawItem)
{
BOOL fSuccess = TRUE;
LPICOBUTT lpIcoButt;
// retrieve icobutt pointer from button handle
//
if ((lpIcoButt = IcoButtGetPropPtr(lpDrawItem->hwndItem)) == NULL)
fSuccess = TraceFALSE(NULL);
// draw the button face
//
else if (IcoButtDrawFace(lpIcoButt, lpDrawItem) != 0)
fSuccess = TraceFALSE(NULL);
// draw the button edges
//
else if (IcoButtDrawEdges(lpIcoButt, lpDrawItem) != 0)
fSuccess = TraceFALSE(NULL);
// draw the button icon
//
else if (IcoButtDrawIcon(lpIcoButt, lpDrawItem) != 0)
fSuccess = TraceFALSE(NULL);
// draw the button text
//
else if (IcoButtDrawText(lpIcoButt, lpDrawItem) != 0)
fSuccess = TraceFALSE(NULL);
return fSuccess ? 0 : -1;
}
// IcoButtDrawFace - draw the button face
// <lpIcoButt> (i) pointer to ICOBUTT structure
// <lpDrawItem> (i) structure describing how to draw control
// return 0 if success
//
static int IcoButtDrawFace(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem)
{
BOOL fSuccess = TRUE;
HDC hdc = lpDrawItem->hDC;
RECT rc = lpDrawItem->rcItem;
HBRUSH hbr = NULL;
HBRUSH hbrOld;
// use the default button face color
//
if ((hbr = CreateSolidBrush(GetSysColor(COLOR_BTNFACE))) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((hbrOld = SelectObject(hdc, hbr)) == NULL)
fSuccess = TraceFALSE(NULL);
else if (FillRect(hdc, &rc, hbr), FALSE)
fSuccess = TraceFALSE(NULL);
else if (SelectObject(hdc, hbrOld) == NULL)
fSuccess = TraceFALSE(NULL);
if (hbr != NULL && !DeleteObject(hbr))
fSuccess = TraceFALSE(NULL);
else
hbr = NULL;
return fSuccess ? 0 : -1;
}
// IcoButtDrawEdges - draw the button edges
// <lpIcoButt> (i) pointer to ICOBUTT structure
// <lpDrawItem> (i) structure describing how to draw control
// return 0 if success
//
static int IcoButtDrawEdges(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem)
{
BOOL fSuccess = TRUE;
HDC hdc = lpDrawItem->hDC;
RECT rc = lpDrawItem->rcItem;
UINT itemState = lpDrawItem->itemState;
int iColor;
HPEN hPen = NULL;
HPEN hPenOld;
// Draw a black frame border
//
//
// We should verify the value returned by GetStockObject
HBRUSH hBrush = (HBRUSH)GetStockObject( BLACK_BRUSH );
if( hBrush )
FrameRect(hdc, &rc, hBrush);
// draw top and left edges of button to give depth
//
if (itemState & ODS_SELECTED)
iColor = COLOR_BTNSHADOW;
#if WINVER >= 0x030A
else if (SysGetWindowsVersion() >= 310)
iColor = COLOR_BTNHIGHLIGHT;
#endif
else
iColor = COLOR_WINDOW;
if ((hPen = CreatePen(PS_SOLID, 1, GetSysColor(iColor))) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((hPenOld = SelectObject(hdc, hPen)) == NULL)
fSuccess = TraceFALSE(NULL);
else
{
MoveToEx(hdc, 1, 1, NULL);
LineTo(hdc, rc.right - 1, 1);
MoveToEx(hdc, 1, 1, NULL);
LineTo(hdc, 1, rc.bottom - 1);
MoveToEx(hdc, 2, 2, NULL);
LineTo(hdc, rc.right - 2, 2);
MoveToEx(hdc, 2, 2, NULL);
LineTo(hdc, 2, rc.bottom - 2);
if (SelectObject(hdc, hPenOld) == NULL)
fSuccess = TraceFALSE(NULL);
}
if (hPen != NULL && !DeleteObject(hPen))
fSuccess = TraceFALSE(NULL);
else
hPen = NULL;
// draw bottom and right edges of button to give depth
//
if (fSuccess && !(itemState & ODS_SELECTED))
{
iColor = COLOR_BTNSHADOW;
if ((hPen = CreatePen(PS_SOLID, 1, GetSysColor(iColor))) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((hPenOld = SelectObject(hdc, hPen)) == NULL)
fSuccess = TraceFALSE(NULL);
else
{
MoveToEx(hdc, rc.right - 2, rc.bottom - 2, NULL);
LineTo(hdc, rc.right - 2, 1);
MoveToEx(hdc, rc.right - 2, rc.bottom - 2, NULL);
LineTo(hdc, 1, rc.bottom - 2);
MoveToEx(hdc, rc.right - 3, rc.bottom - 3, NULL);
LineTo(hdc, rc.right - 3, 2);
MoveToEx(hdc, rc.right - 3, rc.bottom - 3, NULL);
LineTo(hdc, 2, rc.bottom - 3);
if (SelectObject(hdc, hPenOld) == NULL)
fSuccess = TraceFALSE(NULL);
}
}
if (hPen != NULL && !DeleteObject(hPen))
fSuccess = TraceFALSE(NULL);
else
hPen = NULL;
return fSuccess ? 0 : -1;
}
// IcoButtDrawIcon - draw the button icon
// <lpIcoButt> (i) pointer to ICOBUTT structure
// <lpDrawItem> (i) structure describing how to draw control
// return 0 if success
//
static int IcoButtDrawIcon(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem)
{
BOOL fSuccess = TRUE;
HDC hdc = lpDrawItem->hDC;
RECT rc = lpDrawItem->rcItem;
UINT itemState = lpDrawItem->itemState;
HICON hIcon;
int x;
int y;
// choose the appropriate icon
//
if (itemState & ODS_DISABLED)
hIcon = lpIcoButt->hIconGreyed;
else if (GfxDeviceIsMono(hdc))
hIcon = lpIcoButt->hIconMono;
else
hIcon = lpIcoButt->hIconColor;
if (hIcon == NULL)
hIcon = lpIcoButt->hIconMono;
// calculate horizontal position of icon
//
if (lpIcoButt->dwFlags & ICOBUTT_ICONLEFT)
x = 1;
else if (lpIcoButt->dwFlags & ICOBUTT_ICONRIGHT)
x = max(0, rc.right - rc.left - ICONWIDTH);
else // centered is the default
x = max(0, rc.right - rc.left - ICONWIDTH) / 2;
// calculate vertical position of icon
//
if ((lpIcoButt->dwFlags & ICOBUTT_NOTEXT) ||
(lpIcoButt->dwFlags & ICOBUTT_SPLITTEXT))
y = 1;
else
y = 3;
// if button is depressed, adjust icon position down and to the right
//
if (itemState & ODS_SELECTED)
{
x += 2;
y += 2;
}
// draw the icon
//
//
// We should verify if hIcon is a valid resource handler
//
if ( (NULL == hIcon) || !DrawIcon(hdc, x, y, hIcon))
fSuccess = TraceFALSE(NULL);
// draw a rectangle around icon to indicate focus if needed
//
else if ((itemState & ODS_FOCUS) &&
!(lpIcoButt->dwFlags & ICOBUTT_NOFOCUS) &&
(lpIcoButt->dwFlags & ICOBUTT_NOTEXT))
{
RECT rcFocus;
COLORREF crBkColorOld;
rcFocus.left = x + 3;
rcFocus.top = y + 3;
rcFocus.right = x + ICONWIDTH - 3;
rcFocus.bottom = y + ICONHEIGHT - 3;
crBkColorOld = SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
DrawFocusRect(hdc, &rcFocus);
SetBkColor(hdc, crBkColorOld);
}
return fSuccess ? 0 : -1;
}
// IcoButtDrawText - draw the button text
// <lpIcoButt> (i) pointer to ICOBUTT structure
// <lpDrawItem> (i) structure describing how to draw control
// return 0 if success
//
static int IcoButtDrawText(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem)
{
BOOL fSuccess = TRUE;
HDC hdc = lpDrawItem->hDC;
TCHAR szText[64];
*szText = '\0';
Button_GetText(lpIcoButt->hwndButton, szText, SIZEOFARRAY(szText));
if (*szText == '\0' || (lpIcoButt->dwFlags & ICOBUTT_NOTEXT))
; // no need to continue
else
{
HFONT hFontOld;
COLORREF crBkColorOld;
COLORREF crTextColorOld;
int nBkModeOld;
if ((hFontOld = SelectObject(hdc, lpIcoButt->hFont)) == NULL)
fSuccess = TraceFALSE(NULL);
else
{
crBkColorOld = SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
crTextColorOld = SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
nBkModeOld = SetBkMode(hdc, TRANSPARENT);
}
if (fSuccess)
{
LPTSTR lpszLine = szText;
int cLines = 0;
if (lpIcoButt->dwFlags & ICOBUTT_SPLITTEXT)
{
// split text into lines, draw each one
//
lpszLine = StrTok(szText, TEXT("\t\n"));
while (fSuccess && lpszLine != NULL)
{
if (IcoButtDrawLine(lpIcoButt, lpDrawItem,
lpszLine, ++cLines) != 0)
fSuccess = TraceFALSE(NULL);
lpszLine = (LPTSTR) StrTok(NULL, TEXT("\t\n"));
}
}
else
{
// draw entire text as one line
//
if (IcoButtDrawLine(lpIcoButt, lpDrawItem,
lpszLine, 0) != 0)
fSuccess = TraceFALSE(NULL);
}
}
if (fSuccess)
{
// restore foreground and background text colors
//
SetBkColor(hdc, crBkColorOld);
SetTextColor(hdc, crTextColorOld);
SetBkMode(hdc, nBkModeOld);
// restore font
//
if (SelectObject(hdc, hFontOld) == NULL)
fSuccess = TraceFALSE(NULL);
}
}
return fSuccess ? 0 : -1;
}
// IcoButtDrawLine - draw a line of button text
// <lpIcoButt> (i) pointer to ICOBUTT structure
// <lpDrawItem> (i) structure describing how to draw control
// <lpszLine> (i) line of text to draw
// <nLine> (i) line count
// 0 one and only line
// return 0 if success
//
static int IcoButtDrawLine(LPICOBUTT lpIcoButt, const LPDRAWITEMSTRUCT lpDrawItem,
LPTSTR lpszLine, int nLine)
{
BOOL fSuccess = TRUE;
HDC hdc = lpDrawItem->hDC;
RECT rc = lpDrawItem->rcItem;
UINT itemState = lpDrawItem->itemState;
TEXTMETRIC tm;
SIZE size;
int cxTemp;
//
// We should initialize the local variables
//
int xUnderline = 0;
int cxUnderline = 0;
LPTSTR lpsz1;
LPTSTR lpsz2;
int cchLine;
int x;
int y;
if (!GetTextMetrics(hdc, &tm))
fSuccess = TraceFALSE(NULL);
else
{
// determine position and width of underline
//
cxTemp = 0L;
lpsz1 = lpsz2 = lpszLine;
while (*lpsz2 != '\0')
{
if (*lpsz2 == '&' && *(lpsz2 + 1) != '\0')
{
xUnderline = cxTemp;
lpsz2 = StrNextChr(lpsz2);
cxUnderline = 0;
if (GetTextExtentPoint(hdc, lpsz2, 1, &size))
cxUnderline = size.cx;
}
else
{
if (GetTextExtentPoint(hdc, lpsz2, 1, &size))
cxTemp += size.cx;
*lpsz1 = *lpsz2;
lpsz1 = StrNextChr(lpsz1);
lpsz2 = StrNextChr(lpsz2);
}
}
*lpsz1 = '\0';
// determine width of text
//
cchLine = StrLen(lpszLine);
cxTemp = 0;
if (GetTextExtentPoint(hdc, lpszLine, cchLine, &size))
cxTemp = size.cx;
// calculate horizontal position of line
//
if (lpIcoButt->dwFlags & ICOBUTT_ICONLEFT)
x = 1 + ICONWIDTH;
else if (lpIcoButt->dwFlags & ICOBUTT_ICONRIGHT)
x = max(0, rc.right - rc.left - cxTemp) - ICONWIDTH;
else // centered is the default
x = max(0, rc.right - rc.left - cxTemp) / 2;
if ((lpIcoButt->dwFlags & ICOBUTT_ICONLEFT) ||
(lpIcoButt->dwFlags & ICOBUTT_ICONRIGHT))
{
y = nLine == 0 ? 23 : nLine == 1 ? 17 : 29;
}
else // centered
{
if (lpIcoButt->dwFlags & ICOBUTT_SPLITTEXT)
y = nLine == 0 ? 47 : nLine == 1 ? 42 : 53;
else
y = 50;
}
y -= tm.tmHeight;
if (itemState & ODS_SELECTED)
{
x += 2;
y += 2;
}
// draw the text
//
if (!(itemState & ODS_DISABLED))
{
if (!TextOut(hdc, x, y, lpszLine, cchLine))
fSuccess = TraceFALSE(NULL);
}
else
{
COLORREF crGray;
// if ((crGray = GetSysColor(COLOR_GRAYTEXT)) != 0)
if ((crGray = GetSysColor(COLOR_BTNSHADOW)) != 0 &&
crGray != GetSysColor(COLOR_BTNFACE) &&
!GfxDeviceIsMono(hdc))
{
COLORREF crTextOld;
crTextOld = SetTextColor(hdc, crGray);
if (!TextOut(hdc, x, y, lpszLine, cchLine))
fSuccess = TraceFALSE(NULL);
SetTextColor(hdc, crTextOld);
}
else
{
GrayString(hdc, GetStockObject(BLACK_BRUSH),
NULL, (LPARAM) lpszLine, cchLine, x, y, 0, 0);
}
}
// draw underline if necessary
//
if (cxUnderline > 0)
{
HPEN hPen = NULL;
HPEN hPenOld = NULL;
if ((itemState & ODS_DISABLED))
{
if ((hPen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW))) == NULL)
fSuccess = TraceFALSE(NULL);
else if ((hPenOld = SelectObject(hdc, hPen)) == NULL)
fSuccess = TraceFALSE(NULL);
}
MoveToEx(hdc, x + xUnderline, y + tm.tmAscent + 1, NULL);
LineTo(hdc, x + xUnderline + cxUnderline, y + tm.tmAscent + 1);
if (hPenOld != NULL && SelectObject(hdc, hPenOld) == NULL)
fSuccess = TraceFALSE(NULL);
if (hPen != NULL && !DeleteObject(hPen))
fSuccess = TraceFALSE(NULL);
}
// draw a rectangle around text to indicate focus if needed
//
if ((itemState & ODS_FOCUS) &&
!(lpIcoButt->dwFlags & ICOBUTT_NOFOCUS))
{
RECT rcFocus;
COLORREF crBkColorOld;
rcFocus.left = x - 2;
rcFocus.top = y - 1;
rcFocus.right = x + cxTemp + 2;
rcFocus.bottom = y + tm.tmHeight + 1;
crBkColorOld = SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
DrawFocusRect(hdc, &rcFocus);
SetBkColor(hdc, crBkColorOld);
}
}
return fSuccess ? 0 : -1;
}
// IcoButtGetPropPtr - get icobutt pointer from button window property
// <hwndButton> (i) button window handle
// return ICOBUTT pointer (NULL if none)
//
static LPICOBUTT IcoButtGetPropPtr(HWND hwndButton)
{
BOOL fSuccess = TRUE;
LPICOBUTT lpIcoButt;
// retrieve button instance data, construct pointer
//
#ifdef _WIN32
if ((lpIcoButt = (LPICOBUTT) GetProp(hwndButton, TEXT("lpIcoButt"))) == NULL)
; // window property does not exist
#else
WORD wSelector;
WORD wOffset;
wSelector = (WORD) GetProp(hwndButton, TEXT("lpIcoButtSELECTOR"));
wOffset = (WORD) GetProp(hwndButton, TEXT("lpIcoButtOFFSET"));
if ((lpIcoButt = MAKELP(wSelector, wOffset)) == NULL)
; // window property does not exist
#endif
else if (IsBadWritePtr(lpIcoButt, sizeof(ICOBUTT)))
fSuccess = TraceFALSE(NULL);
return fSuccess ? lpIcoButt : NULL;
}
// IcoButtSetPropPtr - set icobutt pointer as button window property
// <hwndButton> (i) button window handle
// <lpIcoButt> (i) pointer to ICOBUTT struct
// return 0 if success
//
static int IcoButtSetPropPtr(HWND hwndButton, LPICOBUTT lpIcoButt)
{
BOOL fSuccess = TRUE;
#ifdef _WIN32
if (!SetProp(hwndButton, TEXT("lpIcoButt"), (HANDLE) lpIcoButt))
fSuccess = TraceFALSE(NULL);
#else
if (!SetProp(hwndButton,
TEXT("lpIcoButtSELECTOR"), (HANDLE) SELECTOROF(lpIcoButt)))
fSuccess = TraceFALSE(NULL);
else if (!SetProp(hwndButton,
TEXT("lpIcoButtOFFSET"), (HANDLE) OFFSETOF(lpIcoButt)))
fSuccess = TraceFALSE(NULL);
#endif
return fSuccess ? 0 : -1;
}
// IcoButtRemovePropPtr - remove icobutt pointer from button window property
// <hwndButton> (i) button window handle
// return 0 if success
//
static LPICOBUTT IcoButtRemovePropPtr(HWND hwndButton)
{
BOOL fSuccess = TRUE;
LPICOBUTT lpIcoButt;
// retrieve button instance data, construct pointer
//
#ifdef _WIN32
if ((lpIcoButt = (LPICOBUTT) RemoveProp(hwndButton, TEXT("lpIcoButt"))) == NULL)
; // window property does not exist
#else
WORD wSelector;
WORD wOffset;
wSelector = (WORD) RemoveProp(hwndButton, TEXT("lpIcoButtSELECTOR"));
wOffset = (WORD) RemoveProp(hwndButton, TEXT("lpIcoButtOFFSET"));
if ((lpIcoButt = MAKELP(wSelector, wOffset)) == NULL)
fSuccess = TraceFALSE(NULL);
#endif
return fSuccess ? lpIcoButt : NULL;
}
// IcoButtGetPtr - verify that icobutt handle is valid,
// <hIcoButt> (i) handle returned from IcoButtCreate
// return corresponding icobutt pointer (NULL if error)
//
static LPICOBUTT IcoButtGetPtr(HICOBUTT hIcoButt)
{
BOOL fSuccess = TRUE;
LPICOBUTT lpIcoButt;
if ((lpIcoButt = (LPICOBUTT) hIcoButt) == NULL)
fSuccess = TraceFALSE(NULL);
else if (IsBadWritePtr(lpIcoButt, sizeof(ICOBUTT)))
fSuccess = TraceFALSE(NULL);
#ifdef CHECKTASK
// make sure current task owns the icobutt handle
//
else if (lpIcoButt->hTask != GetCurrentTask())
fSuccess = TraceFALSE(NULL);
#endif
return fSuccess ? lpIcoButt : NULL;
}
// IcoButtGetHandle - verify that icobutt pointer is valid,
// <lpIcoButt> (i) pointer to ICOBUTT struct
// return corresponding icobutt handle (NULL if error)
//
static HICOBUTT IcoButtGetHandle(LPICOBUTT lpIcoButt)
{
BOOL fSuccess = TRUE;
HICOBUTT hIcoButt;
if ((hIcoButt = (HICOBUTT) lpIcoButt) == NULL)
fSuccess = TraceFALSE(NULL);
return fSuccess ? hIcoButt : NULL;
}