📄 status.c
字号:
} else {
if(plist->isselected) {
hDC = GetDC(hWnd);
InitDC(hDC);
StatusButtonUp(hDC, ip);
ReleaseDC(hWnd, hDC);
plist->isselected = FALSE;
}
}
}
GlobalUnlock(hitems);
break;
case WM_DESTROY:
hitems = (HANDLE) GetWindowLong(hWnd, 0);
GlobalUnlock(hitems);
GlobalFree(hitems);
SetWindowLong(hWnd, 0, 0L);
break;
case SM_NEW:
hitems = (HANDLE) GetWindowLong(hWnd, 0);
if (hitems != NULL) {
GlobalFree(hitems);
}
hitems = (HANDLE) wParam;
if (hitems == NULL) {
SetWindowLong(hWnd, 0, 0L);
InvalidateRect(hWnd, NULL, TRUE);
break;
}
plist = (PILIST) GlobalLock(hitems);
if (plist == NULL) {
SetWindowLong(hWnd, 0, 0L);
InvalidateRect(hWnd, NULL, TRUE);
break;
}
plist->selitem = -1;
StatusResize(hWnd, plist);
GlobalUnlock(hitems);
SetWindowLong(hWnd, 0, (LONG)hitems);
InvalidateRect(hWnd, NULL, TRUE);
break;
case SM_SETTEXT:
hitems = (HANDLE) GetWindowLong(hWnd, 0);
if (hitems == NULL) {
break;
}
plist = (PILIST) GlobalLock(hitems);
ip = StatusGetItem(plist, wParam);
if (ip != NULL) {
if (lParam == 0) {
ip->text[0] = '\0';
} else {
strncpy(ip->text, (LPSTR) lParam, SF_MAXLABEL);
ip->text[SF_MAXLABEL] = '\0';
}
/* if this is a variable width field, we need to redo
* all size calcs in case the field width has changed.
* in that case, we need to repaint the entire window
* and not just this field - so set rc to indicate the
* area to be redrawn.
*/
if (ip->flags & SF_VAR) {
StatusResize(hWnd, plist);
GetClientRect(hWnd, &rc);
RedrawWindow(hWnd, &rc, NULL,
RDW_INVALIDATE|RDW_ERASE|RDW_UPDATENOW);
} else {
/* instead of just invalidating the window, we can
* force the window to be repainted now. This is
* essential for status updates during a busy
* loop when no messages are being processed,
* but we should still update the user on what's
* happening.
*/
RedrawWindow(hWnd, &ip->rc, NULL,
RDW_INVALIDATE|RDW_NOERASE|RDW_UPDATENOW);
}
}
GlobalUnlock(hitems);
break;
default:
return(DefWindowProc(hWnd, message, wParam, lParam));
}
return 0;
}
/***************************************************************************
* Function: StatusResize
*
* Purpose:
*
* Position the labels and buttons within the status window
*/
void
StatusResize(HWND hWnd, PILIST iplistp)
{
RECT rc;
int curpos_right, curpos_left;
int height, width;
int i;
PSTATEL ip;
if (iplistp == NULL) {
return;
}
GetClientRect(hWnd, &rc);
curpos_left = rc.left + status_charwidth / 2;
curpos_right = rc.right - (status_charwidth / 2);
/* loop through all items setting their position rects.
* items are flagged as being left or right. We place them
* in order starting at the left and the right, with a single
* char's width between each item
*/
for (i = 0; i < iplistp->nitems; i++) {
ip = &iplistp->statels[i];
width = StatusCalcWidth(hWnd, ip);
height = StatusCalcHeight(hWnd, ip);
ip->rc.top = (rc.bottom - height) / 2;
ip->rc.bottom = ip->rc.top + height;
/* see if this item fits. Items that partially fit
* are placed reduced in size.
*/
if (ip->flags & SF_LEFT) {
if (curpos_left+width >= curpos_right) {
/* doesn't completely fit-does it partly? */
if ((curpos_left + 1) >= curpos_right){
/* no - this item does not fit */
ip->rc.left = 0;
ip->rc.right = 0;
} else {
/* partial fit */
ip->rc.left = curpos_left;
ip->rc.right = curpos_right - 1;
curpos_left = curpos_right;
}
} else {
/* complete fit */
ip->rc.left = curpos_left;
ip->rc.right = curpos_left + width;
curpos_left += width + 1;
}
} else {
/* same size check for right-aligned items */
if (curpos_right-width <= curpos_left) {
/* partial fit ? */
if (curpos_right <= curpos_left+1) {
ip->rc.left = 0;
ip->rc.right = 0;
} else {
/* yes - partial fit */
ip->rc.left = curpos_left + 1;
ip->rc.right = curpos_right;
curpos_right = curpos_left;
}
} else {
/* complete fit */
ip->rc.right = curpos_right;
ip->rc.left = curpos_right - width;
curpos_right -= (width + 1);
}
}
}
}
/***************************************************************************
* Function: StatusPaint
*
* Purpose:
*
* Paint the status window
*/
void
StatusPaint(HWND hWnd, PILIST iplistp)
{
RECT rc;
HDC hDC;
PAINTSTRUCT ps;
int i;
PSTATEL ip;
HPEN hpenOld;
GetClientRect(hWnd, &rc);
hDC = BeginPaint(hWnd, &ps);
InitDC(hDC);
RaiseRect(hDC, &rc);
if (iplistp == NULL) {
EndPaint(hWnd, &ps);
return;
}
for (i =0; i < iplistp->nitems; i++) {
ip = &iplistp->statels[i];
if (ip->rc.left == ip->rc.right) {
continue;
}
if (ip->type == SF_STATIC) {
if (ip->flags & SF_RAISE) {
RaiseRect(hDC, &ip->rc);
} else if (ip->flags & SF_LOWER) {
LowerRect(hDC, &ip->rc);
}
rc = ip->rc;
rc.left += (status_charwidth / 2);
rc.right--;
rc.top++;
rc.bottom--;
hpenOld = SelectObject(hDC, hpenNeutral);
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
SelectObject(hDC, hpenOld);
DrawText(hDC, ip->text, lstrlen(ip->text), &rc,
DT_LEFT | DT_VCENTER);
} else {
StatusButtonUp(hDC, ip);
}
}
EndPaint(hWnd, &ps);
}
/***************************************************************************
* Function: RaiseRect
*
* Purpose:
*
*/
void
RaiseRect(HDC hDC, LPRECT rcp)
{
TopLeft(hDC, rcp, hpenHilight, FALSE);
BottomRight(hDC, rcp, hpenLowlight, FALSE);
}
/***************************************************************************
* Function: LowerRect
*
* Purpose:
*
*/
void
LowerRect(HDC hDC, LPRECT rcp)
{
TopLeft(hDC, rcp, hpenLowlight, FALSE);
BottomRight(hDC, rcp, hpenHilight, FALSE);
}
/***************************************************************************
* Function: StatusButtonUp
*
* Purpose:
*
*/
void
StatusButtonUp(HDC hDC, PSTATEL ip)
{
RECT rc;
HPEN hpenOld;
rc = ip->rc;
TopLeft(hDC, &rc, hpenBlack, TRUE);
BottomRight(hDC, &rc, hpenBlack, FALSE);
rc.top++;
rc.bottom--;
rc.left++;
rc.right--;
TopLeft(hDC, &rc, hpenHilight, FALSE);
BottomRight(hDC, &rc, hpenLowlight, TRUE);
rc.top++;
rc.bottom--;
rc.left++;
rc.right--;
BottomRight(hDC, &rc, hpenLowlight, TRUE);
rc.bottom--;
rc.right--;
hpenOld = SelectObject(hDC, hpenNeutral);
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
SelectObject(hDC, hpenOld);
DrawText(hDC, ip->text, lstrlen(ip->text), &rc, DT_CENTER | DT_VCENTER);
}
/***************************************************************************
* Function: StatusButtonDown
*
* Purpose:
*
*/
void
StatusButtonDown(HDC hDC, PSTATEL ip)
{
RECT rc;
HPEN hpenOld;
rc = ip->rc;
TopLeft(hDC, &rc, hpenBlack, TRUE);
BottomRight(hDC, &rc, hpenBlack, FALSE);
rc.top++;
rc.bottom--;
rc.left++;
rc.right--;
TopLeft(hDC, &rc, hpenLowlight, TRUE);
rc.top++;
rc.left++;
TopLeft(hDC, &rc, hpenNeutral, TRUE);
rc.top++;
rc.left++;
TopLeft(hDC, &rc, hpenNeutral, TRUE);
rc.top++;
rc.left++;
hpenOld = SelectObject(hDC, hpenNeutral);
Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
SelectObject(hDC, hpenOld);
DrawText(hDC, ip->text, lstrlen(ip->text), &rc, DT_CENTER | DT_VCENTER);
}
/***************************************************************************
* Function: TopLeft
*
* Purpose:
*
*/
void
TopLeft(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners)
{
HPEN hpenOld;
int x, y;
hpenOld = SelectObject(hDC, hpen);
x = rcp->right - 1;
y = rcp->bottom;
if (!bCorners) {
x--;
y--;
}
MoveToEx(hDC, x, rcp->top, NULL);
LineTo(hDC, rcp->left, rcp->top);
LineTo(hDC, rcp->left, y);
SelectObject(hDC, hpenOld);
}
/***************************************************************************
* Function: BottomRight
*
* Purpose:
*
*/
void
BottomRight(HDC hDC, LPRECT rcp, HPEN hpen, BOOL bCorners)
{
HPEN hpenOld;
int x, y;
hpenOld = SelectObject(hDC, hpen);
x = rcp->left - 1;
y = rcp->top;
if (!bCorners) {
x++;
y++;
}
MoveToEx(hDC, rcp->right-1, y, NULL);
LineTo(hDC, rcp->right-1, rcp->bottom-1);
LineTo(hDC, x, rcp->bottom-1);
SelectObject(hDC, hpenOld);
}
/***************************************************************************
* Function: StatusGetItem
*
* Purpose:
*
*/
PSTATEL
StatusGetItem(PILIST plist, int id)
{
int i;
if (plist == NULL) {
return(NULL);
}
for (i = 0; i < plist->nitems; i++) {
if (plist->statels[i].id == id) {
return(&plist->statels[i]);
}
}
return(NULL);
}
/***************************************************************************
* Function: StatusCalcWidth
*
* Purpose:
*
* Calculate the width of a given field. This is the width in characters
* multiplied by the average character width, plus a few units for
* borders.
*
* If SF_VAR is set, this field size varies depending on the text, so
* we use GetTextExtent for the field size. If SF_VAR is selected, the caller
* can specify that the size is not to exceed the (width * avecharwidth)
* size (using SF_SZMAX) or that it is not be less than it (SF_SZMIN).
*/
int
StatusCalcWidth(HWND hWnd, PSTATEL ip)
{
int ch_size, t_size;
SIZE sz;
HDC hDC;
ch_size = ip->width * status_charwidth;
if (ip->flags & SF_VAR) {
hDC = GetDC(hWnd);
InitDC(hDC);
GetTextExtentPoint(hDC, ip->text, lstrlen(ip->text), &sz);
ReleaseDC(hWnd, hDC);
t_size = sz.cx;
/*
* check this size against min/max size if
* requested
*/
if (ip->flags & SF_SZMIN) {
if (ch_size > t_size) {
t_size = ch_size;
}
}
if (ip->flags & SF_SZMAX) {
if (ch_size < t_size) {
t_size = ch_size;
}
}
ch_size = t_size;
}
if (ch_size != 0) {
if (ip->type == SF_BUTTON) {
return(ch_size+6);
} else {
return(ch_size+4);
}
} else {
return(0);
}
}
/***************************************************************************
* Function: StatusCalcHeight
*
* Purpose:
*
* Calculate the height of a given field
*/
int
StatusCalcHeight(HWND hWnd, PSTATEL ip)
{
int size;
size = status_charheight;
if (ip->type == SF_BUTTON) {
return(size + 6);
} else {
return(size + 2);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -