better handling for the style changing during run-time

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14283 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2002-02-17 22:43:43 +00:00
parent 07215d86e0
commit b2d5a7ee00
8 changed files with 218 additions and 94 deletions

View File

@@ -110,7 +110,8 @@ All (GUI):
wxMSW:
- small appearance fixes for native look under Windows XP
- huge (40*) speed up in wxMask::Create() (=> much faster toolbar creation)
- huge (40*) speed up in wxMask::Create()
- changing wxWindows styles also changes the underlying Windows window style
- fixed flicker in wxTreeCtrl::SetItemXXX()
- fixed redraw problems in dynamically resized wxStaticText
- improvements to wxWindows applications behaviour when the system colours

View File

@@ -124,6 +124,8 @@ public:
// Implementation from now on
// --------------------------
virtual void SetWindowStyleFlag(long style);
virtual void Command(wxCommandEvent& event);
virtual bool MSWCommand(WXUINT param, WXWORD id);
virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
@@ -204,6 +206,8 @@ protected:
virtual bool MSWShouldPreProcessMessage(WXMSG* pMsg);
virtual wxSize DoGetBestSize() const;
virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const;
#if wxUSE_RICHEDIT
// we're using RICHEDIT (and not simple EDIT) control if this field is not
// 0, it also gives the version of the RICHEDIT control being used (1, 2 or

View File

@@ -88,11 +88,8 @@ protected:
// common part of Iconize(), Maximize() and Restore()
void DoShowWindow(int nShowCmd);
// get the MSW window flags corresponding to wxWindows ones
//
// the functions returns the flags (WS_XXX) directly and puts the ext
// (WS_EX_XXX) flags into the provided pointer if not NULL
long MSWGetCreateWindowFlags(long *exflags) const;
// translate wxWindows flags to Windows ones
virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle) const;
// is the frame currently iconized?
bool m_iconized;

View File

@@ -98,6 +98,7 @@ public:
virtual void Freeze();
virtual void Thaw();
virtual void SetWindowStyleFlag( long style );
virtual bool SetCursor( const wxCursor &cursor );
virtual bool SetFont( const wxFont &font );
@@ -169,13 +170,6 @@ public:
wxWindow* GetWindowChild(wxWindowID id);
#endif // __WXUNIVERSAL__
// a MSW only function which sends a size event to the window using its
// current size - this has an effect of refreshing the window layout
/*
FUNCTION IS NOW A MEMBER OF wxFrame - gt
void SendSizeEvent();
*/
// implementation from now on
// --------------------------
@@ -215,12 +209,27 @@ public:
// Make a Windows extended style from the given wxWindows window style
static WXDWORD MakeExtendedStyle(long style,
bool eliminateBorders = FALSE);
// Determine whether 3D effects are wanted
WXDWORD Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D) const;
// MSW only: TRUE if this control is part of the main control
virtual bool ContainsHWND(WXHWND WXUNUSED(hWnd)) const { return FALSE; };
// translate wxWindows style flags for this control into the Windows style
// and optional extended style for the corresponding native control
//
// this is the function that should be overridden in the derived classes,
// but you will mostly use MSWGetCreateWindowFlags() below
virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle = NULL) const;
// get the MSW window flags corresponding to wxWindows ones
//
// the functions returns the flags (WS_XXX) directly and puts the ext
// (WS_EX_XXX) flags into the provided pointer if not NULL
WXDWORD MSWGetCreateWindowFlags(WXDWORD *exflags = NULL) const
{ return MSWGetStyle(GetWindowStyle(), exflags); }
// translate wxWindows coords into Windows ones suitable to be passed to
// ::CreateWindow()
//

View File

@@ -327,7 +327,7 @@ public:
// extra style: the less often used style bits which can't be set with
// SetWindowStyleFlag()
void SetExtraStyle(long exStyle) { m_exStyle = exStyle; }
virtual void SetExtraStyle(long exStyle) { m_exStyle = exStyle; }
long GetExtraStyle() const { return m_exStyle; }
// make the window modal (all other windows unresponsive)

View File

