]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/button.cpp
Unicode fixes. Appears that this may be the last before wxMSW will link
[wxWidgets.git] / src / msw / button.cpp
index fbfef488f8053e27b7fc3ff0ab355dceb3fb0e6c..4a5a7bbf4ea151a61d3130d6cb39e0b9df5c3a3a 100644 (file)
 // Created:     04/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) Julian Smart and Markus Holzem
-// Licence:    wxWindows license
+// Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
 #ifdef __GNUG__
-#pragma implementation "button.h"
+    #pragma implementation "button.h"
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
-#include "wx/button.h"
+    #include "wx/button.h"
+    #include "wx/brush.h"
 #endif
 
 #include "wx/msw/private.h"
 
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
 #if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl)
+    IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl)
 #endif
 
-#define BUTTON_HEIGHT_FACTOR (EDIT_CONTROL_FACTOR * 1.1)
+// this macro tries to adjust the default button height to a reasonable value
+// using the char height as the base
+#define BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cy) (11*EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)/10)
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// creation/destruction
+// ----------------------------------------------------------------------------
+
+bool wxButton::Create(wxWindow *parent,
+                      wxWindowID id,
+                      const wxString& label,
+                      const wxPoint& pos,
+                      const wxSize& size,
+                      long style,
+                      const wxValidator& validator,
+                      const wxString& name)
+{
+    if ( !CreateBase(parent, id, pos, size, style, name) )
+        return FALSE;
 
-// Buttons
+    SetValidator(validator);
 
-bool wxButton::MSWCommand(const WXUINT param, const WXWORD id)
-{
-  if (param == BN_CLICKED)
-  {
-    wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, id);
-    event.SetEventObject(this);
-    ProcessCommand(event);
-    return TRUE;
-  }
-  else return FALSE;
-}
+    parent->AddChild((wxButton *)this);
 
-bool wxButton::Create(wxWindow *parent, const wxWindowID id, const wxString& label,
-           const wxPoint& pos,
-           const wxSize& size, const long style,
-           const wxValidator& validator,
-           const wxString& name)
-{
-  SetName(name);
-  SetValidator(validator);
-
-  parent->AddChild((wxButton *)this);
-  m_backgroundColour = parent->GetDefaultBackgroundColour() ;
-  m_foregroundColour = parent->GetDefaultForegroundColour() ;
-
-  m_windowStyle = (long&)style;
-
-  int x = pos.x;
-  int y = pos.y;
-  int width = size.x;
-  int height = size.y;
-
-  if (id == -1)
-    m_windowId = NewControlId();
-  else
-    m_windowId = id;
-
-  DWORD exStyle = MakeExtendedStyle(m_windowStyle);
-  HWND wx_button =
-    CreateWindowEx(exStyle, "BUTTON", label, BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD,
-                    0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId,
-                    wxGetInstance(), NULL);
-
-#if CTL3D
-//  if (!(GetParent()->GetWindowStyleFlag() & wxUSER_COLOURS))
-//    Ctl3dSubclassCtl(wx_button);
-#endif
+    m_backgroundColour = parent->GetBackgroundColour() ;
+    m_foregroundColour = parent->GetForegroundColour() ;
 
-  m_hWnd = (WXHWND)wx_button;
+    m_hWnd = (WXHWND)CreateWindowEx
+                     (
+                      MakeExtendedStyle(m_windowStyle),
+                      _T("BUTTON"),
+                      label,
+                      WS_VISIBLE | WS_TABSTOP | WS_CHILD,
+                      0, 0, 0, 0, 
+                      GetWinHwnd(parent),
+                      (HMENU)m_windowId,
+                      wxGetInstance(),
+                      NULL
+                     );
 
-  // Subclass again for purposes of dialog editing mode
-  SubclassWin((WXHWND)wx_button);
+    // Subclass again for purposes of dialog editing mode
+    SubclassWin(m_hWnd);
 
-  SetFont(* parent->GetFont());
+    SetFont(parent->GetFont());
 
-  SetSize(x, y, width, height);
-  ShowWindow(wx_button, SW_SHOW);
+    SetSize(pos.x, pos.y, size.x, size.y);
 
-  return TRUE;
+    return TRUE;
 }
 
-void wxButton::SetSize(const int x, const int y, const int width, const int height, const int sizeFlags)
+wxButton::~wxButton()
 {
-  int currentX, currentY;
-  GetPosition(&currentX, &currentY);
-  int x1 = x;
-  int y1 = y;
-  if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
-    x1 = currentX;
-  if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
-    y1 = currentY;
-
-  int actualWidth = width;
-  int actualHeight = height;
-  int ww, hh;
-  GetSize(&ww, &hh);
-
-  float current_width;
-  float cyf;
-  char buf[300];
-  GetWindowText((HWND) GetHWND(), buf, 300);
-  GetTextExtent(buf, &current_width, &cyf,NULL,NULL,GetFont());
-
-  // If we're prepared to use the existing width, then...
-  if (width == -1 && ((sizeFlags & wxSIZE_AUTO_WIDTH) != wxSIZE_AUTO_WIDTH))
-    actualWidth = ww;
-  else if (width == -1)
-  {
-    int cx;
-    int cy;
-    wxGetCharSize(GetHWND(), &cx, &cy,GetFont());
-    actualWidth = (int)(current_width + 3*cx) ;
-  }
-  
-  // If we're prepared to use the existing height, then...
-  if (height == -1 && ((sizeFlags & wxSIZE_AUTO_HEIGHT) != wxSIZE_AUTO_HEIGHT))
-    actualHeight = hh;
-  else if (height == -1)
-  {
-    actualHeight = (int)(cyf*BUTTON_HEIGHT_FACTOR) ;
-  }
-
-  MoveWindow((HWND) GetHWND(), x1, y1, actualWidth, actualHeight, TRUE);
-
-/*
-  if (!((width == -1) && (height == -1)))
-  {
-#if WXWIN_COMPATIBILITY
-    GetEventHandler()->OldOnSize(width, height);
-#else
-    wxSizeEvent event(wxSize(width, height), m_windowId);
-    event.eventObject = this;
-    GetEventHandler()->ProcessEvent(event);
-#endif
-  }
-*/
+    wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
+    if ( panel )
+    {
+        if ( panel->GetDefaultItem() == this )
+        {
+            // don't leave the panel with invalid default item
+            panel->SetDefaultItem(NULL);
+        }
+    }
 }
 
-void wxButton::SetDefault(void)
+// ----------------------------------------------------------------------------
+// size management including autosizing
+// ----------------------------------------------------------------------------
+
+void wxButton::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 {
-  wxWindow *parent = (wxWindow *)GetParent();
-  if (parent)
-    parent->SetDefaultItem(this);
-
-  if (parent)
-  {
-    SendMessage((HWND) parent->GetHWND(), DM_SETDEFID, m_windowId, 0L);
-  }
+    int currentX, currentY;
+    GetPosition(&currentX, &currentY);
+    int x1 = x;
+    int y1 = y;
+    if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+        x1 = currentX;
+    if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+        y1 = currentY;
+
+    AdjustForParentClientOrigin(x1, y1, sizeFlags);
+
+    int actualWidth = width;
+    int actualHeight = height;
+    int ww, hh;
+    GetSize(&ww, &hh);
+
+    int current_width;
+    int cyf;
+    wxString buf = wxGetWindowText(GetHWND());
+    GetTextExtent(buf, &current_width, &cyf, NULL, NULL, &GetFont());
+
+    // If we're prepared to use the existing width, then...
+    if (width == -1 && ((sizeFlags & wxSIZE_AUTO_WIDTH) != wxSIZE_AUTO_WIDTH))
+    {
+        actualWidth = ww;
+    }
+    else if (width == -1)
+    {
+        int cx;
+        int cy;
+        wxGetCharSize(GetHWND(), &cx, &cy, & this->GetFont());
+        actualWidth = (int)(current_width + 3*cx) ;
+    }
+
+    // If we're prepared to use the existing height, then...
+    if (height == -1 && ((sizeFlags & wxSIZE_AUTO_HEIGHT) != wxSIZE_AUTO_HEIGHT))
+    {
+        actualHeight = hh;
+    }
+    else if (height == -1)
+    {
+        actualHeight = BUTTON_HEIGHT_FROM_CHAR_HEIGHT(cyf);
+    }
+
+    MoveWindow(GetHwnd(), x1, y1, actualWidth, actualHeight, TRUE);
 }
 
