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