multiple fixes to wxChoice/wxCombobox height getting/setting (replaces patches 888171, 834099; fixes bug 880590)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@25574 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2004-02-07 18:42:56 +00:00
parent eb630bf1ec
commit d99957b6b0
3 changed files with 64 additions and 23 deletions

View File

@@ -35,6 +35,9 @@ INCOMPATIBLE CHANGES SINCE 2.4.x
(when WXWIN_COMPATIBILITY_2_4 == 0) (when WXWIN_COMPATIBILITY_2_4 == 0)
- wxID_SEPARATOR (id used for the menu separators) value changed from -1 to -2 - wxID_SEPARATOR (id used for the menu separators) value changed from -1 to -2
- wxGetNumberFromUser() is now in separate wx/numdlg.h, not wx/textdlg.h - wxGetNumberFromUser() is now in separate wx/numdlg.h, not wx/textdlg.h
- wxChoice and wxCombobox now handle their size in the same way as in all the
other ports under MSW, new code is actually correct but different from weird
stuff they were doing before so the behaviour of your programs might change
DEPRECATED METHODS SINCE 2.4.x DEPRECATED METHODS SINCE 2.4.x

View File

@@ -96,10 +96,14 @@ protected:
// MSW implementation // MSW implementation
virtual wxSize DoGetBestSize() const; virtual wxSize DoGetBestSize() const;
virtual void DoGetSize(int *w, int *h) const;
virtual void DoSetSize(int x, int y, virtual void DoSetSize(int x, int y,
int width, int height, int width, int height,
int sizeFlags = wxSIZE_AUTO); int sizeFlags = wxSIZE_AUTO);
// get the real height of the control
int GetVisibleHeight() const;
// free all memory we have (used by Clear() and dtor) // free all memory we have (used by Clear() and dtor)
void Free(); void Free();

View File

@@ -118,7 +118,7 @@ bool wxChoice::Create(wxWindow *parent,
if ( !CreateControl(parent, id, pos, size, style, validator, name) ) if ( !CreateControl(parent, id, pos, size, style, validator, name) )
return FALSE; return FALSE;
long msStyle = WS_CHILD | CBS_DROPDOWNLIST | WS_TABSTOP | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL /* | WS_CLIPSIBLINGS */; long msStyle = WS_CHILD | CBS_DROPDOWNLIST | WS_TABSTOP | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL;
if ( style & wxCB_SORT ) if ( style & wxCB_SORT )
msStyle |= CBS_SORT; msStyle |= CBS_SORT;
@@ -367,6 +367,11 @@ wxClientData* wxChoice::DoGetItemClientObject( int n ) const
// wxMSW specific helpers // wxMSW specific helpers
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
int wxChoice::GetVisibleHeight() const
{
return ::SendMessage(GetHwnd(), CB_GETITEMHEIGHT, (WPARAM)-1, 0);
}
void wxChoice::DoMoveWindow(int x, int y, int width, int height) void wxChoice::DoMoveWindow(int x, int y, int width, int height)
{ {
// here is why this is necessary: if the width is negative, the combobox // here is why this is necessary: if the width is negative, the combobox
@@ -385,29 +390,65 @@ void wxChoice::DoMoveWindow(int x, int y, int width, int height)
wxControl::DoMoveWindow(x, y, width, height); wxControl::DoMoveWindow(x, y, width, height);
} }
void wxChoice::DoGetSize(int *w, int *h) const
{
wxControl::DoGetSize(w, h);
// we need to return only the height of the visible part, not the entire
// height in the Windows sense which includes the height of the drop down
// list as well
if ( h )
*h = GetVisibleHeight();
}
void wxChoice::DoSetSize(int x, int y, void wxChoice::DoSetSize(int x, int y,
int width, int WXUNUSED(height), int width, int height,
int sizeFlags) int sizeFlags)
{ {
// Ignore height parameter because height doesn't mean 'initially int heightOrig = height;
// displayed' height, it refers to the drop-down menu as well. The
// wxWindows interpretation is different; also, getting the size returns
// the _displayed_ size (NOT the drop down menu size) so
// setting-getting-setting size would not work.
wxControl::DoSetSize(x, y, width, -1, sizeFlags); // the height which we must pass to Windows should be the total height of
// the control including the drop down list while the height given to us
// is, of course, just the height of the permanently visible part of it
if ( height != -1 )
{
// don't make the drop down list too tall, arbitrarily limit it to 40
// items max and also don't leave it empty
size_t nItems = GetCount();
if ( !nItems )
nItems = 9;
else if ( nItems > 39 )
nItems = 39;
// add space for the drop down list
const int hItem = SendMessage(GetHwnd(), CB_GETITEMHEIGHT, 0, 0);
height += hItem*(nItems + 1);
}
wxControl::DoSetSize(x, y, width, height, sizeFlags);
// if the height specified for the visible part of the control is
// different from the current one, we need to change it separately
// as it is not affected by normal WM_SETSIZE
if ( height != -1 )
{
const int hVisibleCurrent = GetVisibleHeight();
if ( hVisibleCurrent != heightOrig )
{
SendMessage(GetHwnd(), CB_SETITEMHEIGHT, (WPARAM)-1, heightOrig);
}
}
} }
wxSize wxChoice::DoGetBestSize() const wxSize wxChoice::DoGetBestSize() const
{ {
// find the widest string // find the widest string
int wLine;
int wChoice = 0; int wChoice = 0;
int nItems = GetCount(); const size_t nItems = GetCount();
for ( int i = 0; i < nItems; i++ ) for ( size_t i = 0; i < nItems; i++ )
{ {
wxString str(GetString(i)); int wLine;
GetTextExtent(str, &wLine, NULL); GetTextExtent(GetString(i), &wLine, NULL);
if ( wLine > wChoice ) if ( wLine > wChoice )
wChoice = wLine; wChoice = wLine;
} }
@@ -417,17 +458,10 @@ wxSize wxChoice::DoGetBestSize() const
if ( wChoice == 0 ) if ( wChoice == 0 )
wChoice = 100; wChoice = 100;
// the combobox should be larger than the widest string // the combobox should be slightly larger than the widest string
int cx, cy; wChoice += 5*GetCharWidth();
wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
wChoice += 5*cx; return wxSize(wChoice, GetVisibleHeight());
// Choice drop-down list depends on number of items (limited to 10)
size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1;
int hChoice = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy)*nStrings;
return wxSize(wChoice, hChoice);
} }
long wxChoice::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) long wxChoice::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)