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:
@@ -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
|
||||||
|
@@ -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();
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user