button.docx
《button.docx》由会员分享,可在线阅读,更多相关《button.docx(39页珍藏版)》请在冰豆网上搜索。
![button.docx](https://file1.bdocx.com/fileroot1/2023-2/4/c1cf36a7-b5c5-4030-bb7a-9a4039fc29c0/c1cf36a7-b5c5-4030-bb7a-9a4039fc29c01.gif)
button
/*File:
button.c--Buttontypewidgets
*
*Copyright(C)1993JohannesRuscheinski
*Copyright(C)1993DavidMetcalfe
*Copyright(C)1994AlexandreJulliard
*
*Thislibraryisfreesoftware;youcanredistributeitand/or
*modifyitunderthetermsoftheGNULesserGeneralPublic
*LicenseaspublishedbytheFreeSoftwareFoundation;either
*version2.1oftheLicense,or(atyouroption)anylaterversion.
*
*Thislibraryisdistributedinthehopethatitwillbeuseful,
*butWITHOUTANYWARRANTY;withouteventheimpliedwarrantyof
*MERCHANTABILITYorFITNESSFORAPARTICULARPURPOSE.SeetheGNU
*LesserGeneralPublicLicenseformoredetails.
*
*YoushouldhavereceivedacopyoftheGNULesserGeneralPublic
*Licensealongwiththislibrary;ifnot,writetotheFreeSoftware
*Foundation,Inc.,59TemplePlace,Suite330,Boston,MA02111-1307USA
*/
#include
/*GetWindowLongoffsetsforwindowextrainformation*/
#defineSTATE_GWL_OFFSET0
#defineHFONT_GWL_OFFSET(sizeof(LONG))
#defineHIMAGE_GWL_OFFSET(HFONT_GWL_OFFSET*sizeof(LONG))
#defineNB_EXTRA_BYTES(HIMAGE_GWL_OFFSET*sizeof(LONG))
/*Buttonstatevalues*/
#defineBUTTON_UNCHECKED0x00
#defineBUTTON_CHECKED0x01
#defineBUTTON_3STATE0x02
#defineBUTTON_HIGHLIGHTED0x04
#defineBUTTON_HASFOCUS0x08
#defineBUTTON_NSTATES0x0F
/*undocumentedflags*/
#defineBUTTON_BTNPRESSED0x40
#defineBUTTON_UNKNOWN20x20
#defineBUTTON_UNKNOWN30x10
#defineBUTTON_NOTIFY_PARENT(hWnd,code)\
do{/*Notifyparentwhichhascreatedthisbuttoncontrol*/\
TRACE("notification"#code"senttohwnd=%p\n",GetParent(hWnd));\
SendMessageW(GetParent(hWnd),WM_COMMAND,\
MAKEWPARAM(GetWindowLongPtrW((hWnd),GWLP_ID),(code)),\
(LPARAM)(hWnd));\
}while(0)
staticUINTBUTTON_CalcLabelRect(HWNDhwnd,HDChdc,RECT*rc);
staticvoidPB_Paint(HWNDhwnd,HDChDC,UINTaction);
staticvoidCB_Paint(HWNDhwnd,HDChDC,UINTaction);
staticvoidGB_Paint(HWNDhwnd,HDChDC,UINTaction);
staticvoidUB_Paint(HWNDhwnd,HDChDC,UINTaction);
staticvoidOB_Paint(HWNDhwnd,HDChDC,UINTaction);
staticvoidBUTTON_CheckAutoRadioButton(HWNDhwnd);
staticLRESULTWINAPIButtonWndProcA(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam);
staticLRESULTWINAPIButtonWndProcW(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam);
#defineMAX_BTN_TYPE12
staticconstWORDmaxCheckState[MAX_BTN_TYPE]=
{
BUTTON_UNCHECKED,/*BS_PUSHBUTTON*/
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_CHECKED,/*BS_AUTORADIOBUTTON*/
BUTTON_UNCHECKED,/*Notdefined*/
BUTTON_UNCHECKED/*BS_OWNERDRAW*/
};
typedefvoid(*pfPaint)(HWNDhwnd,HDChdc,UINTaction);
staticconstpfPaintbtnPaintFunc[MAX_BTN_TYPE]=
{
PB_Paint,/*BS_PUSHBUTTON*/
PB_Paint,/*BS_DEFPUSHBUTTON*/
CB_Paint,/*BS_CHECKBOX*/
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,/*Notdefined*/
OB_Paint/*BS_OWNERDRAW*/
};
staticHBITMAPhbitmapCheckBoxes=0;
staticWORDcheckBoxWidth=0,checkBoxHeight=0;
/*********************************************************************
*buttonclassdescriptor
*/
conststructbuiltin_class_descrBUTTON_builtin_class=
{
#ifdef__REACTOS__
L"Button",/*name*/
CS_DBLCLKS|CS_VREDRAW|CS_HREDRAW|CS_PARENTDC,/*style*/
ButtonWndProcW,/*procW*/
ButtonWndProcA,/*procA*/
NB_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
};
__inlinestaticLONGget_button_state(HWNDhwnd)
{
returnGetWindowLongW(hwnd,STATE_GWL_OFFSET);
}
__inlinestaticvoidset_button_state(HWNDhwnd,LONGstate)
{
SetWindowLongW(hwnd,STATE_GWL_OFFSET,state);
}
__inlinestaticHFONTget_button_font(HWNDhwnd)
{
return(HFONT)GetWindowLongPtrW(hwnd,HFONT_GWL_OFFSET);
}
__inlinestaticvoidset_button_font(HWNDhwnd,HFONTfont)
{
SetWindowLongPtrW(hwnd,HFONT_GWL_OFFSET,(LONG)font);
}
__inlinestaticUINTget_button_type(LONGwindow_style)
{
return(window_style&0x0f);
}
/*paintabuttonofanytype*/
__inlinestaticvoidpaint_button(HWNDhwnd,LONGstyle,UINTaction)
{
if(btnPaintFunc[style]&&IsWindowVisible(hwnd))
{
HDChdc=GetDC(hwnd);
btnPaintFunc[style](hwnd,hdc,action);
ReleaseDC(hwnd,hdc);
}
}
/*retrievethebuttontext;returnedbuffermustbefreedbycaller*/
__inlinestaticWCHAR*get_button_text(HWNDhwnd)
{
INTlen=512;
WCHAR*buffer=HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
if(buffer)InternalGetWindowText(hwnd,buffer,len+1);
returnbuffer;
}
/***********************************************************************
*ButtonWndProc_common
*/
staticLRESULTWINAPIButtonWndProc_common(HWNDhWnd,UINTuMsg,
WPARAMwParam,LPARAMlParam,BOOLunicode)
{
RECTrect;
POINTpt;
LONGstyle=GetWindowLongW(hWnd,GWL_STYLE);
UINTbtn_type=get_button_type(style);
LONGstate;
HANDLEoldHbitmap;
pt.x=LOWORD(lParam);
pt.y=HIWORD(lParam);
switch(uMsg)
{
caseWM_GETDLGCODE:
switch(btn_type)
{
caseBS_USERBUTTON:
caseBS_PUSHBUTTON:
returnDLGC_BUTTON|DLGC_UNDEFPUSHBUTTON;
caseBS_DEFPUSHBUTTON:
returnDLGC_BUTTON|DLGC_DEFPUSHBUTTON;
caseBS_RADIOBUTTON:
caseBS_AUTORADIOBUTTON:
returnDLGC_BUTTON|DLGC_RADIOBUTTON;
caseBS_GROUPBOX:
returnDLGC_STATIC;
default:
returnDLGC_BUTTON;
}
caseWM_ENABLE:
paint_button(hWnd,btn_type,ODA_DRAWENTIRE);
break;
caseWM_CREATE:
if(!
hbitmapCheckBoxes)
{
BITMAPbmp;
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,BUTTON_UNCHECKED);
return0;
caseWM_ERASEBKGND:
if(btn_type==BS_OWNERDRAW)
{
HDChdc=(HDC)wParam;
RECTrc;
HBRUSHhBrush;
HWNDparent=GetParent(hWnd);
if(!
parent)parent=hWnd;
hBrush=(HBRUSH)SendMessageW(parent,WM_CTLCOLORBTN,(WPARAM)hdc,(LPARAM)hWnd);
if(!
hBrush)/*didtheappforgettocalldefwindowproc?
*/
hBrush=(HBRUSH)DefWindowProcW(parent,WM_CTLCOLORBTN,
(WPARAM)hdc,(LPARAM)hWnd);
GetClientRect(hWnd,&rc);
FillRect(hdc,&rc,hBrush);
}
return1;
caseWM_PRINTCLIENT:
caseWM_PAINT:
if(btnPaintFunc[btn_type])
{
PAINTSTRUCTps;
HDChdc=wParam?
(HDC)wParam:
BeginPaint(hWnd,&ps);
intnOldMode=SetBkMode(hdc,OPAQUE);
(btnPaintFunc[btn_type])(hWnd,hdc,ODA_DRAWENTIRE);
SetBkMode(hdc,nOldMode);/*resetpaintingmode*/
if(!
wParam)EndPaint(hWnd,&ps);
}
break;
caseWM_KEYDOWN:
if(wParam==VK_SPACE)
{
SendMessageW(hWnd,BM_SETSTATE,TRUE,0);
set_button_state(hWnd,get_button_state(hWnd)|BUTTON_BTNPRESSED);
}
break;
caseWM_LBUTTONDBLCLK:
if(style&BS_NOTIFY||
btn_type==BS_RADIOBUTTON||
btn_type==BS_USERBUTTON||
btn_type==BS_OWNERDRAW)
{
BUTTON_NOTIFY_PARENT(hWnd,BN_DOUBLECLICKED);
break;
}
/*fallthrough*/
caseWM_LBUTTONDOWN:
SetCapture(hWnd);
SetFocus(hWnd);
set_button_state(hWnd,get_button_state(hWnd)|BUTTON_BTNPRESSED);
SendMessageW(hWnd,BM_SETSTATE,TRUE,0);
break;
caseWM_KEYUP:
if(wParam!
=VK_SPACE)
break;
/*fallthrough*/
caseWM_LBUTTONUP:
state=get_button_state(hWnd);
if(!
(state&BUTTON_BTNPRESSED))break;
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_type)
{
caseBS_AUTOCHECKBOX:
SendMessageW(hWnd,BM_SETCHECK,!
(state&BUTTON_CHECKED),0);
break;
caseBS_AUTORADIOBUTTON:
SendMessageW(hWnd,BM_SETCHECK,TRUE,0);
break;
caseBS_AUTO3STATE:
SendMessageW(hWnd,BM_SETCHECK,
(state&BUTTON_3STATE)?
0:
((state&3)+1),0);
break;
}
BUTTON_NOTIFY_PARENT(hWnd,BN_CLICKED);
}
break;
caseWM_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;
caseWM_MOUSEMOVE:
if((wParam&MK_LBUTTON)&&GetCapture()==hWnd)
{
GetClientRect(hWnd,&rect);
SendMessageW(hWnd,BM_SETSTATE,PtInRect(&rect,pt),0);
}
break;
caseWM_SETTEXT:
{
/*ClearanoldtexthereasWindowsdoes*/
HDChdc=GetDC(hWnd);
HBRUSHhbrush;
RECTclient,rc;
HWNDparent=GetParent(hWnd);
if(!
parent)parent=hWnd;
hbrush=(HBRUSH)SendMessageW(parent,WM_CTLCOLORSTATIC,
(WPARAM)hdc,(LPARAM)hWnd);
if(!
hbrush)/*didtheappforgettocallDefWindowProc?
*/
hbrush=(HBRUSH)DefWindowProcW(parent,WM_CTLCOLORSTATIC,
(WPARAM)hdc,(LPARAM)hWnd);
GetClientRect(hWnd,&client);
rc=client;
BUTTON_CalcLabelRect(hWnd,hdc,&rc);
/*Clipbyclientrectbounds*/
if(rc.right