📄 status.c
字号:
/****************************** Module Header *******************************
* Module Name: STATUS.C
*
* Status line handler.
*
* Functions:
*
* StatusInit()
* StatusCreate()
* StatusHeight()
* StatusAlloc()
* StatusAddItem()
* StatusCreateTools()
* StatusDeleteTools()
* StatusWndProc()
* StatusResize()
* StatusCalcHeight()
* StatusCalcWidth()
* StatusGetItem()
* LowerRect()
* RaiseRect()
* StatusPaint()
* BottomRight()
* TopLeft()
* StatusButtonDown()
* StatusButtonUp()
* InitDC()
*
* Comments:
*
****************************************************************************/
#include <windows.h>
#include <string.h>
#include "gutils.h"
/* --- data structures ------------------------------------------------- */
#define SF_MAXLABEL 80 /* no more than 80 in an item within the bar */
/* Is this adequate for long pathnames on a
hi-res screen?
*/
typedef struct statel {
int type; /* SF_BUTTON or SF_STATIC */
int flags; /* SF_VAR => variable width
SF_LEFT=> left aligned (else right)
SF_RAISE=> paint as 'raised' 3d rect
SF_LOWER=> paint as lowered 3D rect
SF_SZMIN=>together with SF_VAR
allows minimum size for
var sized item
SF_SZMAX=>see SZMIN and use nouse
*/
int id; /* control id */
int width; /* width of control in chars */
char text[SF_MAXLABEL+1]; /* null-term string for label */
RECT rc; /* used by status.c */
} STATEL, FAR * PSTATEL;
typedef struct itemlist {
int nitems;
PSTATEL statels;
int selitem; /* used by status.c */
BOOL isselected; /* used by status.c */
} ILIST, FAR * PILIST;
/* prototypes of routines in this module */
void StatusCreateTools(void);
void StatusDeleteTools(void);
long APIENTRY StatusWndProc(HWND, UINT, UINT, LONG);
void StatusResize(HWND hWnd, PILIST pilist);
int StatusCalcHeight(HWND hWnd, PSTATEL ip);
int StatusCalcWidth(HWND hWnd, PSTATEL ip);
PSTATEL StatusGetItem(PILIST plist, int id);
void LowerRect(HDC hDC, LPRECT rcp);
void RaiseRect(HDC hDC, LPRECT rcp);
void StatusPaint(HWND hWnd, PILIST iplistp);
void BottomRight(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners);
void TopLeft(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners);
void StatusButtonDown(HDC hDC, PSTATEL ip);
void StatusButtonUp(HDC hDC, PSTATEL ip);
void InitDC(HDC hdc);
/*--global data---------------------------------------------------------*/
HPEN hpenHilight, hpenLowlight;
HPEN hpenBlack, hpenNeutral;
HBRUSH hbrBackground; /* pieces and board */
HFONT hFont;
int status_charheight, status_charwidth;
/* default pt size for font (tenths of a pt) */
#define DEF_PTSIZE 80
/***************************************************************************
* Function: StatusInit
*
* Purpose:
*
* Create window class
*/
BOOL
StatusInit(HANDLE hInstance)
{
WNDCLASS wc;
BOOL resp;
TEXTMETRIC tm;
HDC hDC;
StatusCreateTools();
wc.style = CS_HREDRAW|CS_VREDRAW|CS_GLOBALCLASS;
wc.lpfnWndProc = (WNDPROC) StatusWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(HANDLE);
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = hbrBackground;
wc.lpszClassName = (LPSTR) "gdstatusclass";
wc.lpszMenuName = NULL;
resp = RegisterClass(&wc);
hDC = GetDC(NULL);
InitDC(hDC);
GetTextMetrics(hDC, &tm);
status_charheight = (int)(tm.tmHeight + tm.tmExternalLeading);
status_charwidth = (int)tm.tmAveCharWidth;
ReleaseDC(NULL, hDC);
return(resp);
}
/*
/***************************************************************************
* Function: StatusCreate
*
* Purpose:
*
* Create and show the window
*/
HWND APIENTRY
StatusCreate(HANDLE hInst, HWND hParent, int id, LPRECT rcp, HANDLE hmem)
{
HWND hWnd;
/* create a child window of status class */
hWnd = CreateWindow("gdstatusclass",
NULL,
WS_CHILD | WS_VISIBLE,
rcp->left,
rcp->top,
(rcp->right - rcp->left),
(rcp->bottom - rcp->top),
hParent,
(HANDLE) id,
hInst,
(LPVOID) hmem);
return(hWnd);
}
/***************************************************************************
* Function: StatusHeight
*
* Purpose:
*
* Return default height of this window
*/
int APIENTRY
StatusHeight(HANDLE hmem)
/* The window has a number of items which are arranged horizontally,
so the window height is the maximum of the individual heights
*/
{
PILIST plist;
int i;
int sz;
int maxsize = 0;
plist = (PILIST) GlobalLock(hmem);
if (plist != NULL) {
for (i = 0; i<plist->nitems; i++) {
sz = StatusCalcHeight(NULL, &plist->statels[i]);
maxsize = max(sz, maxsize);
}
}
GlobalUnlock(hmem);
if (maxsize > 0) {
return(maxsize + 4);
} else {
return(status_charheight + 4);
}
}
/***************************************************************************
* Function: StatusAlloc
*
* Purpose:
*
* Alloc the plist struct and return handle to caller
*/
HANDLE FAR PASCAL
StatusAlloc(int nitems)
{
HANDLE hmem;
PILIST pilist;
LPSTR chp;
hmem = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
sizeof(ILIST) + (sizeof(STATEL) * nitems));
chp = GlobalLock(hmem);
if (chp == NULL) {
return(NULL);
}
pilist = (PILIST) chp;
pilist->nitems = nitems;
pilist->statels = (PSTATEL) &chp[sizeof(ILIST)];
GlobalUnlock(hmem);
return(hmem);
}
/***************************************************************************
* Function: StatusAddItem
*
* Purpose:
*
* Insert an item into the plist
*/
BOOL FAR PASCAL
StatusAddItem(HANDLE hmem, int itemnr, int type, int flags, int id,
int width, LPSTR text)
{
PILIST pilist;
PSTATEL pel;
pilist = (PILIST) GlobalLock(hmem);
if ((pilist == NULL) || (itemnr >= pilist->nitems)) {
GlobalUnlock(hmem);
return(FALSE);
}
pel = &pilist->statels[itemnr];
pel->type = type;
pel->flags = flags;
pel->id = id;
pel->width = width;
if (text == NULL) {
pel->text[0] = '\0';
} else {
lstrcpy(pel->text, text);
}
GlobalUnlock(hmem);
return(TRUE);
}
/***************************************************************************
* Function: InitDC
*
* Purpose:
*
* Initialize colors and font
*/
void
InitDC(HDC hdc)
{
SetBkColor(hdc, RGB(192,192,192));
SelectObject(hdc, hbrBackground);
SelectObject(hdc, hFont);
}
/***************************************************************************
* Function: StatusCreateTools
*
* Purpose:
*
* Create Pens and brushes
*/
void
StatusCreateTools()
{
LOGFONT lf;
HDC hdc;
int scale;
hbrBackground = CreateSolidBrush(RGB(192,192,192));
hpenHilight = CreatePen(0, 1, RGB(255, 255, 255));
hpenLowlight = CreatePen(0, 1, RGB(128, 128, 128));
hpenNeutral = CreatePen(0, 1, RGB(192, 192, 192));
hpenBlack = CreatePen(0, 1, RGB(0, 0, 0));
hdc = GetDC(NULL);
scale = GetDeviceCaps(hdc, LOGPIXELSY);
ReleaseDC(NULL, hdc);
lf.lfHeight = -MulDiv(DEF_PTSIZE, scale, 720);
lf.lfWidth = 0;
lf.lfEscapement = 0;
lf.lfOrientation = 0;
lf.lfWeight = FW_REGULAR;
lf.lfItalic = 0;
lf.lfUnderline = 0;
lf.lfStrikeOut = 0;
lf.lfCharSet = ANSI_CHARSET;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfQuality = PROOF_QUALITY;
lf.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
lf.lfFaceName[0] = '\0';
#ifdef COMPLEX
hFont = CreateFontIndirect(&lf);
#else
hFont = GetStockObject(SYSTEM_FONT);
#endif
}
/***************************************************************************
* Function: StatusDeleteTools
*
* Purpose:
*
* Delete brushes and pens
*/
void
StatusDeleteTools()
{
DeleteObject(hbrBackground);
DeleteObject(hpenHilight);
DeleteObject(hpenLowlight);
DeleteObject(hpenBlack);
DeleteObject(hpenNeutral);
#ifdef COMPLEX
DeleteObject(hFont);
#endif
}
/***************************************************************************
* Function: StatusWndProc
*
* Purpose:
*
* Main winproc for status windows
*
* handles create/destroy and paint requests
*/
long FAR PASCAL
StatusWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam)
{
HANDLE hitems;
PSTATEL ip;
PILIST plist;
CREATESTRUCT FAR * cp;
int i;
HDC hDC;
RECT rc;
POINT pt;
switch(message) {
case WM_CREATE:
cp = (CREATESTRUCT FAR *) lParam;
hitems = (HANDLE) (LONG) cp->lpCreateParams;
SetWindowLong(hWnd, 0, (LONG)hitems);
plist = (PILIST) GlobalLock(hitems);
if (plist != NULL) {
plist->selitem = -1;
GlobalUnlock(hitems);
}
break;
case WM_SIZE:
hitems = (HANDLE) GetWindowLong(hWnd, 0);
plist = (PILIST) GlobalLock(hitems);
if (plist != NULL) {
StatusResize(hWnd, plist);
GlobalUnlock(hitems);
}
break;
case WM_PAINT:
hitems = (HANDLE) GetWindowLong(hWnd, 0);
plist = (PILIST) GlobalLock(hitems);
StatusPaint(hWnd, plist);
GlobalUnlock(hitems);
break;
case WM_LBUTTONUP:
hitems = (HANDLE) GetWindowLong(hWnd, 0);
plist = (PILIST) GlobalLock(hitems);
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
if (plist == NULL) {
break;
}
if (plist->selitem != -1) {
ip = &plist->statels[plist->selitem];
if (plist->isselected) {
hDC = GetDC(hWnd);
InitDC(hDC);
StatusButtonUp(hDC, ip);
ReleaseDC(hWnd, hDC);
}
plist->selitem = -1;
ReleaseCapture();
if (PtInRect(&ip->rc, pt)) {
SendMessage(GetParent(hWnd), WM_COMMAND,
MAKELONG(ip->id, WM_LBUTTONUP), (LONG)hWnd);
}
}
GlobalUnlock(hitems);
break;
case WM_LBUTTONDOWN:
hitems = (HANDLE) GetWindowLong(hWnd, 0);
plist = (PILIST) GlobalLock(hitems);
if (plist == NULL) {
break;
}
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
if (plist->selitem == -1) {
for (i = 0; i< plist->nitems; i++) {
ip = &plist->statels[i];
if (PtInRect(&ip->rc, pt)) {
if (ip->type != SF_BUTTON) {
break;
}
plist->selitem = i;
SetCapture(hWnd);
plist->isselected = TRUE;
hDC = GetDC(hWnd);
InitDC(hDC);
StatusButtonDown(hDC, ip);
ReleaseDC(hWnd, hDC);
break;
}
}
}
GlobalUnlock(hitems);
break;
case WM_MOUSEMOVE:
hitems = (HANDLE) GetWindowLong(hWnd, 0);
plist = (PILIST) GlobalLock(hitems);
if (plist == NULL) {
break;
}
pt.x = LOWORD(lParam);
pt.y = HIWORD(lParam);
if (plist->selitem != -1) {
ip = &plist->statels[plist->selitem];
if (PtInRect(&ip->rc, pt)) {
if (!plist->isselected) {
hDC = GetDC(hWnd);
InitDC(hDC);
StatusButtonDown(hDC, ip);
ReleaseDC(hWnd, hDC);
plist->isselected = TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -