Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

button.cpp

Go to the documentation of this file.
00001 /* $Id: button.cpp,v 1.45 2001/12/26 11:35:38 sandervl Exp $ */
00002 /* File: button.cpp -- Button type widgets
00003  *
00004  * Copyright (C) 1993 Johannes Ruscheinski
00005  * Copyright (C) 1993 David Metcalfe
00006  * Copyright (C) 1994 Alexandre Julliard
00007  * Copyright (c) 1999 Christoph Bratschi
00008  *
00009  * Corel version: 20000513
00010  * (WINE version: 20000130)
00011  *
00012  * Status: complete
00013  * Version: 5.00
00014  */
00015 
00016 #include <string.h>
00017 #include <stdlib.h>
00018 #include <os2win.h>
00019 #include "controls.h"
00020 #include "button.h"
00021 #include <misc.h>
00022 #include "initterm.h"
00023 #include "syscolor.h"
00024 
00025 #define DBG_LOCALLOG    DBG_button
00026 #include "dbglocal.h"
00027 
00028 #ifdef DEBUG
00029 char *GetMsgText(int Msg);
00030 #endif
00031 
00032 //Prototypes
00033 
00034 static void DrawDisabledText(HDC hdc,char* text,RECT* rtext,UINT format);
00035 
00036 static void PB_Paint(HWND hwnd,HDC hDC,WORD action);
00037 static void CB_Paint(HWND hwnd,HDC hDC,WORD action);
00038 static void GB_Paint(HWND hwnd,HDC hDC,WORD action);
00039 static void UB_Paint(HWND hwnd,HDC hDC,WORD action);
00040 static void OB_Paint(HWND hwnd,HDC hDC,WORD action);
00041 static void BUTTON_CheckAutoRadioButton(HWND hwnd);
00042 static void BUTTON_DrawPushButton(HWND hwnd,HDC hDC,WORD action,BOOL pushedState);
00043 static LRESULT BUTTON_LButtonDown(HWND hwnd,WPARAM wParam,LPARAM lParam);
00044 
00045 #define MAX_BTN_TYPE  12
00046 
00047 static const WORD maxCheckState[MAX_BTN_TYPE] =
00048 {
00049     BUTTON_UNCHECKED,   /* BS_PUSHBUTTON */
00050     BUTTON_UNCHECKED,   /* BS_DEFPUSHBUTTON */
00051     BUTTON_CHECKED,     /* BS_CHECKBOX */
00052     BUTTON_CHECKED,     /* BS_AUTOCHECKBOX */
00053     BUTTON_CHECKED,     /* BS_RADIOBUTTON */
00054     BUTTON_3STATE,      /* BS_3STATE */
00055     BUTTON_3STATE,      /* BS_AUTO3STATE */
00056     BUTTON_UNCHECKED,   /* BS_GROUPBOX */
00057     BUTTON_UNCHECKED,   /* BS_USERBUTTON */
00058     BUTTON_CHECKED,     /* BS_AUTORADIOBUTTON */
00059     BUTTON_UNCHECKED,   /* Not defined */
00060     BUTTON_UNCHECKED    /* BS_OWNERDRAW */
00061 };
00062 
00063 typedef void (*pfPaint)(HWND hwnd,HDC hdc,WORD action);
00064 
00065 static const pfPaint btnPaintFunc[MAX_BTN_TYPE] =
00066 {
00067     PB_Paint,    /* BS_PUSHBUTTON */
00068     PB_Paint,    /* BS_DEFPUSHBUTTON */
00069     CB_Paint,    /* BS_CHECKBOX */
00070     CB_Paint,    /* BS_AUTOCHECKBOX */
00071     CB_Paint,    /* BS_RADIOBUTTON */
00072     CB_Paint,    /* BS_3STATE */
00073     CB_Paint,    /* BS_AUTO3STATE */
00074     GB_Paint,    /* BS_GROUPBOX */
00075     UB_Paint,    /* BS_USERBUTTON */
00076     CB_Paint,    /* BS_AUTORADIOBUTTON */
00077     NULL,        /* Not defined */
00078     OB_Paint     /* BS_OWNERDRAW */
00079 };
00080 
00081 
00082 // 2001-08-29 PH
00083 // Microsoft ACMSETUP has a OWNERDRAW pushbutton dialog. After finishing
00084 // the dialog, the pushbuttons are de-initialized immediately.
00085 // However, OSLibWinDestroyWindow sent WM_SETFOCUS causing the (invisible)
00086 // buttons to be drawn, resulting in immediate crash.
00087 // -> IsWindowVisible() check introduced as is in WINE.
00088 
00089 #define PAINT_BUTTON(hwnd,style,action) \
00090      if (btnPaintFunc[style] && IsWindowVisible(hwnd) ) { \
00091          HDC hdc = GetDC(hwnd); \
00092          (btnPaintFunc[style])(hwnd,hdc,action); \
00093          ReleaseDC(hwnd,hdc); }
00094 
00095 #define BUTTON_SEND_CTLCOLOR(hwnd,hdc) \
00096     SendMessageA( GetParent(hwnd), WM_CTLCOLORBTN, \
00097                     (hdc),hwnd)
00098 
00099 static HBITMAP hbitmapCheckBoxes = 0;
00100 static WORD checkBoxWidth = 0, checkBoxHeight = 0;
00101 
00102 static LRESULT BUTTON_SendNotify(HWND hwnd,DWORD code)
00103 {
00104   return SendMessageA(GetParent(hwnd),WM_COMMAND,MAKEWPARAM(GetWindowLongA(hwnd,GWL_ID),code),hwnd);
00105 }
00106 
00107 static LRESULT BUTTON_GetDlgCode(HWND hwnd,WPARAM wParam,LPARAM lParam)
00108 {
00109   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00110 
00111   switch (dwStyle & 0x0f)
00112   {
00113     case BS_AUTOCHECKBOX:
00114     case BS_CHECKBOX:
00115      return DLGC_WANTCHARS | DLGC_BUTTON;
00116 
00117     case BS_PUSHBUTTON:
00118       return DLGC_UNDEFPUSHBUTTON;
00119 
00120     case BS_DEFPUSHBUTTON:
00121       return DLGC_DEFPUSHBUTTON;
00122 
00123     case BS_AUTORADIOBUTTON:
00124     case BS_RADIOBUTTON:
00125       return DLGC_RADIOBUTTON;
00126 
00127     case BS_GROUPBOX:;
00128       return DLGC_STATIC;
00129 
00130     default:
00131       return DLGC_BUTTON;
00132   }
00133 }
00134 
00135 static LRESULT BUTTON_Enable(HWND hwnd,WPARAM wParam,LPARAM lParam)
00136 {
00137   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00138 
00139 ////  if ((dwStyle & BS_NOTIFY) && !wParam) BUTTON_SendNotify(hwnd,BN_DISABLE);
00140 
00141   //PAINT_BUTTON(hwnd,dwStyle & 0x0f,ODA_DRAWENTIRE);
00142   //SvL: 09/10/99 Force it to redraw properly
00143   InvalidateRect( hwnd, NULL, FALSE );
00144 
00145   return 0;
00146 }
00147 
00148 static LRESULT BUTTON_Create(HWND hwnd,WPARAM wParam,LPARAM lParam)
00149 {
00150   BUTTONINFO* infoPtr;
00151   DWORD style = GetWindowLongA(hwnd,GWL_STYLE) & 0x0f;
00152 
00153   if (!hbitmapCheckBoxes)
00154   {
00155     BITMAP bmp;
00156 
00157     hbitmapCheckBoxes = LoadBitmapA(hInstanceUser32, MAKEINTRESOURCEA(OBM_CHECKBOXES));
00158     GetObjectA( hbitmapCheckBoxes, sizeof(bmp), &bmp );
00159     if (GetObjectA(hbitmapCheckBoxes,sizeof(bmp),&bmp))
00160     {
00161       checkBoxWidth  = bmp.bmWidth / 4;
00162       checkBoxHeight = bmp.bmHeight / 3;
00163     } else checkBoxWidth = checkBoxHeight = 0;
00164   }
00165   if ((style < 0L) || (style >= MAX_BTN_TYPE)) return -1; /* abort */
00166 
00167   infoPtr = (BUTTONINFO*)malloc(sizeof(BUTTONINFO));
00168   infoPtr->state = BUTTON_UNCHECKED;
00169   infoPtr->hFont = 0;
00170   infoPtr->hImage = 0;
00171   SetInfoPtr(hwnd,(DWORD)infoPtr);
00172 
00173   return 0;
00174 }
00175 
00176 static LRESULT BUTTON_Destroy(HWND hwnd,WPARAM wParam,LPARAM lParam)
00177 {
00178   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00179 
00180   free(infoPtr);
00181 
00182   return 0;
00183 }
00184 
00185 static LRESULT BUTTON_EraseBkgnd(HWND hwnd,WPARAM wParam,LPARAM lParam)
00186 {
00187   DWORD style = GetWindowLongA(hwnd,GWL_STYLE) & 0x0f;
00188   //SvL: TODO: NT does something extra for ownerdrawn buttons; check this 
00189   if(style == BS_OWNERDRAW) {
00190         return DefWindowProcA(hwnd, WM_ERASEBKGND, wParam, lParam);
00191   }
00192   return 1;
00193 }
00194 
00195 static LRESULT BUTTON_Paint(HWND hwnd,WPARAM wParam,LPARAM lParam)
00196 {
00197   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00198   DWORD style = dwStyle & 0x0f;
00199 
00200 ////  if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_PAINT);
00201 
00202   if (btnPaintFunc[style])
00203   {
00204     PAINTSTRUCT ps;
00205 
00206     HDC hdc = wParam ? (HDC)wParam : BeginPaint(hwnd,&ps);
00207     SetBkMode(hdc,OPAQUE);
00208     (btnPaintFunc[style])(hwnd,hdc,ODA_DRAWENTIRE);
00209     if(!wParam) EndPaint(hwnd,&ps);
00210   } else return DefWindowProcA(hwnd,WM_PAINT,wParam,lParam);
00211 
00212   return 0;
00213 }
00214 
00215 static LRESULT BUTTON_LButtonDblClk(HWND hwnd,WPARAM wParam,LPARAM lParam)
00216 {
00217   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00218   DWORD style = dwStyle & 0x0f;
00219 
00220   if(dwStyle & BS_NOTIFY || style == BS_RADIOBUTTON ||
00221      style == BS_USERBUTTON || style == BS_OWNERDRAW)
00222     BUTTON_SendNotify(hwnd,BN_DOUBLECLICKED);
00223   else BUTTON_LButtonDown(hwnd,wParam,lParam);
00224 
00225   return 0;
00226 }
00227 
00228 static LRESULT BUTTON_LButtonDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
00229 {
00230   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00231   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00232   DWORD style = dwStyle & 0x0F;
00233 
00234   if (style == BS_GROUPBOX) return 0;
00235   SetCapture(hwnd);
00236   SetFocus(hwnd);
00237   SendMessageA(hwnd,BM_SETSTATE,TRUE,0);
00238   infoPtr->state |= BUTTON_BTNPRESSED;
00239 
00240 ////  if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_HILITE);
00241 
00242   return 0;
00243 }
00244 
00245 static LRESULT BUTTON_LButtonUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
00246 {
00247   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00248   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00249   DWORD style = dwStyle & 0x0F;
00250   RECT rect;
00251   POINT pt;
00252 
00253   pt.x = LOWORD(lParam);
00254   pt.y = HIWORD(lParam);
00255 
00256   if (!(infoPtr->state & BUTTON_BTNPRESSED)) return 0;
00257   infoPtr->state &= BUTTON_NSTATES;
00258   if (!(infoPtr->state & BUTTON_HIGHLIGHTED))
00259   {
00260     ReleaseCapture();
00261     return 0;
00262   }
00263   SendMessageA(hwnd,BM_SETSTATE,FALSE,0);
00264   ReleaseCapture();
00265   GetClientRect(hwnd,&rect);
00266   if (PtInRect(&rect,pt))
00267   {
00268     switch(dwStyle & 0x0f)
00269     {
00270       case BS_AUTOCHECKBOX:
00271         SendMessageA(hwnd,BM_SETCHECK,!(infoPtr->state & BUTTON_CHECKED),0);
00272         break;
00273       case BS_AUTORADIOBUTTON:
00274         SendMessageA(hwnd,BM_SETCHECK,TRUE,0);
00275         break;
00276       case BS_AUTO3STATE:
00277         SendMessageA(hwnd,BM_SETCHECK,
00278                      (infoPtr->state & BUTTON_3STATE) ? 0 :
00279                      ((infoPtr->state & 3)+1),0);
00280         break;
00281     }
00282     BUTTON_SendNotify(hwnd,BN_CLICKED);
00283   }
00284 
00285 ////  if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_UNHILITE);
00286 
00287   return 0;
00288 }
00289 
00290 static LRESULT BUTTON_CaptureChanged(HWND hwnd,WPARAM wParam,LPARAM lParam)
00291 {
00292   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00293   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00294 
00295   if (infoPtr->state & BUTTON_BTNPRESSED)
00296   {
00297     infoPtr->state &= BUTTON_NSTATES;
00298     if (infoPtr->state & BUTTON_HIGHLIGHTED)
00299       SendMessageA( hwnd, BM_SETSTATE, FALSE, 0 );
00300   }
00301 
00302 ////  if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_UNHILITE);
00303 
00304   return 0;
00305 }
00306 
00307 static LRESULT BUTTON_MouseMove(HWND hwnd,WPARAM wParam,LPARAM lParam)
00308 {
00309   if (GetCapture() == hwnd)
00310   {
00311     RECT rect;
00312     POINT pt;
00313 
00314     pt.x = LOWORD(lParam);
00315     pt.y = HIWORD(lParam);
00316 
00317     GetClientRect(hwnd,&rect);
00318     SendMessageA(hwnd,BM_SETSTATE,PtInRect(&rect,pt),0);
00319   }
00320 
00321   return 0;
00322 }
00323 
00324 static LRESULT BUTTON_NCHitTest(HWND hwnd,WPARAM wParam,LPARAM lParam)
00325 {
00326   DWORD style = GetWindowLongA(hwnd,GWL_STYLE) & 0x0f;
00327 
00328   if (style == BS_GROUPBOX) return HTTRANSPARENT;
00329 
00330   return DefWindowProcA(hwnd,WM_NCHITTEST,wParam,lParam);
00331 }
00332 
00333 static LRESULT BUTTON_SetText(HWND hwnd,WPARAM wParam,LPARAM lParam)
00334 {
00335   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00336 
00337   DefWindowProcA(hwnd,WM_SETTEXT,wParam,lParam);
00338 #ifdef __WIN32OS2__
00339   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00340   if ((dwStyle & 0x0f) == BS_GROUPBOX) {
00341     RECT rc;
00342     TEXTMETRICA tm;
00343     HDC  hdc = GetDC(hwnd);
00344     int  fh1 = 0, fh2 = 0;
00345 
00346     // select old font (if exists)
00347     if (infoPtr->hFont) {
00348        SelectObject (hdc, infoPtr->hFont);
00349        GetTextMetricsA (hdc, &tm);
00350        fh1 = tm.tmHeight;
00351     }
00352     // select new font (if exists)
00353     if (wParam) {
00354        SelectObject (hdc, wParam);
00355        GetTextMetricsA (hdc, &tm);
00356        fh2 = tm.tmHeight;
00357     }
00358     // Erases top border line and (old) text background
00359     GetClientRect(hwnd, &rc);
00360     rc.bottom = rc.top + max( fh1, fh2) + 1;
00361     HBRUSH hbr = GetControlBrush( hwnd, hdc, CTLCOLOR_STATIC );
00362     FillRect(hdc, &rc, hbr);
00363     ReleaseDC(hwnd,hdc);
00364   }
00365 #endif
00366 
00367   if (dwStyle & WS_VISIBLE) PAINT_BUTTON(hwnd,dwStyle & 0x0f,ODA_DRAWENTIRE);
00368 
00369   return 0;
00370 }
00371 
00372 static LRESULT BUTTON_SetFont(HWND hwnd,WPARAM wParam,LPARAM lParam)
00373 {
00374   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00375   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00376 
00377 #ifdef __WIN32OS2__
00378   if ((dwStyle & 0x0f) == BS_GROUPBOX) {
00379     RECT rc;
00380     TEXTMETRICA tm;
00381     HDC  hdc = GetDC(hwnd);
00382     int  fh1 = 0, fh2 = 0;
00383 
00384     // select old font (if exists)
00385     if (infoPtr->hFont) {
00386        SelectObject (hdc, infoPtr->hFont);
00387        GetTextMetricsA (hdc, &tm);
00388        fh1 = tm.tmHeight;
00389     }
00390     // select new font (if exists)
00391     if (wParam) {
00392        SelectObject (hdc, wParam);
00393        GetTextMetricsA (hdc, &tm);
00394        fh2 = tm.tmHeight;
00395     }
00396     // Erases top border line and (old) text background
00397     GetClientRect(hwnd, &rc);
00398     rc.bottom = rc.top + max( fh1, fh2) + 1;
00399     HBRUSH hbr = GetControlBrush( hwnd, hdc, CTLCOLOR_STATIC );
00400     FillRect(hdc, &rc, hbr);
00401     ReleaseDC(hwnd,hdc);
00402   }
00403 #endif
00404 
00405   infoPtr->hFont = (HFONT)wParam;
00406   if (lParam && (dwStyle & WS_VISIBLE)) PAINT_BUTTON(hwnd,dwStyle & 0x0f,ODA_DRAWENTIRE);
00407 
00408   return 0;
00409 }
00410 
00411 static LRESULT BUTTON_GetFont(HWND hwnd,WPARAM wParam,LPARAM lParam)
00412 {
00413   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00414 
00415   return infoPtr->hFont;
00416 }
00417 
00418 static LRESULT BUTTON_KeyDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
00419 {
00420   if (wParam == VK_SPACE)
00421   {
00422     BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00423 
00424     SendMessageA(hwnd,BM_SETSTATE,TRUE,0);
00425     infoPtr->state |= BUTTON_BTNPRESSED;
00426   }
00427 
00428   return 0;
00429 }
00430 
00431 static LRESULT BUTTON_KeyUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
00432 {
00433   if (wParam == VK_SPACE)
00434   {
00435     BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00436     DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00437 
00438     if (!(infoPtr->state & BUTTON_BTNPRESSED)) return 0;
00439     infoPtr->state &= BUTTON_NSTATES;
00440     if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) return 0;
00441     SendMessageA(hwnd,BM_SETSTATE,FALSE,0);
00442 
00443     switch(dwStyle & 0x0f)
00444     {
00445       case BS_AUTOCHECKBOX:
00446         SendMessageA(hwnd,BM_SETCHECK,!(infoPtr->state & BUTTON_CHECKED),0);
00447         break;
00448       case BS_AUTORADIOBUTTON:
00449         SendMessageA(hwnd,BM_SETCHECK,TRUE,0);
00450         break;
00451       case BS_AUTO3STATE:
00452         SendMessageA(hwnd,BM_SETCHECK,
00453                      (infoPtr->state & BUTTON_3STATE) ? 0 :
00454                      ((infoPtr->state & 3)+1),0);
00455         break;
00456     }
00457     BUTTON_SendNotify(hwnd,BN_CLICKED);
00458   }
00459 
00460   return 0;
00461 }
00462 
00463 static LRESULT BUTTON_SysKeyUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
00464 {
00465   if (wParam != VK_TAB) ReleaseCapture();
00466 
00467   return 0;
00468 }
00469 
00470 static LRESULT BUTTON_SetFocus(HWND hwnd,WPARAM wParam,LPARAM lParam)
00471 {
00472   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00473   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00474   DWORD style = dwStyle & 0x0f;
00475 
00476   if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_SETFOCUS);
00477 
00478   if (((style == BS_AUTORADIOBUTTON) || (style == BS_RADIOBUTTON)) &&
00479       (GetCapture() != hwnd) && !(SendMessageA(hwnd,BM_GETCHECK,0,0) & BST_CHECKED))
00480   {
00481     /* The notification is sent when the button (BS_AUTORADIOBUTTON)
00482        is unckecked and the focus was not given by a mouse click. */
00483     if (style == BS_AUTORADIOBUTTON) SendMessageA(hwnd,BM_SETCHECK,TRUE,0);
00484     BUTTON_SendNotify(hwnd,BN_CLICKED);
00485   }
00486 
00487   infoPtr->state |= BUTTON_HASFOCUS;
00488   PAINT_BUTTON(hwnd,style,ODA_FOCUS);
00489 
00490   return 0;
00491 }
00492 
00493 static LRESULT BUTTON_KillFocus(HWND hwnd,WPARAM wParam,LPARAM lParam)
00494 {
00495   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00496   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00497   DWORD style = dwStyle & 0x0f;
00498 
00499   if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_KILLFOCUS);
00500 
00501   if (infoPtr->state & BUTTON_HASFOCUS)
00502   {
00503     infoPtr->state &= ~BUTTON_HASFOCUS;
00504     PAINT_BUTTON(hwnd,style,ODA_FOCUS);
00505   }
00506 
00507   return 0;
00508 }
00509 
00510 static LRESULT BUTTON_SysColorChange(HWND hwnd,WPARAM wParam,LPARAM lParam)
00511 {
00512   InvalidateRect(hwnd,NULL,FALSE);
00513 
00514   return 0;
00515 }
00516 
00517 static LRESULT BUTTON_Click(HWND hwnd,WPARAM wParam,LPARAM lParam)
00518 {
00519   RECT rect;
00520   LPARAM point;
00521 
00522   GetClientRect(hwnd,&rect);
00523   point = MAKELPARAM(rect.right/2,rect.bottom/2);
00524   SendMessageA(hwnd,WM_LBUTTONDOWN,MK_LBUTTON,point);
00525   Sleep(100);
00526   SendMessageA(hwnd,WM_LBUTTONUP,0,point);
00527 
00528   return 0;
00529 }
00530 
00531 static LRESULT BUTTON_SetStyle(HWND hwnd,WPARAM wParam,LPARAM lParam)
00532 {
00533   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE),newStyle;
00534 
00535   if ((wParam & 0x0F) >= MAX_BTN_TYPE) return 0;
00536   newStyle = (dwStyle & 0xFFFFFFF0) | (wParam & 0x0000000F);
00537 
00538   if (newStyle != dwStyle)
00539   {
00540     SetWindowLongA(hwnd,GWL_STYLE,newStyle);
00541     PAINT_BUTTON(hwnd,newStyle & 0x0F,ODA_DRAWENTIRE);
00542   }
00543 
00544   return 0;
00545 }
00546 
00547 static LRESULT BUTTON_SetImage(HWND hwnd,WPARAM wParam,LPARAM lParam)
00548 {
00549   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00550   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00551   HANDLE oldHbitmap = infoPtr->hImage;
00552 
00553   if ((dwStyle & BS_BITMAP) || (dwStyle & BS_ICON))
00554   {
00555     infoPtr->hImage = (HANDLE)lParam;
00556     InvalidateRect(hwnd,NULL,FALSE);
00557   }
00558 
00559   return oldHbitmap;
00560 }
00561 
00562 static LRESULT BUTTON_GetImage(HWND hwnd,WPARAM wParam,LPARAM lParam)
00563 {
00564   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00565 
00566   switch(wParam)
00567   {
00568     case IMAGE_BITMAP:
00569       return (HBITMAP)infoPtr->hImage;
00570     case IMAGE_ICON:
00571       return (HICON)infoPtr->hImage;
00572     default:
00573       return (HICON)0;
00574   }
00575 }
00576 
00577 static LRESULT BUTTON_GetCheck(HWND hwnd,WPARAM wParam,LPARAM lParam)
00578 {
00579   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00580 
00581   return infoPtr->state & 3;
00582 }
00583 
00584 static LRESULT BUTTON_SetCheck(HWND hwnd,WPARAM wParam,LPARAM lParam)
00585 {
00586   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00587   DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00588   DWORD style = dwStyle & 0x0f;
00589 
00590   if (wParam > maxCheckState[style]) wParam = maxCheckState[style];
00591 #ifndef __WIN32OS2__
00592   //Must clear WS_TABSTOP of control that is already disabled or else 
00593   //multiple control can have this style ((auto)radiobutton) and 
00594   //GetNextDlgTabItem will return the wrong one
00595   //Happens in Opera preferences dialog (multimedia) where all autoradio
00596   //buttons have the WS_TABSTOP style.
00597   if ((infoPtr->state & 3) != wParam)
00598   {
00599 #endif
00600     if ((style == BS_RADIOBUTTON) || (style == BS_AUTORADIOBUTTON))
00601     {
00602       DWORD oldStyle = dwStyle;
00603 
00604       if (wParam)
00605         dwStyle |= WS_TABSTOP;
00606       else
00607         dwStyle &= ~WS_TABSTOP;
00608 
00609       if (oldStyle != dwStyle) SetWindowLongA(hwnd,GWL_STYLE,dwStyle);
00610     }
00611 #ifdef __WIN32OS2__
00612     if ((infoPtr->state & 3) != wParam)
00613     {
00614 #endif
00615     infoPtr->state = (infoPtr->state & ~3) | wParam;
00616     PAINT_BUTTON(hwnd,style,ODA_SELECT);
00617   }
00618   if ((style == BS_AUTORADIOBUTTON) && (wParam == BUTTON_CHECKED))
00619     BUTTON_CheckAutoRadioButton(hwnd);
00620 
00621   return 0;
00622 }
00623 
00624 static LRESULT BUTTON_GetState(HWND hwnd,WPARAM wParam,LPARAM lParam)
00625 {
00626   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00627 
00628   return infoPtr->state;
00629 }
00630 
00631 static LRESULT BUTTON_SetState(HWND hwnd,WPARAM wParam,LPARAM lParam)
00632 {
00633   BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
00634   DWORD style = GetWindowLongA(hwnd,GWL_STYLE) & 0x0F;
00635 
00636   if (wParam)
00637   {
00638     if (infoPtr->state & BUTTON_HIGHLIGHTED) return 0;
00639     infoPtr->state |= BUTTON_HIGHLIGHTED;
00640   } else
00641   {
00642     if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) return 0;
00643     infoPtr->state &= ~BUTTON_HIGHLIGHTED;
00644   }
00645   PAINT_BUTTON(hwnd,style,ODA_SELECT);
00646 
00647   return 0;
00648 }
00649 
00650 /***********************************************************************
00651  *           ButtonWndProc
00652  */
00653 static
00654 LRESULT WINAPI ButtonWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
00655 {
00656 //  dprintf(("ButtonWndProc hwnd: %04x, msg %s, wp %08x lp %08lx\n",
00657 //           hwnd, GetMsgText(uMsg), wParam, lParam));
00658 
00659   switch (uMsg)
00660   {
00661     case WM_GETDLGCODE:
00662       return BUTTON_GetDlgCode(hwnd,wParam,lParam);
00663 
00664     case WM_ENABLE:
00665       return BUTTON_Enable(hwnd,wParam,lParam);
00666 
00667     case WM_CREATE:
00668       return BUTTON_Create(hwnd,wParam,lParam);
00669 
00670     case WM_DESTROY:
00671       return BUTTON_Destroy(hwnd,wParam,lParam);
00672 
00673     case WM_ERASEBKGND:
00674       return BUTTON_EraseBkgnd(hwnd,wParam,lParam);
00675 
00676     case WM_PAINT:
00677       return BUTTON_Paint(hwnd,wParam,lParam);
00678 
00679     case WM_LBUTTONDBLCLK:
00680       return BUTTON_LButtonDblClk(hwnd,wParam,lParam);
00681 
00682     case WM_LBUTTONDOWN:
00683       return BUTTON_LButtonDown(hwnd,wParam,lParam);
00684 
00685     case WM_LBUTTONUP:
00686       return BUTTON_LButtonUp(hwnd,wParam,lParam);
00687 
00688     case WM_CAPTURECHANGED:
00689       return BUTTON_CaptureChanged(hwnd,wParam,lParam);
00690 
00691     case WM_MOUSEMOVE:
00692       return BUTTON_MouseMove(hwnd,wParam,lParam);
00693 
00694     case WM_NCHITTEST:
00695       return BUTTON_NCHitTest(hwnd,wParam,lParam);
00696 
00697     case WM_SETTEXT:
00698       return BUTTON_SetText(hwnd,wParam,lParam);
00699 
00700     case WM_SETFONT:
00701       return BUTTON_SetFont(hwnd,wParam,lParam);
00702 
00703     case WM_GETFONT:
00704       return BUTTON_GetFont(hwnd,wParam,lParam);
00705 
00706     case WM_KEYDOWN:
00707       return BUTTON_KeyDown(hwnd,wParam,lParam);
00708 
00709     case WM_KEYUP:
00710       return BUTTON_KeyUp(hwnd,wParam,lParam);
00711 
00712     case WM_SYSKEYUP:
00713       return BUTTON_SysKeyUp(hwnd,wParam,lParam);
00714 
00715     case WM_SETFOCUS:
00716       return BUTTON_SetFocus(hwnd,wParam,lParam);
00717 
00718     case WM_KILLFOCUS:
00719       return BUTTON_KillFocus(hwnd,wParam,lParam);
00720 
00721     case WM_SYSCOLORCHANGE:
00722       return BUTTON_SysColorChange(hwnd,wParam,lParam);
00723 
00724     case BM_CLICK:
00725       return BUTTON_Click(hwnd,wParam,lParam);
00726 
00727     case BM_SETSTYLE:
00728       return BUTTON_SetStyle(hwnd,wParam,lParam);
00729 
00730     case BM_SETIMAGE:
00731       return BUTTON_SetImage(hwnd,wParam,lParam);
00732 
00733     case BM_GETIMAGE:
00734       return BUTTON_GetImage(hwnd,wParam,lParam);
00735 
00736     case BM_GETCHECK:
00737       return BUTTON_GetCheck(hwnd,wParam,lParam);
00738 
00739     case BM_SETCHECK:
00740       return BUTTON_SetCheck(hwnd,wParam,lParam);
00741 
00742     case BM_GETSTATE:
00743       return BUTTON_GetState(hwnd,wParam,lParam);
00744 
00745     case BM_SETSTATE:
00746       return BUTTON_SetState(hwnd,wParam,lParam);
00747 
00748     default:
00749       return DefWindowProcA(hwnd,uMsg,wParam,lParam);
00750   }
00751 
00752   return 0;
00753 }
00754 
00755 
00756 /**********************************************************************
00757  *       Push Button Functions
00758  */
00759 static void PB_Paint( HWND hwnd, HDC hDC, WORD action )
00760 {
00761     BUTTONINFO *infoPtr      = (BUTTONINFO *)GetInfoPtr(hwnd);
00762     BOOL        bHighLighted = (infoPtr->state & BUTTON_HIGHLIGHTED);
00763 
00764     /*
00765      * Delegate this to the more generic pushbutton painting
00766      * method.
00767      */
00768     BUTTON_DrawPushButton(hwnd,
00769                           hDC,
00770                           action,
00771                           bHighLighted);
00772 }
00773 
00774 static INT BUTTON_GetTextFormat(DWORD dwStyle,DWORD dwExStyle,INT defHorz,INT defVert)
00775 {
00776   INT format = 0;
00777 
00778   if (dwStyle & BS_LEFT) format = DT_LEFT;
00779   else if (dwStyle & BS_CENTER) format = DT_CENTER;
00780   else if ((dwStyle & BS_RIGHT) || (dwExStyle & WS_EX_RIGHT)) format = DT_RIGHT;
00781   else format = defHorz;
00782 
00783   if (dwStyle & BS_TOP) format |= DT_TOP;
00784   else if (dwStyle & BS_VCENTER) format |= DT_VCENTER;
00785   else if (dwStyle & BS_BOTTOM) format |= DT_BOTTOM;
00786   else format |= defVert;
00787 
00788   if (!(dwStyle & BS_MULTILINE)) format |= DT_SINGLELINE;
00789 
00790   return format;
00791 }
00792 
00793 /**********************************************************************
00794  * This method will actually do the drawing of the pushbutton
00795  * depending on it's state and the pushedState parameter.
00796  */
00797 static void BUTTON_DrawPushButton(
00798   HWND hwnd,
00799   HDC  hDC,
00800   WORD action,
00801   BOOL pushedState )
00802 {
00803     RECT rc, focus_rect;
00804     HPEN hOldPen;
00805     HBRUSH hOldBrush;
00806     BUTTONINFO *infoPtr = (BUTTONINFO *)GetInfoPtr(hwnd);
00807     DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
00808     int xBorderOffset, yBorderOffset;
00809     xBorderOffset = yBorderOffset = 0;
00810     INT textLen;
00811     char* text;
00812 
00813     GetClientRect( hwnd, &rc );
00814 
00815       /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */
00816     if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
00817     BUTTON_SEND_CTLCOLOR( hwnd, hDC );
00818     hOldPen = (HPEN)SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME));
00819     hOldBrush =(HBRUSH)SelectObject(hDC,GetSysColorBrush(COLOR_BTNFACE));
00820     SetBkMode(hDC, TRANSPARENT);
00821 
00822     if ((dwStyle & 0x000f) == BS_DEFPUSHBUTTON)
00823     {
00824         Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
00825         InflateRect( &rc, -1, -1 );
00826     }
00827 
00828     UINT uState = DFCS_BUTTONPUSH;
00829 
00830     if (pushedState)
00831     {
00832       if ( (dwStyle & 0x000f) == BS_DEFPUSHBUTTON )
00833         uState |= DFCS_FLAT;
00834       else
00835         uState |= DFCS_PUSHED;
00836     }
00837 
00838     if (dwStyle & BS_FLAT) uState |= DFCS_FLAT;
00839 
00840     DrawFrameControl( hDC, &rc, DFC_BUTTON, uState );
00841     InflateRect( &rc, -2, -2 );
00842 
00843     focus_rect = rc;
00844 
00845     if (pushedState)
00846     {
00847       rc.left += 2;  /* To position the text down and right */
00848       rc.top  += 2;
00849     }
00850 
00851 
00852     /* draw button label, if any:
00853      *
00854      * In win9x we don't show text if there is a bitmap or icon.
00855      * I don't know about win31 so I leave it as it was for win31.
00856      * Dennis Björklund 12 Jul, 99
00857      */
00858     textLen = GetWindowTextLengthA(hwnd);
00859     if ((textLen > 0) && (!(dwStyle & (BS_ICON|BS_BITMAP))))
00860     {
00861         INT format = BUTTON_GetTextFormat(dwStyle,GetWindowLongA(hwnd,GWL_EXSTYLE),DT_CENTER,DT_VCENTER);
00862 
00863         textLen++;
00864         text = (char*)malloc(textLen);
00865         GetWindowTextA(hwnd,text,textLen);
00866 
00867         if (dwStyle & WS_DISABLED) DrawDisabledText(hDC,text,&rc,format); else
00868         {
00869             SetTextColor(hDC,GetSysColor(COLOR_BTNTEXT));
00870             DrawTextA(hDC,text,-1,&rc,format);
00871             /* do we have the focus?
00872              * Win9x draws focus last with a size prop. to the button
00873              */
00874         }
00875         free(text);
00876     }
00877     if ( ((dwStyle & BS_ICON) || (dwStyle & BS_BITMAP) ) &&
00878          (infoPtr->hImage != 0) )
00879     {
00880         int yOffset, xOffset;
00881         int imageWidth, imageHeight;
00882 
00883         /*
00884          * We extract the size of the image from the handle.
00885          */
00886         if (dwStyle & BS_ICON)
00887         {
00888             ICONINFO iconInfo;
00889             BITMAP   bm;
00890 
00891             GetIconInfo((HICON)infoPtr->hImage,&iconInfo);
00892             if (iconInfo.hbmColor)
00893             {
00894               GetObjectA(iconInfo.hbmColor,sizeof(BITMAP),&bm);
00895               imageWidth  = bm.bmWidth;
00896               imageHeight = bm.bmHeight;
00897             } else
00898             {
00899               GetObjectA(iconInfo.hbmMask,sizeof(BITMAP),&bm);
00900               imageWidth  = bm.bmWidth;
00901               imageHeight = bm.bmHeight/2;
00902             }
00903 
00904             if (iconInfo.hbmColor) DeleteObject(iconInfo.hbmColor);
00905             if (iconInfo.hbmMask) DeleteObject(iconInfo.hbmMask);
00906 
00907         }
00908         else
00909         {
00910             BITMAP   bm;
00911 
00912             GetObjectA (infoPtr->hImage, sizeof(BITMAP), &bm);
00913 
00914             imageWidth  = bm.bmWidth;
00915             imageHeight = bm.bmHeight;
00916         }
00917 
00918         /* Center the bitmap */
00919         xOffset = (((rc.right - rc.left) - 2*xBorderOffset) - imageWidth ) / 2;
00920         yOffset = (((rc.bottom - rc.top) - 2*yBorderOffset) - imageHeight) / 2;
00921 
00922         /* If the image is too big for the button then create a region*/
00923         if(xOffset < 0 || yOffset < 0)
00924         {
00925             HRGN hBitmapRgn = 0;
00926             hBitmapRgn = CreateRectRgn(
00927                 rc.left + xBorderOffset, rc.top +yBorderOffset,
00928                 rc.right - xBorderOffset, rc.bottom - yBorderOffset);
00929             SelectClipRgn(hDC, hBitmapRgn);
00930             DeleteObject(hBitmapRgn);
00931         }
00932 
00933         /* Let minimum 1 space from border */
00934         xOffset++, yOffset++;
00935 
00936         /*
00937          * Draw the image now.
00938          */
00939         if (dwStyle & BS_ICON)
00940         {
00941             DrawIcon(hDC,
00942                 rc.left + xOffset, rc.top + yOffset,
00943                      (HICON)infoPtr->hImage);
00944         }
00945         else
00946         {
00947             HDC hdcMem;
00948 
00949             hdcMem = CreateCompatibleDC (hDC);
00950             SelectObject (hdcMem, (HBITMAP)infoPtr->hImage);
00951             BitBlt(hDC,
00952                    rc.left + xOffset,
00953                    rc.top + yOffset,
00954                    imageWidth, imageHeight,
00955                    hdcMem, 0, 0, SRCCOPY);
00956 
00957             DeleteDC (hdcMem);
00958         }
00959 
00960         if(xOffset < 0 || yOffset < 0)
00961         {
00962             SelectClipRgn(hDC, 0);
00963         }
00964     }
00965 
00966     SelectObject( hDC, hOldPen );
00967     SelectObject( hDC, hOldBrush );
00968 
00969     if ((infoPtr->state & BUTTON_HASFOCUS) && IsWindowEnabled(hwnd))
00970     {
00971         InflateRect( &focus_rect, -1, -1 );
00972         DrawFocusRect( hDC, &focus_rect );
00973     }
00974 }
00975 
00976 
00977 static void DrawDisabledText(HDC hdc,char* text,RECT* rtext,UINT format)
00978 {
00979   COLORREF textColor = (GetSysColor(COLOR_GRAYTEXT) == GetBkColor(hdc)) ? COLOR_BTNTEXT:COLOR_GRAYTEXT;
00980   RECT rect = *rtext;
00981   COLORREF oldMode;
00982 
00983   //CB: bug in Open32 DrawText: underscore is always black! -> two black lines!
00984   SetTextColor(hdc,GetSysColor(COLOR_3DHILIGHT));
00985   DrawTextA(hdc,text,-1,&rect,format);
00986   SetTextColor(hdc,GetSysColor(COLOR_GRAYTEXT));
00987   oldMode = SetBkMode(hdc,TRANSPARENT);
00988   OffsetRect(&rect,-1,-1);
00989   DrawTextA(hdc,text,-1,&rect,format);
00990   SetBkMode(hdc,oldMode);
00991 }
00992 
00993 /**********************************************************************
00994  *       Check Box & Radio Button Functions
00995  */
00996 
00997 static void CB_Paint(HWND hwnd,HDC hDC,WORD action)
00998 {
00999     BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
01000     DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
01001     RECT rbox, rtext, client;
01002     HBRUSH hBrush, hOldBrush;
01003     HPEN hPen, hOldPen;
01004     COLORREF colour;
01005     int textLen, delta;
01006     char* text = NULL;
01007 
01008     /*
01009      * if the button has a bitmap/icon, draw a normal pushbutton
01010      * instead of a radion button.
01011      */
01012     if (infoPtr->hImage != 0)
01013     {
01014         BOOL bHighLighted = ((infoPtr->state & BUTTON_HIGHLIGHTED) ||
01015                              (infoPtr->state & BUTTON_CHECKED));
01016 
01017         BUTTON_DrawPushButton(hwnd,
01018                               hDC,
01019                               action,
01020                               bHighLighted);
01021         return;
01022     }
01023 
01024     textLen = 0;
01025     GetClientRect(hwnd, &client);
01026     rbox = rtext = client;
01027 
01028     if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
01029 
01030 #ifdef __WIN32OS2__
01031     //(Auto)Check, (Auto)Radio & (Auto)3State buttons send WM_CTLCOLORSTATIC
01032     //instead of WM_CTLCOLORBTN (verified in NT4)
01033     hBrush = SendMessageW( GetParent(hwnd), WM_CTLCOLORSTATIC, hDC, (LPARAM)hwnd );
01034     if (!hBrush) /* did the app forget to call defwindowproc ? */
01035         hBrush = DefWindowProcW( GetParent(hwnd), WM_CTLCOLORSTATIC, hDC, (LPARAM)hwnd );
01036 #endif
01037 
01038     if (dwStyle & BS_LEFTTEXT)
01039     {
01040         /* magic +4 is what CTL3D expects */
01041 
01042         rtext.right -= checkBoxWidth + 4;
01043         //CB: space for focus rect
01044         rtext.left++;
01045         rtext.right++;
01046         rbox.left = rbox.right - checkBoxWidth;
01047     }
01048     else
01049     {
01050         rtext.left += checkBoxWidth + 4;
01051         rbox.right = checkBoxWidth;
01052     }
01053 
01054       /* Draw the check-box bitmap */
01055 
01056     textLen = GetWindowTextLengthA(hwnd);
01057     if (textLen > 0)
01058     {
01059       textLen++;
01060       text = (char*)malloc(textLen);
01061       GetWindowTextA(hwnd,text,textLen);
01062     }
01063     if ((action == ODA_DRAWENTIRE) || (action == ODA_SELECT))
01064     {
01065         UINT state;
01066 
01067         /* Since WM_ERASEBKGND does nothing, first prepare background */
01068         if (action == ODA_SELECT) FillRect( hDC, &rbox, hBrush );
01069         else FillRect( hDC, &client, hBrush );
01070 
01071         if (((dwStyle & 0x0f) == BS_RADIOBUTTON) ||
01072             ((dwStyle & 0x0f) == BS_AUTORADIOBUTTON)) state = DFCS_BUTTONRADIO;
01073         else if (infoPtr->state & BUTTON_3STATE) state = DFCS_BUTTON3STATE;
01074         else state = DFCS_BUTTONCHECK;
01075 
01076         if (infoPtr->state & (BUTTON_CHECKED | BUTTON_3STATE)) state |= DFCS_CHECKED;
01077 
01078         if (infoPtr->state & BUTTON_HIGHLIGHTED) state |= DFCS_PUSHED;
01079 
01080         if (dwStyle & WS_DISABLED) state |= DFCS_INACTIVE;
01081 
01082         if (dwStyle & BS_FLAT) state |= DFCS_FLAT;
01083 
01084         DrawFrameControl( hDC, &rbox, DFC_BUTTON, state );
01085 
01086         if( text && action != ODA_SELECT )
01087         {
01088           INT format = BUTTON_GetTextFormat(dwStyle,GetWindowLongA(hwnd,GWL_EXSTYLE),DT_TOP,DT_VCENTER);
01089 
01090           if (dwStyle & WS_DISABLED) DrawDisabledText(hDC,text,&rtext,format);
01091           else DrawTextA(hDC,text,-1,&rtext,format);
01092         }
01093     }
01094 
01095     if ((action == ODA_FOCUS) ||
01096         ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS) && IsWindowEnabled(hwnd)))
01097     {
01098         /* again, this is what CTL3D expects */
01099 
01100         SetRectEmpty(&rbox);
01101         if(textLen > 0)
01102           DrawTextA(hDC,text,-1,&rbox,DT_SINGLELINE | DT_CALCRECT);
01103         textLen = rbox.bottom - rbox.top;
01104         delta = ((rtext.bottom - rtext.top) - textLen)/2;
01105         rbox.bottom = (rbox.top = rtext.top + delta - 1) + textLen + 2;
01106         textLen = rbox.right - rbox.left;
01107         rbox.right = (rbox.left += --rtext.left) + textLen + 2;
01108         IntersectRect(&rbox, &rbox, &rtext);
01109         DrawFocusRect( hDC, &rbox );
01110     }
01111     if (text) free(text);
01112 }
01113 
01114 
01115 /**********************************************************************
01116  *       BUTTON_CheckAutoRadioButton
01117  *
01118  * wndPtr is checked, uncheck every other auto radio button in group
01119  */
01120 static void BUTTON_CheckAutoRadioButton(HWND hwnd)
01121 {
01122     DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
01123     HWND parent, sibling, start;
01124 
01125     if (!(dwStyle & WS_CHILD)) return;
01126     parent = GetParent(hwnd);
01127     /* assure that starting control is not disabled or invisible */
01128     //start = sibling = GetNextDlgGroupItem( parent, hwnd, TRUE );
01129     //@YD: bugfix
01130     //CB: doesn't work!
01131     start = sibling = GetNextDlgGroupItem( parent, hwnd, FALSE );
01132     do
01133     {
01134         if (!sibling) break;
01135         if ((hwnd != sibling) &&
01136             ((GetWindowLongA(sibling,GWL_STYLE) & 0x0f) == BS_AUTORADIOBUTTON))
01137             SendMessageA( sibling, BM_SETCHECK, BUTTON_UNCHECKED, 0 );
01138         sibling = GetNextDlgGroupItem( parent, sibling, FALSE );
01139     } while (sibling != start);
01140 }
01141 
01142 
01143 /**********************************************************************
01144  *       Group Box Functions
01145  */
01146 
01147 static void GB_Paint(HWND hwnd,HDC hDC,WORD action)
01148 {
01149     BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
01150     DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
01151     RECT rc, rcFrame;
01152     TEXTMETRICA tm;
01153     INT textLen;
01154     char* text;
01155     HBRUSH hbr;
01156 
01157     if (action != ODA_DRAWENTIRE) return;
01158 
01159     /* GroupBox acts like static control, so it sends CTLCOLORSTATIC */
01160     hbr = GetControlBrush( hwnd, hDC, CTLCOLOR_STATIC );
01161 
01162     GetClientRect(hwnd,&rc);
01163 
01164     rcFrame = rc;
01165 
01166     if (infoPtr->hFont)
01167        SelectObject (hDC, infoPtr->hFont);
01168     GetTextMetricsA (hDC, &tm);
01169     rcFrame.top += (tm.tmHeight / 2) - 1;
01170     DrawEdge (hDC, &rcFrame, EDGE_ETCHED, BF_RECT);
01171 
01172     textLen = GetWindowTextLengthA(hwnd);
01173     if (textLen > 0)
01174     {
01175       INT format = BUTTON_GetTextFormat(dwStyle,GetWindowLongA(hwnd,GWL_EXSTYLE),DT_LEFT,DT_TOP) | DT_NOCLIP | DT_SINGLELINE;
01176 
01177       textLen++;
01178       text = (char*)malloc(textLen);
01179       GetWindowTextA(hwnd,text,textLen);
01180       if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
01181       rc.left += 10;
01182 
01183       if (dwStyle & WS_DISABLED) {
01184            DrawDisabledText(hDC,text,&rc,format); 
01185       }
01186       else
01187       {
01188            SetTextColor(hDC,GetSysColor(COLOR_BTNTEXT));
01189            DrawTextA(hDC,text,-1,&rc,format);
01190       }
01191 
01192       free(text);
01193     }
01194 }
01195 
01196 
01197 /**********************************************************************
01198  *       User Button Functions
01199  */
01200 
01201 static void UB_Paint(HWND hwnd,HDC hDC,WORD action)
01202 {
01203     BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
01204     DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
01205     RECT rc;
01206     HBRUSH hBrush;
01207     if (action == ODA_SELECT) return;
01208 
01209     GetClientRect(hwnd,&rc);
01210 
01211     if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
01212     hBrush = GetControlBrush( hwnd, hDC, CTLCOLOR_BTN );
01213 
01214     FillRect( hDC, &rc, hBrush );
01215     if ((action == ODA_FOCUS) ||
01216         ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS) && IsWindowEnabled(hwnd)))
01217     {
01218       DrawFocusRect( hDC, &rc );
01219       InflateRect(&rc,-1,-1);
01220     }
01221 }
01222 
01223 
01224 /**********************************************************************
01225  *       Ownerdrawn Button Functions
01226  */
01227 
01228 static void OB_Paint(HWND hwnd,HDC hDC,WORD action)
01229 {
01230     BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
01231     DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
01232     DRAWITEMSTRUCT dis;
01233 
01234     dis.CtlType    = ODT_BUTTON;
01235     dis.CtlID      = GetWindowLongA(hwnd,GWL_ID);
01236     dis.itemID     = 0;
01237     dis.itemAction = action;
01238     dis.itemState  = ((infoPtr->state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0) |
01239                      ((infoPtr->state & BUTTON_HIGHLIGHTED) ? ODS_SELECTED : 0) |
01240                      ((dwStyle & WS_DISABLED) ? ODS_DISABLED : 0);
01241     dis.hwndItem   = hwnd;
01242     dis.hDC        = hDC;
01243     dis.itemData   = 0;
01244     GetClientRect( hwnd, &dis.rcItem );
01245 
01246     SetBkColor( hDC, GetSysColor( COLOR_BTNFACE ) );
01247 
01248     dprintf(("OWNERDRAW button %x, enabled %d", hwnd, !(dwStyle & WS_DISABLED)));
01249     SendMessageA( GetParent(hwnd), WM_DRAWITEM,
01250                     GetWindowLongA(hwnd,GWL_ID), (LPARAM)&dis );
01251 }
01252 
01253 BOOL BUTTON_Register()
01254 {
01255     WNDCLASSA wndClass;
01256 
01257 //SvL: Don't check this now
01258 //    if (GlobalFindAtomA(BUTTONCLASSNAME)) return FALSE;
01259 
01260     ZeroMemory(&wndClass,sizeof(WNDCLASSA));
01261     wndClass.style         = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW | CS_PARENTDC | CS_DBLCLKS;
01262     wndClass.lpfnWndProc   = (WNDPROC)ButtonWndProc;
01263     wndClass.cbClsExtra    = 0;
01264     wndClass.cbWndExtra    = sizeof(BUTTONINFO);
01265     wndClass.hCursor       = LoadCursorA(0,IDC_ARROWA);
01266     wndClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
01267     wndClass.lpszClassName = BUTTONCLASSNAME;
01268 
01269     return RegisterClassA(&wndClass);
01270 }
01271 
01272 BOOL BUTTON_Unregister()
01273 {
01274     if (GlobalFindAtomA(BUTTONCLASSNAME))
01275         return UnregisterClassA(BUTTONCLASSNAME,(HINSTANCE)NULL);
01276     else return FALSE;
01277 }

Generated on Wed Jan 23 23:17:25 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001