]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/button.cpp
better learn the operators...
[wxWidgets.git] / src / msw / button.cpp
index 86f833762c9e4a77ecac30d891699d595b399567..24d5340b6e8a5a2fc769ae12ddc21bb86c06ed91 100644 (file)
@@ -28,6 +28,8 @@
     #pragma hdrstop
 #endif
 
+#if wxUSE_BUTTON
+
 #ifndef WX_PRECOMP
     #include "wx/button.h"
     #include "wx/brush.h"
@@ -74,13 +76,28 @@ bool wxButton::Create(wxWindow *parent,
     m_backgroundColour = parent->GetBackgroundColour();
     m_foregroundColour = parent->GetForegroundColour();
 
+    long msStyle = WS_VISIBLE | WS_TABSTOP | WS_CHILD /* | WS_CLIPSIBLINGS */ ;
+
+    if ( m_windowStyle & wxCLIP_SIBLINGS )
+        msStyle |= WS_CLIPSIBLINGS;
+
+#ifdef __WIN32__
+    if(m_windowStyle & wxBU_LEFT)
+        msStyle |= BS_LEFT;
+    if(m_windowStyle & wxBU_RIGHT)
+        msStyle |= BS_RIGHT;
+    if(m_windowStyle & wxBU_TOP)
+        msStyle |= BS_TOP;
+    if(m_windowStyle & wxBU_BOTTOM)
+        msStyle |= BS_BOTTOM;
+#endif
 
     m_hWnd = (WXHWND)CreateWindowEx
                      (
                       MakeExtendedStyle(m_windowStyle),
                       wxT("BUTTON"),
                       label,
-                      WS_VISIBLE | WS_TABSTOP | WS_CHILD,
+                      msStyle,
                       0, 0, 0, 0,
                       GetWinHwnd(parent),
                       (HMENU)m_windowId,
@@ -88,6 +105,17 @@ bool wxButton::Create(wxWindow *parent,
                       NULL
                      );
 
+    if (m_hWnd == 0)
+    {
+        wxString msg;
+#ifdef __WIN16__
+        msg.Printf(wxT("CreateWindowEx failed"));
+#else
+        msg.Printf(wxT("CreateWindowEx failed with error number %ld"), (long) GetLastError());
+#endif
+        wxFAIL_MSG(msg);
+    }
+
     // Subclass again for purposes of dialog editing mode
     SubclassWin(m_hWnd);
 
@@ -100,15 +128,6 @@ bool wxButton::Create(wxWindow *parent,
 
 wxButton::~wxButton()
 {
-    wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
-    if ( panel )
-    {
-        if ( panel->GetDefaultItem() == this )
-        {
-            // don't leave the panel with invalid default item
-            panel->SetDefaultItem(NULL);
-        }
-    }
 }
 
 // ----------------------------------------------------------------------------
@@ -138,7 +157,7 @@ wxSize wxButton::DoGetBestSize() const
 }
 
 /* static */
-wxSize wxButton::GetDefaultSize()
+wxSize wxButtonBase::GetDefaultSize()
 {
     static wxSize s_sizeBtn;
 
@@ -169,20 +188,20 @@ wxSize wxButton::GetDefaultSize()
 void wxButton::SetDefault()
 {
     wxWindow *parent = GetParent();
-    wxButton *btnOldDefault = NULL;
-    wxPanel *panel = wxDynamicCast(parent, wxPanel);
-    if ( panel )
+    wxButton *btnOldDefault;
+    if ( parent )
     {
-        btnOldDefault = panel->GetDefaultItem();
-        panel->SetDefaultItem(this);
-    }
+        wxWindow *winOldDefault = parent->SetDefaultItem(this);
+        btnOldDefault = wxDynamicCast(winOldDefault, wxButton);
 
-    if ( parent )
+        ::SendMessage(GetWinHwnd(parent), DM_SETDEFID, m_windowId, 0L);
+    }
+    else // is a button without parent really normal?
     {
-        SendMessage(GetWinHwnd(parent), DM_SETDEFID, m_windowId, 0L);
+        btnOldDefault = NULL;
     }
 
-    if ( btnOldDefault )
+    if ( btnOldDefault && btnOldDefault != this )
     {
         // remove the BS_DEFPUSHBUTTON style from the other button
         long style = GetWindowLong(GetHwndOf(btnOldDefault), GWL_STYLE);
@@ -232,13 +251,14 @@ void wxButton::Command(wxCommandEvent & event)
 // event/message handlers
 // ----------------------------------------------------------------------------
 
-bool wxButton::MSWCommand(WXUINT param, WXWORD id)
+bool wxButton::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
 {
     bool processed = FALSE;
     switch ( param )
     {
-        case 1: // means that the message came from an accelerator
-        case BN_CLICKED:
+        case 1:                     // message came from an accelerator
+        case BN_CLICKED:            // normal buttons send this
+        case BN_DOUBLECLICKED:      // owner-drawn ones also send this
             processed = SendClickEvent();
             break;
     }
@@ -256,6 +276,14 @@ long wxButton::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 
         // let the default processign take place too
     }
+    else if ( nMsg == WM_LBUTTONDBLCLK )
+    {
+        // emulate a click event to force an owner-drawn button to change its
+        // appearance - without this, it won't do it
+        (void)wxControl::MSWWindowProc(WM_LBUTTONDOWN, wParam, lParam);
+
+        // and conitnue with processing the message normally as well
+    }
 
     // let the base class do all real processing
     return wxControl::MSWWindowProc(nMsg, wParam, lParam);
@@ -338,10 +366,11 @@ bool wxButton::SetForegroundColour(const wxColour &colour)
    The button frame looks like this normally:
 
    WWWWWWWWWWWWWWWWWWB
-   W                GB
-   W                GB
-   W                GB  where W, G, B are white, grey and black pixels
-   W                GB
+   WHHHHHHHHHHHHHHHHGB  W = white       (HILIGHT)
+   WH               GB  H = light grey  (LIGHT)
+   WH               GB  G = dark grey   (SHADOW)
+   WH               GB  B = black       (DKSHADOW)
+   WH               GB
    WGGGGGGGGGGGGGGGGGB
    BBBBBBBBBBBBBBBBBBB
 
@@ -350,8 +379,9 @@ bool wxButton::SetForegroundColour(const wxColour &colour)
 
    BBBBBBBBBBBBBBBBBBB
    BWWWWWWWWWWWWWWWWBB
-   BW              GBB
-   BW              GBB
+   BWHHHHHHHHHHHHHHGBB
+   BWH             GBB
+   BWH             GBB
    BWGGGGGGGGGGGGGGGBB
    BBBBBBBBBBBBBBBBBBB
    BBBBBBBBBBBBBBBBBBB
@@ -363,6 +393,7 @@ bool wxButton::SetForegroundColour(const wxColour &colour)
    BG               GB
    BG               GB
    BG               GB
+   BG               GB
    BGGGGGGGGGGGGGGGGGB
    BBBBBBBBBBBBBBBBBBB
 */
@@ -373,9 +404,10 @@ static void DrawButtonFrame(HDC hdc, const RECT& rectBtn,
     RECT r;
     CopyRect(&r, &rectBtn);
 
-    HPEN hpenBlack = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW)),
-         hpenGrey = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)),
-         hpenWhite = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
+    HPEN hpenBlack   = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW)),
+         hpenGrey    = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)),
+         hpenLightGr = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DLIGHT)),
+         hpenWhite   = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DHILIGHT));
 
     HPEN hpenOld = (HPEN)SelectObject(hdc, hpenBlack);
 
@@ -409,6 +441,11 @@ static void DrawButtonFrame(HDC hdc, const RECT& rectBtn,
         LineTo(hdc, r.left, r.top);
         LineTo(hdc, r.right, r.top);
 
+        (void)SelectObject(hdc, hpenLightGr);
+        MoveToEx(hdc, r.left + 1, r.bottom - 2, NULL);
+        LineTo(hdc, r.left + 1, r.top + 1);
+        LineTo(hdc, r.right - 1, r.top + 1);
+
         (void)SelectObject(hdc, hpenGrey);
         MoveToEx(hdc, r.left + 1, r.bottom - 1, NULL);
         LineTo(hdc, r.right - 1, r.bottom - 1);
@@ -417,6 +454,7 @@ static void DrawButtonFrame(HDC hdc, const RECT& rectBtn,
 
     (void)SelectObject(hdc, hpenOld);
     DeleteObject(hpenWhite);
+    DeleteObject(hpenLightGr);
     DeleteObject(hpenGrey);
     DeleteObject(hpenBlack);
 }
@@ -482,3 +520,6 @@ bool wxButton::MSWOnDraw(WXDRAWITEMSTRUCT *wxdis)
 }
 
 #endif // __WIN32__
+
+#endif // wxUSE_BUTTON
+