@@ -195,44 +195,8 @@ bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
if ( parent )
parent->AddChild(this);
// translate wxWin style flags to MSW ones, checking for consistency while
// doing it
long msStyle = ES_LEFT | WS_TABSTOP;
if ( m_windowStyle & wxCLIP_SIBLINGS )
msStyle |= WS_CLIPSIBLINGS;
if ( m_windowStyle & wxTE_MULTILINE )
{
wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
msStyle |= ES_MULTILINE | ES_WANTRETURN;
if ((m_windowStyle & wxTE_NO_VSCROLL) == 0)
msStyle |= WS_VSCROLL;
m_windowStyle |= wxTE_PROCESS_ENTER;
}
else // !multiline
{
// there is really no reason to not have this style for single line
// text controls
msStyle |= ES_AUTOHSCROLL;
}
if ( m_windowStyle & wxHSCROLL )
msStyle |= WS_HSCROLL | ES_AUTOHSCROLL;
if ( m_windowStyle & wxTE_READONLY )
msStyle |= ES_READONLY;
if ( m_windowStyle & wxTE_PASSWORD )
msStyle |= ES_PASSWORD;
if ( m_windowStyle & wxTE_AUTO_SCROLL )
msStyle |= ES_AUTOHSCROLL;
if ( m_windowStyle & wxTE_NOHIDESEL )
msStyle |= ES_NOHIDESEL;
// translate wxWin style flags to MSW ones
WXDWORD msStyle = MSWGetCreateWindowFlags();
// do create the control - either an EDIT or RICHEDIT
wxString windowClass = wxT("EDIT");
@@ -391,6 +355,68 @@ void wxTextCtrl::AdoptAttributesFromHWND()
m_windowStyle |= wxTE_PROCESS_ENTER;
}
WXDWORD wxTextCtrl::MSWGetStyle(long style, WXDWORD *exstyle) const
{
long msStyle = wxControl::MSWGetStyle(style, exstyle);
// default styles
msStyle |= ES_LEFT | WS_TABSTOP;
if ( style & wxTE_MULTILINE )
{
wxASSERT_MSG( !(style & wxTE_PROCESS_ENTER),
wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
msStyle |= ES_MULTILINE | ES_WANTRETURN;
if ( !(style & wxTE_NO_VSCROLL) )
msStyle |= WS_VSCROLL;
style |= wxTE_PROCESS_ENTER;
}
else // !multiline
{
// there is really no reason to not have this style for single line
// text controls
msStyle |= ES_AUTOHSCROLL;
}
if ( style & wxHSCROLL )
msStyle |= WS_HSCROLL | ES_AUTOHSCROLL;
if ( style & wxTE_READONLY )
msStyle |= ES_READONLY;
if ( style & wxTE_PASSWORD )
msStyle |= ES_PASSWORD;
if ( style & wxTE_AUTO_SCROLL )
msStyle |= ES_AUTOHSCROLL;
if ( style & wxTE_NOHIDESEL )
msStyle |= ES_NOHIDESEL;
return msStyle;
}
void wxTextCtrl::SetWindowStyleFlag(long style)
{
#if wxUSE_RICHEDIT
// we have to deal with some styles separately because they can't be
// changed by simply calling SetWindowLong(GWL_STYLE) but can be changed
// using richedit-specific EM_SETOPTIONS
if ( IsRich() &&
((style & wxTE_NOHIDESEL) != (GetWindowStyle() & wxTE_NOHIDESEL)) )
{
bool set = (style & wxTE_NOHIDESEL) != 0;
::SendMessage(GetHwnd(), EM_SETOPTIONS, set ? ECOOP_OR : ECOOP_AND,
set ? ECO_NOHIDESEL : ~ECO_NOHIDESEL);
}
#endif // wxUSE_RICHEDIT
wxControl::SetWindowStyleFlag(style);
}
// ----------------------------------------------------------------------------
// set/get the controls text
// ----------------------------------------------------------------------------

View File

@@ -101,20 +101,24 @@ void wxTopLevelWindowMSW::Init()
m_fsIsShowing = FALSE;
}
long wxTopLevelWindowMSW::MSWGetCreateWindowFlags(long *exflags) const
WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
{
long style = GetWindowStyle();
// let the base class deal with the common styles but fix the ones which
// don't make sense for us (we also deal with the borders ourselves)
WXDWORD msflags = wxWindow::MSWGetStyle
(
(style & ~wxBORDER_MASK) | wxBORDER_NONE, exflags
) & ~WS_CHILD;
// first select the kind of window being created
//
// note that if we don't set WS_POPUP, Windows assumes WS_OVERLAPPED and
// creates a window with both caption and border, hence we also test it
// below in some other cases
long msflags;
if ( style & wxFRAME_TOOL_WINDOW )
msflags = WS_POPUP;
msflags |= WS_POPUP;
else
msflags = WS_OVERLAPPED;
msflags |= WS_OVERLAPPED;
// border and caption styles
if ( style & wxRESIZE_BORDER )
@@ -141,9 +145,6 @@ long wxTopLevelWindowMSW::MSWGetCreateWindowFlags(long *exflags) const
if ( style & wxMAXIMIZE )
msflags |= WS_MAXIMIZE;
if ( style & wxCLIP_CHILDREN )
msflags |= WS_CLIPCHILDREN;
// Keep this here because it saves recoding this function in wxTinyFrame
#if wxUSE_ITSY_BITSY && !defined(__WIN32__)
if ( style & wxTINY_CAPTION_VERT )
@@ -157,8 +158,6 @@ long wxTopLevelWindowMSW::MSWGetCreateWindowFlags(long *exflags) const
if ( exflags )
{
*exflags = MakeExtendedStyle(style);
#if !defined(__WIN16__) && !defined(__SC__)
if ( !(GetExtraStyle() & wxTOPLEVEL_EX_DIALOG) )
{
@@ -177,7 +176,7 @@ long wxTopLevelWindowMSW::MSWGetCreateWindowFlags(long *exflags) const
*exflags |= WS_EX_TOPMOST;
#ifdef __WIN32__
if ( m_exStyle & wxFRAME_EX_CONTEXTHELP )
if ( GetExtraStyle() & wxFRAME_EX_CONTEXTHELP )
*exflags |= WS_EX_CONTEXTHELP;
#endif // __WIN32__
}
@@ -232,7 +231,7 @@ bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate,
return FALSE;
}
long exflags;
WXDWORD exflags;
(void)MSWGetCreateWindowFlags(&exflags);
if ( exflags )
@@ -315,8 +314,8 @@ bool wxTopLevelWindowMSW::CreateFrame(const wxString& title,
const wxPoint& pos,
const wxSize& size)
{
long exflags;
long flags = MSWGetCreateWindowFlags(&exflags);
WXDWORD exflags;
WXDWORD flags = MSWGetCreateWindowFlags(&exflags);
return MSWCreate(wxCanvasClassName, title, pos, size, flags, exflags);
}

View File

@@ -386,45 +386,26 @@ bool wxWindowMSW::Create(wxWindow *parent,
parent->AddChild(this);
// all windows are created visible
DWORD msflags = WS_CHILD | WS_VISIBLE;
// note that all windows are created visible by default
WXDWORD exstyle;
DWORD msflags = WS_VISIBLE | MSWGetCreateWindowFlags(&exstyle);
#ifdef __WXUNIVERSAL__
// no 3d effects, we draw them ourselves
WXDWORD exStyle = 0;
#else // !wxUniversal
if ( style & wxCLIP_CHILDREN )
msflags |= WS_CLIPCHILDREN;
if ( style & wxCLIP_SIBLINGS )
msflags |= WS_CLIPSIBLINGS;
bool want3D;
WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
// Even with extended styles, need to combine with WS_BORDER
// for them to look right.
if ( want3D ||
(m_windowStyle & (wxBORDER |
wxSIMPLE_BORDER |
wxRAISED_BORDER |
wxSUNKEN_BORDER |
wxDOUBLE_BORDER)) )
{
msflags |= WS_BORDER;
}
#endif // wxUniversal/!wxUniversal
exStyle = 0;
#endif // wxUniversal
if ( style & wxPOPUP_WINDOW )
{
// a popup window floats on top of everything
exStyle |= WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
exstyle |= WS_EX_TOPMOST | WS_EX_TOOLWINDOW;
// it is also created hidden as other top level windows
msflags &= ~WS_VISIBLE;
m_isShown = FALSE;
}
return MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exStyle);
return MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle);
}
// ---------------------------------------------------------------------------
@@ -962,7 +943,7 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
wxAssociateWinWithHandle(hwnd, this);
m_oldWndProc = (WXFARPROC)::GetWindowLong((HWND)hWnd, GWL_WNDPROC);
// we don't need to subclass the window of our own class (in the Windows
// sense of the word)
if ( !wxCheckWindowWndProc(hWnd, (WXFARPROC)wxWndProc) )
@@ -1028,6 +1009,113 @@ bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
#endif
}
// ----------------------------------------------------------------------------
// Style handling
// ----------------------------------------------------------------------------
void wxWindowMSW::SetWindowStyleFlag(long flags)
{
long flagsOld = GetWindowStyleFlag();
if ( flags == flagsOld )
return;
// update the internal variable
wxWindowBase::SetWindowStyleFlag(flags);
// now update the Windows style as well if needed
WXDWORD exstyle, exstyleOld;
long style = MSWGetStyle(flags, &exstyle),
styleOld = MSWGetStyle(flagsOld, &exstyleOld);
if ( style != styleOld )
{
// some flags (e.g. WS_VISIBLE or WS_DISABLED) should not be changed by
// this function so instead of simply setting the style to the new
// value we clear the bits which were set in styleOld but are set in
// the new one and set the ones which were not set before
long styleReal = ::GetWindowLong(GetHwnd(), GWL_STYLE);
styleReal &= ~styleOld;
styleReal |= style;
::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
}
// and the extended style
if ( exstyle != exstyleOld )
{
long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
exstyleReal &= ~exstyleOld;
exstyleReal |= exstyle;
::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
// we must call SetWindowPos() to flash the cached extended style and
// also to make the change to wxSTAY_ON_TOP style take effect: just
// setting the style simply doesn't work
if ( !::SetWindowPos(GetHwnd(),
exstyleReal & WS_EX_TOPMOST ? HWND_TOPMOST
: HWND_NOTOPMOST,
0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE) )
{
wxLogLastError(_T("SetWindowPos"));
}
}
}
WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
{
// translate the style
WXDWORD style = WS_CHILD;
if ( flags & wxCLIP_CHILDREN )
style |= WS_CLIPCHILDREN;
if ( flags & wxCLIP_SIBLINGS )
style |= WS_CLIPSIBLINGS;
if ( (flags & wxBORDER_MASK) != wxBORDER_NONE )
style |= WS_BORDER;
// now deal with ext style if the caller wants it
if ( exstyle )
{
*exstyle = 0;
if ( flags & wxTRANSPARENT_WINDOW )
*exstyle |= WS_EX_TRANSPARENT;
switch ( flags & wxBORDER_MASK )
{
default:
wxFAIL_MSG( _T("unknown border style") );
// fall through
case wxBORDER_NONE:
case wxBORDER_SIMPLE:
break;
case wxBORDER_STATIC:
*exstyle |= WS_EX_STATICEDGE;
break;
case wxBORDER_RAISED:
*exstyle |= WS_EX_WINDOWEDGE;
break;
case wxBORDER_DEFAULT:
case wxBORDER_SUNKEN:
*exstyle |= WS_EX_CLIENTEDGE;
break;
case wxBORDER_DOUBLE:
*exstyle |= WS_EX_DLGMODALFRAME;
break;
}
}
return style;
}
// Make a Windows extended style from the given wxWindows window style
WXDWORD wxWindowMSW::MakeExtendedStyle(long style, bool eliminateBorders)
@@ -3667,7 +3755,7 @@ bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
MINMAXINFO *info = (MINMAXINFO *)mmInfo;
bool rc = FALSE;
int minWidth = GetMinWidth(),
minHeight = GetMinHeight(),
maxWidth = GetMaxWidth(),