1、button/* File: button.c - Button type widgets * * Copyright (C) 1993 Johannes Ruscheinski * Copyright (C) 1993 David Metcalfe * Copyright (C) 1994 Alexandre Julliard * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * Licen
2、se as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICU
3、LAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include /
4、* GetWindowLong offsets for window extra information */#define STATE_GWL_OFFSET 0#define HFONT_GWL_OFFSET (sizeof(LONG)#define HIMAGE_GWL_OFFSET (HFONT_GWL_OFFSET*sizeof(LONG)#define NB_EXTRA_BYTES (HIMAGE_GWL_OFFSET*sizeof(LONG) /* Button state values */#define BUTTON_UNCHECKED 0x00#define BUTTON_C
5、HECKED 0x01#define BUTTON_3STATE 0x02#define BUTTON_HIGHLIGHTED 0x04#define BUTTON_HASFOCUS 0x08#define BUTTON_NSTATES 0x0F /* undocumented flags */#define BUTTON_BTNPRESSED 0x40#define BUTTON_UNKNOWN2 0x20#define BUTTON_UNKNOWN3 0x10#define BUTTON_NOTIFY_PARENT(hWnd, code) do /* Notify parent which
6、 has created this button control */ TRACE(notification #code sent to hwnd=%pn, GetParent(hWnd); SendMessageW(GetParent(hWnd), WM_COMMAND, MAKEWPARAM(GetWindowLongPtrW(hWnd),GWLP_ID), (code), (LPARAM)(hWnd); while(0)static UINT BUTTON_CalcLabelRect( HWND hwnd, HDC hdc, RECT *rc );static void PB_Paint
7、( HWND hwnd, HDC hDC, UINT action );static void CB_Paint( HWND hwnd, HDC hDC, UINT action );static void GB_Paint( HWND hwnd, HDC hDC, UINT action );static void UB_Paint( HWND hwnd, HDC hDC, UINT action );static void OB_Paint( HWND hwnd, HDC hDC, UINT action );static void BUTTON_CheckAutoRadioButton(
8、 HWND hwnd );static LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );static LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );#define MAX_BTN_TYPE 12static const WORD maxCheckStateMAX_BTN_TYPE = BUTTON_UNCHECKED, /* BS_PUSHBUTTON *
9、/ BUTTON_UNCHECKED, /* BS_DEFPUSHBUTTON */ BUTTON_CHECKED, /* BS_CHECKBOX */ BUTTON_CHECKED, /* BS_AUTOCHECKBOX */ BUTTON_CHECKED, /* BS_RADIOBUTTON */ BUTTON_3STATE, /* BS_3STATE */ BUTTON_3STATE, /* BS_AUTO3STATE */ BUTTON_UNCHECKED, /* BS_GROUPBOX */ BUTTON_UNCHECKED, /* BS_USERBUTTON */ BUTTON_C
10、HECKED, /* BS_AUTORADIOBUTTON */ BUTTON_UNCHECKED, /* Not defined */ BUTTON_UNCHECKED /* BS_OWNERDRAW */;typedef void (*pfPaint)( HWND hwnd, HDC hdc, UINT action );static const pfPaint btnPaintFuncMAX_BTN_TYPE = PB_Paint, /* BS_PUSHBUTTON */ PB_Paint, /* BS_DEFPUSHBUTTON */ CB_Paint, /* BS_CHECKBOX
11、*/ CB_Paint, /* BS_AUTOCHECKBOX */ CB_Paint, /* BS_RADIOBUTTON */ CB_Paint, /* BS_3STATE */ CB_Paint, /* BS_AUTO3STATE */ GB_Paint, /* BS_GROUPBOX */ UB_Paint, /* BS_USERBUTTON */ CB_Paint, /* BS_AUTORADIOBUTTON */ NULL, /* Not defined */ OB_Paint /* BS_OWNERDRAW */;static HBITMAP hbitmapCheckBoxes
12、= 0;static WORD checkBoxWidth = 0, checkBoxHeight = 0;/* * button class descriptor */const struct builtin_class_descr BUTTON_builtin_class =#ifdef _REACTOS_ LButton, /* name */ CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style */ ButtonWndProcW, /* procW */ ButtonWndProcA, /* procA */ NB_
13、EXTRA_BYTES, /* extra */ (LPWSTR)IDC_ARROW, /* cursor */ 0 /* brush */#else Button, /* name */ CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style */ ButtonWndProcA, /* procA */ ButtonWndProcW, /* procW */ NB_EXTRA_BYTES, /* extra */ IDC_ARROW, /* cursor */ 0 /* brush */#endif;_inline stati
14、c LONG get_button_state( HWND hwnd ) return GetWindowLongW( hwnd, STATE_GWL_OFFSET );_inline static void set_button_state( HWND hwnd, LONG state ) SetWindowLongW( hwnd, STATE_GWL_OFFSET, state );_inline static HFONT get_button_font( HWND hwnd ) return (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET
15、 );_inline static void set_button_font( HWND hwnd, HFONT font ) SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, (LONG)font );_inline static UINT get_button_type( LONG window_style ) return (window_style & 0x0f);/* paint a button of any type */_inline static void paint_button( HWND hwnd, LONG style, UINT
16、action ) if (btnPaintFuncstyle & IsWindowVisible(hwnd) HDC hdc = GetDC( hwnd ); btnPaintFuncstyle( hwnd, hdc, action ); ReleaseDC( hwnd, hdc ); /* retrieve the button text; returned buffer must be freed by caller */_inline static WCHAR *get_button_text( HWND hwnd ) INT len = 512; WCHAR *buffer = Hea
17、pAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ); if (buffer) InternalGetWindowText( hwnd, buffer, len + 1 ); return buffer;/* * ButtonWndProc_common */static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL unicode ) RECT rect; POINT pt; LONG styl
18、e = GetWindowLongW( hWnd, GWL_STYLE ); UINT btn_type = get_button_type( style ); LONG state; HANDLE oldHbitmap; pt.x = LOWORD(lParam); pt.y = HIWORD(lParam); switch (uMsg) case WM_GETDLGCODE: switch(btn_type) case BS_USERBUTTON: case BS_PUSHBUTTON: return DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON; case BS_
19、DEFPUSHBUTTON: return DLGC_BUTTON | DLGC_DEFPUSHBUTTON; case BS_RADIOBUTTON: case BS_AUTORADIOBUTTON: return DLGC_BUTTON | DLGC_RADIOBUTTON; case BS_GROUPBOX: return DLGC_STATIC; default: return DLGC_BUTTON; case WM_ENABLE: paint_button( hWnd, btn_type, ODA_DRAWENTIRE ); break; case WM_CREATE: if (!
20、hbitmapCheckBoxes) BITMAP bmp; hbitmapCheckBoxes = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CHECKBOXES); GetObjectW( hbitmapCheckBoxes, sizeof(bmp), &bmp ); checkBoxWidth = bmp.bmWidth / 4; checkBoxHeight = bmp.bmHeight / 3; if (btn_type = MAX_BTN_TYPE) return -1; /* abort */ set_button_state( hWnd, BUTT
21、ON_UNCHECKED ); return 0; case WM_ERASEBKGND: if (btn_type = BS_OWNERDRAW) HDC hdc = (HDC)wParam; RECT rc; HBRUSH hBrush; HWND parent = GetParent(hWnd); if (!parent) parent = hWnd; hBrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORBTN, (WPARAM)hdc, (LPARAM)hWnd); if (!hBrush) /* did the app forget to
22、 call defwindowproc ? */ hBrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORBTN, (WPARAM)hdc, (LPARAM)hWnd); GetClientRect(hWnd, &rc); FillRect(hdc, &rc, hBrush); return 1; case WM_PRINTCLIENT: case WM_PAINT: if (btnPaintFuncbtn_type) PAINTSTRUCT ps; HDC hdc = wParam ? (HDC)wParam : BeginPaint( hWnd
23、, &ps ); int nOldMode = SetBkMode( hdc, OPAQUE ); (btnPaintFuncbtn_type)( hWnd, hdc, ODA_DRAWENTIRE ); SetBkMode(hdc, nOldMode); /* reset painting mode */ if( !wParam ) EndPaint( hWnd, &ps ); break; case WM_KEYDOWN: if (wParam = VK_SPACE) SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 ); set_button_state(
24、 hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED ); break; case WM_LBUTTONDBLCLK: if(style & BS_NOTIFY | btn_type = BS_RADIOBUTTON | btn_type = BS_USERBUTTON | btn_type = BS_OWNERDRAW) BUTTON_NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED); break; /* fall through */ case WM_LBUTTONDOWN: SetCapture( hWnd );
25、 SetFocus( hWnd ); set_button_state( hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED ); SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 ); break; case WM_KEYUP: if (wParam != VK_SPACE) break; /* fall through */ case WM_LBUTTONUP: state = get_button_state( hWnd ); if (!(state & BUTTON_BTNPRESSED) break;
26、state &= BUTTON_NSTATES; set_button_state( hWnd, state ); if (!(state & BUTTON_HIGHLIGHTED) ReleaseCapture(); break; SendMessageW( hWnd, BM_SETSTATE, FALSE, 0 ); ReleaseCapture(); GetClientRect( hWnd, &rect ); if (uMsg = WM_KEYUP | PtInRect( &rect, pt ) state = get_button_state( hWnd ); switch(btn_t
27、ype) case BS_AUTOCHECKBOX: SendMessageW( hWnd, BM_SETCHECK, !(state & BUTTON_CHECKED), 0 ); break; case BS_AUTORADIOBUTTON: SendMessageW( hWnd, BM_SETCHECK, TRUE, 0 ); break; case BS_AUTO3STATE: SendMessageW( hWnd, BM_SETCHECK, (state & BUTTON_3STATE) ? 0 : (state & 3) + 1), 0 ); break; BUTTON_NOTIF
28、Y_PARENT(hWnd, BN_CLICKED); break; case WM_CAPTURECHANGED: state = get_button_state( hWnd ); if (state & BUTTON_BTNPRESSED) state &= BUTTON_NSTATES; set_button_state( hWnd, state ); if (state & BUTTON_HIGHLIGHTED) SendMessageW( hWnd, BM_SETSTATE, FALSE, 0 ); break; case WM_MOUSEMOVE: if (wParam & MK
29、_LBUTTON) & GetCapture() = hWnd) GetClientRect( hWnd, &rect ); SendMessageW( hWnd, BM_SETSTATE, PtInRect(&rect, pt), 0 ); break; case WM_SETTEXT: /* Clear an old text here as Windows does */ HDC hdc = GetDC(hWnd); HBRUSH hbrush; RECT client, rc; HWND parent = GetParent(hWnd); if (!parent) parent = h
30、Wnd; hbrush = (HBRUSH)SendMessageW(parent, WM_CTLCOLORSTATIC, (WPARAM)hdc, (LPARAM)hWnd); if (!hbrush) /* did the app forget to call DefWindowProc ? */ hbrush = (HBRUSH)DefWindowProcW(parent, WM_CTLCOLORSTATIC, (WPARAM)hdc, (LPARAM)hWnd); GetClientRect(hWnd, &client); rc = client; BUTTON_CalcLabelRect(hWnd, hdc, &rc); /* Clip by client rect bounds */ if (rc.right
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1