📄 button.c
字号:
#include "windows.h"#include "windowsx.h"#include "wintools.h"/* * WINCTL Custom Control Library * Push button Custom Control * This control implements a custom pushbutton control. * * 4/8/98 g haerr original version from control palette v2.00, Blaise Computing */#define GET_PBSTATE(h) (GetWindowWord(h, 0))#define GET_PBCAPTURE(h) (GetWindowWord(h, 2))#define GET_PBWASINSIDE(h) (GetWindowWord(h, 4))#define GET_PBDELETEFONT(h) (GetWindowWord(h, 6))#define GET_PBFONT(h) (GetWindowWord(h, 8))#define SET_PBSTATE(h,x) (SetWindowWord(h, 0, x))#define SET_PBCAPTURE(h,x) (SetWindowWord(h, 2, x))#define SET_PBWASINSIDE(h,x) (SetWindowWord(h, 4, x))#define SET_PBDELETEFONT(h,x) (SetWindowWord(h, 6, x))#define SET_PBFONT(h,x) (SetWindowWord(h, 8, x))#define PARENT(hwnd) ((HWND)GetWindowLong(hwnd,GWL_HWNDPARENT))/* Internal state variable bit positions */#define PUSH_UP 0x0000#define PUSH_DOWN 0x0001 /* Button is down */#define PUSH_FOCUS 0x0002 /* Button is focused */#define PUSH_DISABLED 0x0004 /* Button is disabled */#define PUSH_DEFAULT 0x0008 /* Button is currently a default */#define PUSH_CHECKED 0x0010/* Push Button states */#define PBS_UP 0x0000 /* Normal button state. */#define PBS_FOCUSDOWN 0x0001 /* Button pressed. */#define PBS_FOCUSUP 0x0002 /* Focused state. */#define PBS_DISABLED 0x0004 /* Disabled state. */#define PBS_DEFAULT 0x0008 /* Default state. */#define PBS_CHECKED 0x0010 /* checked state. */#define WM_PAINT_SPECIAL WM_PAINT#define HANDLE_WM_PAINT_SPECIAL(hwnd, wParam, lParam, fn) \ ((fn)((hwnd),(HDC)(wParam)), 0L)/* BOOL Cls_OnGetState( HWND hwnd); */#define HANDLE_BM_GETSTATE(hwnd, wParam, lParam, fn) ((fn)(hwnd))#define FORWARD_BM_GETSTATE(hwnd) \ (LONG)(fn)((hwnd), BM_GETSTATE, (WPARAM)0, (LPARAM)0)/* void Cls_OnSetState( HWND hwnd, WORD wState); */#define HANDLE_BM_SETSTATE( hwnd, wParam, lParam, fn) \ ((fn)((hwnd), (WORD)wParam), 0)#define FORWARD_BM_SETSTATE( hwnd, wState) \ (fn)((hwnd), BM_SETSTATE, (WPARAM)wState, (LPARAM)0)/* void Cls_OnSetStyle( HWND hwnd, WORD style, BOOL bRedraw); */#define HANDLE_BM_SETSTYLE( hwnd, wParam, lParam, fn) \ ((fn)((hwnd), (WORD)wParam, (BOOL)LOWORD(lParam)), 0)#define FORWARD_BM_SETSTYLE( hwnd, style, bRedraw, fn) \ (fn)((hwnd), BM_SETSTYLE, (WPARAM)style, MAKELPARAM(bRedraw, 0))/* entry points*/void WINAPI CheckRadioButton(HWND hDlg, int nIDFirst,int nIDLast, int nIDCheckButton);/* local procs*/static void WINAPI cenButton_FnEnd( HWND, WORD);static WORD WINAPI cenButton_FnStart( HWND);static BOOL WINAPI cenButton_OnCreate( HWND, LPCREATESTRUCT);/*static void WINAPI cenButton_OnDestroy( HWND);*//*static void WINAPI cenButton_OnEnable( HWND, BOOL);*/static BOOL WINAPI cenButton_OnEraseBkgnd( HWND, HDC);/*static UINT WINAPI cenButton_OnGetDlgCode( HWND, LPMSG);*/static LONG WINAPI cenButton_OnGetState( HWND);/*static void WINAPI cenButton_OnKey( HWND, UINT, BOOL, int, UINT);*/static void WINAPI cenButton_OnKillFocus( HWND, HWND);static void WINAPI cenButton_OnLButtonDown( HWND, BOOL, UINT, UINT, UINT);static void WINAPI cenButton_OnLButtonUp( HWND, UINT, UINT, UINT);static void WINAPI cenButton_OnMouseMove( HWND, UINT, UINT, UINT);static void WINAPI cenButton_OnPaint( HWND, HDC);static void WINAPI DrawPushButton(HWND hwnd,HDC hDCwParam,UINT wEnumState, DWORD dwStyle);static void WINAPI DrawGroupBox(HWND hwnd,HDC hDCwParam, DWORD dwStyle);static void WINAPI cenButton_OnSetFocus( HWND, HWND);static void WINAPI cenButton_OnSetStyle( HWND, WORD, BOOL);static void WINAPI cenButton_OnSetState( HWND, WORD);static void WINAPI cenButton_SetState( HWND, WORD, BOOL);static void WINAPI cenButton_OnSetText( HWND, LPCSTR);static void WINAPIcenButton_FnEnd(HWND hwnd,WORD wState){ if( wState != GET_PBSTATE( hwnd)) { if( IsWindowVisible( hwnd)) UpdateWindow( hwnd); }}static WORD WINAPIcenButton_FnStart(HWND hwnd){ return GET_PBSTATE( hwnd);}static BOOL WINAPIcenButton_OnCreate(HWND hwnd,LPCREATESTRUCT lpCreate){ /* Set initial states */ /*SET_PBDELETEFONT( hwnd, FALSE);*/ /*SET_PBFONT( hwnd, NULL);*/ SET_PBSTATE( hwnd, PUSH_UP ); SET_PBCAPTURE( hwnd, FALSE ); SET_PBWASINSIDE( hwnd, FALSE ); if ((lpCreate->style & 0x0f) == BS_DEFPUSHBUTTON) cenButton_SetState( hwnd, PUSH_DEFAULT, TRUE ); if (lpCreate->style & WS_DISABLED) cenButton_SetState( hwnd, PUSH_DISABLED, TRUE ); return( TRUE);}#if 0static void WINAPIcenButton_OnDestroy(HWND hwnd){ if( GET_PBDELETEFONT( hwnd)) { DeleteObject( GET_PBFONT( hwnd)); SET_PBDELETEFONT( hwnd, FALSE); }}static void WINAPIcenButton_OnEnable(HWND hwnd,BOOL bEnable){ WORD wState; wState = cenButton_FnStart( hwnd); cenButton_SetState( hwnd, PUSH_DISABLED, !bEnable); cenButton_FnEnd( hwnd, wState);}#endifstatic BOOL WINAPIcenButton_OnEraseBkgnd(HWND hwnd,HDC hdc){ /* Background is erased at WM_PAINT time, so return TRUE*/ return TRUE;}#if 0static UINT WINAPIcenButton_OnGetDlgCode(HWND hwnd,LPMSG lpMsg){ /* WM_GETDLGCODE is sent by the dialog manager to find */ /* what type/style of control is responding and/or to */ /* determine what keystrokes the control wants to process */ /* itself. In this case, the pushbutton identifies itself */ /* and also indicates whether it is currently the default */ /* pushbutton. */ /*return( DLGC_BUTTON | ((GET_PBSTATE( hwnd) & PUSH_DEFAULT) ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON));*/ return( DLGC_BUTTON);}#endifstatic LONG WINAPIcenButton_OnGetState(HWND hwnd){ /* BM_GETSTATE is sent to enquire about the state of the */ /* control. It returns TRUE if the button is in the down */ /* state. */ return( ( GET_PBSTATE( hwnd) & PUSH_DOWN) == PUSH_DOWN);}#if 0static void WINAPIcenButton_OnKey(HWND hwnd,UINT vk,BOOL bDown,int cRepeat,UINT flag){ WORD wState; wState = cenButton_FnStart( hwnd); if (bDown) { /* WM_KEYDOWN is sent when a non-system key is pressed. */ /* If a spacebar is detected and the previous key state */ /* was up, then the control should switch to the down */ /* state. */ if ( (vk == ' ') && !(HIBYTE(flag) & 0x40) ) cenButton_SetState( hwnd, PUSH_DOWN, TRUE ); } else { /* WM_KEYUP is sent when a non-system key is released. */ /* If a space bar is detected, change to the up state. If */ /* the control is the focused control, send the BN_CLICKED */ /* notification message. */ if ( vk == ' ' ) { cenButton_SetState( hwnd, PUSH_DOWN, FALSE ); if (GET_PBSTATE( hwnd) & PUSH_FOCUS) { FORWARD_WM_COMMAND( PARENT( hwnd), GetDlgCtrlID( hwnd), hwnd, BN_CLICKED, SendMessage); if(!IsWindow(hwnd)) return; } } } cenButton_FnEnd( hwnd, wState);}#endifstatic void WINAPIcenButton_OnKillFocus(HWND hwnd,HWND hwndNewFocus){ WORD wState; wState = cenButton_FnStart( hwnd); cenButton_SetState( hwnd, PUSH_FOCUS, FALSE ); cenButton_FnEnd( hwnd, wState);}static void WINAPIcenButton_OnLButtonDown(HWND hwnd,BOOL bDblClick,UINT x,UINT y,UINT keyState){ WORD wState; wState = cenButton_FnStart( hwnd); /* capture the mouse*/ SetCapture( hwnd ); /* set focus to ourself*/ SetFocus( hwnd ); SET_PBCAPTURE( hwnd, TRUE ); SET_PBWASINSIDE( hwnd, TRUE ); /* set down state*/ cenButton_SetState( hwnd, PUSH_DOWN, TRUE ); cenButton_FnEnd( hwnd, wState);}static void WINAPIcenButton_OnLButtonUp(HWND hwnd,UINT x,UINT y,UINT keys){ WORD wState; DWORD dwStyle; dwStyle = GetWindowLong(hwnd, GWL_STYLE); wState = cenButton_FnStart( hwnd); /* only draw up state if we captured mouse*/ if(GetCapture() == hwnd) cenButton_SetState( hwnd, PUSH_DOWN, FALSE ); /* release mouse capture*/ ReleaseCapture(); /* if cursor is inside control, send clicked notification to parent*/ if (GET_PBWASINSIDE( hwnd)) { switch((int)(dwStyle & 0x0f)) { case BS_AUTOCHECKBOX: SendMessage(hwnd,BM_SETCHECK,(wState & PBS_CHECKED)?0:1,0L); break; case BS_AUTORADIOBUTTON: CheckRadioButton(PARENT(hwnd),0,0xffff,hwnd->id); break; } FORWARD_WM_COMMAND( PARENT( hwnd), GetDlgCtrlID( hwnd), hwnd, BN_CLICKED, SendMessage); if(!IsWindow(hwnd)) return; } SET_PBCAPTURE( hwnd, FALSE ); SET_PBWASINSIDE( hwnd, FALSE ); cenButton_FnEnd( hwnd, wState);}static void WINAPIcenButton_OnMouseMove(HWND hwnd,UINT x,UINT y,UINT keys){ /* WM_MOUSEMOVE is sent at every discernable mouse */ /* movement. It is necessary to detect this because if */ /* the mouse has been captured (because of a button down */ /* message), the location of the cursor needs to be */ /* tracked. If it moves out of the confines of the */ /* control, the control should change to the focus/up */ /* state (and retain capture.) If the cursor then moves */ /* back into the control, change back to the down state. */ WORD wState; DWORD dwStyle; wState = cenButton_FnStart( hwnd); dwStyle = GetWindowLong(hwnd, GWL_STYLE); if( GET_PBCAPTURE( hwnd)) { if( !PtInsideWindow( hwnd, x, y) ) { if( GET_PBWASINSIDE( hwnd)) { cenButton_SetState( hwnd, PUSH_DOWN, FALSE); SET_PBWASINSIDE( hwnd, FALSE ); } } else { if( !GET_PBWASINSIDE( hwnd) ) { cenButton_SetState( hwnd, PUSH_DOWN, TRUE ); SET_PBWASINSIDE( hwnd, TRUE ); } } } cenButton_FnEnd( hwnd, wState);}static void WINAPIcenButton_OnPaint(HWND hwnd,HDC hDCwParam){ UINT wEnumState; DWORD dwStyle; if( GET_PBSTATE( hwnd) & PUSH_DISABLED) wEnumState = PBS_DISABLED; else if( GET_PBSTATE( hwnd) & PUSH_DOWN) wEnumState = PBS_FOCUSDOWN; else if( GET_PBSTATE( hwnd) & PUSH_CHECKED) wEnumState = PBS_CHECKED; else { if( GET_PBSTATE( hwnd) & PUSH_FOCUS) wEnumState = PBS_FOCUSUP; else wEnumState = PBS_UP; if( GET_PBSTATE( hwnd) & PUSH_DEFAULT) wEnumState |= PBS_DEFAULT; } /* common draw code for button and checkbox*/ dwStyle = GetWindowLong(hwnd, GWL_STYLE); switch((int)(dwStyle & 0x0f)) { case BS_GROUPBOX: DrawGroupBox( hwnd, hDCwParam, dwStyle); break; default: DrawPushButton( hwnd, hDCwParam, wEnumState, dwStyle); }}static void WINAPIDrawPushButton(HWND hwnd,HDC hDCwParam,UINT wEnumState,DWORD dwStyle){ HDC hdc; HBRUSH hNewBrush; RECT rect; RECT rectClient; RECT rectSave; RECT rc; int iFaceOffset = 0; INT uiHeight; INT uiWidth; COLORREF crOld; COLORREF crBkOld; int oldBkMode; HFONT hNewFont; HFONT hOldFont; HPEN hOldPen; COLORREF hOldColor; PAINTSTRUCT ps; char buf[256];#define uiWidthFrame 0#define uiWidthShadow 2 hdc = BeginPaint(hwnd, &ps); if(!hdc) goto Return; GetWindowText(hwnd, buf, sizeof(buf)); GetClientRect( hwnd, &rectClient ); uiWidth = rectClient.right - rectClient.left; uiHeight = rectClient.bottom - rectClient.top; hNewBrush = (HBRUSH) GetStockObject(LTGRAY_BRUSH); crOld = SetTextColor( hdc, GetSysColor( COLOR_BTNTEXT)); crBkOld = SetBkColor( hdc, GetSysColor( COLOR_BTNFACE)); rc = rectClient; switch((int)(dwStyle & 0x0f)) { case BS_PUSHBUTTON: case BS_DEFPUSHBUTTON: if( wEnumState & PBS_FOCUSDOWN) { if(dwStyle & BS_BITMAP) DrawDIB(hdc, rc.left+1, rc.top+1, (PMWIMAGEHDR)hwnd->userdata); Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, GetSysColor(COLOR_WINDOWFRAME), GetSysColor(COLOR_WINDOWFRAME)); InsetR(&rc, 1, 1); Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNSHADOW)); InsetR(&rc, 1, 1); if(!(dwStyle & BS_BITMAP)) FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE)); iFaceOffset = 1; } else { if(dwStyle & BS_BITMAP) DrawDIB(hdc, rc.left, rc.top, (PMWIMAGEHDR)hwnd->userdata); if(wEnumState & PBS_DEFAULT) { Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, GetSysColor(COLOR_WINDOWFRAME), GetSysColor(COLOR_WINDOWFRAME)); InsetR(&rc, 1, 1); } Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, GetSysColor(COLOR_BTNHIGHLIGHT),GetSysColor(COLOR_WINDOWFRAME)); InsetR(&rc, 1, 1); Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, GetSysColor(COLOR_3DLIGHT), GetSysColor(COLOR_BTNSHADOW)); InsetR(&rc, 1, 1); if(!(dwStyle & BS_BITMAP)) FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE)); iFaceOffset = 0; } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -