📄 toolbar.c
字号:
#ifdef _WIN32
PostMessage(
GetParent(hwnd),
WM_COMMAND,
GET_WM_COMMAND_MPS(GetWindowLong(hwnd, GWL_ID), hwnd, iButton));
#else
PostMessage(GetParent(hwnd),WM_COMMAND,
GetWindowWord(hwnd,GWW_ID),MAKELONG(hwnd,iButton));
#endif
}
/***************************************************************************/
/* toolbarPaintControl: Handles paint messages by blitting each bitmap */
/* that is on the toolbar to its rect. */
/* First, it fixes the states of the buttons to give */
/* the focus to the proper button. */
/* Returns FALSE for an error. */
/***************************************************************************/
static BOOL NEAR PASCAL toolbarPaintControl(HWND hwnd, HDC hdc)
{
int iBtnPos; /* 0 to toolbarGetNumButtons inclusive */
int iButton; /* 0 to NUMBUTTONS-1 inclusive */
int iState; /* 0 to NUMSTATES-1 inclusive */
HDC hdcBtn; /* DC onto button bitmap */
RECT rcDest;
POINT pt;
long l;
HANDLE hbm;
/* Make a source HDC for the button pictures, and select the button */
/* bitmap into it. */
hdcBtn = CreateCompatibleDC(hdc);
if (!hdcBtn)
return FALSE;
hbm = GETBMPHANDLE(hwnd);
if (hbm) {
if (!SelectObject(hdcBtn, GETBMPHANDLE(hwnd))) {
DeleteDC(hdcBtn);
return FALSE;
}
}
toolbarFixFocus(hwnd); // set the focus field correctly
/* Go through all buttons on the toolbar */
for (iBtnPos = 0; iBtnPos < toolbarGetNumButtons(hwnd); iBtnPos++) {
iButton = toolbarButtonFromIndex(hwnd, iBtnPos); // button
iState = toolbarFullStateFromButton(hwnd, iButton); // state
toolbarRectFromIndex(hwnd, iBtnPos, &rcDest); // Dest Rect
/* If we have the focus, we should draw it that way */
if (GetFocus() == hwnd && GETWHICH(hwnd) == iBtnPos
&& iState == BTNST_UP)
iState = BTNST_FOCUSUP;
if (GetFocus() == hwnd && GETWHICH(hwnd) == iBtnPos
&& iState == BTNST_DOWN)
iState = BTNST_FOCUSDOWN;
/* If we don't have the focus, we should take it away */
if ((GetFocus() != hwnd || GETWHICH(hwnd) != iBtnPos)
&& iState == BTNST_FOCUSUP)
iState = BTNST_UP;
if ((GetFocus() != hwnd || GETWHICH(hwnd) == iBtnPos)
&& iState == BTNST_FOCUSDOWN)
iState = BTNST_DOWN;
/* The size of each button */
l = GETBUTTONSIZE(hwnd);
pt.x = HIWORD(l);
pt.y = LOWORD(l);
/* Blit from the button picture to the toolbar window */
BitBlt(hdc, rcDest.left, rcDest.top,
rcDest.right - rcDest.left, rcDest.bottom - rcDest.top,
hdcBtn, pt.x * iButton, pt.y * iState,
SRCCOPY);
}
DeleteDC(hdcBtn);
return TRUE;
}
/***************************************************************************/
/* toolbarMoveFocus: Move Focus forward or backward one button. You give */
/* it the direction to move the focus. The routine will*/
/* stop at the end of the button list without wrapping */
/* around. */
/* Returns TRUE if focus moved, or FALSE if it ran out */
/* of buttons before finding a non-grayed one. */
/***************************************************************************/
BOOL FAR PASCAL toolbarMoveFocus(HWND hwnd, BOOL fBackward)
{
int iBtnPos, iButton, nOffset, nStopAt;
RECT rc;
int iPrevPos = GETWHICH(hwnd); /* Who used to have focus? */
/* Fix illegal value. It's OK to be one less or greater than range */
if (iPrevPos < -1 || iPrevPos > GETNUMBUTTONS(hwnd))
SETWHICH(hwnd, 0); // good a default as any
if (fBackward) {
nOffset = -1;
nStopAt = -1;
} else {
nOffset = 1;
nStopAt = GETNUMBUTTONS(hwnd);
}
/* look for next button that isn't grayed */
/* DON'T wrap around - future code will pass */
/* the focus to another window (???) */
for (iBtnPos = GETWHICH(hwnd) + nOffset;
iBtnPos != nStopAt;
iBtnPos += nOffset) {
iButton = toolbarButtonFromIndex(hwnd, iBtnPos);
if (toolbarStateFromButton(hwnd, iButton) !=
BTNST_GRAYED) {
SETWHICH(hwnd, iBtnPos); // set focus
/* Redraw both old and new focused button */
toolbarRectFromIndex(hwnd, iPrevPos, &rc);
InvalidateRect(hwnd, &rc, FALSE);
toolbarRectFromIndex(hwnd, iBtnPos, &rc);
InvalidateRect(hwnd, &rc, FALSE);
break;
}
}
if (GETWHICH(hwnd) != iPrevPos)
return TRUE;
else
return FALSE;
}
/***************************************************************************/
/* toolbarSetFocus : Set the focus in the toolbar to the specified button.*/
/* If it's gray, it'll set focus to next ungrayed btn. */
/* Returns TRUE if focus set, or FALSE if the button */
/* doesn't exist or if it and all buttons after it were */
/* grayed... You can use TB_FIRST or TB_LAST in */
/* place of a button ID. This uses the first or last */
/* un-grayed button. */
/***************************************************************************/
BOOL FAR PASCAL toolbarSetFocus(HWND hwnd, int iButton)
{
int iBtnPos;
RECT rc;
/* Don't move focus while a button is down */
if (GetCapture() != hwnd && !GETKEYPRESSED(hwnd)) {
/* redraw button with focus in case focus moves */
toolbarRectFromIndex(hwnd, GETWHICH(hwnd), &rc);
InvalidateRect(hwnd, &rc, FALSE);
if (iButton == TB_FIRST) {
SETWHICH(hwnd, -1); // move forward to 1st button
return toolbarMoveFocus(hwnd, FALSE);
} else if (iButton == TB_LAST) {
SETWHICH(hwnd, GETNUMBUTTONS(hwnd));
return toolbarMoveFocus(hwnd, TRUE);
} else {
iBtnPos = toolbarIndexFromButton(hwnd, iButton);
if (iBtnPos != -1) {
SETWHICH(hwnd, --iBtnPos);
return toolbarMoveFocus(hwnd, FALSE);
} else
return FALSE;
}
return TRUE;
} else
return FALSE;
}
//
// LoadUIBitmap() - load a bitmap resource
//
// load a bitmap resource from a resource file, converting all
// the standard UI colors to the current user specifed ones.
//
// this code is designed to load bitmaps used in "gray ui" or
// "toolbar" code.
//
// the bitmap must be a 4bpp windows 3.0 DIB, with the standard
// VGA 16 colors.
//
// the bitmap must be authored with the following colors
//
// Button Text Black (index 0)
// Button Face lt gray (index 7)
// Button Shadow gray (index 8)
// Button Highlight white (index 15)
// Window Color yellow (index 11)
// Window Frame green (index 10)
//
// Example:
//
// hbm = LoadUIBitmap(hInstance, "TestBmp",
// GetSysColor(COLOR_BTNTEXT),
// GetSysColor(COLOR_BTNFACE),
// GetSysColor(COLOR_BTNSHADOW),
// GetSysColor(COLOR_BTNHIGHLIGHT),
// GetSysColor(COLOR_WINDOW),
// GetSysColor(COLOR_WINDOWFRAME));
//
// Author: JimBov, ToddLa
//
//
HBITMAP FAR PASCAL LoadUIBitmap(
HANDLE hInstance, // EXE file to load resource from
LPCSTR szName, // name of bitmap resource
COLORREF rgbText, // color to use for "Button Text"
COLORREF rgbFace, // color to use for "Button Face"
COLORREF rgbShadow, // color to use for "Button Shadow"
COLORREF rgbHighlight, // color to use for "Button Hilight"
COLORREF rgbWindow, // color to use for "Window Color"
COLORREF rgbFrame) // color to use for "Window Frame"
{
LPBYTE lpb;
HBITMAP hbm;
LPBITMAPINFOHEADER lpbi;
HANDLE h;
HDC hdc;
LPDWORD lprgb;
int isize;
HANDLE hmem;
LPBYTE lpCopy;
// convert a RGB into a RGBQ
#define RGBQ(dw) RGB(GetBValue(dw),GetGValue(dw),GetRValue(dw))
h = LoadResource (hInstance,FindResource(hInstance, szName, RT_BITMAP));
lpbi = (LPBITMAPINFOHEADER)LockResource(h);
if (!lpbi)
return(NULL);
if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
return NULL;
if (lpbi->biBitCount != 4)
return NULL;
/*
* copy the resource since they are now loaded read-only
*/
#ifdef _WIN32
isize = lpbi->biSize + lpbi->biSizeImage +
((int)lpbi->biClrUsed ?
(int)lpbi->biClrUsed :
(1 << (int)lpbi->biBitCount))
* sizeof(RGBQUAD);
hmem = GlobalAlloc(GHND, isize);
lpCopy = GlobalLock(hmem);
if ((hmem == NULL) || (lpCopy == NULL)) {
UnlockResource(h);
FreeResource(h);
return(NULL);
}
CopyMemory(lpCopy, lpbi, isize);
UnlockResource(h);
FreeResource(h);
lpbi = (LPBITMAPINFOHEADER)lpCopy;
#endif
/* Calcluate the pointer to the Bits information */
/* First skip over the header structure */
lprgb = (LPDWORD)((LPBYTE)(lpbi) + lpbi->biSize);
/* Skip the color table entries, if any */
lpb = (LPBYTE)lprgb + ((int)lpbi->biClrUsed ? (int)lpbi->biClrUsed :
(1 << (int)lpbi->biBitCount)) * sizeof(RGBQUAD);
lprgb[0] = RGBQ(rgbText); // Black
lprgb[7] = RGBQ(rgbFace); // lt gray
lprgb[8] = RGBQ(rgbShadow); // gray
lprgb[15] = RGBQ(rgbHighlight); // white
lprgb[11] = RGBQ(rgbWindow); // yellow
lprgb[10] = RGBQ(rgbFrame); // green
hdc = GetDC(NULL);
hbm = CreateDIBitmap (hdc, lpbi, CBM_INIT, (LPVOID)lpb,
(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
ReleaseDC(NULL, hdc);
UnlockResource(h);
FreeResource(h);
return(hbm);
}
/****************************************************************************
toolbarWndProc()
Window proc for toolbar.
Arguments:
Standard window proc
****************************************************************************/
LONG FAR PASCAL toolbarWndProc(HWND hwnd, unsigned message,
UINT wParam, LONG lParam)
{
PAINTSTRUCT ps;
POINT pt;
RECT rc;
int iBtnPos, iButton, ibmp;
HANDLE lpaButtons, hbm, hInst;
switch (message) {
case WM_CREATE: // do all initialization
/* What do these do? */
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
SWP_NOZORDER | SWP_NOSIZE |
SWP_NOMOVE | SWP_NOACTIVATE);
SetWindowLong(hwnd,GWL_STYLE,lpCreate->style & 0xFFFF00FF);
/* Alloc some space for the array of buttons on this bar */
lpaButtons = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
TOOLGROW * sizeof(TOOLBUTTON));
SETARRAYBUTT(hwnd, lpaButtons); // list of buttons on toolbar
SETNUMBUTTONS(hwnd, 0); // # buttons in toolbar
SETPRESSED(hwnd, FALSE); // mouse button being pressed?
SETKEYPRESSED(hwnd, FALSE); // is a key being pressed?
SETWHICH(hwnd, -1); // which button has the focus?
SETSHIFTED(hwnd, FALSE); // shift-click or right-click?
/* This wParam will be sent to the parent window to indentify */
/* that the toolbar sent the WM_COMMAND msg. The hwnd of the */
/* toolbar that sent the msg will be in the lParam. */
#ifdef _WIN32
SetWindowLong(hwnd, GWL_ID, IDC_TOOLBAR);
#else
SetWindowWord(hwnd, GWW_ID, (WORD)IDC_TOOLBAR);
#endif
/* later on, someone will set the bmp handle of the buttons */
SETBMPHANDLE(hwnd, NULL);
break;
case WM_LBUTTONDOWN: // button goes down on a toolbar button
case WM_RBUTTONDOWN:
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
/* If we don't give ourself focus, we'll never get KEYDOWN */
/* or KEYUP messages. */
/* Get the focus only if we're a TABSTOP and the app wants */
/* us to take focus. */
if ( (GetWindowLong(hwnd, GWL_STYLE) & WS_TABSTOP)
&& GetFocus() != hwnd)
SetFocus(hwnd);
/* ignore messages if window is disabled */
if (!IsWindowEnabled(hwnd))
return 0L;
/* ignore multiple down messages (we set Capture here) */
/* also ignore if a key is down */
if (GetCapture() == hwnd || GETPRESSED(hwnd))
return 0L;
/* Where did the mouse go down? */
pt.x = (short)LOWORD(lParam);
pt.y = (short)HIWORD(lParam);
/* which button was pressed? */
iBtnPos = toolbarIndexFromPoint(hwnd, pt);
/* If it was a valid button... */
if (iBtnPos >= 0) {
int iOldPos;
int iState, iType, iButton;
/* Everything you wanted to know about this button */
iType = toolbarTypeFromIndex(hwnd, iBtnPos);
iButton = toolbarButtonFromIndex(hwnd, iBtnPos);
iState = toolbarFullStateFromButton(hwnd, iButton);
/* ignore downs on a grayed button, unless it's a */
/* custom button, then tell them anyway */
if (iType != BTNTYPE_CUSTOM && iState == BTNST_GRAYED)
return 0;
/* We better get all mouse messages from now on */
SetCapture(hwnd);
/* Shift key or right button indicates a SHIFT down */
SETSHIFTED(hwnd, (message == WM_RBUTTONDOWN) ||
(wParam & MK_SHIFT));
/* Yes, we've pressed the button down */
SETPRESSED(hwnd, TRUE);
/* Remember who used to have the focus, and we get it now */
iOldPos = GETWHICH(hwnd);
SETWHICH(hwnd, iBtnPos);
/* For a push button, send it down */
if (iType == BTNTYPE_PUSH)
toolbarModifyState(hwnd, iButton, BTNST_DOWN);
/* for a checkbox or radio button (of any group), */
/* remember what state it was in, and send it FULL down */
/* (with focus). */
if (iType == BTNTYPE_CHECKBOX || iType >= BTNTYPE_RADIO) {
toolbarModifyPrevState(hwnd, iButton, iState);
toolbarModifyState(hwnd,iButton,BTNST_FULLDOWN);
}
toolbarModifyActivity(hwnd, iButton, BTNACT_MOUSEDOWN);
/* Set Double click flag appropriately */
if (message == WM_LBUTTONDBLCLK ||
message == WM_RBUTTONDBLCLK)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -