X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5de76427c87d8289f5c343cef16e9375056fc49f..af547d51b7494fd365ae29e048d458ff72b27056:/src/msw/combobox.cpp diff --git a/src/msw/combobox.cpp b/src/msw/combobox.cpp index b53e312577..f00c1297c9 100644 --- a/src/msw/combobox.cpp +++ b/src/msw/combobox.cpp @@ -6,7 +6,7 @@ // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -20,77 +20,89 @@ #pragma hdrstop #endif +#if wxUSE_COMBOBOX + #ifndef WX_PRECOMP -#include "wx/setup.h" +#include "wx/settings.h" #endif -#if USE_COMBOBOX - #include "wx/combobox.h" #include "wx/clipbrd.h" #include "wx/msw/private.h" -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl) -#endif bool wxComboBox::MSWCommand(WXUINT param, WXWORD WXUNUSED(id)) { - if (param == CBN_SELCHANGE) - { - wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, m_windowId); - event.SetInt(GetSelection()); - event.SetEventObject(this); - event.SetString(copystring(GetStringSelection())); - ProcessCommand(event); - delete[] event.GetString(); - return TRUE; - } - else if (param == CBN_EDITCHANGE) - { - wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId); - event.SetString(copystring(GetValue())); - ProcessCommand(event); - delete[] event.GetString(); - return TRUE; - } - else return FALSE; + switch ( param ) + { + case CBN_SELCHANGE: + if (GetSelection() > -1) + { + wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, GetId()); + event.SetInt(GetSelection()); + event.SetEventObject(this); + event.SetString(GetStringSelection()); + ProcessCommand(event); + } + break; + + case CBN_EDITCHANGE: + { + wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, GetId()); + event.SetString(GetValue()); + event.SetEventObject(this); + ProcessCommand(event); + } + break; + } + + // there is no return value for the CBN_ notifications, so always return + // FALSE from here to pass the message to DefWindowProc() + return FALSE; } bool wxComboBox::Create(wxWindow *parent, wxWindowID id, - const wxString& value, - const wxPoint& pos, - const wxSize& size, - int n, const wxString choices[], - long style, - const wxValidator& validator, - const wxString& name) + const wxString& value, + const wxPoint& pos, + const wxSize& size, + int n, const wxString choices[], + long style, + const wxValidator& validator, + const wxString& name) { SetName(name); +#if wxUSE_VALIDATORS SetValidator(validator); +#endif // wxUSE_VALIDATORS if (parent) parent->AddChild(this); - SetBackgroundColour(parent->GetDefaultBackgroundColour()) ; - SetForegroundColour(parent->GetDefaultForegroundColour()) ; - no_strings = n; +// SetBackgroundColour(parent->GetBackgroundColour()) ; + + // A choice/combobox normally has a white background (or other, depending + // on global settings) rather than inheriting the parent's background colour. + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOW)); + + SetForegroundColour(parent->GetForegroundColour()) ; m_windowStyle = style; if ( id == -1 ) - m_windowId = (int)NewControlId(); + m_windowId = (int)NewControlId(); else - m_windowId = id; + m_windowId = id; int x = pos.x; int y = pos.y; int width = size.x; int height = size.y; - long msStyle = WS_CHILD | WS_HSCROLL | WS_VSCROLL - | WS_TABSTOP | WS_VISIBLE | CBS_NOINTEGRALHEIGHT; + long msStyle = WS_CHILD | WS_TABSTOP | WS_VISIBLE | + WS_VSCROLL | WS_HSCROLL | CBS_AUTOHSCROLL | CBS_NOINTEGRALHEIGHT; + if (m_windowStyle & wxCB_READONLY) msStyle |= CBS_DROPDOWNLIST; - else if (m_windowStyle & wxCB_SIMPLE) // A list (shown always) and edit control - msStyle |= CBS_SIMPLE; + else if (m_windowStyle & wxCB_SIMPLE) + msStyle |= CBS_SIMPLE; // A list (shown always) and edit control else msStyle |= CBS_DROPDOWN; @@ -102,16 +114,18 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, // Even with extended styles, need to combine with WS_BORDER // for them to look right. - if (want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) || - (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER)) + if ( want3D || wxStyleHasBorder(m_windowStyle) ) msStyle |= WS_BORDER; - HWND wx_combo = CreateWindowEx(exStyle, "COMBOBOX", NULL, + m_hWnd = (WXHWND)::CreateWindowEx(exStyle, wxT("COMBOBOX"), NULL, msStyle, 0, 0, 0, 0, (HWND) parent->GetHWND(), (HMENU)m_windowId, wxGetInstance(), NULL); + + wxCHECK_MSG( m_hWnd, FALSE, wxT("Failed to create combobox") ); + /* -#if CTL3D +#if wxUSE_CTL3D if (want3D) { Ctl3dSubclassCtl(wx_combo); @@ -120,30 +134,27 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, #endif */ - m_hWnd = (WXHWND)wx_combo; - // Subclass again for purposes of dialog editing mode - SubclassWin((WXHWND)wx_combo); + SubclassWin(m_hWnd); - SetFont(* parent->GetFont()); + SetFont(parent->GetFont()); int i; for (i = 0; i < n; i++) - SendMessage(wx_combo, CB_INSERTSTRING, i, (LONG)(const char *)choices[i]); - SendMessage(wx_combo, CB_SETCURSEL, i, 0); + { + Append(choices[i]); + } + + SetSelection(i); SetSize(x, y, width, height); - if ( value != "" ) - SetWindowText(wx_combo, (const char *)value); + if ( !value.IsEmpty() ) + { + SetValue(value); + } return TRUE; } -wxString wxComboBox::GetValue(void) const -{ - GetWindowText((HWND) GetHWND(), wxBuffer, 500); - return wxString(wxBuffer); -} - void wxComboBox::SetValue(const wxString& value) { // If newlines are denoted by just 10, must stick 13 in front. @@ -157,7 +168,7 @@ void wxComboBox::SetValue(const wxString& value) } if (singletons > 0) { - char *tmp = new char[len + singletons + 1]; + wxChar *tmp = new wxChar[len + singletons + 1]; int j = 0; for (i = 0; i < len; i ++) { @@ -170,43 +181,43 @@ void wxComboBox::SetValue(const wxString& value) j ++; } tmp[j] = 0; - SetWindowText((HWND) GetHWND(), tmp); + SetWindowText(GetHwnd(), tmp); delete[] tmp; } else - SetWindowText((HWND) GetHWND(), (const char *)value); + SetWindowText(GetHwnd(), value); } // Clipboard operations -void wxComboBox::Copy(void) +void wxComboBox::Copy() { - HWND hWnd = (HWND) GetHWND(); + HWND hWnd = GetHwnd(); SendMessage(hWnd, WM_COPY, 0, 0L); } -void wxComboBox::Cut(void) +void wxComboBox::Cut() { - HWND hWnd = (HWND) GetHWND(); + HWND hWnd = GetHwnd(); SendMessage(hWnd, WM_CUT, 0, 0L); } -void wxComboBox::Paste(void) +void wxComboBox::Paste() { - HWND hWnd = (HWND) GetHWND(); + HWND hWnd = GetHwnd(); SendMessage(hWnd, WM_PASTE, 0, 0L); } void wxComboBox::SetEditable(bool editable) { // Can't implement in MSW? -// HWND hWnd = (HWND) GetHWND(); +// HWND hWnd = GetHwnd(); // SendMessage(hWnd, EM_SETREADONLY, (WPARAM)!editable, (LPARAM)0L); } void wxComboBox::SetInsertionPoint(long pos) { /* - HWND hWnd = (HWND) GetHWND(); + HWND hWnd = GetHwnd(); #ifdef __WIN32__ SendMessage(hWnd, EM_SETSEL, pos, pos); SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0); @@ -218,7 +229,7 @@ void wxComboBox::SetInsertionPoint(long pos) */ } -void wxComboBox::SetInsertionPointEnd(void) +void wxComboBox::SetInsertionPointEnd() { /* long pos = GetLastPosition(); @@ -226,26 +237,26 @@ void wxComboBox::SetInsertionPointEnd(void) */ } -long wxComboBox::GetInsertionPoint(void) const +long wxComboBox::GetInsertionPoint() const { /* - DWORD Pos=(DWORD)SendMessage((HWND) GetHWND(), EM_GETSEL, 0, 0L); + DWORD Pos=(DWORD)SendMessage(GetHwnd(), EM_GETSEL, 0, 0L); return Pos&0xFFFF; */ return 0; } -long wxComboBox::GetLastPosition(void) const +long wxComboBox::GetLastPosition() const { /* - HWND hWnd = (HWND) GetHWND(); + HWND hWnd = GetHwnd(); // Will always return a number > 0 (according to docs) int noLines = (int)SendMessage(hWnd, EM_GETLINECOUNT, (WPARAM)0, (LPARAM)0L); // This gets the char index for the _beginning_ of the last line int charIndex = (int)SendMessage(hWnd, EM_LINEINDEX, (WPARAM)(noLines-1), (LPARAM)0L); - + // Get number of characters in the last line. We'll add this to the character // index for the last line, 1st position. int lineLength = (int)SendMessage(hWnd, EM_LINELENGTH, (WPARAM)charIndex, (LPARAM)0L); @@ -257,11 +268,11 @@ long wxComboBox::GetLastPosition(void) const void wxComboBox::Replace(long from, long to, const wxString& value) { -#if USE_CLIPBOARD - HWND hWnd = (HWND) GetHWND(); +#if wxUSE_CLIPBOARD + HWND hWnd = GetHwnd(); long fromChar = from; long toChar = to; - + // Set selection and remove it #ifdef __WIN32__ SendMessage(hWnd, CB_SETEDITSEL, fromChar, toChar); @@ -271,7 +282,7 @@ void wxComboBox::Replace(long from, long to, const wxString& value) SendMessage(hWnd, WM_CUT, (WPARAM)0, (LPARAM)0); // Now replace with 'value', by pasting. - wxSetClipboardData(wxDF_TEXT, (wxObject *)(const char *)value, 0, 0); + wxSetClipboardData(wxDF_TEXT, (wxObject *)(const wxChar *)value, 0, 0); // Paste into edit control SendMessage(hWnd, WM_PASTE, (WPARAM)0, (LPARAM)0L); @@ -280,10 +291,10 @@ void wxComboBox::Replace(long from, long to, const wxString& value) void wxComboBox::Remove(long from, long to) { - HWND hWnd = (HWND) GetHWND(); + HWND hWnd = GetHwnd(); long fromChar = from; long toChar = to; - + // Cut all selected text #ifdef __WIN32__ SendMessage(hWnd, CB_SETEDITSEL, fromChar, toChar); @@ -295,7 +306,7 @@ void wxComboBox::Remove(long from, long to) void wxComboBox::SetSelection(long from, long to) { - HWND hWnd = (HWND) GetHWND(); + HWND hWnd = GetHwnd(); long fromChar = from; long toChar = to; // if from and to are both -1, it means @@ -306,7 +317,7 @@ void wxComboBox::SetSelection(long from, long to) fromChar = 0; toChar = -1; } - + #ifdef __WIN32__ SendMessage(hWnd, CB_SETEDITSEL, (WPARAM)fromChar, (LPARAM)toChar); // SendMessage(hWnd, EM_SCROLLCARET, (WPARAM)0, (LPARAM)0); @@ -316,6 +327,38 @@ void wxComboBox::SetSelection(long from, long to) #endif } +void wxComboBox::DoMoveWindow(int x, int y, int width, int height) +{ + int cx, cy; + wxGetCharSize(GetHWND(), &cx, &cy, &GetFont()); + + // what should the height of the drop down list be? we choose 10 items by + // default and also 10 items max (if we always use n, the list will never + // have vertical scrollbar) + int n = GetCount(); + if ( !n ) + n = 10; + else if ( n > 10 ) + n = 10; + + height = n * EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); + + wxControl::DoMoveWindow(x, y, width, height); +} + +wxSize wxComboBox::DoGetBestSize() const +{ + // the choice calculates the horz size correctly, but not the vertical + // component: correct it + wxSize size = wxChoice::DoGetBestSize(); + + int cx, cy; + wxGetCharSize(GetHWND(), &cx, &cy, &GetFont()); + size.y = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy); + + return size; +} + #endif - // USE_COMBOBOX + // wxUSE_COMBOBOX