00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017
00018 #define CBR_CLIENTRECT 0
00019 #define CBR_CHECKBOX 1
00020 #define CBR_CHECKTEXT 2
00021 #define CBR_GROUPTEXT 3
00022 #define CBR_GROUPFRAME 4
00023 #define CBR_PUSHBUTTON 5
00024
00025 CONST
BYTE mpStyleCbr[] = {
00026
CBR_PUSHBUTTON,
00027
CBR_PUSHBUTTON,
00028
CBR_CHECKTEXT,
00029
CBR_CHECKTEXT,
00030
CBR_CHECKTEXT,
00031
CBR_CHECKTEXT,
00032
CBR_CHECKTEXT,
00033
CBR_GROUPTEXT,
00034
CBR_CLIENTRECT,
00035
CBR_CHECKTEXT,
00036
CBR_CLIENTRECT,
00037
CBR_CLIENTRECT,
00038 };
00039
00040 #define IMAGE_BMMAX IMAGE_CURSOR+1
00041 static CONST
BYTE rgbType[
IMAGE_BMMAX] = {
00042 BS_BITMAP,
00043 BS_ICON,
00044 BS_ICON
00045 };
00046
00047 #define IsValidImage(imageType, realType, max) \
00048
((imageType < max) && (rgbType[imageType] == realType))
00049
00050 typedef struct tagBTNDATA {
00051 LPWSTR
lpsz;
00052 PBUTN pbutn;
00053 WORD
wFlags;
00054 }
BTNDATA,
FAR *
LPBTNDATA;
00055
00056
void xxxDrawButton(
PBUTN pbutn, HDC hdc, UINT pbfPush);
00057
00058 LOOKASIDE ButtonLookaside;
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 UINT IsPushButton(
00072
PWND pwnd)
00073 {
00074
BYTE bStyle;
00075
UINT flags;
00076
00077 bStyle =
TestWF(pwnd,
BFTYPEMASK);
00078
00079 flags = 0;
00080
00081
switch (bStyle) {
00082
case LOBYTE(BS_PUSHBUTTON):
00083 flags |=
PBF_PUSHABLE;
00084
break;
00085
00086
case LOBYTE(BS_DEFPUSHBUTTON):
00087 flags |=
PBF_PUSHABLE |
PBF_DEFAULT;
00088
break;
00089
00090
default:
00091
if (
TestWF(pwnd,
BFPUSHLIKE))
00092 flags |=
PBF_PUSHABLE;
00093
break;
00094 }
00095
00096
return(flags);
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 WORD
GetAlignment(
00137
PWND pwnd)
00138 {
00139
BYTE bHorz;
00140
BYTE bVert;
00141
00142 bHorz =
TestWF(pwnd,
BFHORZMASK);
00143 bVert =
TestWF(pwnd,
BFVERTMASK);
00144
00145
if (!bHorz || !bVert) {
00146
if (
IsPushButton(pwnd)) {
00147
if (!bHorz)
00148 bHorz =
LOBYTE(
BFCENTER);
00149 }
else {
00150
if (!bHorz)
00151 bHorz =
LOBYTE(
BFLEFT);
00152 }
00153
00154
if (!bVert)
00155 bVert =
LOBYTE(
BFVCENTER);
00156 }
00157
00158
return bHorz | bVert;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 void BNSetFont(
00172
PBUTN pbutn,
00173 HFONT hfn,
00174 BOOL fRedraw)
00175 {
00176
PWND pwnd = pbutn->
spwnd;
00177
00178 pbutn->
hFont = hfn;
00179
00180
if (fRedraw &&
IsVisible(pwnd)) {
00181
NtUserInvalidateRect(
HWq(pwnd),
NULL,
TRUE);
00182 }
00183
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193 HBRUSH
xxxBNInitDC(
00194
PBUTN pbutn,
00195 HDC hdc)
00196 {
00197
UINT wColor;
00198
BYTE bStyle;
00199 HBRUSH hbr;
00200
PWND pwnd = pbutn->
spwnd;
00201
00202
CheckLock(pwnd);
00203
00204
00205
00206
00207
00208 SetBkMode(hdc, OPAQUE);
00209
00210 bStyle =
TestWF(pwnd,
BFTYPEMASK);
00211
00212
switch (bStyle) {
00213
default:
00214
if (
TestWF(pwnd,
WFWIN40COMPAT) && !
TestWF(pwnd,
BFPUSHLIKE)) {
00215 wColor = WM_CTLCOLORSTATIC;
00216
break;
00217 }
00218
00219
case LOBYTE(BS_PUSHBUTTON):
00220
case LOBYTE(BS_DEFPUSHBUTTON):
00221
case LOBYTE(BS_OWNERDRAW):
00222
case LOBYTE(BS_USERBUTTON):
00223 wColor = WM_CTLCOLORBTN;
00224
break;
00225 }
00226
00227 hbr =
GetControlBrush(
HWq(pwnd), hdc, wColor);
00228
00229
00230
00231
00232
00233
if (pbutn->
hFont) {
00234 SelectObject(hdc, pbutn->
hFont);
00235 }
00236
00237
00238
00239
00240
if (bStyle !=
LOBYTE(BS_GROUPBOX)) {
00241 IntersectClipRect(hdc, 0, 0,
00242 pwnd->
rcClient.right - pwnd->
rcClient.left,
00243 pwnd->
rcClient.bottom - pwnd->
rcClient.top);
00244 }
00245
00246
if (
TestWF(pwnd,
WEFRTLREADING))
00247 SetTextAlign(hdc, TA_RTLREADING | GetTextAlign(hdc));
00248
00249
return(hbr);
00250 }
00251
00252
00253
00254
00255
00256
00257
00258 HDC
xxxBNGetDC(
00259
PBUTN pbutn,
00260 HBRUSH *lphbr)
00261 {
00262 HDC hdc;
00263
PWND pwnd = pbutn->
spwnd;
00264
00265
CheckLock(pwnd);
00266
00267
if (
IsVisible(pwnd)) {
00268 HBRUSH hbr;
00269
00270 hdc =
NtUserGetDC(
HWq(pwnd));
00271 hbr =
xxxBNInitDC(pbutn, hdc);
00272
00273
if (lphbr!=
NULL)
00274 *lphbr = hbr;
00275
00276
return hdc;
00277 }
00278
00279
return NULL;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288 void BNReleaseDC(
00289
PBUTN pbutn,
00290 HDC hdc)
00291 {
00292
PWND pwnd = pbutn->
spwnd;
00293
00294
if (
TestWF(pwnd,
WEFRTLREADING))
00295 SetTextAlign(hdc, GetTextAlign(hdc) & ~TA_RTLREADING);
00296
00297
if (pbutn->
hFont) {
00298 SelectObject(hdc,
ghFontSys);
00299 }
00300
00301
ReleaseDC(
HWq(pwnd), hdc);
00302 }
00303
00304
00305
00306
00307
00308
00309
00310 void xxxBNOwnerDraw(
00311
PBUTN pbutn,
00312 HDC hdc,
00313 UINT itemAction)
00314 {
00315 DRAWITEMSTRUCT drawItemStruct;
00316
TL tlpwndParent;
00317
PWND pwnd = pbutn->
spwnd;
00318
UINT itemState = 0;
00319
00320
if (
TestWF(pwnd,
WEFPUIFOCUSHIDDEN)) {
00321 itemState |= ODS_NOFOCUSRECT;
00322 }
00323
if (
TestWF(pwnd,
WEFPUIACCELHIDDEN)) {
00324 itemState |= ODS_NOACCEL;
00325 }
00326
if (
BUTTONSTATE(pbutn) & BST_FOCUS) {
00327 itemState |= ODS_FOCUS;
00328 }
00329
if (
BUTTONSTATE(pbutn) & BST_PUSHED) {
00330 itemState |= ODS_SELECTED;
00331 }
00332
00333
if (
TestWF(pwnd,
WFDISABLED))
00334 itemState |= ODS_DISABLED;
00335
00336 drawItemStruct.CtlType = ODT_BUTTON;
00337 drawItemStruct.CtlID = PtrToUlong(pwnd->
spmenu);
00338 drawItemStruct.itemAction = itemAction;
00339 drawItemStruct.itemState = itemState;
00340 drawItemStruct.hwndItem =
HWq(pwnd);
00341 drawItemStruct.hDC = hdc;
00342
_GetClientRect(pwnd, &drawItemStruct.rcItem);
00343 drawItemStruct.itemData = 0
L;
00344
00345
00346
00347
00348
00349
ThreadLock(
REBASEPWND(pwnd, spwndParent), &tlpwndParent);
00350
SendMessage(
HW(
REBASEPWND(pwnd, spwndParent)), WM_DRAWITEM, (WPARAM)pwnd->
spmenu,
00351 (LPARAM)&drawItemStruct);
00352
ThreadUnlock(&tlpwndParent);
00353 }
00354
00355
00356
00357
00358
00359
00360
00361 void BNCalcRect(
00362
PWND pwnd,
00363 HDC hdc,
00364 LPRECT lprc,
00365
int code,
00366 UINT pbfFlags)
00367 {
00368
int cch;
00369 SIZE extent;
00370
int dy;
00371 LPWSTR lpName;
00372
UINT align;
00373
00374
_GetClientRect(pwnd, lprc);
00375
00376 align =
GetAlignment(pwnd);
00377
00378
switch (code) {
00379
case CBR_PUSHBUTTON:
00380
00381
InflateRect(lprc, -
SYSMET(CXEDGE), -
SYSMET(CYEDGE));
00382
00383
if (pbfFlags &
PBF_DEFAULT)
00384
InflateRect(lprc, -
SYSMET(CXBORDER), -
SYSMET(CYBORDER));
00385
break;
00386
00387
case CBR_CHECKBOX:
00388
switch (align &
LOBYTE(
BFVERTMASK))
00389 {
00390
case LOBYTE(
BFVCENTER):
00391 lprc->top = (lprc->top + lprc->bottom -
gpsi->oembmi[
OBI_CHECK].cy) / 2;
00392
break;
00393
00394
case LOBYTE(
BFTOP):
00395
case LOBYTE(
BFBOTTOM):
00396
PSMGetTextExtent(hdc, (LPWSTR)
szOneChar, 1, &extent);
00397 dy = extent.cy + extent.cy/4;
00398
00399
00400 extent.cx = dy;
00401
00402
00403
00404 dy = (dy -
gpsi->oembmi[
OBI_CHECK].cy) / 2;
00405
if ((align &
LOBYTE(
BFVERTMASK)) ==
LOBYTE(
BFTOP))
00406 lprc->top += dy;
00407
else
00408 lprc->top = lprc->bottom - extent.cx + dy;
00409
break;
00410 }
00411
00412
if (
TestWF(pwnd,
BFRIGHTBUTTON))
00413 lprc->left = lprc->right -
gpsi->oembmi[
OBI_CHECK].cx;
00414
else
00415 lprc->right = lprc->left +
gpsi->oembmi[
OBI_CHECK].cx;
00416
00417
break;
00418
00419
case CBR_CHECKTEXT:
00420
if (
TestWF(pwnd,
BFRIGHTBUTTON)) {
00421 lprc->right -=
gpsi->oembmi[
OBI_CHECK].cx;
00422
00423
00424
if (
TestWF(pwnd,
WFWIN40COMPAT)) {
00425
PSMGetTextExtent(hdc,
szOneChar, 1, &extent);
00426 lprc->right -= extent.cx / 2;
00427 }
00428 }
else {
00429 lprc->left +=
gpsi->oembmi[
OBI_CHECK].cx;
00430
00431
00432
if (
TestWF(pwnd,
WFWIN40COMPAT)) {
00433
PSMGetTextExtent(hdc,
szOneChar, 1, &extent);
00434 lprc->left += extent.cx / 2;
00435 }
00436 }
00437
break;
00438
00439
case CBR_GROUPTEXT:
00440
if (!pwnd->
strName.
Length)
00441
goto EmptyRect;
00442
00443 lpName =
REBASE(pwnd, strName.Buffer);
00444
if (!(cch = pwnd->
strName.
Length /
sizeof(WCHAR))) {
00445
EmptyRect:
00446
SetRectEmpty(lprc);
00447
break;
00448 }
00449
00450
PSMGetTextExtent(hdc, lpName, cch, &extent);
00451 extent.cx +=
SYSMET(CXEDGE) * 2;
00452
00453
switch (align &
LOBYTE(
BFHORZMASK))
00454 {
00455
00456
case LOBYTE(
BFLEFT):
00457 lprc->left += (
gpsi->cxSysFontChar -
SYSMET(CXBORDER));
00458 lprc->right = lprc->left + (
int)(extent.cx);
00459
break;
00460
00461
case LOBYTE(
BFRIGHT):
00462 lprc->right -= (
gpsi->cxSysFontChar -
SYSMET(CXBORDER));
00463 lprc->left = lprc->right - (
int)(extent.cx);
00464
break;
00465
00466
case LOBYTE(
BFCENTER):
00467 lprc->left = (lprc->left + lprc->right - (
int)(extent.cx)) / 2;
00468 lprc->right = lprc->left + (
int)(extent.cx);
00469
break;
00470 }
00471
00472
00473 lprc->bottom = lprc->top + extent.cy +
SYSMET(CYEDGE);
00474
break;
00475
00476
case CBR_GROUPFRAME:
00477
PSMGetTextExtent(hdc, (LPWSTR)
szOneChar, 1, &extent);
00478 lprc->top += extent.cy / 2;
00479
break;
00480 }
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 void BNMultiExtent(
00492 WORD wFlags,
00493 HDC hdc,
00494 LPRECT lprcMax,
00495 LPWSTR lpsz,
00496
int cch,
00497
PINT pcx,
00498 PINT pcy)
00499 {
00500 RECT rcT;
00501
00502
UINT dtFlags = DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL;
00503
CopyRect(&rcT, lprcMax);
00504
00505
00506
00507
00508
00509
00510
InflateRect(&rcT, -
SYSMET(CXEDGE), -
SYSMET(CYBORDER));
00511
00512
if ((wFlags & LOWORD(BS_HORZMASK)) == LOWORD(BS_CENTER))
00513 dtFlags |= DT_CENTER;
00514
00515
if ((wFlags & LOWORD(BS_VERTMASK)) == LOWORD(BS_VCENTER))
00516 dtFlags |= DT_VCENTER;
00517
00518
DrawTextExW(hdc, lpsz, cch, &rcT, dtFlags,
NULL);
00519
00520
if (pcx)
00521 *pcx = rcT.right-rcT.left;
00522
if (pcy)
00523 *pcy = rcT.bottom-rcT.top;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 BOOL BNMultiDraw(
00535 HDC hdc,
00536 LPBTNDATA lpbd,
00537
int cch,
00538
int cx,
00539
int cy)
00540 {
00541 RECT rcT;
00542
UINT dtFlags = DT_WORDBREAK | DT_EDITCONTROL;
00543
PBUTN pbutn = lpbd->
pbutn;
00544
00545
if (
TestWF(pbutn->
spwnd,
WEFPUIACCELHIDDEN)) {
00546 dtFlags |= DT_HIDEPREFIX;
00547 }
else if (pbutn->
fPaintKbdCuesOnly){
00548 dtFlags |= DT_PREFIXONLY;
00549 }
00550
00551 rcT.left = 0;
00552 rcT.top = 0;
00553 rcT.right = cx;
00554 rcT.bottom =
cy;
00555
00556
00557 UserAssert(DT_LEFT == 0);
00558
switch (lpbd->
wFlags & LOWORD(BS_HORZMASK)) {
00559
case LOWORD(BS_CENTER):
00560 dtFlags |= DT_CENTER;
00561
break;
00562
00563
case LOWORD(BS_RIGHT):
00564 dtFlags |= DT_RIGHT;
00565
break;
00566 }
00567
00568
00569 UserAssert(DT_TOP == 0);
00570
switch (lpbd->
wFlags & LOWORD(BS_VERTMASK)) {
00571
case LOWORD(BS_VCENTER):
00572 dtFlags |= DT_VCENTER;
00573
break;
00574
00575
case LOWORD(BS_BOTTOM):
00576 dtFlags |= DT_BOTTOM;
00577
break;
00578 }
00579
00580
DrawTextExW(hdc, lpbd->
lpsz, cch, &rcT, dtFlags,
NULL);
00581
return(
TRUE);
00582 }
00583
00584
00585
00586
00587
00588
00589
00590 BOOL xxxBNSetCapture(
00591
PBUTN pbutn,
00592 UINT codeMouse)
00593 {
00594
PWND pwnd = pbutn->
spwnd;
00595
00596
BUTTONSTATE(pbutn) |= codeMouse;
00597
00598
CheckLock(pwnd);
00599
00600
if (!(
BUTTONSTATE(pbutn) &
BST_CAPTURED)) {
00601
NtUserSetCapture(
HWq(pwnd));
00602
BUTTONSTATE(pbutn) |=
BST_CAPTURED;
00603
00604
00605
00606
00607
00608
00609
BUTTONSTATE(pbutn) |=
BST_INCLICK;
00610
00611
NtUserSetFocus(
HWq(pwnd));
00612
00613
BUTTONSTATE(pbutn) &= ~
BST_INCLICK;
00614 }
00615
return(
BUTTONSTATE(pbutn) &
BST_CAPTURED);
00616 }
00617
00618
00619
00620
00621
00622
00623
00624
00625 void xxxButtonNotifyParent(
00626
PWND pwnd,
00627 UINT code)
00628 {
00629
TL tlpwndParent;
00630
PWND pwndParent;
00631
00632
CheckLock(pwnd);
00633
00634
if (pwnd->
spwndParent)
00635 pwndParent =
REBASEPWND(pwnd, spwndParent);
00636
else
00637 pwndParent = pwnd;
00638
00639
00640
00641
00642
ThreadLock(pwndParent, &tlpwndParent);
00643
SendMessage(
HW(pwndParent), WM_COMMAND,
00644 MAKELONG(
PTR_TO_ID(pwnd->spmenu), code), (LPARAM)
HWq(pwnd));
00645
ThreadUnlock(&tlpwndParent);
00646 }
00647
00648
00649
00650
00651
00652
00653
00654 void xxxBNReleaseCapture(
00655
PBUTN pbutn,
00656 BOOL fCheck)
00657 {
00658
PWND pwndT;
00659
UINT check;
00660
BOOL fNotifyParent =
FALSE;
00661
TL tlpwndT;
00662
PWND pwnd = pbutn->
spwnd;
00663
00664
CheckLock(pwnd);
00665
00666
if (
BUTTONSTATE(pbutn) & BST_PUSHED) {
00667
SendMessageWorker(pwnd, BM_SETSTATE,
FALSE, 0,
FALSE);
00668
if (fCheck) {
00669
switch (
TestWF(pwnd,
BFTYPEMASK)) {
00670
case BS_AUTOCHECKBOX:
00671
case BS_AUTO3STATE:
00672 check = (
UINT)((
BUTTONSTATE(pbutn) &
BST_CHECKMASK) + 1);
00673
00674
if (check > (
UINT)(
TestWF(pwnd,
BFTYPEMASK) == BS_AUTO3STATE? BST_INDETERMINATE : BST_CHECKED)) {
00675 check = BST_UNCHECKED;
00676 }
00677
SendMessageWorker(pwnd, BM_SETCHECK, check, 0,
FALSE);
00678
break;
00679
00680
case BS_AUTORADIOBUTTON:
00681 pwndT = pwnd;
00682
do {
00683
ThreadLock(pwndT, &tlpwndT);
00684
00685
if ((
UINT)
SendMessage(
HW(pwndT), WM_GETDLGCODE, 0, 0
L) &
00686 DLGC_RADIOBUTTON) {
00687
SendMessage(
HW(pwndT), BM_SETCHECK, (pwnd == pwndT), 0
L);
00688 }
00689 pwndT =
_GetNextDlgGroupItem(
REBASEPWND(pwndT, spwndParent),
00690 pwndT,
FALSE);
00691
ThreadUnlock(&tlpwndT);
00692
00693 }
while (pwndT != pwnd);
00694 }
00695
00696 fNotifyParent =
TRUE;
00697 }
00698 }
00699
00700
if (
BUTTONSTATE(pbutn) &
BST_CAPTURED) {
00701
BUTTONSTATE(pbutn) &= ~(
BST_CAPTURED |
BST_MOUSE);
00702
NtUserReleaseCapture();
00703 }
00704
00705
if (fNotifyParent) {
00706
00707
00708
00709
00710
xxxButtonNotifyParent(pwnd, BN_CLICKED);
00711 }
00712 }
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722 void xxxBNDrawText(
00723
PBUTN pbutn,
00724 HDC hdc,
00725 BOOL dbt,
00726 BOOL fDepress)
00727 {
00728 RECT rc;
00729 HBRUSH hbr;
00730
int x;
00731
int y;
00732
int cx;
00733
int cy;
00734 LPWSTR lpName;
00735
BYTE bStyle;
00736
int cch;
00737
UINT dsFlags;
00738
BTNDATA bdt;
00739
UINT pbfPush;
00740
PWND pwnd = pbutn->
spwnd;
00741
00742 bStyle =
TestWF(pwnd,
BFTYPEMASK);
00743
00744
if (bStyle >
sizeof(
mpStyleCbr)) {
00745 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Invalid button style");
00746 }
else if ((bStyle ==
LOBYTE(BS_GROUPBOX)) && (dbt ==
DBT_FOCUS))
00747
return;
00748
00749 pbfPush =
IsPushButton(pwnd);
00750
if (pbfPush) {
00751
BNCalcRect(pwnd, hdc, &rc,
CBR_PUSHBUTTON, pbfPush);
00752 IntersectClipRect(hdc, rc.left, rc.top, rc.right, rc.bottom);
00753
00754
00755
00756
00757
00758
00759 SetBkColor(hdc,
SYSRGB(3DFACE));
00760 SetTextColor(hdc,
SYSRGB(BTNTEXT));
00761 hbr =
SYSHBR(BTNTEXT);
00762 }
else {
00763
BNCalcRect(pwnd, hdc, &rc,
mpStyleCbr[bStyle], pbfPush);
00764
00765
00766
00767
if (bStyle ==
LOBYTE(BS_OWNERDRAW))
00768
goto DrawFocus;
00769
else
00770 hbr =
SYSHBR(WINDOWTEXT);
00771 }
00772
00773
00774 bdt.
wFlags =
GetAlignment(pwnd);
00775 bdt.
pbutn = pbutn;
00776
00777
00778
if (
TestWF(pwnd,
BFBITMAP)) {
00779 BITMAP bmp;
00780
00781
00782
if (!pbutn->
hImage)
00783
return;
00784
00785 GetObject(pbutn->
hImage,
sizeof(BITMAP), &bmp);
00786 cx = bmp.bmWidth;
00787
cy = bmp.bmHeight;
00788
00789 dsFlags = DST_BITMAP;
00790
goto UseImageForName;
00791 }
else if (
TestWF(pwnd,
BFICON)) {
00792
00793
if (!pbutn->
hImage)
00794
return;
00795
00796
NtUserGetIconSize(pbutn->
hImage, 0, &cx, &
cy);
00797
cy /= 2;
00798
00799 dsFlags = DST_ICON;
00800 UseImageForName:
00801 lpName = (LPWSTR)pbutn->
hImage;
00802 cch =
TRUE;
00803 }
else {
00804
00805
if (!pwnd->
strName.
Length)
00806
return;
00807
00808 lpName =
REBASE(pwnd, strName.Buffer);
00809 cch = pwnd->
strName.
Length /
sizeof(WCHAR);
00810
00811
if (
TestWF(pwnd,
BFMULTILINE)) {
00812
00813 bdt.
lpsz = lpName;
00814
00815
BNMultiExtent(bdt.
wFlags, hdc, &rc, lpName, cch, &cx, &
cy);
00816
00817 lpName = (LPWSTR)(
LPBTNDATA)&bdt;
00818 dsFlags = DST_COMPLEX;
00819
00820 }
else {
00821 SIZE size;
00822
00823
PSMGetTextExtent(hdc, lpName, cch, &size);
00824 cx = size.cx;
00825
cy = size.cy;
00826
00827
00828
00829
00830 dsFlags = DST_PREFIXTEXT;
00831
if (
TestWF(pwnd,
WEFPUIACCELHIDDEN)) {
00832 dsFlags |= DSS_HIDEPREFIX;
00833 }
else if (pbutn->
fPaintKbdCuesOnly) {
00834 dsFlags |= DSS_PREFIXONLY;
00835 }
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
cy++;
00845 }
00846
00847
00848
00849
00850
00851
00852
switch (bdt.
wFlags &
LOBYTE(
BFHORZMASK)) {
00853
00854
00855
00856
00857
case LOBYTE(
BFLEFT):
00858 x = rc.left +
SYSMET(CXEDGE);
00859
break;
00860
00861
case LOBYTE(
BFRIGHT):
00862 x = rc.right - cx -
SYSMET(CXEDGE);
00863
break;
00864
00865
default:
00866 x = (rc.left + rc.right - cx) / 2;
00867
break;
00868 }
00869
00870
00871
switch (bdt.
wFlags &
LOBYTE(
BFVERTMASK)) {
00872
00873
00874
00875
00876
case LOBYTE(
BFTOP):
00877 y = rc.top +
SYSMET(CYBORDER);
00878
break;
00879
00880
case LOBYTE(
BFBOTTOM):
00881 y = rc.bottom -
cy -
SYSMET(CYBORDER);
00882
break;
00883
00884
default:
00885 y = (rc.top + rc.bottom -
cy) / 2;
00886
break;
00887 }
00888
00889
00890
00891
00892
if (dbt &
DBT_TEXT) {
00893
00894
00895
00896 UserAssert(bStyle !=
LOBYTE(BS_USERBUTTON));
00897
00898
if (fDepress) {
00899 x +=
SYSMET(CXBORDER);
00900 y +=
SYSMET(CYBORDER);
00901 }
00902
00903
if (
TestWF(pwnd,
WFDISABLED)) {
00904 UserAssert(
HIBYTE(
BFICON) ==
HIBYTE(
BFBITMAP));
00905
if (
SYSMET(SLOWMACHINE) &&
00906 !
TestWF(pwnd,
BFICON |
BFBITMAP) &&
00907 (GetBkColor(hdc) !=
SYSRGB(GRAYTEXT)))
00908 {
00909
00910 SetTextColor(hdc,
SYSRGB(GRAYTEXT));
00911 }
00912
else
00913 dsFlags |= DSS_DISABLED;
00914 }
00915
00916
00917
00918
00919
00920
if (pbfPush) {
00921
switch (
BUTTONSTATE(pbutn) &
BST_CHECKMASK) {
00922
case BST_INDETERMINATE:
00923 hbr =
SYSHBR(GRAYTEXT);
00924 dsFlags |= DSS_MONO;
00925
00926
00927
case BST_CHECKED:
00928
00929 SetBkMode(hdc, TRANSPARENT);
00930
break;
00931 }
00932 }
00933
00934
00935
00936
00937
00938 DrawState(hdc, hbr, (DRAWSTATEPROC)
BNMultiDraw, (LPARAM)lpName,
00939 (WPARAM)cch, x, y, cx,
cy,
00940 dsFlags);
00941 }
00942
00943
00944
00945
00946
00947 DrawFocus:
00948
if (dbt &
DBT_FOCUS) {
00949
if (bStyle ==
LOBYTE(BS_OWNERDRAW)) {
00950
00951
00952
00953
00954
xxxBNOwnerDraw(pbutn, hdc, ODA_FOCUS);
00955 }
else {
00956
00957
if (!
TestWF(pwnd,
WEFPUIFOCUSHIDDEN)) {
00958
00959
00960
00961
00962
if (!pbfPush) {
00963
00964 RECT rcClient;
00965
00966
_GetClientRect(pwnd, &rcClient);
00967
if (bStyle ==
LOBYTE(BS_USERBUTTON))
00968
CopyRect(&rc, &rcClient);
00969
else {
00970
00971
00972 rc.top =
max(rcClient.top, y-
SYSMET(CYBORDER));
00973 rc.bottom =
min(rcClient.bottom, rc.top +
SYSMET(CYEDGE) +
cy);
00974
00975 rc.left =
max(rcClient.left, x-
SYSMET(CXBORDER));
00976 rc.right =
min(rcClient.right, rc.left +
SYSMET(CXEDGE) + cx);
00977 }
00978 }
else
00979
InflateRect(&rc, -
SYSMET(CXBORDER), -
SYSMET(CYBORDER));
00980
00981
00982
DrawFocusRect(hdc, &rc);
00983 }
00984 }
00985 }
00986 }
00987
00988
00989
00990
00991
00992
00993
00994
00995 void xxxButtonDrawCheck(
00996
PBUTN pbutn,
00997 HDC hdc,
00998 HBRUSH hbr)
00999 {
01000 RECT rc;
01001
int bm;
01002
UINT flags;
01003
BOOL fDoubleBlt =
FALSE;
01004
TL tlpwnd;
01005
PWND pwnd = pbutn->
spwnd;
01006
PWND pwndParent;
01007
01008
BNCalcRect(pwnd, hdc, &rc,
CBR_CHECKBOX, 0);
01009
01010 flags = 0;
01011
if (
BUTTONSTATE(pbutn) &
BST_CHECKMASK)
01012 flags |= DFCS_CHECKED;
01013
if (
BUTTONSTATE(pbutn) & BST_PUSHED)
01014 flags |= DFCS_PUSHED;
01015
if (
TestWF(pwnd,
WFDISABLED))
01016 flags |= DFCS_INACTIVE;
01017
01018 bm =
OBI_CHECK;
01019
switch (
TestWF(pwnd,
BFTYPEMASK)) {
01020
case BS_AUTORADIOBUTTON:
01021
case BS_RADIOBUTTON:
01022 fDoubleBlt =
TRUE;
01023 bm =
OBI_RADIO;
01024 flags |= DFCS_BUTTONRADIO;
01025
break;
01026
01027
case BS_3STATE:
01028
case BS_AUTO3STATE:
01029
if ((
BUTTONSTATE(pbutn) &
BST_CHECKMASK) == BST_INDETERMINATE) {
01030 bm =
OBI_3STATE;
01031 flags |= DFCS_BUTTON3STATE;
01032
break;
01033 }
01034
01035
01036
default:
01037 flags |= DFCS_BUTTONCHECK;
01038
break;
01039 }
01040
01041 rc.right = rc.left +
gpsi->oembmi[bm].cx;
01042 rc.bottom = rc.top +
gpsi->oembmi[bm].cy;
01043
01044
ThreadLockAlways(pwnd->
spwndParent, &tlpwnd);
01045 pwndParent =
REBASEPWND(pwnd, spwndParent);
01046
PaintRect(
HW(pwndParent),
HWq(pwnd), hdc, hbr, &rc);
01047
ThreadUnlock(&tlpwnd);
01048
01049
if (
TestWF(pwnd,
BFFLAT) &&
gpsi->BitCount != 1) {
01050 flags |= DFCS_MONO | DFCS_FLAT;
01051
DrawFrameControl(hdc, &rc, DFC_BUTTON, flags);
01052 }
else {
01053
01054
switch (flags & (DFCS_CHECKED | DFCS_PUSHED | DFCS_INACTIVE))
01055 {
01056
case 0:
01057
break;
01058
01059
case DFCS_CHECKED:
01060 bm +=
DOBI_CHECK;
01061
break;
01062
01063
01064
case DFCS_PUSHED:
01065
case DFCS_INACTIVE:
01066 bm +=
DOBI_DOWN;
01067
break;
01068
01069
case DFCS_CHECKED | DFCS_PUSHED:
01070 bm +=
DOBI_CHECKDOWN;
01071
break;
01072
01073
case DFCS_CHECKED | DFCS_INACTIVE:
01074 bm +=
DOBI_CHECKDOWN + 1;
01075
break;
01076 }
01077
01078
if (fDoubleBlt) {
01079
01080
01081
DWORD clrTextSave = SetTextColor(hdc, 0x00000000L);
01082
DWORD clrBkSave = SetBkColor(hdc, 0x00FFFFFFL);
01083
POEMBITMAPINFO pOem =
gpsi->oembmi +
OBI_RADIOMASK;
01084
01085
NtUserBitBltSysBmp(hdc, rc.left, rc.top, pOem->
cx, pOem->
cy,
01086 pOem->
x, pOem->
y, SRCAND);
01087
01088 pOem =
gpsi->oembmi + bm;
01089
NtUserBitBltSysBmp(hdc, rc.left, rc.top, pOem->
cx, pOem->
cy,
01090 pOem->
x, pOem->
y, SRCINVERT);
01091
01092 SetTextColor(hdc, clrTextSave);
01093 SetBkColor(hdc, clrBkSave);
01094 }
else {
01095
POEMBITMAPINFO pOem =
gpsi->oembmi + bm;
01096
DWORD dwROP = 0;
01097
#ifdef USE_MIRRORING
01098
01099
if (MIRRORED_HDC(hdc)) {
01100 dwROP = NOMIRRORBITMAP;
01101 }
01102
#endif
01103
NtUserBitBltSysBmp(hdc, rc.left, rc.top, pOem->
cx, pOem->
cy,
01104 pOem->
x, pOem->
y, SRCCOPY | dwROP);
01105 }
01106 }
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
01116 void xxxButtonDrawNewState(
01117
PBUTN pbutn,
01118 HDC hdc,
01119 HBRUSH hbr,
01120 UINT sOld)
01121 {
01122
PWND pwnd = pbutn->
spwnd;
01123
01124
CheckLock(pwnd);
01125
01126
if (sOld != (
UINT)(
BUTTONSTATE(pbutn) & BST_PUSHED)) {
01127
UINT pbfPush;
01128
01129 pbfPush =
IsPushButton(pwnd);
01130
01131
switch (
TestWF(pwnd,
BFTYPEMASK)) {
01132
case BS_GROUPBOX:
01133
case BS_OWNERDRAW:
01134
break;
01135
01136
default:
01137
if (!pbfPush) {
01138
xxxButtonDrawCheck(pbutn, hdc, hbr);
01139
break;
01140 }
01141
01142
case BS_PUSHBUTTON:
01143
case BS_DEFPUSHBUTTON:
01144
case BS_PUSHBOX:
01145
xxxDrawButton(pbutn, hdc, pbfPush);
01146
break;
01147 }
01148 }
01149 }
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159 void xxxDrawButton(
01160
PBUTN pbutn,
01161 HDC hdc,
01162 UINT pbfPush)
01163 {
01164 RECT rc;
01165
UINT flags = 0;
01166
UINT state = 0;
01167
PWND pwnd = pbutn->
spwnd;
01168
01169
if (
BUTTONSTATE(pbutn) & BST_PUSHED)
01170 state |= DFCS_PUSHED;
01171
01172
if (!pbutn->
fPaintKbdCuesOnly) {
01173
if (
BUTTONSTATE(pbutn) &
BST_CHECKMASK)
01174 state |= DFCS_CHECKED;
01175
01176
if (
TestWF(pwnd,
WFWIN40COMPAT))
01177 flags = BF_SOFT;
01178
01179
if (
TestWF(pwnd,
BFFLAT))
01180 flags |= BF_FLAT | BF_MONO;
01181
01182
_GetClientRect(pwnd, &rc);
01183
01184
if (pbfPush &
PBF_DEFAULT) {
01185
DrawFrame(hdc, &rc, 1,
DF_WINDOWFRAME);
01186
InflateRect(&rc, -
SYSMET(CXBORDER), -
SYSMET(CYBORDER));
01187
01188
if (state & DFCS_PUSHED)
01189 flags |= BF_FLAT;
01190 }
01191
01192
DrawPushButton(hdc, &rc, state, flags);
01193 }
01194
01195
xxxBNDrawText(pbutn, hdc,
DBT_TEXT | (
BUTTONSTATE(pbutn) &
01196 BST_FOCUS ?
DBT_FOCUS : 0), (state & DFCS_PUSHED));
01197 }
01198
01199
01200
01201
01202
01203
01204
01205
01206 void xxxBNPaint(
01207
PBUTN pbutn,
01208 HDC hdc)
01209 {
01210
UINT bsWnd;
01211 RECT rc;
01212 HBRUSH hbr;
01213 HBRUSH hbrBtnSave;
01214
TL tlpwndParent;
01215
UINT pbfPush;
01216
PWND pwnd = pbutn->
spwnd;
01217
PWND pwndParent;
01218
01219
CheckLock(pwnd);
01220
01221 hbr =
xxxBNInitDC(pbutn, hdc);
01222
01223 bsWnd =
TestWF(pwnd,
BFTYPEMASK);
01224 pbfPush =
IsPushButton(pwnd);
01225
if (!pbfPush && !pbutn->
fPaintKbdCuesOnly) {
01226
_GetClientRect(pwnd, &rc);
01227
01228
if ((bsWnd !=
LOBYTE(BS_OWNERDRAW)) &&
01229 (bsWnd !=
LOBYTE(BS_GROUPBOX))) {
01230
ThreadLock(pwnd->
spwndParent, &tlpwndParent);
01231 pwndParent =
REBASEPWND(pwnd, spwndParent);
01232
PaintRect(
HW(pwndParent),
HWq(pwnd), hdc, hbr, &rc);
01233
ThreadUnlock(&tlpwndParent);
01234 }
01235
01236 hbrBtnSave = SelectObject(hdc, hbr);
01237 }
01238
01239
switch (bsWnd) {
01240
case BS_CHECKBOX:
01241
case BS_RADIOBUTTON:
01242
case BS_AUTORADIOBUTTON:
01243
case BS_3STATE:
01244
case BS_AUTOCHECKBOX:
01245
case BS_AUTO3STATE:
01246
if (!pbfPush) {
01247
xxxBNDrawText(pbutn, hdc,
01248
DBT_TEXT | (
BUTTONSTATE(pbutn) & BST_FOCUS ?
DBT_FOCUS : 0),
FALSE);
01249
if (!pbutn->fPaintKbdCuesOnly) {
01250
xxxButtonDrawCheck(pbutn, hdc, hbr);
01251 }
01252
break;
01253 }
01254
01255
01256
01257
01258
case BS_PUSHBUTTON:
01259
case BS_DEFPUSHBUTTON:
01260
xxxDrawButton(pbutn, hdc, pbfPush);
01261
break;
01262
01263
case BS_PUSHBOX:
01264
xxxBNDrawText(pbutn, hdc,
01265
DBT_TEXT | (
BUTTONSTATE(pbutn) & BST_FOCUS ?
DBT_FOCUS : 0),
FALSE);
01266
01267
xxxButtonDrawNewState(pbutn, hdc, hbr, 0);
01268
break;
01269
01270
case BS_USERBUTTON:
01271
xxxButtonNotifyParent(pwnd, BN_PAINT);
01272
01273
if (
BUTTONSTATE(pbutn) & BST_PUSHED) {
01274
xxxButtonNotifyParent(pwnd, BN_PUSHED);
01275 }
01276
if (
TestWF(pwnd,
WFDISABLED)) {
01277
xxxButtonNotifyParent(pwnd, BN_DISABLE);
01278 }
01279
if (
BUTTONSTATE(pbutn) & BST_FOCUS) {
01280
xxxBNDrawText(pbutn, hdc,
DBT_FOCUS,
FALSE);
01281 }
01282
break;
01283
01284
case BS_OWNERDRAW:
01285
xxxBNOwnerDraw(pbutn, hdc, ODA_DRAWENTIRE);
01286
break;
01287
01288
case BS_GROUPBOX:
01289
if (!pbutn->fPaintKbdCuesOnly) {
01290
BNCalcRect(pwnd, hdc, &rc,
CBR_GROUPFRAME, 0);
01291
DrawEdge(hdc, &rc, EDGE_ETCHED, BF_RECT |
01292 (
TestWF(pwnd,
BFFLAT) ? BF_FLAT | BF_MONO : 0));
01293
01294
BNCalcRect(pwnd, hdc, &rc,
CBR_GROUPTEXT, 0);
01295
ThreadLock(pwnd->spwndParent, &tlpwndParent);
01296 pwndParent =
REBASEPWND(pwnd, spwndParent);
01297
PaintRect(
HW(pwndParent),
HWq(pwnd), hdc, hbr, &rc);
01298
ThreadUnlock(&tlpwndParent);
01299 }
01300
01301
01302
01303
01304
xxxBNDrawText(pbutn, hdc,
DBT_TEXT,
FALSE);
01305
break;
01306 }
01307
01308
if (!pbfPush)
01309 SelectObject(hdc, hbrBtnSave);
01310
01311
01312
01313
01314
if (pbutn->
hFont) {
01315 SelectObject(hdc,
ghFontSys);
01316 }
01317 }
01318
01319
01320
01321
01322 void RepaintButton (
PBUTN pbutn)
01323 {
01324 HDC hdc =
xxxBNGetDC(pbutn,
NULL);
01325
if (hdc !=
NULL) {
01326
xxxBNPaint(pbutn, hdc);
01327
BNReleaseDC(pbutn, hdc);
01328 }
01329 }
01330
01331
01332
01333
01334
01335
01336
01337
01338 LRESULT
APIENTRY ButtonWndProcWorker(
01339
PWND pwnd,
01340 UINT message,
01341 WPARAM wParam,
01342 LPARAM lParam,
01343 DWORD fAnsi)
01344 {
01345 HWND hwnd =
HWq(pwnd);
01346
UINT bsWnd;
01347
UINT wOldState;
01348 RECT rc;
01349 POINT pt;
01350 HDC hdc;
01351 HBRUSH hbr;
01352 PAINTSTRUCT ps;
01353
TL tlpwndParent;
01354
PBUTN pbutn;
01355
PWND pwndParent;
01356
static BOOL fInit =
TRUE;
01357 LONG lResult;
01358
01359
CheckLock(pwnd);
01360
01361 bsWnd =
TestWF(pwnd,
BFTYPEMASK);
01362
01363
VALIDATECLASSANDSIZE(pwnd,
FNID_BUTTON);
01364
INITCONTROLLOOKASIDE(&
ButtonLookaside,
BUTN, spwnd, 8);
01365
01366
01367
01368
01369
01370
01371 pbutn = ((
PBUTNWND)pwnd)->pbutn;
01372
01373
switch (message) {
01374
case WM_NCHITTEST:
01375
if (bsWnd ==
LOBYTE(BS_GROUPBOX)) {
01376
return (LONG)HTTRANSPARENT;
01377 }
else {
01378
goto CallDWP;
01379 }
01380
01381
case WM_ERASEBKGND:
01382
if (bsWnd ==
LOBYTE(BS_OWNERDRAW)) {
01383
01384
01385
01386
01387
_GetClientRect(pwnd, &rc);
01388
ThreadLock(pwnd->
spwndParent, &tlpwndParent);
01389 pwndParent =
REBASEPWND(pwnd, spwndParent);
01390
PaintRect(
HW(pwndParent), hwnd, (HDC)wParam, (HBRUSH)CTLCOLOR_BTN, &rc);
01391
ThreadUnlock(&tlpwndParent);
01392 }
01393
01394
01395
01396
01397
01398
return (LONG)
TRUE;
01399
01400
case WM_PRINTCLIENT:
01401
xxxBNPaint(pbutn, (HDC)wParam);
01402
break;
01403
01404
case WM_PAINT:
01405
01406
01407
01408
01409
if ((hdc = (HDC)wParam) ==
NULL)
01410 hdc =
NtUserBeginPaint(hwnd, &ps);
01411
01412
if (
IsVisible(pwnd))
01413
xxxBNPaint(pbutn, hdc);
01414
01415
if (!wParam)
01416
NtUserEndPaint(hwnd, &ps);
01417
break;
01418
01419
case WM_SETFOCUS:
01420
BUTTONSTATE(pbutn) |= BST_FOCUS;
01421
if ((hdc =
xxxBNGetDC(pbutn,
NULL)) !=
NULL) {
01422
xxxBNDrawText(pbutn, hdc,
DBT_FOCUS,
FALSE);
01423
01424
BNReleaseDC(pbutn, hdc);
01425 }
01426
01427
if (
TestWF(pwnd,
BFNOTIFY))
01428
xxxButtonNotifyParent(pwnd, BN_SETFOCUS);
01429
01430
if (!(
BUTTONSTATE(pbutn) &
BST_INCLICK)) {
01431
switch (bsWnd) {
01432
case LOBYTE(BS_RADIOBUTTON):
01433
case LOBYTE(BS_AUTORADIOBUTTON):
01434
if (!(
BUTTONSTATE(pbutn) &
BST_DONTCLICK)) {
01435
if (!(
BUTTONSTATE(pbutn) &
BST_CHECKMASK)) {
01436
xxxButtonNotifyParent(pwnd, BN_CLICKED);
01437 }
01438 }
01439
break;
01440 }
01441 }
01442
break;
01443
01444
case WM_GETDLGCODE:
01445
switch (bsWnd) {
01446
case LOBYTE(BS_DEFPUSHBUTTON):
01447 wParam = DLGC_DEFPUSHBUTTON;
01448
break;
01449
01450
case LOBYTE(BS_PUSHBUTTON):
01451
case LOBYTE(BS_PUSHBOX):
01452 wParam = DLGC_UNDEFPUSHBUTTON;
01453
break;
01454
01455
case LOBYTE(BS_AUTORADIOBUTTON):
01456
case LOBYTE(BS_RADIOBUTTON):
01457 wParam = DLGC_RADIOBUTTON;
01458
break;
01459
01460
case LOBYTE(BS_GROUPBOX):
01461
return (LONG)DLGC_STATIC;
01462
01463
case LOBYTE(BS_CHECKBOX):
01464
case LOBYTE(BS_AUTOCHECKBOX):
01465
01466
01467
01468
01469
if (lParam && ((LPMSG)lParam)->message == WM_CHAR) {
01470
switch (wParam) {
01471
case TEXT(
'='):
01472
case TEXT(
'+'):
01473
case TEXT(
'-'):
01474 wParam = DLGC_WANTCHARS;
01475
break;
01476
01477
default:
01478 wParam = 0;
01479 }
01480 }
else {
01481 wParam = 0;
01482 }
01483
break;
01484
01485
default:
01486 wParam = 0;
01487 }
01488
return (LONG)(wParam | DLGC_BUTTON);
01489
01490
case WM_CAPTURECHANGED:
01491
if (
BUTTONSTATE(pbutn) &
BST_CAPTURED) {
01492
01493
01494
if (
BUTTONSTATE(pbutn) &
BST_MOUSE)
01495
SendMessageWorker(pwnd, BM_SETSTATE,
FALSE, 0,
FALSE);
01496
BUTTONSTATE(pbutn) &= ~(
BST_CAPTURED |
BST_MOUSE);
01497 }
01498
break;
01499
01500
case WM_KILLFOCUS:
01501
01502
01503
01504
01505
01506
01507
if (
BUTTONSTATE(pbutn) &
BST_MOUSE) {
01508
01509
01510
01511
01512
01513
01514
SendMessageWorker(pwnd, BM_SETSTATE,
FALSE, 0,
FALSE);
01515 }
01516
01517
xxxBNReleaseCapture(pbutn,
TRUE);
01518
01519
BUTTONSTATE(pbutn) &= ~BST_FOCUS;
01520
if ((hdc =
xxxBNGetDC(pbutn,
NULL)) !=
NULL) {
01521
xxxBNDrawText(pbutn, hdc,
DBT_FOCUS,
FALSE);
01522
01523
BNReleaseDC(pbutn, hdc);
01524 }
01525
01526
if (
TestWF(pwnd,
BFNOTIFY))
01527
xxxButtonNotifyParent(pwnd, BN_KILLFOCUS);
01528
01529
01530
01531
01532
01533
01534
NtUserInvalidateRect(hwnd,
NULL,
FALSE);
01535
break;
01536
01537
case WM_LBUTTONDBLCLK:
01538
01539
01540
01541
01542
01543
01544
switch (bsWnd) {
01545
default:
01546
if (!
TestWF(pwnd,
BFNOTIFY))
01547
goto btnclick;
01548
01549
case LOBYTE(BS_USERBUTTON):
01550
case LOBYTE(BS_RADIOBUTTON):
01551
case LOBYTE(BS_OWNERDRAW):
01552
xxxButtonNotifyParent(pwnd, BN_DOUBLECLICKED);
01553
break;
01554 }
01555
break;
01556
01557
case WM_LBUTTONUP:
01558
if (
BUTTONSTATE(pbutn) &
BST_MOUSE) {
01559
xxxBNReleaseCapture(pbutn,
TRUE);
01560 }
01561
break;
01562
01563
case WM_MOUSEMOVE:
01564
if (!(
BUTTONSTATE(pbutn) &
BST_MOUSE)) {
01565
break;
01566 }
01567
01568
01569
01570
01571
case WM_LBUTTONDOWN:
01572 btnclick:
01573
if (
xxxBNSetCapture(pbutn,
BST_MOUSE)) {
01574
_GetClientRect(pwnd, &rc);
01575 POINTSTOPOINT(pt, lParam);
01576
SendMessageWorker(pwnd, BM_SETSTATE,
PtInRect(&rc, pt), 0,
FALSE);
01577 }
01578
break;
01579
01580
case WM_CHAR:
01581
if (
BUTTONSTATE(pbutn) &
BST_MOUSE)
01582
goto CallDWP;
01583
01584
if (bsWnd !=
LOBYTE(BS_CHECKBOX) &&
01585 bsWnd !=
LOBYTE(BS_AUTOCHECKBOX))
01586
goto CallDWP;
01587
01588
switch (wParam) {
01589
case TEXT(
'+'):
01590
case TEXT(
'='):
01591 wParam = 1;
01592
goto SetCheck;
01593
01594
case TEXT(
'-'):
01595 wParam = 0;
01596 SetCheck:
01597
01598
if ((WORD)(
BUTTONSTATE(pbutn) &
BST_CHECKMASK) != (WORD)wParam)
01599 {
01600
01601
if (bsWnd ==
LOBYTE(BS_AUTOCHECKBOX))
01602 {
01603
if (
xxxBNSetCapture(pbutn, 0))
01604 {
01605
SendMessageWorker(pwnd, BM_SETCHECK, wParam, 0,
FALSE);
01606
01607
xxxBNReleaseCapture(pbutn,
TRUE);
01608 }
01609 }
01610
01611
xxxButtonNotifyParent(pwnd, BN_CLICKED);
01612 }
01613
break;
01614
01615
default:
01616
goto CallDWP;
01617 }
01618
break;
01619
01620
case BM_CLICK:
01621
01622
if (
BUTTONSTATE(pbutn) &
BST_INBMCLICK)
01623
break;
01624
01625
BUTTONSTATE(pbutn) |=
BST_INBMCLICK;
01626
SendMessageWorker(pwnd, WM_LBUTTONDOWN, 0, 0,
FALSE);
01627
SendMessageWorker(pwnd, WM_LBUTTONUP, 0, 0,
FALSE);
01628
BUTTONSTATE(pbutn) &= ~
BST_INBMCLICK;
01629
01630
01631
01632
01633
01634
case WM_KEYDOWN:
01635
if (
BUTTONSTATE(pbutn) &
BST_MOUSE)
01636
break;
01637
01638
if (wParam == VK_SPACE) {
01639
if (
xxxBNSetCapture(pbutn, 0)) {
01640
SendMessageWorker(pwnd, BM_SETSTATE,
TRUE, 0,
FALSE);
01641 }
01642 }
else {
01643
xxxBNReleaseCapture(pbutn,
FALSE);
01644 }
01645
break;
01646
01647
case WM_KEYUP:
01648
case WM_SYSKEYUP:
01649
if (
BUTTONSTATE(pbutn) &
BST_MOUSE) {
01650
goto CallDWP;
01651 }
01652
01653
01654
01655
01656
01657
if (wParam == VK_TAB) {
01658
goto CallDWP;
01659 }
01660
01661
01662
01663
01664
xxxBNReleaseCapture(pbutn, (wParam == VK_SPACE));
01665
01666
if (message == WM_SYSKEYUP) {
01667
goto CallDWP;
01668 }
01669
break;
01670
01671
case BM_GETSTATE:
01672
return (LONG)
BUTTONSTATE(pbutn);
01673
01674
case BM_SETSTATE:
01675 wOldState = (
UINT)(
BUTTONSTATE(pbutn) & BST_PUSHED);
01676
if (wParam) {
01677
BUTTONSTATE(pbutn) |= BST_PUSHED;
01678 }
else {
01679
BUTTONSTATE(pbutn) &= ~BST_PUSHED;
01680 }
01681
01682
if ((hdc =
xxxBNGetDC(pbutn, &hbr)) !=
NULL) {
01683
if (bsWnd ==
LOBYTE(BS_USERBUTTON)) {
01684
xxxButtonNotifyParent(pwnd, (
UINT)(wParam ? BN_PUSHED : BN_UNPUSHED));
01685 }
else if (bsWnd ==
LOBYTE(BS_OWNERDRAW)) {
01686
if (wOldState != (
UINT)(
BUTTONSTATE(pbutn) & BST_PUSHED)) {
01687
01688
01689
01690
xxxBNOwnerDraw(pbutn, hdc, ODA_SELECT);
01691 }
01692 }
else {
01693
xxxButtonDrawNewState(pbutn, hdc, hbr, wOldState);
01694 }
01695
01696
BNReleaseDC(pbutn, hdc);
01697 }
01698
if (
FWINABLE() && (wOldState != (
BOOL)(
BUTTONSTATE(pbutn) & BST_PUSHED))) {
01699
NotifyWinEvent(EVENT_OBJECT_STATECHANGE, hwnd, OBJID_CLIENT, INDEXID_CONTAINER);
01700 }
01701
break;
01702
01703
case BM_GETCHECK:
01704
return (LONG)(
BUTTONSTATE(pbutn) &
BST_CHECKMASK);
01705
01706
case BM_SETCHECK:
01707
switch (bsWnd) {
01708
case LOBYTE(BS_RADIOBUTTON):
01709
case LOBYTE(BS_AUTORADIOBUTTON):
01710
if (wParam) {
01711
SetWindowState(pwnd,
WFTABSTOP);
01712 }
else {
01713
ClearWindowState(pwnd,
WFTABSTOP);
01714 }
01715
01716
01717
01718
01719
case LOBYTE(BS_CHECKBOX):
01720
case LOBYTE(BS_AUTOCHECKBOX):
01721
if (wParam) {
01722 wParam = 1;
01723 }
01724
goto CheckIt;
01725
01726
case LOBYTE(BS_3STATE):
01727
case LOBYTE(BS_AUTO3STATE):
01728
if (wParam > BST_INDETERMINATE) {
01729 wParam = BST_INDETERMINATE;
01730 }
01731 CheckIt:
01732
if ((
UINT)(
BUTTONSTATE(pbutn) &
BST_CHECKMASK) != (
UINT)wParam) {
01733
BUTTONSTATE(pbutn) &= ~
BST_CHECKMASK;
01734
BUTTONSTATE(pbutn) |= (
UINT)wParam;
01735
01736
if (!
IsVisible(pwnd))
01737
break;
01738
01739
if ((hdc =
xxxBNGetDC(pbutn, &hbr)) !=
NULL) {
01740
if (
TestWF(pwnd,
BFPUSHLIKE)) {
01741
xxxDrawButton(pbutn, hdc,
PBF_PUSHABLE);
01742 }
else {
01743
xxxButtonDrawCheck(pbutn, hdc, hbr);
01744 }
01745
BNReleaseDC(pbutn, hdc);
01746 }
01747
01748
if (
FWINABLE())
01749
NotifyWinEvent(EVENT_OBJECT_STATECHANGE, hwnd, OBJID_CLIENT, INDEXID_CONTAINER);
01750 }
01751
break;
01752 }
01753
break;
01754
01755
case BM_SETSTYLE:
01756
NtUserAlterWindowStyle(hwnd, BS_TYPEMASK, (
DWORD)wParam);
01757
01758
if (lParam) {
01759
NtUserInvalidateRect(hwnd,
NULL,
TRUE);
01760 }
01761
if (
FWINABLE()) {
01762
NotifyWinEvent(EVENT_OBJECT_STATECHANGE, hwnd, OBJID_CLIENT, INDEXID_CONTAINER);
01763 }
01764
break;
01765
01766
case WM_SETTEXT:
01767
01768
01769
01770
01771
01772
01773
if (bsWnd ==
LOBYTE(BS_GROUPBOX)) {
01774 hdc =
xxxBNGetDC(pbutn, &hbr);
01775
if (hdc !=
NULL) {
01776
BNCalcRect(pwnd, hdc, &rc,
CBR_GROUPTEXT, 0);
01777
NtUserInvalidateRect(hwnd, &rc,
TRUE);
01778
01779 pwndParent =
REBASEPWND(pwnd, spwndParent);
01780
ThreadLock(pwnd->
spwndParent, &tlpwndParent);
01781
PaintRect(
HW(pwndParent), hwnd, hdc, hbr, &rc);
01782
ThreadUnlock(&tlpwndParent);
01783
01784
BNReleaseDC(pbutn, hdc);
01785 }
01786 }
01787
01788 lResult =
_DefSetText(hwnd, (LPWSTR)lParam, (
BOOL)fAnsi);
01789
01790
if (
FWINABLE()) {
01791
NotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hwnd, OBJID_WINDOW, INDEXID_CONTAINER);
01792 }
01793
goto DoEnable;
01794
01795
01796
01797
01798
case WM_ENABLE:
01799 lResult = 0
L;
01800 DoEnable:
01801
RepaintButton(pbutn);
01802
return lResult;
01803
01804
case WM_SETFONT:
01805
01806
01807
01808
01809
BNSetFont(pbutn, (HFONT)wParam, (
BOOL)(lParam != 0));
01810
break;
01811
01812
case WM_GETFONT:
01813
return (LRESULT)pbutn->
hFont;
01814
01815
case BM_GETIMAGE:
01816
case BM_SETIMAGE:
01817
if (!
IsValidImage(wParam,
TestWF(pwnd,
BFIMAGEMASK),
IMAGE_BMMAX)) {
01818 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING,
"Invalid button image type");
01819 }
else {
01820 HANDLE hOld = pbutn->
hImage;
01821
01822
if (message == BM_SETIMAGE) {
01823 pbutn->
hImage = (HANDLE)lParam;
01824
if (
TestWF(pwnd,
WFVISIBLE)) {
01825
NtUserInvalidateRect(hwnd,
NULL,
TRUE);
01826 }
01827 }
01828
return (LRESULT)hOld;
01829 }
01830
break;
01831
01832
case WM_NCDESTROY:
01833
case WM_FINALDESTROY:
01834
if (pbutn) {
01835
Unlock(&pbutn->
spwnd);
01836
FreeLookasideEntry(&
ButtonLookaside, pbutn);
01837 }
01838
NtUserSetWindowFNID(hwnd,
FNID_CLEANEDUP_BIT);
01839
break;
01840
01841
case WM_NCCREATE:
01842
01843
01844
01845
01846
01847
if (
TestWF(pwnd,
WFWIN31COMPAT)) {
01848
if(((!
TestWF(pwnd,
WFWIN40COMPAT)) &&
01849 (((
LOBYTE(pwnd->style)) & (
LOBYTE(~BS_LEFTTEXT))) ==
LOBYTE(BS_USERBUTTON))) ||
01850 (
TestWF(pwnd,
WFWIN40COMPAT) &&
01851 (bsWnd ==
LOBYTE(BS_USERBUTTON))))
01852 {
01853
01854
01855
NtUserAlterWindowStyle(hwnd, BS_TYPEMASK, 0);
01856 RIPMSG0(RIP_WARNING,
"BS_USERBUTTON no longer supported");
01857 }
01858 }
01859
if (
TestWF(pwnd,
WEFRIGHT)) {
01860
NtUserAlterWindowStyle(hwnd, BS_RIGHT | BS_RIGHTBUTTON, BS_RIGHT | BS_RIGHTBUTTON);
01861 }
01862
goto CallDWP;
01863
01864
case WM_INPUTLANGCHANGEREQUEST:
01865
01866
01867
01868
01869
01870
01871
if (
TestwndChild(pwnd) && pwnd->
spwndParent) {
01872
PWND pwndParent =
REBASEPWND(pwnd, spwndParent);
01873
if (pwndParent) {
01874
PCLS pclsParent =
REBASEALWAYS(pwndParent, pcls);
01875
01876 UserAssert(pclsParent !=
NULL);
01877
if (pclsParent->
atomClassName ==
gpsi->
atomSysClass[
ICLS_DIALOG]) {
01878 RIPMSG0(RIP_VERBOSE,
"Button: WM_INPUTLANGCHANGEREQUEST is sent to parent.\n");
01879
return SendMessageWorker(pwndParent, message, wParam, lParam,
FALSE);
01880 }
01881 }
01882 }
01883
goto CallDWP;
01884
01885
case WM_UPDATEUISTATE:
01886 {
01887
DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
01888
if (
ISBSTEXTOROD(pwnd)) {
01889 pbutn->
fPaintKbdCuesOnly =
TRUE;
01890
RepaintButton(pbutn);
01891 pbutn->
fPaintKbdCuesOnly =
FALSE;
01892 }
01893 }
01894
break;
01895
01896
default:
01897 CallDWP:
01898
return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
01899 }
01900
01901
return 0
L;
01902 }
01903
01904
01905
01906
01907 LRESULT WINAPI
ButtonWndProcA(
01908 HWND hwnd,
01909 UINT message,
01910 WPARAM wParam,
01911 LPARAM lParam)
01912 {
01913
PWND pwnd;
01914
01915
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
01916
return (0
L);
01917 }
01918
01919
01920
01921
01922
01923
if (!
FWINDOWMSG(message,
FNID_BUTTON))
01924
return DefWindowProcWorker(pwnd, message, wParam, lParam,
TRUE);
01925
01926
return ButtonWndProcWorker(pwnd, message, wParam, lParam,
TRUE);
01927 }
01928
01929 LRESULT WINAPI
ButtonWndProcW(
01930 HWND hwnd,
01931 UINT message,
01932 WPARAM wParam,
01933 LPARAM lParam)
01934 {
01935
PWND pwnd;
01936
01937
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
01938
return (0
L);
01939 }
01940
01941
01942
01943
01944
01945
if (!
FWINDOWMSG(message,
FNID_BUTTON))
01946
return DefWindowProcWorker(pwnd, message, wParam, lParam,
FALSE);
01947
01948
return ButtonWndProcWorker(pwnd, message, wParam, lParam,
FALSE);
01949 }