|
|
/////////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997 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
//
/////////////////////////////////////////////////////////////////////////////////////////
////
// tmeter.c - TrackMeter custom control
////
#include "tmeter.h"
#include "resource.h"
#include <commctrl.h>
#include <custcntl.h>
#include "trace.h"
#include "mem.h"
////
// public
////
BOOL WINAPI DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved); UINT DLLEXPORT CALLBACK CustomControlInfoA(LPCCINFOA acci); BOOL DLLEXPORT CALLBACK TrackMeter_Style(HWND hWndParent, LPCCSTYLEA pccs); INT DLLEXPORT CALLBACK TrackMeter_SizeToText( DWORD flStyle, DWORD flExtStyle, HFONT hFont, LPSTR pszText); LRESULT DLLEXPORT CALLBACK TrackMeter_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
////
// private
////
static HINSTANCE g_hInstLib;
#define GWL_USER 0
#define TRACKMETER_DESCRIPTION "TrackBar with level meter"
#define TRACKMETER_DEFAULTTEXT "[===||=======]"
// control styles
//
#define SS_HORIZONTAL 0x0001
#define SS_VERTICAL 0x0002
CCSTYLEFLAGA aTrackMeterStyleFlags[] = { { TMS_HORZ, 0, "TMS_HORZ" }, { TMS_VERT, 0, "TMS_VERT" }, { TMS_NOTHUMB, 0, "TMS_NOTHUMB" } };
// number of extra bytes for control window
//
#define TRACKMETER_EXTRABYTES (1*sizeof(DWORD_PTR))
// tmeter control struct
//
typedef struct TMETER { HWND hwnd; HWND hwndParent; HDC hdcCompat; HBITMAP hbmpSave; HBITMAP hbmpCompat; long lPosition; long lMinimum; long lMaximum; long lLevel; long lLineSize; long lPageSize; BOOL fHasFocus; BOOL fIsEnabled; BOOL fIsThumbPressed; DWORD dwFlags;
RECT rcCtrl; RECT rcTrack; RECT rcMeter; RECT rcLevel; POINT aptThumb[5]; COLORREF acr[TMCR_MAX];
} TMETER, FAR *LPTMETER;
// helper functions
//
static BOOL TrackMeter_OnNCCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct); static void TrackMeter_OnNCDestroy(LPTMETER lptm); static BOOL TrackMeter_OnCreate(LPTMETER lptm, CREATESTRUCT FAR* lpCreateStruct); static void TrackMeter_OnDestroy(LPTMETER lptm); static void TrackMeter_OnSize(LPTMETER lptm, UINT state, int cx, int cy); static BOOL TrackMeter_OnEraseBkgnd(LPTMETER lptm, HDC hdc); static void TrackMeter_OnPaint(LPTMETER lptm); static int TrackMeter_Draw(LPTMETER lptm, HDC hdc); static void TrackMeter_OnCommand(LPTMETER lptm, int id, HWND hwndCtl, UINT codeNotify); static void TrackMeter_OnSetFocus(LPTMETER lptm, HWND hwndOldFocus); static void TrackMeter_OnKillFocus(LPTMETER lptm, HWND hwndNewFocus); static void TrackMeter_OnEnable(LPTMETER lptm, BOOL fEnable); static UINT TrackMeter_OnGetDlgCode(LPTMETER lptm, LPMSG lpmsg); static void TrackMeter_OnKey(LPTMETER lptm, UINT vk, BOOL fDown, int cRepeat, UINT flags); static void TrackMeter_OnLButtonDown(LPTMETER lptm, BOOL fDoubleClick, int x, int y, UINT keyFlags); static void TrackMeter_OnLButtonUp(LPTMETER lptm, int x, int y, UINT keyFlags); static void TrackMeter_OnRButtonDown(LPTMETER lptm, BOOL fDoubleClick, int x, int y, UINT keyFlags); static void TrackMeter_OnRButtonUp(LPTMETER lptm, int x, int y, UINT keyFlags); static void TrackMeter_OnMouseMove(LPTMETER lptm, int x, int y, UINT keyFlags); static void TrackMeter_OnCaptureChanged(LPTMETER lptm, HWND hwndNewCapture); static void TrackMeter_NotifyParent(LPTMETER lptm, UINT code, UINT nPos);
static LONG TrackMeter_OnTMMGetPos(LPTMETER lptm); static void TrackMeter_OnTMMSetPos(LPTMETER lptm, LONG lPosition, BOOL fRedraw); static LONG TrackMeter_OnTMMGetLevel(LPTMETER lptm); static void TrackMeter_OnTMMSetLevel(LPTMETER lptm, LONG lLevel, BOOL fRedraw); static LONG TrackMeter_OnTMMGetRangeMin(LPTMETER lptm); static void TrackMeter_OnTMMSetRangeMin(LPTMETER lptm, LONG lMinimum, BOOL fRedraw); static LONG TrackMeter_OnTMMGetRangeMax(LPTMETER lptm); static void TrackMeter_OnTMMSetRangeMax(LPTMETER lptm, LONG lMaximum, BOOL fRedraw); static void TrackMeter_OnTMMSetRange(LPTMETER lptm, LONG lMinimum, LONG lMaximum, BOOL fRedraw); static COLORREF TrackMeter_OnTMMGetColor(LPTMETER lptm, UINT elem); static void TrackMeter_OnTMMSetColor(LPTMETER lptm, COLORREF cr, UINT elem, BOOL fRedraw);
#define TrackMeter_DefProc(hwnd, msg, wParam, lParam) \
DefWindowProc(hwnd, msg, wParam, lParam)
static int TrackMeter_Recalc(LPTMETER lptm, DWORD dwFlags); #define TMR_TRACK 0x00000001
#define TMR_METER 0x00000002
#define TMR_LEVEL 0x00000004
#define TMR_THUMB 0x00000008
#define TMR_COLORS 0x00000010
#define TMR_PAGESIZE 0x00000020
#define TMR_ALL (TMR_TRACK | TMR_METER | TMR_LEVEL | TMR_THUMB | TMR_COLORS | TMR_PAGESIZE)
static int TrackMeter_PositionToX(LPTMETER lptm, long lPosition); static long TrackMeter_XToPosition(LPTMETER lptm, int xPosition); static BOOL TrackMeter_PtInThumb(LPTMETER lptm, int x, int y);
// for some reason this is not in windowsx.h
//
#ifndef HANDLE_WM_CAPTURECHANGED
/* void Cls_OnCaptureChanged(HWND hwnd, HWND hwndNewCapture) */ #define HANDLE_WM_CAPTURECHANGED(hwnd, wParam, lParam, fn) \
((fn)((hwnd), (HWND)(wParam)), 0L) #define FORWARD_WM_CAPTURECHANEGED(hwnd, hwndNewCapture, fn) \
(void)(fn)((hwnd), WM_CAPTURECHANGED, (WPARAM)(HWND)(hwndNewCapture), 0L) #endif
////
// public
////
BOOL WINAPI DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpReserved) { BOOL fSuccess = TRUE;
switch (fdwReason) { case DLL_PROCESS_ATTACH: { WNDCLASS wc;
g_hInstLib = hModule;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_GLOBALCLASS; wc.lpfnWndProc = TrackMeter_WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = TRACKMETER_EXTRABYTES; wc.hInstance = hModule; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = (LPTSTR) NULL; wc.lpszClassName = (LPTSTR) TRACKMETER_CLASS;
if (!RegisterClass (&wc)) { fSuccess = TraceFALSE(NULL); return FALSE; } } break;
case DLL_THREAD_ATTACH: break;
case DLL_THREAD_DETACH: break;
case DLL_PROCESS_DETACH: if (!UnregisterClass ((LPTSTR) TRACKMETER_CLASS, hModule)) fSuccess = TraceFALSE(NULL); break;
default: break; }
return fSuccess; }
// CustomControlInfoA
// <lpacci> (i/o) pointer to array of CCINFOA structs
// returns number of controls supported by this DLL
// NOTE: see CUSTCNTL.H for more info
//
UINT DLLEXPORT CALLBACK CustomControlInfoA(LPCCINFOA acci) { UINT uControls = 1;
if (acci != NULL) { // calculate width and height of dialog units (in pixels)
//
DWORD dw = GetDialogBaseUnits(); WORD cxBaseUnits = LOWORD(dw); WORD cyBaseUnits = HIWORD(dw);
// fill in a CCINFOA struct for each supported control
//
strncpy(acci[0].szClass, TRACKMETER_CLASS_A, sizeof(acci[0].szClass)); acci[0].flOptions = CCF_NOTEXT; strncpy(acci[0].szDesc, TRACKMETER_DESCRIPTION, sizeof(acci[0].szDesc)); acci[0].cxDefault = (120 * 4) / max(1, cxBaseUnits); acci[0].cyDefault = (18 * 8) / max(1, cyBaseUnits); acci[0].flStyleDefault = WS_CHILD | WS_VISIBLE | SS_HORIZONTAL; acci[0].flExtStyleDefault = 0; acci[0].flCtrlTypeMask = 0; strncpy(acci[0].szTextDefault, TRACKMETER_DEFAULTTEXT, sizeof(acci[0].szTextDefault)); acci[0].cStyleFlags = (sizeof(aTrackMeterStyleFlags) / sizeof(aTrackMeterStyleFlags[0])); acci[0].aStyleFlags = aTrackMeterStyleFlags; acci[0].lpfnStyle = TrackMeter_Style; acci[0].lpfnSizeToText = TrackMeter_SizeToText; acci[0].dwReserved1 = 0; acci[0].dwReserved2 = 0; }
// return the number of controls that the DLL supports
//
return uControls; }
// TrackMeter_Style - do modal dialog for custom control style
// <hwndParent> (i) parent window (dialog editor)
// <pccs> (i/o) pointer to CCSTYLE struct
// returns TRUE if success, otherwise FALSE
//
BOOL DLLEXPORT CALLBACK TrackMeter_Style(HWND hWndParent, LPCCSTYLEA pccs) { BOOL fSuccess = TRUE; #if 0
if (DialogBox(g_hInstLib, MAKEINTRESOURCE(IDD_TMETERSTYLE), hWndParent, TrackMeter_DlgProc) == -1) fSuccess = TraceFALSE(NULL); #else
fSuccess = TraceFALSE(NULL); #endif
return fSuccess; }
// TrackMeter_SizeToText
// <flStyle> (i) control style
// <flExtStyle> (i) control extended style
// <hFont> (i) handle of font used to draw text
// <pszText> (i) control text
// returns control width (pixels) needed to accomodate text, -1 if error
//
INT DLLEXPORT CALLBACK TrackMeter_SizeToText( DWORD flStyle, DWORD flExtStyle, HFONT hFont, LPSTR pszText) { // this control has no text to resize, so do nothing
//
return -1; }
LRESULT DLLEXPORT CALLBACK TrackMeter_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL fSuccess = TRUE; LPTMETER lptm = (LPTMETER) GetWindowLongPtr(hwnd, GWL_USER);
#if 0
TracePrintf_1(NULL, 1, TEXT("msg 0x%X\n"), (unsigned int) msg); #endif
switch (msg) { HANDLE_MSG(hwnd, WM_NCCREATE, TrackMeter_OnNCCreate); HANDLE_MSG(lptm, WM_NCDESTROY, TrackMeter_OnNCDestroy); HANDLE_MSG(lptm, WM_CREATE, TrackMeter_OnCreate); HANDLE_MSG(lptm, WM_DESTROY, TrackMeter_OnDestroy); HANDLE_MSG(lptm, WM_SIZE, TrackMeter_OnSize); HANDLE_MSG(lptm, WM_ERASEBKGND, TrackMeter_OnEraseBkgnd); HANDLE_MSG(lptm, WM_PAINT, TrackMeter_OnPaint); HANDLE_MSG(lptm, WM_COMMAND, TrackMeter_OnCommand); HANDLE_MSG(lptm, WM_SETFOCUS, TrackMeter_OnSetFocus); HANDLE_MSG(lptm, WM_KILLFOCUS, TrackMeter_OnKillFocus); HANDLE_MSG(lptm, WM_ENABLE, TrackMeter_OnEnable); HANDLE_MSG(lptm, WM_GETDLGCODE, TrackMeter_OnGetDlgCode); HANDLE_MSG(lptm, WM_KEYDOWN, TrackMeter_OnKey); HANDLE_MSG(lptm, WM_KEYUP, TrackMeter_OnKey); HANDLE_MSG(lptm, WM_LBUTTONDOWN, TrackMeter_OnLButtonDown); HANDLE_MSG(lptm, WM_LBUTTONUP, TrackMeter_OnLButtonUp); // HANDLE_MSG(lptm, WM_RBUTTONDOWN, TrackMeter_OnRButtonDown);
// HANDLE_MSG(lptm, WM_RBUTTONUP, TrackMeter_OnRButtonUp);
HANDLE_MSG(lptm, WM_MOUSEMOVE, TrackMeter_OnMouseMove); HANDLE_MSG(lptm, WM_CAPTURECHANGED, TrackMeter_OnCaptureChanged);
HANDLE_MSG(lptm, TMM_GETPOS, TrackMeter_OnTMMGetPos); HANDLE_MSG(lptm, TMM_SETPOS, TrackMeter_OnTMMSetPos); HANDLE_MSG(lptm, TMM_GETRANGEMIN, TrackMeter_OnTMMGetRangeMin); HANDLE_MSG(lptm, TMM_SETRANGEMIN, TrackMeter_OnTMMSetRangeMin); HANDLE_MSG(lptm, TMM_GETRANGEMAX, TrackMeter_OnTMMGetRangeMax); HANDLE_MSG(lptm, TMM_SETRANGEMAX, TrackMeter_OnTMMSetRangeMax); HANDLE_MSG(lptm, TMM_SETRANGE, TrackMeter_OnTMMSetRange);
HANDLE_MSG(lptm, TMM_GETLEVEL, TrackMeter_OnTMMGetLevel); HANDLE_MSG(lptm, TMM_SETLEVEL, TrackMeter_OnTMMSetLevel); HANDLE_MSG(lptm, TMM_GETCOLOR, TrackMeter_OnTMMGetColor); HANDLE_MSG(lptm, TMM_SETCOLOR, TrackMeter_OnTMMSetColor);
default: return TrackMeter_DefProc(hwnd, msg, wParam, lParam); } return (LRESULT) TRUE; }
////
// helper functions
////
static BOOL TrackMeter_OnNCCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) { BOOL fSuccess = TRUE; LPTMETER lptm;
// create control struct and associate it with window
//
if ((lptm = (LPTMETER) GetWindowLongPtr(hwnd, GWL_USER)) == NULL && (lptm = (LPTMETER) MemAlloc(NULL, sizeof(TMETER), 0)) == NULL) { fSuccess = TraceFALSE(NULL); return FALSE; } else { lptm->hwnd = hwnd; SetWindowLongPtr(hwnd, GWL_USER, (LONG_PTR) lptm); }
return FORWARD_WM_NCCREATE(hwnd, lpCreateStruct, DefWindowProc); }
static void TrackMeter_OnNCDestroy(LPTMETER lptm) { BOOL fSuccess = TRUE;
// destroy control struct and disassociate it from window
//
if (lptm != NULL) { HWND hwnd = lptm->hwnd;
SetWindowLongPtr(hwnd, GWL_USER, (LPARAM) NULL);
if ((lptm = MemFree(NULL, lptm)) != NULL) fSuccess = TraceFALSE(NULL);
FORWARD_WM_NCDESTROY(hwnd, DefWindowProc); } }
static BOOL TrackMeter_OnCreate(LPTMETER lptm, CREATESTRUCT FAR* lpCreateStruct) { BOOL fSuccess = TRUE; HWND hwnd = lptm->hwnd; LPVOID lpParam = (LPVOID) lpCreateStruct->lpCreateParams; HDC hdc = NULL;
if ((hdc = GetDC(hwnd)) == NULL) fSuccess = TraceFALSE(NULL);
else if ((lptm->hdcCompat = CreateCompatibleDC(hdc)) == NULL) fSuccess = TraceFALSE(NULL);
else { lptm->hwndParent = lpCreateStruct->hwndParent; lptm->hdcCompat = lptm->hdcCompat; // recalc during WM_CREATE
lptm->hbmpSave = NULL; lptm->hbmpCompat = NULL; lptm->lPosition = 0; lptm->lMinimum = 0; lptm->lMaximum = 100; lptm->lLevel = 0; lptm->lLineSize = 1; lptm->lPageSize = lptm->lPageSize; // recalc later
lptm->fHasFocus = FALSE; lptm->fIsEnabled = TRUE; lptm->fIsThumbPressed = FALSE; lptm->dwFlags = 0;
TrackMeter_Recalc(lptm, TMR_ALL); }
if (hdc != NULL) ReleaseDC(hwnd, hdc);
return fSuccess ? 1 : -1; }
static void TrackMeter_OnDestroy(LPTMETER lptm) { BOOL fSuccess = TRUE; SelectObject(lptm->hdcCompat, lptm->hbmpSave);
if (lptm->hbmpCompat != NULL && !DeleteObject(lptm->hbmpCompat)) fSuccess = TraceFALSE(NULL); else lptm->hbmpCompat = NULL;
if (lptm->hdcCompat != NULL && !DeleteDC(lptm->hdcCompat)) fSuccess = TraceFALSE(NULL); else lptm->hdcCompat = NULL; }
static void TrackMeter_OnSize(LPTMETER lptm, UINT state, int cx, int cy) { BOOL fSuccess = TRUE; HWND hwnd = lptm->hwnd;
TracePrintf_3(NULL, 6, TEXT("WM_SIZE, state=%u, cx=%d, cy=%d\n"), (unsigned) state, (int) cx, (int) cy);
switch (state) { case SIZE_RESTORED: case SIZE_MAXIMIZED: { HDC hdc = NULL; HBITMAP hbmpTemp = NULL;
if ((hdc = GetDC(hwnd)) == NULL) fSuccess = TraceFALSE(NULL);
else if (TrackMeter_Recalc(lptm, TMR_TRACK | TMR_METER | TMR_LEVEL | TMR_THUMB) != 0) fSuccess = TraceFALSE(NULL);
else if ((hbmpTemp = CreateCompatibleBitmap(hdc, cx, cy)) == NULL) fSuccess = TraceFALSE(NULL);
else { lptm->hbmpSave = SelectObject(lptm->hdcCompat, hbmpTemp);
if (lptm->hbmpCompat != NULL && !DeleteObject(lptm->hbmpCompat)) fSuccess = TraceFALSE(NULL); else lptm->hbmpCompat = hbmpTemp; }
if (hdc != NULL) ReleaseDC(hwnd, hdc);
InvalidateRect(hwnd, NULL, FALSE); } break;
default: break; } }
static BOOL TrackMeter_OnEraseBkgnd(LPTMETER lptm, HDC hdc) { BOOL fSuccess = TRUE;
// we do nothing
//
return fSuccess; }
static void TrackMeter_OnPaint(LPTMETER lptm) { BOOL fSuccess = TRUE; PAINTSTRUCT ps; BOOL fBitBlt = TRUE; HDC hdc;
//
// We have tot ake care for EndPaint
//
if (!BeginPaint(lptm->hwnd, &ps)) { fSuccess = TraceFALSE(NULL); } else { if ((hdc = (fBitBlt ? lptm->hdcCompat : ps.hdc)) == NULL) { EndPaint( lptm->hwnd, &ps); fSuccess = TraceFALSE(NULL); } else if (TrackMeter_Draw(lptm, hdc)) { EndPaint( lptm->hwnd, &ps); fSuccess = TraceFALSE(NULL); } else if (!EndPaint(lptm->hwnd, &ps)) fSuccess = TraceFALSE(NULL);
else if (fBitBlt && !BitBlt(ps.hdc, ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top, lptm->hdcCompat, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY)) { fSuccess = TraceFALSE(NULL); } } }
static int TrackMeter_Draw(LPTMETER lptm, HDC hdc) { BOOL fSuccess = TRUE; HPEN hpenOld = GetCurrentObject(hdc, OBJ_PEN); HBRUSH hbrushOld = GetCurrentObject(hdc, OBJ_BRUSH); LONG_PTR LPStyle = GetWindowLongPtr(lptm->hwnd, GWL_STYLE); BOOL fDrawThumb = !(LPStyle & TMS_NOTHUMB);
// draw background of control
//
if (1) { HBRUSH hbrushCtrlBackground;
if ((hbrushCtrlBackground = CreateSolidBrush(lptm->acr[TMCR_CTRLBACKGROUND])) == NULL) fSuccess = TraceFALSE(NULL);
else { if (!FillRect(hdc, &lptm->rcCtrl, hbrushCtrlBackground)) fSuccess = TraceFALSE(NULL);
if (!DeleteObject(hbrushCtrlBackground)) fSuccess = TraceFALSE(NULL); } }
// draw background of track
//
if (1) { HBRUSH hbrushTrackBackground;
if ((hbrushTrackBackground = CreateSolidBrush(lptm->acr[TMCR_TRACKBACKGROUND])) == NULL) fSuccess = TraceFALSE(NULL);
else { if (!FillRect(hdc, &lptm->rcTrack, hbrushTrackBackground)) fSuccess = TraceFALSE(NULL);
if (!DeleteObject(hbrushTrackBackground)) fSuccess = TraceFALSE(NULL); } }
// draw track light
//
if (1) { HPEN hpenTrackLight;
if ((hpenTrackLight = CreatePen(PS_SOLID, 1, lptm->acr[TMCR_TRACKLIGHT])) == NULL) fSuccess = TraceFALSE(NULL);
else { SelectObject(hdc, hpenTrackLight); MoveToEx(hdc, lptm->rcTrack.right, lptm->rcTrack.top, NULL); LineTo(hdc, lptm->rcTrack.right, lptm->rcTrack.bottom + 1); MoveToEx(hdc, lptm->rcTrack.right, lptm->rcTrack.bottom, NULL); LineTo(hdc, lptm->rcTrack.left - 1, lptm->rcTrack.bottom);
if (!DeleteObject(hpenTrackLight)) fSuccess = TraceFALSE(NULL); } }
// draw track shadow
//
if (1) { HPEN hpenTrackShadow;
if ((hpenTrackShadow = CreatePen(PS_SOLID, 1, lptm->fIsEnabled ? lptm->acr[TMCR_TRACKSHADOW] : lptm->acr[TMCR_CTRLBACKGROUND])) == NULL) fSuccess = TraceFALSE(NULL);
else { SelectObject(hdc, hpenTrackShadow); MoveToEx(hdc, lptm->rcTrack.left, lptm->rcTrack.top, NULL); LineTo(hdc, lptm->rcTrack.right, lptm->rcTrack.top); MoveToEx(hdc, lptm->rcTrack.left, lptm->rcTrack.top, NULL); LineTo(hdc, lptm->rcTrack.left, lptm->rcTrack.bottom);
if (!DeleteObject(hpenTrackShadow)) fSuccess = TraceFALSE(NULL); } }
// draw track dark shadow
//
if (1) { HPEN hpenTrackDkShadow;
if ((hpenTrackDkShadow = CreatePen(PS_SOLID, 1, lptm->fIsEnabled ? lptm->acr[TMCR_TRACKDKSHADOW] : lptm->acr[TMCR_TRACKSHADOW])) == NULL) fSuccess = TraceFALSE(NULL);
else { SelectObject(hdc, hpenTrackDkShadow); MoveToEx(hdc, lptm->rcTrack.left + 1, lptm->rcTrack.top + 1, NULL); LineTo(hdc, lptm->rcTrack.right - 1, lptm->rcTrack.top + 1); MoveToEx(hdc, lptm->rcTrack.left + 1, lptm->rcTrack.top + 1, NULL); LineTo(hdc, lptm->rcTrack.left + 1, lptm->rcTrack.bottom - 1);
if (!DeleteObject(hpenTrackDkShadow)) fSuccess = TraceFALSE(NULL); } }
// fill track up to current level
//
if (lptm->fIsEnabled && lptm->lLevel > lptm->lMinimum) { HBRUSH hbrushLevel;
if ((hbrushLevel = CreateSolidBrush(lptm->acr[TMCR_LEVEL])) == NULL) fSuccess = TraceFALSE(NULL);
else { FillRect(hdc, &lptm->rcLevel, hbrushLevel);
if (!DeleteObject(hbrushLevel)) fSuccess = TraceFALSE(NULL); } }
// fill thumb region
//
if (fDrawThumb) { HRGN hrgnThumb;
if ((hrgnThumb = CreatePolygonRgn(lptm->aptThumb, (sizeof(lptm->aptThumb)/sizeof(lptm->aptThumb[0])), WINDING)) == NULL) fSuccess = TraceFALSE(NULL);
else { HBRUSH hbrushThumbFace;
if ((hbrushThumbFace = CreateSolidBrush(lptm->acr[lptm->fIsThumbPressed ? TMCR_THUMBFACEPRESSED : TMCR_THUMBFACE])) == NULL) fSuccess = TraceFALSE(NULL);
else { if (!FillRgn(hdc, hrgnThumb, hbrushThumbFace)) fSuccess = TraceFALSE(NULL);
if (!DeleteObject(hbrushThumbFace)) fSuccess = TraceFALSE(NULL); }
if (!DeleteObject(hrgnThumb)) fSuccess = TraceFALSE(NULL); } }
// draw thumb light
//
if (fDrawThumb) { HPEN hpenThumbLight;
if ((hpenThumbLight = CreatePen(PS_SOLID, 1, lptm->fIsEnabled ? lptm->acr[TMCR_THUMBLIGHT] : lptm->acr[TMCR_THUMBSHADOW])) == NULL) fSuccess = TraceFALSE(NULL);
else { SelectObject(hdc, hpenThumbLight); MoveToEx(hdc, lptm->aptThumb[0].x, lptm->aptThumb[0].y, NULL); LineTo(hdc, lptm->aptThumb[1].x - 1, lptm->aptThumb[1].y + 1); MoveToEx(hdc, lptm->aptThumb[1].x, lptm->aptThumb[1].y, NULL); LineTo(hdc, lptm->aptThumb[2].x, lptm->aptThumb[2].y);
if (!DeleteObject(hpenThumbLight)) fSuccess = TraceFALSE(NULL); } }
// draw thumb dark shadow
//
if (fDrawThumb) { HPEN hpenThumbDkShadow;
if ((hpenThumbDkShadow = CreatePen(PS_SOLID, 1, lptm->fIsEnabled ? lptm->acr[TMCR_THUMBDKSHADOW] : lptm->acr[TMCR_THUMBLIGHT])) == NULL) fSuccess = TraceFALSE(NULL);
else { SelectObject(hdc, hpenThumbDkShadow); MoveToEx(hdc, lptm->aptThumb[2].x, lptm->aptThumb[2].y, NULL); LineTo(hdc, lptm->aptThumb[3].x + 1, lptm->aptThumb[3].y); MoveToEx(hdc, lptm->aptThumb[3].x, lptm->aptThumb[3].y, NULL); LineTo(hdc, lptm->aptThumb[4].x, lptm->aptThumb[4].y - 1); MoveToEx(hdc, lptm->aptThumb[4].x, lptm->aptThumb[4].y, NULL); LineTo(hdc, lptm->aptThumb[0].x, lptm->aptThumb[0].y);
if (!DeleteObject(hpenThumbDkShadow)) fSuccess = TraceFALSE(NULL); } }
// draw focus border, if necessary
//
if (lptm->fHasFocus) { COLORREF crBkColorOld = SetBkColor(hdc, lptm->acr[TMCR_FOCUSBACKGROUND]);
if (!DrawFocusRect(hdc, &lptm->rcCtrl)) fSuccess = TraceFALSE(NULL);
SetBkColor(hdc, crBkColorOld); }
// cleanup
//
if (hpenOld != NULL) SelectObject(hdc, hpenOld);
if (hbrushOld != NULL) SelectObject(hdc, hbrushOld);
return fSuccess ? 0 : -1; }
static void TrackMeter_OnCommand(LPTMETER lptm, int id, HWND hwndCtl, UINT codeNotify) { }
static void TrackMeter_OnSetFocus(LPTMETER lptm, HWND hwndOldFocus) { BOOL fSuccess = TRUE;
TracePrintf_0(NULL, 6, TEXT("WM_SETFOCUS\n"));
lptm->fHasFocus = TRUE;
if (!InvalidateRect(lptm->hwnd, NULL, TRUE)) fSuccess = TraceFALSE(NULL); }
static void TrackMeter_OnKillFocus(LPTMETER lptm, HWND hwndNewFocus) { BOOL fSuccess = TRUE;
TracePrintf_0(NULL, 6, TEXT("WM_KILLFOCUS\n"));
lptm->fHasFocus = FALSE;
if (!InvalidateRect(lptm->hwnd, NULL, TRUE)) fSuccess = TraceFALSE(NULL); }
static void TrackMeter_OnEnable(LPTMETER lptm, BOOL fEnable) { BOOL fSuccess = TRUE;
TracePrintf_1(NULL, 6, TEXT("WM_ENABLE, fEnable=%d\n"), (int) fEnable);
lptm->fIsEnabled = fEnable;
if (!InvalidateRect(lptm->hwnd, NULL, TRUE)) fSuccess = TraceFALSE(NULL); }
static UINT TrackMeter_OnGetDlgCode(LPTMETER lptm, LPMSG lpmsg) { return DLGC_WANTARROWS; }
static void TrackMeter_OnKey(LPTMETER lptm, UINT vk, BOOL fDown, int cRepeat, UINT flags) { UINT code = 0; UINT nPos = 0; LONG lPosition;
switch (vk) { case VK_UP: case VK_RIGHT: lPosition = lptm->lPosition + lptm->lLineSize; code = TB_LINEDOWN; break;
case VK_DOWN: case VK_LEFT: lPosition = lptm->lPosition - lptm->lLineSize; code = TB_LINEUP; break;
case VK_NEXT: lPosition = lptm->lPosition + lptm->lPageSize; code = TB_PAGEDOWN; break;
case VK_PRIOR: lPosition = lptm->lPosition - lptm->lPageSize; code = TB_PAGEUP; break;
case VK_HOME: lPosition = lptm->lMinimum; code = TB_TOP; break;
case VK_END: lPosition = lptm->lMaximum; code = TB_BOTTOM; break;
default: return; }
// Adjust position of thumb
if (fDown) { // we change the current position for WM_KEYDOWN only
TrackMeter_OnTMMSetPos(lptm, lPosition, TRUE); TrackMeter_NotifyParent(lptm, code, 0); }
TrackMeter_NotifyParent(lptm, TB_ENDTRACK, 0); }
static void TrackMeter_OnLButtonDown(LPTMETER lptm, BOOL fDoubleClick, int x, int y, UINT keyFlags) { SetFocus(lptm->hwnd); SetCapture(lptm->hwnd);
TracePrintf_3(NULL, 6, TEXT("WM_LBUTTONDOWN, fDoubleClick=%d, x=%d, y=%d\n"), (int) fDoubleClick, (int) x, (int) y);
if (TrackMeter_PtInThumb(lptm, x, y)) { lptm->fIsThumbPressed = TRUE; TrackMeter_OnMouseMove(lptm, x, y, 0); }
else if (x < lptm->aptThumb[0].x) TrackMeter_OnKey(lptm, VK_PRIOR, TRUE, 1, 0);
else if (x > lptm->aptThumb[0].x) TrackMeter_OnKey(lptm, VK_NEXT, TRUE, 1, 0); }
static void TrackMeter_OnLButtonUp(LPTMETER lptm, int x, int y, UINT keyFlags) { TracePrintf_2(NULL, 6, TEXT("WM_LBUTTONUP, x=%d, y=%d\n"), (int) x, (int) y);
ReleaseCapture();
if (lptm->fIsThumbPressed) { LONG lPosition = TrackMeter_XToPosition(lptm, x);
lptm->fIsThumbPressed = FALSE; TrackMeter_OnTMMSetPos(lptm, lptm->lPosition, TRUE); // just redraw
if (lPosition >= lptm->lMinimum && lPosition <= lptm->lMaximum) TrackMeter_NotifyParent(lptm, TB_THUMBPOSITION, lptm->lPosition); }
TrackMeter_NotifyParent(lptm, TB_ENDTRACK, 0); }
static void TrackMeter_OnRButtonDown(LPTMETER lptm, BOOL fDoubleClick, int x, int y, UINT keyFlags) { SetFocus(lptm->hwnd); SetCapture(lptm->hwnd);
TracePrintf_3(NULL, 6, TEXT("WM_RBUTTONDOWN, fDoubleClick=%d, x=%d, y=%d\n"), (int) fDoubleClick, (int) x, (int) y);
if (TrackMeter_PtInThumb(lptm, x, y)) { LONG lPosition = TrackMeter_XToPosition(lptm, x);
lptm->fIsThumbPressed = TRUE; TrackMeter_OnTMMSetPos(lptm, lPosition, TRUE); TrackMeter_OnMouseMove(lptm, lptm->aptThumb[0].x, y, 0); TrackMeter_NotifyParent(lptm, TB_THUMBPOSITION, lptm->lPosition); } }
static void TrackMeter_OnRButtonUp(LPTMETER lptm, int x, int y, UINT keyFlags) { TracePrintf_2(NULL, 6, TEXT("WM_RBUTTONUP, x=%d, y=%d\n"), (int) x, (int) y);
ReleaseCapture();
if ( lptm->fIsThumbPressed ) TrackMeter_NotifyParent(lptm, TB_ENDTRACK, 0); }
static void TrackMeter_OnMouseMove(LPTMETER lptm, int x, int y, UINT keyFlags) { if (lptm->fIsThumbPressed) { LONG lPosition = TrackMeter_XToPosition(lptm, x);
TracePrintf_2(NULL, 6, TEXT("WM_MOUSEMOVE, x=%d, y=%d\n"), (int) x, (int) y);
if (lPosition != lptm->lPosition) { TrackMeter_OnTMMSetPos(lptm, lPosition, TRUE); TrackMeter_NotifyParent(lptm, TB_THUMBTRACK, lptm->lPosition); } } }
static void TrackMeter_OnCaptureChanged(LPTMETER lptm, HWND hwndNewCapture) { TracePrintf_0(NULL, 6, TEXT("WM_CAPTURECHANGED\n")); }
static void TrackMeter_NotifyParent(LPTMETER lptm, UINT code, UINT nPos) { if (TraceGetLevel(NULL) >= 6) { LPTSTR lpszCode; switch (code) { case TB_LINEUP: lpszCode = TEXT("LB_LINEUP"); break; case TB_LINEDOWN: lpszCode = TEXT("LB_LINEDOWN"); break; case TB_PAGEUP: lpszCode = TEXT("LB_PAGEUP"); break; case TB_PAGEDOWN: lpszCode = TEXT("LB_PAGEDOWN"); break; case TB_TOP: lpszCode = TEXT("LB_TOP"); break; case TB_BOTTOM: lpszCode = TEXT("LB_BOTTOM"); break; case TB_ENDTRACK: lpszCode = TEXT("LB_ENDTRACK"); break; case TB_THUMBTRACK: lpszCode = TEXT("LB_THUMBTRACK"); break; case TB_THUMBPOSITION: lpszCode = TEXT("LB_THUMBPOSITION"); break; default: lpszCode = TEXT("***unknown***"); break; }
TracePrintf_4(NULL, 6, TEXT("WM_HSCROLL, %s, code=%u, nPos=%u, lPosition=%ld\n"), (LPTSTR) lpszCode, (unsigned) code, (unsigned) nPos, (long) lptm->lPosition); }
if (1) // $FIXUP - check for horizontal style here
{ FORWARD_WM_HSCROLL(lptm->hwndParent, lptm->hwnd, code, nPos, SendMessage); } else { FORWARD_WM_VSCROLL(lptm->hwndParent, lptm->hwnd, code, nPos, SendMessage); } }
static LONG TrackMeter_OnTMMGetPos(LPTMETER lptm) { BOOL fSuccess = TRUE; LONG lPosition = 0;
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else lPosition = lptm->lPosition;
return lPosition; }
static void TrackMeter_OnTMMSetPos(LPTMETER lptm, LONG lPosition, BOOL fRedraw) { BOOL fSuccess = TRUE;
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else { lptm->lPosition = max(lptm->lMinimum, min(lPosition, lptm->lMaximum));
if (TrackMeter_Recalc(lptm, TMR_THUMB) != 0) fSuccess = TraceFALSE(NULL);
if (fRedraw && !InvalidateRect(lptm->hwnd, NULL, TRUE)) fSuccess = TraceFALSE(NULL); } }
static LONG TrackMeter_OnTMMGetRangeMin(LPTMETER lptm) { BOOL fSuccess = TRUE; LONG lMinimum = 0;
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else lMinimum = lptm->lMinimum;
return lMinimum; }
static void TrackMeter_OnTMMSetRangeMin(LPTMETER lptm, LONG lMinimum, BOOL fRedraw) { BOOL fSuccess = TRUE;
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else { lptm->lMinimum = lMinimum; // adjust position and level if necessary
//
TrackMeter_OnTMMSetPos(lptm, lptm->lPosition, FALSE); TrackMeter_OnTMMSetLevel(lptm, lptm->lLevel, FALSE);
if (TrackMeter_Recalc(lptm, TMR_PAGESIZE) != 0) fSuccess = TraceFALSE(NULL);
if (fRedraw && !InvalidateRect(lptm->hwnd, NULL, TRUE)) fSuccess = TraceFALSE(NULL); } }
static LONG TrackMeter_OnTMMGetRangeMax(LPTMETER lptm) { BOOL fSuccess = TRUE; LONG lMaximum = 0;
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else lMaximum = lptm->lMaximum;
return lMaximum; }
static void TrackMeter_OnTMMSetRangeMax(LPTMETER lptm, LONG lMaximum, BOOL fRedraw) { BOOL fSuccess = TRUE;
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else { lptm->lMaximum = lMaximum; // adjust position and level if necessary
//
TrackMeter_OnTMMSetPos(lptm, lptm->lPosition, FALSE); TrackMeter_OnTMMSetLevel(lptm, lptm->lLevel, FALSE);
if (TrackMeter_Recalc(lptm, TMR_PAGESIZE) != 0) fSuccess = TraceFALSE(NULL);
if (fRedraw && !InvalidateRect(lptm->hwnd, NULL, TRUE)) fSuccess = TraceFALSE(NULL); } }
static void TrackMeter_OnTMMSetRange(LPTMETER lptm, LONG lMinimum, LONG lMaximum, BOOL fRedraw) { TrackMeter_OnTMMSetRangeMin(lptm, lMinimum, FALSE); TrackMeter_OnTMMSetRangeMax(lptm, lMaximum, fRedraw); }
static LONG TrackMeter_OnTMMGetLevel(LPTMETER lptm) { BOOL fSuccess = TRUE; LONG lLevel = 0;
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else lLevel = lptm->lLevel;
return lLevel; }
static void TrackMeter_OnTMMSetLevel(LPTMETER lptm, LONG lLevel, BOOL fRedraw) { BOOL fSuccess = TRUE;
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else { lptm->lLevel = max(lptm->lMinimum, min(lLevel, lptm->lMaximum));
if (TrackMeter_Recalc(lptm, TMR_LEVEL) != 0) fSuccess = TraceFALSE(NULL);
if (fRedraw && !InvalidateRect(lptm->hwnd, NULL, TRUE)) fSuccess = TraceFALSE(NULL); } }
static COLORREF TrackMeter_OnTMMGetColor(LPTMETER lptm, UINT elem) { BOOL fSuccess = TRUE; COLORREF cr = RGB(0, 0, 0);
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else cr = lptm->acr[elem];
return cr; }
static void TrackMeter_OnTMMSetColor(LPTMETER lptm, COLORREF cr, UINT elem, BOOL fRedraw) { BOOL fSuccess = TRUE;
if (lptm == NULL) fSuccess = TraceFALSE(NULL);
else { lptm->acr[elem] = cr;
if (fRedraw && !InvalidateRect(lptm->hwnd, NULL, TRUE)) fSuccess = TraceFALSE(NULL); } }
static int TrackMeter_Recalc(LPTMETER lptm, DWORD dwFlags) { BOOL fSuccess = TRUE;
if (!GetClientRect(lptm->hwnd, &lptm->rcCtrl)) fSuccess = TraceFALSE(NULL);
else { int cxCtrl = lptm->rcCtrl.right - lptm->rcCtrl.left; int cyCtrl = lptm->rcCtrl.bottom - lptm->rcCtrl.top; int cxBorder = 2; int cyBorder = 2; int cxThumb = ((cyCtrl - cyBorder - cyBorder) / 2) * 2 - 1; int cyThumb = cxThumb - 2; int cyTrackTopBorder = 2; int cxTrackLeftBorder = 2; int cxTrackRightBorder = 2; int cyTrackBottomBorder = 1; int xTrack = cxThumb / 2 - cxTrackLeftBorder + cxBorder; int yTrack = cyBorder; int cxTrack = cxCtrl - xTrack - xTrack; int cyTrack = (cyCtrl - cyBorder - cyBorder) / 2 + 1; int xMeter = xTrack + cxTrackLeftBorder; int yMeter = yTrack + cyTrackTopBorder; int cxMeter = cxTrack - cxTrackLeftBorder - cxTrackRightBorder; int cyMeter = cyTrack - cyTrackTopBorder - cyTrackBottomBorder;
if (dwFlags & TMR_TRACK) { lptm->rcTrack.left = xTrack; lptm->rcTrack.top = yTrack; lptm->rcTrack.right = xTrack + cxTrack - 1; lptm->rcTrack.bottom = yTrack + cyTrack - 1; }
if (dwFlags & TMR_METER) { lptm->rcMeter.left = xMeter; lptm->rcMeter.top = yMeter; lptm->rcMeter.right = xMeter + cxMeter - 1; lptm->rcMeter.bottom = yMeter + cyMeter; } if (dwFlags & TMR_LEVEL) { lptm->rcLevel.left = xMeter; lptm->rcLevel.top = yMeter; lptm->rcLevel.right = TrackMeter_PositionToX(lptm, lptm->lLevel) + 1; lptm->rcLevel.bottom = yMeter + cyMeter; } if (dwFlags & TMR_THUMB) { lptm->aptThumb[0].x = TrackMeter_PositionToX(lptm, lptm->lPosition); lptm->aptThumb[0].y = cyCtrl - cyBorder - cyThumb; lptm->aptThumb[1].x = lptm->aptThumb[0].x - (cxThumb / 2); lptm->aptThumb[1].y = lptm->aptThumb[0].y + (cyThumb / 2) + 1; lptm->aptThumb[2].x = lptm->aptThumb[1].x; lptm->aptThumb[2].y = lptm->aptThumb[0].y + cyThumb - 1; lptm->aptThumb[3].x = lptm->aptThumb[2].x + cxThumb - 1; lptm->aptThumb[3].y = lptm->aptThumb[2].y; lptm->aptThumb[4].x = lptm->aptThumb[3].x; lptm->aptThumb[4].y = lptm->aptThumb[1].y; }
if (dwFlags & TMR_COLORS) { COLORREF crWindow = GetSysColor(COLOR_WINDOW); COLORREF cr3DFace = GetSysColor(COLOR_3DFACE); COLORREF cr3DLight = GetSysColor(COLOR_3DLIGHT); COLORREF cr3DHilight = GetSysColor(COLOR_3DHILIGHT); COLORREF cr3DShadow = GetSysColor(COLOR_3DSHADOW); COLORREF cr3DDkShadow = GetSysColor(COLOR_3DDKSHADOW); COLORREF crGreen = RGB(0, 128, 0);
// try to make cr3DLight distinctive
//
if (cr3DLight == cr3DFace || cr3DLight == cr3DHilight) { HDC hdc = NULL; int nColors;
if ((hdc = GetDC(NULL)) == NULL) fSuccess = TraceFALSE(NULL);
// make sure screen device has more than 8 bits per pixel
//
else if ((nColors = GetDeviceCaps(hdc, NUMCOLORS)) == -1) { cr3DLight = RGB((GetRValue(cr3DFace) + GetRValue(cr3DHilight)) / 2, (GetGValue(cr3DFace) + GetGValue(cr3DHilight)) / 2, (GetBValue(cr3DFace) + GetBValue(cr3DHilight)) / 2); }
else { cr3DLight = cr3DHilight; }
if (hdc != NULL && !ReleaseDC(NULL, hdc)) fSuccess = TraceFALSE(NULL); }
lptm->acr[TMCR_CTRLBACKGROUND] = cr3DFace; lptm->acr[TMCR_FOCUSBACKGROUND] = crWindow; lptm->acr[TMCR_TRACKBACKGROUND] = cr3DLight; lptm->acr[TMCR_TRACKLIGHT] = cr3DHilight; lptm->acr[TMCR_TRACKSHADOW] = cr3DShadow; lptm->acr[TMCR_TRACKDKSHADOW] = cr3DDkShadow; lptm->acr[TMCR_THUMBFACE] = cr3DFace; lptm->acr[TMCR_THUMBFACEPRESSED] = cr3DLight; lptm->acr[TMCR_THUMBLIGHT] = cr3DHilight; lptm->acr[TMCR_THUMBSHADOW] = cr3DShadow; lptm->acr[TMCR_THUMBDKSHADOW] = cr3DDkShadow; lptm->acr[TMCR_LEVEL] = crGreen; }
if (dwFlags & TMR_PAGESIZE) { lptm->lPageSize = max(1, (lptm->lMaximum - lptm->lMinimum) / 5); } }
return fSuccess ? 0 : -1; }
// given lPosition between lptm->lMinimum and lptm->lMaximum,
// return x coordinate between lptm->rcMeter.left and lptm->rcMeter.right
//
static int TrackMeter_PositionToX(LPTMETER lptm, long lPosition) { long lPos = max(lptm->lMinimum, min(lPosition, lptm->lMaximum)); long lPct = ((1000 * (lPos - lptm->lMinimum) / max(1, lptm->lMaximum - lptm->lMinimum)) + 5) / 10; int cxMeter = lptm->rcMeter.right - lptm->rcMeter.left + 1; long cxPosition = ((10 * max(0, min(100, lPct)) * cxMeter / 100) + 5) / 10; int xPosition = max(lptm->rcMeter.left, lptm->rcMeter.left + min(cxPosition, cxMeter) - 1); return xPosition; }
// given x coordinate between lptm->rcMeter.left and lptm->rcMeter.right,
// return lPosition between lptm->lMinimum and lptm->lMaximum
//
static long TrackMeter_XToPosition(LPTMETER lptm, int xPosition) { int x = max(lptm->rcMeter.left, min(xPosition, lptm->rcMeter.right)); long lPct = ((1000 * (x - lptm->rcMeter.left) / max(1, lptm->rcMeter.right - lptm->rcMeter.left)) + 5) / 10; long lRange = lptm->lMaximum - lptm->lMinimum + 1; long cxPosition = ((10 * max(0, min(100, lPct)) * lRange / 100) + 5) / 10; long lPosition = max(lptm->lMinimum, lptm->lMinimum + min(cxPosition, lRange) - 1); return lPosition; }
static BOOL TrackMeter_PtInThumb(LPTMETER lptm, int x, int y) { BOOL fSuccess = TRUE; BOOL fInThumb = FALSE; HRGN hrgnThumb;
if ((hrgnThumb = CreatePolygonRgn(lptm->aptThumb, (sizeof(lptm->aptThumb) / sizeof(lptm->aptThumb[0])), WINDING)) == NULL) fSuccess = TraceFALSE(NULL);
else { if (PtInRegion(hrgnThumb, x, y)) fInThumb = TRUE;
if (!DeleteObject(hrgnThumb)) fSuccess = TraceFALSE(NULL); }
return fInThumb; }
|