mirror of https://github.com/tongzx/nt5src
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.
1658 lines
42 KiB
1658 lines
42 KiB
/*
|
|
==============================================================================
|
|
|
|
Application:
|
|
|
|
Microsoft Windows NT (TM) Performance Monitor
|
|
|
|
File:
|
|
utils.c -- miscellaneous utility routines.
|
|
|
|
This file contains miscellaneous utiltity routines, mostly
|
|
low-level windows helpers. These routines are not specific
|
|
to the perfmon utillity.
|
|
|
|
Copyright 1992, Microsoft Corporation. All Rights Reserved.
|
|
Microsoft Confidential.
|
|
==============================================================================
|
|
*/
|
|
|
|
|
|
//==========================================================================//
|
|
// Includes //
|
|
//==========================================================================//
|
|
|
|
|
|
|
|
#include <stdarg.h> // For ANSI variable args. Dont use UNIX <varargs.h>
|
|
#include <stdlib.h> // For itoa
|
|
#include <stdio.h> // for vsprintf.
|
|
#include <string.h> // for strtok
|
|
#include <wchar.h> // for swscanf
|
|
|
|
#include "setedit.h"
|
|
#include "pmemory.h" // for MemoryXXX (mallloc-type) routines
|
|
#include "utils.h"
|
|
#include "pmhelpid.h" // IDs for WinHelp
|
|
#include "perfmops.h"
|
|
|
|
//==========================================================================//
|
|
// Constants //
|
|
//==========================================================================//
|
|
|
|
|
|
#define DOS_FILES 0x0000 // Ordinary files
|
|
#define DOS_READONLY 0x0001 // Read-only files
|
|
#define DOS_HIDDEN 0x0002 // Hidden files
|
|
#define DOS_SYSTEM 0x0004 // System files
|
|
#define DOS_SUBDIRECTORIES 0x0010 // Subdirectories
|
|
#define DOS_ARCHIVES 0x0020 // Archives
|
|
#define DOS_LIB_DIR 0x2000 // LB_DIR flag
|
|
#define DOS_DRIVES 0x4000 // Drives
|
|
#define DOS_EXCLUSIVE 0x8000 // Exclusive bit
|
|
#define DOS_DRIVES_DIRECTORIES 0xC010 // Find drives and directories only
|
|
|
|
|
|
#define WILD_ONE '?'
|
|
#define WILD_ANY '*'
|
|
|
|
|
|
|
|
|
|
//==========================================================================//
|
|
// Local Functions //
|
|
//==========================================================================//
|
|
|
|
|
|
|
|
void ClientRectToScreen (HWND hWnd,
|
|
LPRECT lpRect)
|
|
/*
|
|
Effect: Remaps lpRect from client coordinates to screen
|
|
coordinates. Analogous to ClientToScreen for rectangles.
|
|
|
|
Note: To convert a rectangle from the client coordinates of
|
|
Wnd1 to the client coordinates of Wnd2, call:
|
|
|
|
ClientRectToScreen (hWnd1, &rect) ;
|
|
ScreenRectToClient (hWnd2, &rect) ;
|
|
|
|
See Also: ClientToScreen (windows), ScreenRectToClient.
|
|
|
|
Internals: Since a rectangle is really only two points, let
|
|
windows do the work with ClientToScreen.
|
|
*/
|
|
{ /* ClientRectToScreen */
|
|
POINT pt1, pt2 ;
|
|
|
|
pt1.x = lpRect->left ;
|
|
pt1.y = lpRect->top ;
|
|
|
|
pt2.x = lpRect->right ;
|
|
pt2.y = lpRect->bottom ;
|
|
|
|
ClientToScreen (hWnd, &pt1) ;
|
|
ClientToScreen (hWnd, &pt2) ;
|
|
|
|
lpRect->left = pt1.x ;
|
|
lpRect->top = pt1.y ;
|
|
|
|
lpRect->right = pt2.x ;
|
|
lpRect->bottom = pt2.y ;
|
|
} // ClientRectToScreen
|
|
|
|
|
|
void ScreenRectToClient (HWND hWnd, LPRECT lpRect)
|
|
/*
|
|
Effect: Remaps lpRect from screen coordinates to client
|
|
coordinates. Analogous to ScreenToClient for rectangles.
|
|
|
|
Note: To convert a rectangle from the client coordinates of
|
|
Wnd1 to the client coordinates of Wnd2, call:
|
|
|
|
ClientRectToScreen (hWnd1, &rect) ;
|
|
ScreenRectToClient (hWnd2, &rect) ;
|
|
|
|
See Also: ScreenToClient (windows), ClientRectToScreen.
|
|
|
|
Internals: Since a rectangle is really only two points, let
|
|
windows do the work with ScreenToClient.
|
|
*/
|
|
{ // ScreenRectToClient
|
|
POINT pt1, pt2 ;
|
|
|
|
pt1.x = lpRect->left ;
|
|
pt1.y = lpRect->top ;
|
|
|
|
pt2.x = lpRect->right ;
|
|
pt2.y = lpRect->bottom ;
|
|
|
|
ScreenToClient (hWnd, &pt1) ;
|
|
ScreenToClient (hWnd, &pt2) ;
|
|
|
|
lpRect->left = pt1.x ;
|
|
lpRect->top = pt1.y ;
|
|
|
|
lpRect->right = pt2.x ;
|
|
lpRect->bottom = pt2.y ;
|
|
} // ScreenRectToClient
|
|
|
|
|
|
//==========================================================================//
|
|
// Exported Functions //
|
|
//==========================================================================//
|
|
|
|
|
|
void Line (HDC hDC,
|
|
HPEN hPen,
|
|
int x1, int y1,
|
|
int x2, int y2)
|
|
{ // Line
|
|
HPEN hPenPrevious ;
|
|
|
|
if (hPen)
|
|
hPenPrevious = SelectPen (hDC, hPen) ;
|
|
MoveToEx (hDC, x1, y1, NULL) ;
|
|
LineTo (hDC, x2, y2) ;
|
|
if (hPen)
|
|
SelectObject (hDC, hPenPrevious) ;
|
|
} // Line
|
|
|
|
#if 0
|
|
void HLine (HDC hDC,
|
|
HPEN hPen,
|
|
int x1,
|
|
int x2,
|
|
int y)
|
|
{ // HLine
|
|
Line (hDC, hPen, x1, y, x2, y) ;
|
|
}
|
|
|
|
|
|
void VLine (HDC hDC,
|
|
HPEN hPen,
|
|
int x,
|
|
int y1,
|
|
int y2)
|
|
{ // VLine
|
|
Line (hDC, hPen, x, y1, x, y2) ;
|
|
} // VLine
|
|
#endif
|
|
|
|
#ifdef KEEP_UTIL
|
|
void Fill (HDC hDC,
|
|
DWORD rgbColor,
|
|
LPRECT lpRect)
|
|
{ // Fill
|
|
HBRUSH hBrush ;
|
|
|
|
hBrush = CreateSolidBrush (rgbColor) ;
|
|
if (hBrush) {
|
|
FillRect (hDC, lpRect, hBrush) ;
|
|
DeleteBrush (hBrush) ;
|
|
}
|
|
} // Fill
|
|
|
|
void ThreeDConvex (HDC hDC,
|
|
int x1, int y1,
|
|
int x2, int y2)
|
|
{ // ThreeDConvex
|
|
HBRUSH hBrushPrevious ;
|
|
POINT aPoints [8] ;
|
|
DWORD aCounts [2] ;
|
|
HPEN hPenPrevious ;
|
|
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Face ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
hBrushPrevious = SelectBrush (hDC, hBrushFace) ;
|
|
PatBlt (hDC,
|
|
x1 + ThreeDPad, y1 + ThreeDPad,
|
|
x2 - x1 - ThreeDPad, y2 - y1 - ThreeDPad,
|
|
PATCOPY) ;
|
|
SelectBrush (hDC, hBrushPrevious) ;
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Highlight ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
if (hPenHighlight)
|
|
hPenPrevious = SelectPen (hDC, hPenHighlight) ;
|
|
|
|
aPoints [0].x = x1 ;
|
|
aPoints [0].y = y2 - 1 ; // this works slightly diff. than Line ??
|
|
aPoints [1].x = x1 ;
|
|
aPoints [1].y = y1 ;
|
|
aPoints [2].x = x2 ;
|
|
aPoints [2].y = y1 ;
|
|
|
|
aPoints [3].x = x1 + 1 ;
|
|
aPoints [3].y = y2 - 1 ;
|
|
aPoints [4].x = x1 + 1 ;
|
|
aPoints [4].y = y1 + 1 ;
|
|
aPoints [5].x = x2 - 1 ;
|
|
aPoints [5].y = y1 + 1 ;
|
|
|
|
aCounts [0] = 3 ;
|
|
aCounts [1] = 3 ;
|
|
|
|
PolyPolyline (hDC, aPoints, aCounts, 2) ;
|
|
|
|
|
|
if (hPenHighlight)
|
|
hPenPrevious = SelectPen (hDC, hPenPrevious) ;
|
|
|
|
// HLine (hDC, hPenHighlight, x1, x2, y1) ; // outside top line
|
|
// HLine (hDC, hPenHighlight, x1 + 1, x2 - 1, y1 + 1) ; // inside top line
|
|
// VLine (hDC, hPenHighlight, x1, y1, y2) ; // outside left line
|
|
// VLine (hDC, hPenHighlight, x1 + 1, y1 + 1, y2 - 1) ; // inside left line
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Shadow ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
if (hPenShadow)
|
|
hPenPrevious = SelectPen (hDC, hPenShadow) ;
|
|
|
|
aPoints [0].x = x1 + 1 ;
|
|
aPoints [0].y = y2 - 1 ;
|
|
aPoints [1].x = x2 ;
|
|
aPoints [1].y = y2 - 1 ;
|
|
aPoints [2].x = x2 ;
|
|
aPoints [2].y = y2 - 2 ;
|
|
aPoints [3].x = x1 + 2 ;
|
|
aPoints [3].y = y2 - 2 ;
|
|
|
|
aPoints [4].x = x2 - 1 ;
|
|
aPoints [4].y = y1 ;
|
|
aPoints [5].x = x2 - 1 ;
|
|
aPoints [5].y = y2 - 1;
|
|
aPoints [6].x = x2 - 2 ;
|
|
aPoints [6].y = y2 - 1 ;
|
|
aPoints [7].x = x2 - 2 ;
|
|
aPoints [7].y = y1 ;
|
|
|
|
aCounts [0] = 4 ;
|
|
aCounts [1] = 4 ;
|
|
|
|
PolyPolyline (hDC, aPoints, aCounts, 2) ;
|
|
|
|
|
|
if (hPenShadow)
|
|
hPenPrevious = SelectPen (hDC, hPenPrevious) ;
|
|
|
|
// HLine (hDC, hPenShadow, x1 + 1, x2, y2 - 1) ; // outside bottom line
|
|
// HLine (hDC, hPenShadow, x1 + 2, x2, y2 - 2) ; // inside bottom line
|
|
// VLine (hDC, hPenShadow, x2 - 1, y1 + 1, y2) ; // outside right line
|
|
// VLine (hDC, hPenShadow, x2 - 2, y1 + 2, y2) ; // inside right line
|
|
|
|
} // ThreeDConvex
|
|
|
|
|
|
|
|
void ThreeDConcave (HDC hDC,
|
|
int x1, int y1,
|
|
int x2, int y2,
|
|
BOOL bFace)
|
|
{ // ThreeDConcave
|
|
HBRUSH hBrushPrevious ;
|
|
POINT aPoints [6] ;
|
|
DWORD aCounts [2] ;
|
|
HPEN hPenPrevious ;
|
|
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Face ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
if (bFace) {
|
|
hBrushPrevious = SelectBrush (hDC, hBrushFace) ;
|
|
PatBlt (hDC,
|
|
x1 + ThreeDPad, y1 + ThreeDPad,
|
|
x2 - x1 - ThreeDPad, y2 - y1 - ThreeDPad,
|
|
PATCOPY) ;
|
|
SelectBrush (hDC, hBrushPrevious) ;
|
|
}
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Shadow ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
#if 1
|
|
if (hPenShadow)
|
|
hPenPrevious = SelectPen (hDC, hPenShadow) ;
|
|
|
|
aPoints [0].x = x1 ;
|
|
aPoints [0].y = y2 - 1 ;
|
|
aPoints [1].x = x1 ;
|
|
aPoints [1].y = y1 ;
|
|
aPoints [2].x = x2 ;
|
|
aPoints [2].y = y1 ;
|
|
|
|
aPoints [3].x = x1 + 1 ;
|
|
aPoints [3].y = y2 - 1 ;
|
|
aPoints [4].x = x1 + 1 ;
|
|
aPoints [4].y = y1 + 1 ;
|
|
aPoints [5].x = x2 - 1 ;
|
|
aPoints [5].y = y1 + 1 ;
|
|
|
|
aCounts [0] = 3 ;
|
|
aCounts [1] = 3 ;
|
|
|
|
PolyPolyline (hDC, aPoints, aCounts, 2) ;
|
|
|
|
if (hPenShadow)
|
|
hPenPrevious = SelectPen (hDC, hPenPrevious) ;
|
|
|
|
#else
|
|
HLine (hDC, hPenShadow, x1, x2, y1) ; // outside top line
|
|
HLine (hDC, hPenShadow, x1 + 1, x2 - 1, y1 + 1) ; // inside top line
|
|
VLine (hDC, hPenShadow, x1, y1, y2) ; // outside left line
|
|
VLine (hDC, hPenShadow, x1 + 1, y1 + 1, y2 - 1) ; // inside left line
|
|
#endif
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Highlight ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
#if 1
|
|
if (hPenHighlight)
|
|
hPenPrevious = SelectPen (hDC, hPenHighlight) ;
|
|
|
|
aPoints [0].x = x1 + 1 ;
|
|
aPoints [0].y = y2 - 1 ;
|
|
aPoints [1].x = x2 ;
|
|
aPoints [1].y = y2 - 1 ;
|
|
|
|
aPoints [2].x = x2 - 1 ;
|
|
aPoints [2].y = y2 - 1 ;
|
|
aPoints [3].x = x2 - 1 ;
|
|
aPoints [3].y = y1 ;
|
|
|
|
aCounts [0] = 2 ;
|
|
aCounts [1] = 2 ;
|
|
|
|
PolyPolyline (hDC, aPoints, aCounts, 2) ;
|
|
|
|
if (hPenHighlight)
|
|
hPenPrevious = SelectPen (hDC, hPenPrevious) ;
|
|
|
|
#else
|
|
HLine (hDC, hPenHighlight, x1 + 1, x2, y2 - 1) ; // outside bottom line
|
|
VLine (hDC, hPenHighlight, x2 - 1, y1 + 1, y2) ; // outside right line
|
|
#endif
|
|
} // ThreeDConcave
|
|
#endif // KEEP_UTIL
|
|
|
|
|
|
void ThreeDConvex1 (HDC hDC,
|
|
int x1, int y1,
|
|
int x2, int y2)
|
|
{ // ThreeDConvex1
|
|
HBRUSH hBrushPrevious ;
|
|
POINT aPoints [6] ;
|
|
DWORD aCounts [2] ;
|
|
HPEN hPenPrevious ;
|
|
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Face ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
#if 1
|
|
hBrushPrevious = SelectBrush (hDC, hBrushFace) ;
|
|
PatBlt (hDC,
|
|
x1 + 1, y1 + 1,
|
|
x2 - x1 - 1, y2 - y1 - 1,
|
|
PATCOPY) ;
|
|
SelectBrush (hDC, hBrushPrevious) ;
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Highlight ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
if (hPenHighlight)
|
|
hPenPrevious = SelectPen (hDC, hPenHighlight) ;
|
|
|
|
aPoints [0].x = x1 ;
|
|
aPoints [0].y = y2 - 1 ;
|
|
aPoints [1].x = x1 ;
|
|
aPoints [1].y = y1 ;
|
|
aPoints [2].x = x2 ;
|
|
aPoints [2].y = y1 ;
|
|
|
|
Polyline (hDC, aPoints, 3) ;
|
|
|
|
if (hPenHighlight)
|
|
hPenPrevious = SelectPen (hDC, hPenPrevious) ;
|
|
|
|
#else
|
|
HLine (hDC, hPenHighlight, x1, x2, y1) ; // outside top line
|
|
VLine (hDC, hPenHighlight, x1, y1, y2) ; // outside left line
|
|
#endif
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Shadow ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
#if 1
|
|
if (hPenShadow)
|
|
hPenPrevious = SelectPen (hDC, hPenShadow) ;
|
|
|
|
aPoints [0].x = x1 + 1 ;
|
|
aPoints [0].y = y2 - 1 ;
|
|
aPoints [1].x = x2 ;
|
|
aPoints [1].y = y2 - 1 ;
|
|
|
|
aPoints [2].x = x2 - 1 ;
|
|
aPoints [2].y = y2 - 1 ;
|
|
aPoints [3].x = x2 - 1 ;
|
|
aPoints [3].y = y1 ;
|
|
|
|
aCounts [0] = 2 ;
|
|
aCounts [1] = 2 ;
|
|
|
|
PolyPolyline (hDC, aPoints, aCounts, 2) ;
|
|
|
|
if (hPenShadow)
|
|
hPenPrevious = SelectPen (hDC, hPenPrevious) ;
|
|
#else
|
|
HLine (hDC, hPenShadow, x1 + 1, x2, y2 - 1) ; // outside bottom line
|
|
VLine (hDC, hPenShadow, x2 - 1, y1 + 1, y2) ; // outside right line
|
|
#endif
|
|
|
|
} // ThreeDConvex1
|
|
|
|
|
|
|
|
void
|
|
ThreeDConcave1 (
|
|
HDC hDC,
|
|
int x1,
|
|
int y1,
|
|
int x2,
|
|
int y2
|
|
)
|
|
{ // ThreeDConcave1
|
|
HBRUSH hBrushPrevious ;
|
|
POINT aPoints [6] ;
|
|
DWORD aCounts [2] ;
|
|
HPEN hPenPrevious ;
|
|
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Face ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
hBrushPrevious = SelectBrush (hDC, hBrushFace) ;
|
|
PatBlt (hDC,
|
|
x1 + 1, y1 + 1,
|
|
x2 - x1 - 1, y2 - y1 - 1,
|
|
PATCOPY) ;
|
|
SelectBrush (hDC, hBrushPrevious) ;
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Shadow ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
|
|
#if 1
|
|
if (hPenShadow)
|
|
hPenPrevious = SelectPen (hDC, hPenShadow) ;
|
|
|
|
aPoints [0].x = x1 ;
|
|
aPoints [0].y = y2 - 1 ;
|
|
aPoints [1].x = x1 ;
|
|
aPoints [1].y = y1 ;
|
|
aPoints [2].x = x2 ;
|
|
aPoints [2].y = y1 ;
|
|
|
|
Polyline (hDC, aPoints, 3) ;
|
|
|
|
if (hPenShadow)
|
|
hPenPrevious = SelectPen (hDC, hPenPrevious) ;
|
|
#else
|
|
HLine (hDC, hPenShadow, x1, x2, y1) ; // outside top line
|
|
VLine (hDC, hPenShadow, x1, y1, y2) ; // outside left line
|
|
#endif
|
|
|
|
//ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
//³ Draw Highlight ³
|
|
//ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
#if 1
|
|
if (hPenHighlight)
|
|
hPenPrevious = SelectPen (hDC, hPenHighlight) ;
|
|
|
|
aPoints [0].x = x1 + 1 ;
|
|
aPoints [0].y = y2 - 1 ;
|
|
aPoints [1].x = x2 ;
|
|
aPoints [1].y = y2 - 1 ;
|
|
|
|
aPoints [2].x = x2 - 1 ;
|
|
aPoints [2].y = y2 - 2 ;
|
|
aPoints [3].x = x2 - 1 ;
|
|
aPoints [3].y = y1 ;
|
|
|
|
aCounts [0] = 2 ;
|
|
aCounts [1] = 2 ;
|
|
|
|
PolyPolyline (hDC, aPoints, aCounts, 2) ;
|
|
|
|
if (hPenHighlight)
|
|
hPenPrevious = SelectPen (hDC, hPenPrevious) ;
|
|
#else
|
|
HLine (hDC, hPenHighlight, x1 + 1, x2, y2 - 1) ; // outside bottom line
|
|
VLine (hDC, hPenHighlight, x2 - 1, y1 + 1, y2) ; // outside right line
|
|
#endif
|
|
|
|
} // ThreeDConcave1
|
|
|
|
|
|
int
|
|
TextWidth (
|
|
HDC hDC,
|
|
LPTSTR lpszText
|
|
)
|
|
{
|
|
SIZE size ;
|
|
|
|
if (!lpszText)
|
|
return (0) ;
|
|
|
|
GetTextExtentPoint (hDC, lpszText, lstrlen (lpszText), &size) ;
|
|
return (size.cx) ;
|
|
}
|
|
|
|
|
|
int
|
|
_cdecl
|
|
DlgErrorBox (
|
|
HWND hDlg,
|
|
UINT id,
|
|
...
|
|
)
|
|
{
|
|
TCHAR szMessageFmt [FilePathLen + 1] ;
|
|
TCHAR szBuffer [FilePathLen * 2] ;
|
|
va_list vaList ;
|
|
int NumOfChar ;
|
|
TCHAR szApplication [WindowCaptionLen] ;
|
|
|
|
NumOfChar = StringLoad (id, szMessageFmt) ;
|
|
|
|
if (NumOfChar) {
|
|
va_start (vaList, id) ;
|
|
wvsprintf (szBuffer, szMessageFmt, vaList) ;
|
|
va_end (vaList) ;
|
|
|
|
StringLoad (IDS_APPNAME, szApplication) ;
|
|
|
|
MessageBox (hDlg, szBuffer, szApplication,
|
|
MB_OK | MB_ICONSTOP | MB_TASKMODAL) ;
|
|
}
|
|
|
|
return (0) ;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
FontHeight (
|
|
HDC hDC,
|
|
BOOL bIncludeLeading
|
|
)
|
|
{ // FontHeight
|
|
TEXTMETRIC tm ;
|
|
|
|
GetTextMetrics (hDC, &tm) ;
|
|
if (bIncludeLeading)
|
|
return (tm.tmHeight + tm.tmExternalLeading) ;
|
|
else
|
|
return (tm.tmHeight) ;
|
|
} // FontHeight
|
|
|
|
|
|
|
|
int
|
|
TextAvgWidth (
|
|
HDC hDC,
|
|
int iNumChars
|
|
)
|
|
{
|
|
TEXTMETRIC tm ;
|
|
int xAvgWidth ;
|
|
|
|
GetTextMetrics (hDC, &tm) ;
|
|
|
|
xAvgWidth = iNumChars * tm.tmAveCharWidth ;
|
|
|
|
// add 10% slop
|
|
return (MulDiv (xAvgWidth, 11, 10)) ;
|
|
}
|
|
|
|
|
|
void
|
|
WindowCenter (
|
|
HWND hWnd
|
|
)
|
|
/*
|
|
Effect: Center the window hWnd in the center of the screen.
|
|
Physically update the windows appearance as well.
|
|
|
|
Globals: xScreenWidth, yScreenHeight.
|
|
*/
|
|
{ // WindowCenter
|
|
RECT rectWindow ;
|
|
int xWindowWidth, yWindowHeight ;
|
|
|
|
GetWindowRect (hWnd, &rectWindow) ;
|
|
xWindowWidth = rectWindow.right - rectWindow.left ;
|
|
yWindowHeight = rectWindow.bottom - rectWindow.top ;
|
|
|
|
MoveWindow (hWnd,
|
|
(xScreenWidth - xWindowWidth) / 2,
|
|
(yScreenHeight - yWindowHeight) / 2,
|
|
xWindowWidth,
|
|
yWindowHeight,
|
|
TRUE) ;
|
|
} // WindowCenter
|
|
|
|
|
|
|
|
BOOL
|
|
DialogMove (
|
|
HDLG hDlg,
|
|
WORD wControlID,
|
|
int xPos,
|
|
int yPos,
|
|
int xWidth,
|
|
int yHeight
|
|
)
|
|
/*
|
|
Effect: Move the control identified by wControlID in the dialog
|
|
hDlg to the new position (xPos, yPos), and resize to
|
|
(xWidth, yHeight). If any of these values are NOCHANGE, retain
|
|
the current value.
|
|
|
|
Examples: DialogMove (hDlg, IDD_FOO, 10, 20, NOCHANGE, NOCHANGE)
|
|
moves control but does not resize it
|
|
|
|
DialogMove (hDlg, IDD_FOO, NOCHANGE, NOCHANGE, 100, NOCHANGE)
|
|
sets width of control to 100
|
|
*/
|
|
{ // DialogMove
|
|
HWND hWndControl ;
|
|
RECT rectControl ;
|
|
|
|
hWndControl = DialogControl (hDlg, wControlID) ;
|
|
if (!hWndControl)
|
|
return (FALSE) ;
|
|
GetWindowRect (hWndControl, &rectControl) ;
|
|
ScreenRectToClient (hDlg, &rectControl) ;
|
|
|
|
MoveWindow (hWndControl,
|
|
(xPos == NOCHANGE) ? rectControl.left : xPos,
|
|
(yPos == NOCHANGE) ? rectControl.top : yPos,
|
|
(xWidth == NOCHANGE) ? rectControl.right - rectControl.left : xWidth,
|
|
(yHeight == NOCHANGE) ? rectControl.bottom - rectControl.top : yHeight,
|
|
TRUE) ;
|
|
|
|
return (TRUE) ;
|
|
} // DialogMove
|
|
|
|
|
|
int
|
|
DialogWidth (
|
|
HDLG hDlg,
|
|
WORD wControlID
|
|
)
|
|
{
|
|
HWND hWndControl ;
|
|
RECT rectControl ;
|
|
|
|
hWndControl = DialogControl (hDlg, wControlID) ;
|
|
if (!hWndControl)
|
|
return (0) ;
|
|
|
|
GetWindowRect (hWndControl, &rectControl) ;
|
|
return (rectControl.right - rectControl.left) ;
|
|
}
|
|
|
|
|
|
int
|
|
DialogHeight (
|
|
HDLG hDlg,
|
|
WORD wControlID
|
|
)
|
|
{
|
|
HWND hWndControl ;
|
|
RECT rectControl ;
|
|
|
|
hWndControl = DialogControl (hDlg, wControlID) ;
|
|
if (!hWndControl)
|
|
return (0) ;
|
|
|
|
GetWindowRect (hWndControl, &rectControl) ;
|
|
return (rectControl.bottom - rectControl.top) ;
|
|
}
|
|
|
|
|
|
int
|
|
DialogXPos (
|
|
HDLG hDlg,
|
|
WORD wControlID
|
|
)
|
|
{ // DialogXPos
|
|
HWND hWndControl ;
|
|
RECT rectControl ;
|
|
|
|
hWndControl = DialogControl (hDlg, wControlID) ;
|
|
if (!hWndControl)
|
|
return (0) ;
|
|
|
|
GetWindowRect (hWndControl, &rectControl) ;
|
|
ScreenRectToClient (hDlg, &rectControl) ;
|
|
|
|
return (rectControl.left) ;
|
|
} // DialogXPos
|
|
|
|
|
|
int
|
|
DialogYPos (
|
|
HDLG hDlg,
|
|
WORD wControlID
|
|
)
|
|
{ // DialogYPos
|
|
HWND hWndControl ;
|
|
RECT rectControl ;
|
|
|
|
hWndControl = DialogControl (hDlg, wControlID) ;
|
|
if (!hWndControl)
|
|
return (0) ;
|
|
|
|
GetWindowRect (hWndControl, &rectControl) ;
|
|
ScreenRectToClient (hDlg, &rectControl) ;
|
|
|
|
return (rectControl.top) ;
|
|
} // DialogYPos
|
|
|
|
|
|
void
|
|
DialogEnable (
|
|
HDLG hDlg,
|
|
WORD wID,
|
|
BOOL bEnable
|
|
)
|
|
/*
|
|
Effect: Enable or disable (based on bEnable) the control
|
|
identified by wID in dialog hDlg.
|
|
|
|
See Also: DialogShow.
|
|
*/
|
|
{ // DialogEnable
|
|
HCONTROL hControl ;
|
|
|
|
hControl = GetDlgItem (hDlg, wID) ;
|
|
if (hControl)
|
|
EnableWindow (hControl, bEnable) ;
|
|
} // DialogEnable
|
|
|
|
|
|
void
|
|
DialogShow (
|
|
HDLG hDlg,
|
|
WORD wID,
|
|
BOOL bShow
|
|
)
|
|
{ // DialogShow
|
|
HCONTROL hControl ;
|
|
|
|
hControl = GetDlgItem (hDlg, wID) ;
|
|
if (hControl)
|
|
ShowWindow (hControl, bShow ? SW_SHOW : SW_HIDE) ;
|
|
} // DialogShow
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
_cdecl
|
|
DialogSetText (
|
|
HDLG hDlg,
|
|
WORD wControlID,
|
|
WORD wStringID,
|
|
...
|
|
)
|
|
{ // DialogSetText
|
|
TCHAR szFormat [ControlStringLen] ;
|
|
TCHAR szText [ControlStringLen] ;
|
|
va_list vaList ;
|
|
|
|
if (LoadString (hInstance, wStringID,
|
|
szFormat, ControlStringLen - 1)) {
|
|
va_start (vaList, wStringID) ;
|
|
wvsprintf (szText, szFormat, vaList) ;
|
|
va_end (vaList) ;
|
|
|
|
SetDlgItemText (hDlg, wControlID, szText) ;
|
|
return (TRUE) ;
|
|
} // if
|
|
else
|
|
return (FALSE) ;
|
|
} // DialogSetText
|
|
|
|
|
|
BOOL
|
|
_cdecl
|
|
DialogSetString (
|
|
HDLG hDlg,
|
|
WORD wControlID,
|
|
LPTSTR lpszFormat,
|
|
...
|
|
)
|
|
{ // DialogSetString
|
|
TCHAR szText [ControlStringLen] ;
|
|
va_list vaList ;
|
|
|
|
va_start (vaList, lpszFormat) ;
|
|
wvsprintf (szText, lpszFormat, vaList) ;
|
|
va_end (vaList) ;
|
|
|
|
SetDlgItemText (hDlg, wControlID, szText) ;
|
|
return (TRUE) ;
|
|
} // DialogSetString
|
|
|
|
|
|
|
|
LPTSTR
|
|
LongToCommaString (
|
|
LONG lNumber,
|
|
LPTSTR lpszText
|
|
)
|
|
{ // LongToCommaString
|
|
BOOL bNegative ;
|
|
TCHAR szTemp1 [40] ;
|
|
TCHAR szTemp2 [40] ;
|
|
LPTSTR lpsz1 ;
|
|
LPTSTR lpsz2 ;
|
|
int i ;
|
|
int iDigit ;
|
|
|
|
// 1. Convert the number to a reversed string.
|
|
lpsz1 = szTemp1 ;
|
|
bNegative = (lNumber < 0) ;
|
|
lNumber = labs (lNumber) ;
|
|
|
|
if (lNumber)
|
|
while (lNumber) {
|
|
iDigit = (int) (lNumber % 10L) ;
|
|
lNumber /= 10L ;
|
|
*lpsz1++ = (TCHAR) (TEXT('0') + iDigit) ;
|
|
} else
|
|
*lpsz1++ = TEXT('0') ;
|
|
*lpsz1++ = TEXT('\0') ;
|
|
|
|
|
|
// 2. reverse the string and add commas
|
|
lpsz1 = szTemp1 + lstrlen (szTemp1) - 1 ;
|
|
lpsz2 = szTemp2 ;
|
|
|
|
if (bNegative)
|
|
*lpsz2++ = TEXT('-') ;
|
|
|
|
for (i = lstrlen (szTemp1) - 1;
|
|
i >= 0 ;
|
|
i--) { // for
|
|
*lpsz2++ = *lpsz1-- ;
|
|
if (i && !(i % 3))
|
|
*lpsz2++ = TEXT(',') ;
|
|
} // for
|
|
*lpsz2++ = TEXT('\0') ;
|
|
|
|
return (lstrcpy (lpszText, szTemp2)) ;
|
|
} // LongToCommaString
|
|
|
|
|
|
|
|
BOOL
|
|
MenuSetPopup (
|
|
HWND hWnd,
|
|
int iPosition,
|
|
WORD wControlID,
|
|
LPTSTR lpszResourceID
|
|
)
|
|
{
|
|
HMENU hMenuMain ;
|
|
HMENU hMenuPopup ;
|
|
TCHAR szTopChoice [MenuStringLen + 1] ;
|
|
|
|
hMenuMain = GetMenu (hWnd) ;
|
|
if (!hMenuMain)
|
|
return (FALSE);
|
|
hMenuPopup = LoadMenu (hInstance, lpszResourceID) ;
|
|
|
|
if (!hMenuPopup) {
|
|
DestroyMenu(hMenuMain);
|
|
return (FALSE) ;
|
|
}
|
|
|
|
StringLoad (wControlID, szTopChoice) ;
|
|
return (ModifyMenu (hMenuMain, iPosition, MF_BYPOSITION | MF_POPUP,
|
|
(UINT_PTR) hMenuPopup, szTopChoice)) ;
|
|
}
|
|
|
|
|
|
|
|
LPTSTR
|
|
FileCombine (
|
|
LPTSTR lpszFileSpec,
|
|
LPTSTR lpszFileDirectory,
|
|
LPTSTR lpszFileName
|
|
)
|
|
{ // FileCombine
|
|
|
|
int stringLen ;
|
|
TCHAR DIRECTORY_DELIMITER[2] ;
|
|
|
|
DIRECTORY_DELIMITER[0] = TEXT('\\') ;
|
|
DIRECTORY_DELIMITER[1] = TEXT('\0') ;
|
|
|
|
lstrcpy (lpszFileSpec, lpszFileDirectory) ;
|
|
|
|
stringLen = lstrlen (lpszFileSpec) ;
|
|
if (stringLen > 0 &&
|
|
lpszFileSpec [stringLen - 1] != DIRECTORY_DELIMITER [0])
|
|
lstrcat (lpszFileSpec, DIRECTORY_DELIMITER) ;
|
|
|
|
lstrcat (lpszFileSpec, lpszFileName) ;
|
|
|
|
return (lpszFileSpec) ;
|
|
} // FileCombine
|
|
|
|
// This routine extract the filename portion from a given full-path filename
|
|
LPTSTR
|
|
ExtractFileName (
|
|
LPTSTR pFileSpec
|
|
)
|
|
{
|
|
LPTSTR pFileName = NULL ;
|
|
TCHAR DIRECTORY_DELIMITER1 = TEXT('\\') ;
|
|
TCHAR DIRECTORY_DELIMITER2 = TEXT(':') ;
|
|
|
|
if (pFileSpec) {
|
|
pFileName = pFileSpec + lstrlen (pFileSpec) ;
|
|
|
|
while (*pFileName != DIRECTORY_DELIMITER1 &&
|
|
*pFileName != DIRECTORY_DELIMITER2) {
|
|
if (pFileName == pFileSpec) {
|
|
// done when no directory delimiter is found
|
|
break ;
|
|
}
|
|
pFileName-- ;
|
|
}
|
|
|
|
if (*pFileName == DIRECTORY_DELIMITER1 ||
|
|
*pFileName == DIRECTORY_DELIMITER2) {
|
|
// directory delimiter found, point the
|
|
// filename right after it
|
|
pFileName++ ;
|
|
}
|
|
}
|
|
return pFileName ;
|
|
} // ExtractFileName
|
|
|
|
int
|
|
CBAddInt (
|
|
HWND hWndCB,
|
|
int iValue
|
|
)
|
|
{ // CBAddInt
|
|
TCHAR szValue [ShortTextLen + 1] ;
|
|
CHAR szCharValue [ShortTextLen + 1] ;
|
|
|
|
_itoa (iValue, (LPSTR)szCharValue, 10) ;
|
|
#ifdef UNICODE
|
|
mbstowcs (szValue, (LPSTR)szCharValue, strlen((LPSTR)szCharValue)+1) ;
|
|
return (CBAdd (hWndCB, szValue)) ;
|
|
#else
|
|
return (CBAdd (hWndCB, szCharValue)) ;
|
|
#endif
|
|
|
|
} // CBAddInt
|
|
|
|
void
|
|
DialogSetInterval (
|
|
HDLG hDlg,
|
|
WORD wControlID,
|
|
int IntervalMSec
|
|
)
|
|
{
|
|
TCHAR szValue [MiscTextLen] ;
|
|
|
|
TSPRINTF (szValue, TEXT("%3.3f"),
|
|
(FLOAT)(IntervalMSec) / (FLOAT)1000.0) ;
|
|
|
|
ConvertDecimalPoint (szValue);
|
|
SetDlgItemText (hDlg, wControlID, szValue) ;
|
|
}
|
|
|
|
void
|
|
DialogSetFloat (
|
|
HDLG hDlg,
|
|
WORD wControlID,
|
|
FLOAT eValue
|
|
)
|
|
{
|
|
TCHAR szValue [40] ;
|
|
FLOAT tempValue = eValue ;
|
|
|
|
if (tempValue < (FLOAT) 0.0) {
|
|
tempValue = - tempValue ;
|
|
}
|
|
|
|
if (tempValue < (FLOAT) 1.0E+8) {
|
|
TSPRINTF (szValue, TEXT("%1.4f"), eValue) ;
|
|
} else {
|
|
TSPRINTF (szValue, TEXT("%14.6e"), eValue) ;
|
|
}
|
|
|
|
ConvertDecimalPoint (szValue);
|
|
SetDlgItemText (hDlg, wControlID, szValue) ;
|
|
}
|
|
|
|
|
|
FLOAT DialogFloat (HDLG hDlg,
|
|
WORD wControlID,
|
|
BOOL *pbOK)
|
|
/*
|
|
Effect: Return a floating point representation of the string
|
|
value found in the control wControlID of hDlg.
|
|
|
|
Internals: We use sscanf instead of atof becuase atof returns a
|
|
double. This may or may not be the right thing to do.
|
|
*/
|
|
{ // DialogFloat
|
|
TCHAR szValue [ShortTextLen+1] ;
|
|
FLOAT eValue ;
|
|
int iNumScanned ;
|
|
|
|
DialogText (hDlg, wControlID, szValue) ;
|
|
ReconvertDecimalPoint (szValue);
|
|
iNumScanned = swscanf (szValue, TEXT("%e"), &eValue) ;
|
|
|
|
if (pbOK)
|
|
*pbOK = (iNumScanned == 1) ;
|
|
|
|
return (eValue) ;
|
|
} // DialogFloat
|
|
|
|
|
|
|
|
LPTSTR StringAllocate (LPTSTR lpszText1)
|
|
{ // StringAllocate
|
|
LPTSTR lpszText2 ;
|
|
|
|
if (!lpszText1)
|
|
return (NULL) ;
|
|
|
|
if (lstrlen (lpszText1) == 0)
|
|
return (NULL) ;
|
|
|
|
lpszText2 = MemoryAllocate ((lstrlen (lpszText1)+1) * sizeof (TCHAR)) ;
|
|
if (lpszText2)
|
|
lstrcpy (lpszText2, lpszText1) ;
|
|
|
|
return (lpszText2) ;
|
|
} // StringAllocate
|
|
|
|
|
|
|
|
int DivRound (int iNumerator, int iDenominator)
|
|
/*
|
|
Effect: Return the quotient (iNumerator / iDenominator).
|
|
Round the quotient to the nearest integer.
|
|
This function is similar to normal integer division (/),
|
|
but normal division always rounds down.
|
|
|
|
Note: Surely there must already be a runtime version of this,
|
|
but I couldn't find it.
|
|
|
|
Note: This function originally used the runtime div function
|
|
instead of (/ and %), but the div runtime function is
|
|
now broken (build 265).
|
|
*/
|
|
{ // DivRound
|
|
int iQuotient ;
|
|
int iRemainder ;
|
|
|
|
|
|
iQuotient = iNumerator / iDenominator ;
|
|
iRemainder = iNumerator % iDenominator ;
|
|
|
|
if (iRemainder >= (iDenominator / 2))
|
|
iQuotient++ ;
|
|
|
|
return (iQuotient) ;
|
|
}
|
|
|
|
|
|
BOOL MenuEnableItem (HMENU hMenu,
|
|
WORD wID,
|
|
BOOL bEnable)
|
|
/*
|
|
Effect: Enable or disable, depending on bEnable, the menu item
|
|
associated with id wID in the menu hMenu.
|
|
|
|
Any disabled menu items are displayed grayed out.
|
|
|
|
See Also: EnableMenuItem (windows).
|
|
*/
|
|
{ // MenuEnableItem
|
|
return (EnableMenuItem (hMenu, wID,
|
|
bEnable ?
|
|
(MF_ENABLED | MF_BYCOMMAND) :
|
|
(MF_GRAYED | MF_BYCOMMAND))) ;
|
|
} // MenuEnableItem
|
|
|
|
|
|
int BitmapWidth (HBITMAP hBitmap)
|
|
{ // BitmapWidth
|
|
BITMAP bm ;
|
|
|
|
GetObject (hBitmap, sizeof (BITMAP), (LPSTR) &bm) ;
|
|
return (bm.bmWidth) ;
|
|
} // BitmapWidth
|
|
|
|
|
|
int BitmapHeight (HBITMAP hBitmap)
|
|
{ // BitmapHeight
|
|
BITMAP bm ;
|
|
|
|
GetObject (hBitmap, sizeof (BITMAP), (LPSTR) &bm) ;
|
|
return (bm.bmHeight) ;
|
|
} // BitmapHeight
|
|
|
|
|
|
|
|
int WindowHeight (HWND hWnd)
|
|
{ // WindowHeight
|
|
RECT rectWindow ;
|
|
|
|
GetWindowRect (hWnd, &rectWindow) ;
|
|
return (rectWindow.bottom - rectWindow.top) ;
|
|
} // WindowHeight
|
|
|
|
|
|
|
|
int WindowWidth (HWND hWnd)
|
|
{ // WindowWidth
|
|
RECT rectWindow ;
|
|
|
|
GetWindowRect (hWnd, &rectWindow) ;
|
|
return (rectWindow.right - rectWindow.left) ;
|
|
} // WindowWidth
|
|
|
|
|
|
|
|
void WindowResize (HWND hWnd,
|
|
int xWidth,
|
|
int yHeight)
|
|
/*
|
|
Effect: Change the size of the window hWnd, leaving the
|
|
starting position intact. Redraw the window.
|
|
|
|
If either xWidth or yHeight is NULL, keep the
|
|
corresponding dimension unchanged.
|
|
|
|
Internals: Since hWnd may be a child of another parent, we need
|
|
to scale the MoveWindow arguments to be in the client
|
|
coordinates of the parent.
|
|
|
|
*/
|
|
{ // WindowResize
|
|
RECT rectWindow ;
|
|
HWND hWndParent ;
|
|
|
|
GetWindowRect (hWnd, &rectWindow) ;
|
|
hWndParent = WindowParent (hWnd) ;
|
|
|
|
if (hWndParent)
|
|
ScreenRectToClient (hWndParent, &rectWindow) ;
|
|
|
|
MoveWindow (hWnd,
|
|
rectWindow.left,
|
|
rectWindow.top,
|
|
xWidth ? xWidth : rectWindow.right - rectWindow.left,
|
|
yHeight ? yHeight : rectWindow.bottom - rectWindow.top,
|
|
TRUE) ;
|
|
} // WindowResize
|
|
|
|
|
|
|
|
|
|
void WindowSetTopmost (HWND hWnd, BOOL bTopmost)
|
|
/*
|
|
Effect: Set or clear the "topmost" attribute of hWnd. If a window
|
|
is "topmost", it remains ontop of other windows, even ones
|
|
that have the focus.
|
|
*/
|
|
{
|
|
SetWindowPos (hWnd, bTopmost ? HWND_TOPMOST : HWND_NOTOPMOST,
|
|
0, 0, 0, 0,
|
|
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE) ;
|
|
}
|
|
|
|
|
|
void WindowEnableTitle (HWND hWnd, BOOL bTitle)
|
|
{
|
|
DWORD dwStyle ;
|
|
|
|
|
|
dwStyle = WindowStyle (hWnd) ;
|
|
|
|
if (bTitle)
|
|
dwStyle = WS_TILEDWINDOW | dwStyle ;
|
|
else
|
|
dwStyle =
|
|
dwStyle &
|
|
~ (WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) ;
|
|
|
|
if (!bTitle)
|
|
SetMenu (hWnd, NULL) ;
|
|
|
|
WindowSetStyle (hWnd, dwStyle) ;
|
|
SetWindowPos (hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE |
|
|
SWP_NOZORDER | SWP_FRAMECHANGED );
|
|
}
|
|
|
|
// removing the following routines since LINK32 is not doing that for us
|
|
#ifdef KEEP_UTIL
|
|
int MessageBoxResource (HWND hWndParent,
|
|
WORD wTextID,
|
|
WORD wTitleID,
|
|
UINT uiStyle)
|
|
/*
|
|
Effect: Just like MessageBox, but takes the title and format
|
|
strings from the resoure. In addition, the format string
|
|
is used as a printf style format, combined with the
|
|
additional arguments.
|
|
*/
|
|
{ // MessageBoxResource
|
|
TCHAR szText [MessageLen + 1] ;
|
|
TCHAR szCaption [WindowCaptionLen + 1] ;
|
|
|
|
StringLoad (wTextID, szText) ;
|
|
StringLoad (wTitleID, szCaption) ;
|
|
|
|
return (MessageBox (hWndParent, szText, szCaption, uiStyle)) ;
|
|
} // MessageBoxResource
|
|
|
|
|
|
#define WndProcKey TEXT("OLDWNDPROC")
|
|
|
|
FARPROC WindowSetWndProc (HWND hWnd,
|
|
HANDLE hInstance,
|
|
FARPROC lpfnNewWndProc)
|
|
/*
|
|
Effect: Replace the window procedure of hWnd with lpfnNewWndProc.
|
|
Return the existing window procedure.
|
|
|
|
Note: For proper subclassing, NewWndProc should pass all
|
|
unhandled messages to the original wndproc.
|
|
|
|
Called By: WindowSubclass, WindowUnsubclass.
|
|
*/
|
|
{ // WindowSetWndProc
|
|
FARPROC lpfnNewProcInstance ;
|
|
FARPROC lpfnOldProc ;
|
|
|
|
lpfnOldProc = (FARPROC) GetWindowLongPtr (hWnd, GWLP_WNDPROC) ;
|
|
lpfnNewProcInstance = MakeProcInstance (lpfnNewWndProc, hInstance) ;
|
|
SetWindowLongPtr (hWnd, GWLP_WNDPROC, (LONG_PTR) lpfnNewProcInstance) ;
|
|
|
|
return (lpfnOldProc) ;
|
|
} // WindowSetWndProc
|
|
|
|
WNDPROC WindowGetOriginalWndProc (HWND hWnd)
|
|
/*
|
|
Effect: Return a far pointer to the "original" wndproc for
|
|
hWnd.
|
|
|
|
Assert: WindowSetOriginalProc was already called on this hWnd.
|
|
|
|
See Also: WindowSetOriginalWndProc.
|
|
*/
|
|
{ // WindowGetOriginalWndProc
|
|
return (WNDPROC) GetProp (hWnd, WndProcKey) ;
|
|
} // WindowGetOriginalWndProc
|
|
|
|
|
|
void WindowSetOriginalWndProc (HWND hWnd,
|
|
FARPROC lpfnWndProc)
|
|
/*
|
|
Effect: Save away a far pointer to the "original" wndproc for
|
|
hWnd.
|
|
|
|
See Also: WindowGetOriginalProc.
|
|
*/
|
|
{ // WindowSetOriginalProc
|
|
SetProp (hWnd, WndProcKey, (LPSTR) lpfnWndProc) ;
|
|
} // WindowSetOriginalProc
|
|
|
|
|
|
void WindowSubclass (HWND hWnd,
|
|
HANDLE hInstance,
|
|
FARPROC lpfnNewWndProc)
|
|
/*
|
|
Effect: Replace the wndproc for hWnd with lpfnNewWndProc.
|
|
Save away a pointer to the original procedure.
|
|
|
|
See Also: WindowUnsubclass.
|
|
*/
|
|
{ // WindowSubclass
|
|
FARPROC lpfnOldWndProc ;
|
|
|
|
lpfnOldWndProc = WindowSetWndProc (hWnd, hInstance, lpfnNewWndProc) ;
|
|
WindowSetOriginalWndProc (hWnd, lpfnOldWndProc) ;
|
|
} // WindowSubclass
|
|
|
|
|
|
LONG
|
|
WindowCallOriginalWndProc (
|
|
HWND hWnd,
|
|
UINT msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
WNDPROC lpfnOriginalWndProc ;
|
|
|
|
lpfnOriginalWndProc = WindowGetOriginalWndProc (hWnd) ;
|
|
if (lpfnOriginalWndProc)
|
|
return ((LONG) CallWindowProc (lpfnOriginalWndProc,
|
|
hWnd, msg, wParam, lParam)) ;
|
|
else return (FALSE) ;
|
|
}
|
|
|
|
|
|
|
|
LRESULT
|
|
APIENTRY
|
|
FocusCtlWndProc (
|
|
HWND hWnd,
|
|
UINT wMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{ // FocusCtlWndProc
|
|
BOOL bCallDefProc ;
|
|
LRESULT lReturnValue ;
|
|
|
|
|
|
bCallDefProc = TRUE ;
|
|
lReturnValue = 0L ;
|
|
|
|
switch (wMsg) { // switch
|
|
case WM_SETFOCUS:
|
|
SendMessage (WindowParent (hWnd),
|
|
WM_DLGSETFOCUS, WindowID (hWnd), 0) ;
|
|
break ;
|
|
|
|
|
|
case WM_KILLFOCUS:
|
|
SendMessage (WindowParent (hWnd),
|
|
WM_DLGKILLFOCUS, WindowID (hWnd), 0) ;
|
|
break ;
|
|
|
|
default:
|
|
bCallDefProc = TRUE ;
|
|
} // switch
|
|
|
|
|
|
if (bCallDefProc)
|
|
lReturnValue = WindowCallOriginalWndProc (hWnd, wMsg, wParam, lParam) ;
|
|
|
|
return (lReturnValue);
|
|
} // FocusWndProc
|
|
|
|
|
|
|
|
BOOL DlgFocus (HDLG hDlg, WORD wControlID)
|
|
{ // DlgFocus
|
|
HWND hWndControl ;
|
|
|
|
hWndControl = DialogControl (hDlg, wControlID) ;
|
|
if (!hWndControl)
|
|
return (FALSE) ;
|
|
|
|
WindowSubclass (hWndControl, hInstance, (FARPROC) FocusCtlWndProc) ;
|
|
return (TRUE) ;
|
|
} // DlgFocus
|
|
|
|
|
|
BOOL DeviceNumColors (HDC hDC)
|
|
{ // DeviceNumColors
|
|
int nPlanes ;
|
|
int nBitsPixel ;
|
|
|
|
nPlanes = GetDeviceCaps (hDC, PLANES) ;
|
|
nBitsPixel = GetDeviceCaps (hDC, BITSPIXEL) ;
|
|
|
|
return (1 << (nPlanes * nBitsPixel)) ;
|
|
} // DeviceNumColors
|
|
|
|
|
|
void DrawBitmap (HDC hDC,
|
|
HBITMAP hBitmap,
|
|
int xPos,
|
|
int yPos,
|
|
LONG lROPCode)
|
|
{ // DrawBitmap
|
|
BITMAP bm ;
|
|
HDC hDCMemory ;
|
|
|
|
hDCMemory = CreateCompatibleDC (hDC) ;
|
|
if (hDCMemory) {
|
|
SelectObject (hDCMemory, hBitmap) ;
|
|
|
|
GetObject (hBitmap, sizeof (BITMAP), (LPSTR) &bm) ;
|
|
|
|
BitBlt (hDC, // DC for Destination surface
|
|
xPos, yPos, // location in destination surface
|
|
bm.bmWidth, bm.bmHeight, // dimension of bitmap
|
|
hDCMemory, // DC for Source surface
|
|
0, 0, // location in source surface
|
|
lROPCode) ; // ROP code
|
|
|
|
DeleteDC (hDCMemory) ;
|
|
}
|
|
} // DrawBitmap
|
|
|
|
|
|
#endif // KEEP_UTIL
|
|
|
|
#ifdef PERFMON_DEBUG
|
|
|
|
#define MikeBufferSize 256
|
|
|
|
|
|
int _cdecl mike (TCHAR *szFormat, ...)
|
|
/*
|
|
Note: This function returns a value so that it can more easily
|
|
be used in conditional expressions.
|
|
*/
|
|
{ // mike
|
|
TCHAR szBuffer [MikeBufferSize] ;
|
|
va_list vaList ;
|
|
|
|
va_start (vaList, szFormat) ;
|
|
wvsprintf (szBuffer, szFormat, vaList) ;
|
|
va_end (vaList) ;
|
|
|
|
MessageBox (NULL, szBuffer, TEXT("Debug"), MB_OK | MB_TASKMODAL) ;
|
|
return (0) ;
|
|
} // mike
|
|
|
|
|
|
|
|
int _cdecl mike1 (TCHAR *szFormat, ...)
|
|
/*
|
|
Note: This function returns a value so that it can more easily
|
|
be used in conditional expressions.
|
|
*/
|
|
{ // mike1
|
|
TCHAR szBuffer [MikeBufferSize] ;
|
|
va_list vaList ;
|
|
HDC hDC ;
|
|
RECT rect ;
|
|
|
|
va_start (vaList, szFormat) ;
|
|
wvsprintf (szBuffer, szFormat, vaList) ;
|
|
va_end (vaList) ;
|
|
|
|
rect.left = 0 ;
|
|
rect.right = xScreenWidth ;
|
|
rect.top = 0 ;
|
|
rect.bottom = 20 ;
|
|
|
|
hDC = CreateScreenDC () ;
|
|
ExtTextOut (hDC, 0, 0, ETO_OPAQUE, &rect,
|
|
szBuffer, lstrlen (szBuffer), NULL) ;
|
|
DeleteDC (hDC) ;
|
|
|
|
return (0) ;
|
|
} // mike1
|
|
|
|
int _cdecl mike2 (TCHAR *szFormat, ...)
|
|
/*
|
|
Note: This function returns a value so that it can more easily
|
|
be used in conditional expressions.
|
|
*/
|
|
{ // mike2
|
|
TCHAR szBuffer [MikeBufferSize] ;
|
|
va_list vaList ;
|
|
|
|
va_start (vaList, szFormat) ;
|
|
wvsprintf (szBuffer, szFormat, vaList) ;
|
|
va_end (vaList) ;
|
|
|
|
OutputDebugString (szBuffer) ;
|
|
|
|
return (0) ;
|
|
} // mike2
|
|
#endif // PERFMON_DEBUG
|
|
|
|
|
|
|
|
int inttok (LPSTR lpszText, LPSTR lpszDelimiters)
|
|
{ // inttok
|
|
|
|
// Inttok only works with LPSTRs because of the atoi & strtok
|
|
|
|
LPSTR lpszToken ;
|
|
|
|
lpszToken = strtok (lpszText, lpszDelimiters) ;
|
|
|
|
if (lpszToken)
|
|
return (atoi (lpszToken)) ;
|
|
else
|
|
return (0) ;
|
|
} // inttok
|
|
|
|
|
|
void WindowPlacementToString (PWINDOWPLACEMENT pWP,
|
|
LPTSTR lpszText)
|
|
{
|
|
TSPRINTF (lpszText, TEXT("%d %d %d %d %d %d %d %d %d"),
|
|
pWP->showCmd,
|
|
pWP->ptMinPosition.x,
|
|
pWP->ptMinPosition.y,
|
|
pWP->ptMaxPosition.x,
|
|
pWP->ptMaxPosition.y,
|
|
pWP->rcNormalPosition.left,
|
|
pWP->rcNormalPosition.top,
|
|
pWP->rcNormalPosition.right,
|
|
pWP->rcNormalPosition.bottom) ;
|
|
}
|
|
|
|
|
|
void StringToWindowPlacement (LPTSTR lpszText,
|
|
PWINDOWPLACEMENT pWP)
|
|
{ // StringToWindowPlacement
|
|
CHAR SpaceStr[2];
|
|
CHAR LocalText[TEMP_BUF_LEN];
|
|
|
|
|
|
SpaceStr[0] = ' ' ;
|
|
SpaceStr[1] = '\0' ;
|
|
|
|
#ifdef UNICODE
|
|
// convert the unicode string to char string
|
|
// so we could use inttok
|
|
wcstombs (LocalText, lpszText, sizeof(LocalText)) ;
|
|
#else
|
|
strcpy (LocalText, lpszText) ;
|
|
#endif
|
|
|
|
pWP->length = sizeof (WINDOWPLACEMENT) ;
|
|
pWP->flags = 0 ;
|
|
pWP->showCmd = inttok (LocalText, SpaceStr) ;
|
|
pWP->ptMinPosition.x = inttok (NULL, SpaceStr) ;
|
|
pWP->ptMinPosition.y = inttok (NULL, SpaceStr) ;
|
|
pWP->ptMaxPosition.x = inttok (NULL, SpaceStr) ;
|
|
pWP->ptMaxPosition.y = inttok (NULL, SpaceStr) ;
|
|
pWP->rcNormalPosition.left = inttok (NULL, SpaceStr) ;
|
|
pWP->rcNormalPosition.top = inttok (NULL, SpaceStr) ;
|
|
pWP->rcNormalPosition.right = inttok (NULL, SpaceStr) ;
|
|
pWP->rcNormalPosition.bottom = inttok (NULL, SpaceStr) ;
|
|
} // StringToWindowPlacement
|
|
|
|
|
|
|
|
int LogFontHeight (HDC hDC,
|
|
int iPointSize)
|
|
/*
|
|
Effect: Return the appropriate pixel height for the lfHeight
|
|
field of the LOGFONT structure for the requested point
|
|
size. This size depends on the number of pixels per
|
|
logical inch of the current display context, hDC.
|
|
|
|
Called By: Any function which wants to create a particular
|
|
point-height font.
|
|
*/
|
|
{ // LogFontHeight
|
|
return (-MulDiv (iPointSize, GetDeviceCaps (hDC, LOGPIXELSY), 72)) ;
|
|
} // LogFontHeight
|
|
|
|
|
|
// this routine converts the input menu id into help id.
|
|
DWORD MenuIDToHelpID (DWORD MenuID)
|
|
{
|
|
DWORD HelpID = 0 ;
|
|
|
|
if (MenuID >= IDM_FIRSTMENUID && MenuID <= IDM_LASTMENUID) {
|
|
// only special cases...
|
|
if (MenuID >= IDM_OPTIONSREFRESHNOWCHART &&
|
|
MenuID <= IDM_OPTIONSREFRESHNOWREPORT) {
|
|
HelpID = HC_PM_MENU_OPTIONSREFRESHNOW ;
|
|
} else {
|
|
HelpID = MenuID - MENUIDTOHELPID ;
|
|
}
|
|
#ifndef ADVANCED_PERFMON
|
|
// need to convert these 2 IDs for Perf. Meter
|
|
if (HelpID == HC_PM_MENU_HELPABOUT) {
|
|
HelpID = HC_NTPM_MENU_HELPABOUT ;
|
|
} else if (HelpID == HC_PM_MENU_FILEEXIT) {
|
|
HelpID = HC_NTPM_MENU_FILEEXIT ;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return (HelpID) ;
|
|
}
|
|
|