-wxString wxButton::GetLabel(void) const
+void wxButton::SetDefault()
 {
-    GetWindowText((HWND) GetHWND(), wxBuffer, 300);
-    return wxString(wxBuffer);
+    wxWindow *parent = GetParent();
+    wxPanel *panel = wxDynamicCast(parent, wxPanel);
+    if ( panel )
+        panel->SetDefaultItem(this);
+
+    if ( parent )
+    {
+        SendMessage(GetWinHwnd(parent), DM_SETDEFID, m_windowId, 0L);
+    }
+
+    SendMessage(GetHwnd(), BM_SETSTYLE, BS_DEFPUSHBUTTON, 1L);
 }
 
-void wxButton::SetLabel(const wxString& label)
+// ----------------------------------------------------------------------------
+// helpers
+// ----------------------------------------------------------------------------
+
+bool wxButton::SendClickEvent()
 {
-  SetWindowText((HWND) GetHWND(), (const char *) label);
+    wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
+    event.SetEventObject(this);
+
+    return ProcessCommand(event);
 }
 
-WXHBRUSH wxButton::OnCtlColor(const WXHDC pDC, const WXHWND pWnd, const WXUINT nCtlColor,
-                       WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
+void wxButton::Command(wxCommandEvent & event)
 {
-/*
-    WXHBRUSH hBrush = (WXHBRUSH) MSWDefWindowProc(message, wParam, lParam);
-//    ::SetTextColor((HDC) pDC, GetSysColor(COLOR_BTNTEXT));
-    ::SetTextColor((HDC) pDC, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(),
-        GetForegroundColour().Blue()));
-
-       return hBrush;
-*/
-  // This doesn't in fact seem to make any difference at all - buttons are always
-  // the same colour.
-  ::SetBkColor((HDC) pDC, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
-  ::SetTextColor((HDC) pDC, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
+    ProcessCommand(event);
+}
 
-  wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
+// ----------------------------------------------------------------------------
+// event/message handlers
+// ----------------------------------------------------------------------------
 
-  // Note that this will be cleaned up in wxApp::OnIdle, if backgroundBrush
-  // has a zero usage count.
-  // NOT NOW; CHANGED.
-//  backgroundBrush->RealizeResource();
-  return (WXHBRUSH) backgroundBrush->GetResourceHandle();
+bool wxButton::MSWCommand(WXUINT param, WXWORD id)
+{
+    bool processed = FALSE;
+    if ( param == BN_CLICKED || param == 1 ) // 1 for accelerator
+    {
+        processed = SendClickEvent();
+    }
+
+    return processed;
 }
 
-void wxButton::Command (wxCommandEvent & event)
+WXHBRUSH wxButton::OnCtlColor(WXHDC pDC,
+                              WXHWND pWnd,
+                              WXUINT nCtlColor,
+                              WXUINT message,
+                              WXWPARAM wParam,
+                              WXLPARAM lParam)
 {
-  ProcessCommand (event);
-}
+  wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
 
+  return (WXHBRUSH) backgroundBrush->GetResourceHandle();
+}