From 71e57cd6506760f7ca0e3195a5ecf99d78a77be9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 7 Feb 2004 19:26:22 +0000 Subject: [PATCH] use new style creation (MSWCreateControl() and MSWGetStyle()); adjust the drop down list height after appending/inserting/deleting items git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@25578 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/choice.h | 15 +++++++ include/wx/msw/combobox.h | 3 ++ src/msw/choice.cpp | 77 +++++++++++++++++++++++++++-------- src/msw/combobox.cpp | 84 +++++++++++++++++++-------------------- 4 files changed, 119 insertions(+), 60 deletions(-) diff --git a/include/wx/msw/choice.h b/include/wx/msw/choice.h index ce9d5b58e2..2ee9390c57 100644 --- a/include/wx/msw/choice.h +++ b/include/wx/msw/choice.h @@ -101,9 +101,24 @@ protected: int width, int height, int sizeFlags = wxSIZE_AUTO); + virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const; + // get the real height of the control int GetVisibleHeight() const; + // update the height of the drop down list to fit the number of items we + // have (without changing the visible height) + void UpdateVisibleHeight(); + + // create and initialize the control + bool CreateAndInit(wxWindow *parent, wxWindowID id, + const wxPoint& pos, + const wxSize& size, + int n, const wxString choices[], + long style, + const wxValidator& validator, + const wxString& name); + // free all memory we have (used by Clear() and dtor) void Free(); diff --git a/include/wx/msw/combobox.h b/include/wx/msw/combobox.h index f47d004cb6..8b6ed98e25 100644 --- a/include/wx/msw/combobox.h +++ b/include/wx/msw/combobox.h @@ -100,6 +100,9 @@ public: WXHWND GetEditHWND() const; +protected: + virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const; + private: DECLARE_DYNAMIC_CLASS_NO_COPY(wxComboBox) }; diff --git a/src/msw/choice.cpp b/src/msw/choice.cpp index 4d1df2c1a4..719e977f41 100644 --- a/src/msw/choice.cpp +++ b/src/msw/choice.cpp @@ -115,17 +115,6 @@ bool wxChoice::Create(wxWindow *parent, const wxValidator& validator, const wxString& name) { - if ( !CreateControl(parent, id, pos, size, style, validator, name) ) - return FALSE; - - long msStyle = WS_CHILD | CBS_DROPDOWNLIST | WS_TABSTOP | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL; - if ( style & wxCB_SORT ) - msStyle |= CBS_SORT; - - if ( style & wxCLIP_SIBLINGS ) - msStyle |= WS_CLIPSIBLINGS; - - // Experience shows that wxChoice vs. wxComboBox distinction confuses // quite a few people - try to help them wxASSERT_MSG( !(style & wxCB_DROPDOWN) && @@ -134,20 +123,37 @@ bool wxChoice::Create(wxWindow *parent, _T("this style flag is ignored by wxChoice, you ") _T("probably want to use a wxComboBox") ); - if ( !MSWCreateControl(wxT("COMBOBOX"), msStyle) ) + return CreateAndInit(parent, id, pos, size, n, choices, style, + validator, name); +} + +bool wxChoice::CreateAndInit(wxWindow *parent, wxWindowID id, + const wxPoint& pos, + const wxSize& size, + int n, const wxString choices[], + long style, + const wxValidator& validator, + const wxString& name) +{ + // initialize wxControl + if ( !CreateControl(parent, id, pos, size, style, validator, name) ) return FALSE; - // A choice/combobox normally has a white background (or other, depending - // on global settings) rather than inheriting the parent's background colour. + // now create the real HWND + if ( !MSWCreateControl(wxT("COMBOBOX"), _T(""), pos, size) ) + return FALSE; + + + // choice/combobox normally has "white" (depends on colour scheme, of + // course) background rather than inheriting the parent's background SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); + // initialize for ( int i = 0; i < n; i++ ) { Append(choices[i]); } - SetSize(pos.x, pos.y, size.x, size.y); - return TRUE; } @@ -165,6 +171,26 @@ bool wxChoice::Create(wxWindow *parent, style, validator, name); } +WXDWORD wxChoice::MSWGetStyle(long style, WXDWORD *exstyle) const +{ + // we never have an external border + WXDWORD msStyle = wxControl::MSWGetStyle + ( + (style & ~wxBORDER_MASK) | wxBORDER_NONE, exstyle + ); + + // WS_CLIPSIBLINGS is useful with wxChoice and doesn't seem to result in + // any problems + msStyle |= WS_CLIPSIBLINGS; + + // wxChoice-specific styles + msStyle |= CBS_DROPDOWNLIST | WS_HSCROLL | WS_VSCROLL; + if ( style & wxCB_SORT ) + msStyle |= CBS_SORT; + + return msStyle; +} + wxChoice::~wxChoice() { Free(); @@ -181,6 +207,12 @@ int wxChoice::DoAppend(const wxString& item) { wxLogLastError(wxT("SendMessage(CB_ADDSTRING)")); } + else // ok + { + // we need to refresh our size in order to have enough space for the + // newly added items + UpdateVisibleHeight(); + } return n; } @@ -195,6 +227,10 @@ int wxChoice::DoInsert(const wxString& item, int pos) { wxLogLastError(wxT("SendMessage(CB_INSERTSTRING)")); } + else // ok + { + UpdateVisibleHeight(); + } return n; } @@ -209,6 +245,8 @@ void wxChoice::Delete(int n) } SendMessage(GetHwnd(), CB_DELETESTRING, n, 0); + + UpdateVisibleHeight(); } void wxChoice::Clear() @@ -216,6 +254,8 @@ void wxChoice::Clear() Free(); SendMessage(GetHwnd(), CB_RESETCONTENT, 0, 0); + + UpdateVisibleHeight(); } void wxChoice::Free() @@ -372,6 +412,11 @@ int wxChoice::GetVisibleHeight() const return ::SendMessage(GetHwnd(), CB_GETITEMHEIGHT, (WPARAM)-1, 0); } +void wxChoice::UpdateVisibleHeight() +{ + DoSetSize(-1, -1, -1, GetVisibleHeight()); +} + void wxChoice::DoMoveWindow(int x, int y, int width, int height) { // here is why this is necessary: if the width is negative, the combobox diff --git a/src/msw/combobox.cpp b/src/msw/combobox.cpp index e23e1fa66e..ebbd7b83e8 100644 --- a/src/msw/combobox.cpp +++ b/src/msw/combobox.cpp @@ -355,6 +355,10 @@ WXHWND wxComboBox::GetEditHWND() const return (WXHWND)hwndEdit; } +// ---------------------------------------------------------------------------- +// wxComboBox creation +// ---------------------------------------------------------------------------- + bool wxComboBox::Create(wxWindow *parent, wxWindowID id, const wxString& value, const wxPoint& pos, @@ -369,50 +373,11 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, // some noticeable flicker while the control rearranges itself m_isShown = FALSE; - // first create wxWin object - if ( !CreateControl(parent, id, pos, size, style, validator, name) ) - return FALSE; - - // get the right style - long msStyle = WS_TABSTOP | WS_VSCROLL | WS_HSCROLL | - CBS_AUTOHSCROLL | CBS_NOINTEGRALHEIGHT /* | WS_CLIPSIBLINGS */; - if ( style & wxCB_READONLY ) - msStyle |= CBS_DROPDOWNLIST; -#ifndef __WXWINCE__ - else if ( style & wxCB_SIMPLE ) - msStyle |= CBS_SIMPLE; // A list (shown always) and edit control -#endif - else - msStyle |= CBS_DROPDOWN; - - if ( style & wxCB_SORT ) - msStyle |= CBS_SORT; - - if ( style & wxCLIP_SIBLINGS ) - msStyle |= WS_CLIPSIBLINGS; - - - // and now create the MSW control - if ( !MSWCreateControl(_T("COMBOBOX"), msStyle) ) + if ( !CreateAndInit(parent, id, pos, size, n, choices, style, + validator, name) ) return FALSE; - // A choice/combobox normally has a white background (or other, depending - // on global settings) rather than inheriting the parent's background colour. - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)); - - for ( int i = 0; i < n; i++ ) - { - Append(choices[i]); - } - - if ( !value.IsEmpty() ) - { - SetValue(value); - } - - // do this after appending the values to the combobox so that autosizing - // works correctly - SetSize(pos.x, pos.y, size.x, size.y); + SetValue(value); // a (not read only) combobox is, in fact, 2 controls: the combobox itself // and an edit control inside it and if we want to catch events from this @@ -447,6 +412,38 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, chs.GetStrings(), style, validator, name); } +WXDWORD wxComboBox::MSWGetStyle(long style, WXDWORD *exstyle) const +{ + // we never have an external border + WXDWORD msStyle = wxChoice::MSWGetStyle + ( + (style & ~wxBORDER_MASK) | wxBORDER_NONE, exstyle + ); + + // remove the style always added by wxChoice + msStyle &= ~CBS_DROPDOWNLIST; + + if ( style & wxCB_READONLY ) + msStyle |= CBS_DROPDOWNLIST; +#ifndef __WXWINCE__ + else if ( style & wxCB_SIMPLE ) + msStyle |= CBS_SIMPLE; // A list (shown always) and edit control +#endif + else + msStyle |= CBS_DROPDOWN; + + // there is no reason to not always use CBS_AUTOHSCROLL, so do use it + msStyle |= CBS_AUTOHSCROLL; + + // NB: we used to also add CBS_NOINTEGRALHEIGHT here but why? + + return msStyle; +} + +// ---------------------------------------------------------------------------- +// wxComboBox text control-like methods +// ---------------------------------------------------------------------------- + void wxComboBox::SetValue(const wxString& value) { if ( HasFlag(wxCB_READONLY) ) @@ -574,6 +571,5 @@ void wxComboBox::SetSelection(long from, long to) } } -#endif - // wxUSE_COMBOBOX +#endif // wxUSE_COMBOBOX -- 2.45.2