#include "wx/dcclient.h"
#include "wx/utils.h"
#include "wx/app.h"
- #include "wx/panel.h"
#include "wx/layout.h"
#include "wx/dialog.h"
#include "wx/frame.h"
#include "wx/button.h"
#include "wx/msgdlg.h"
#include "wx/settings.h"
-
- #include <stdio.h>
+ #include "wx/statbox.h"
#endif
#if wxUSE_OWNER_DRAWN
wxMenu *wxCurrentPopupMenu = NULL;
#endif // wxUSE_MENUS_NATIVE
-extern wxList WXDLLEXPORT wxPendingDelete;
extern const wxChar *wxCanvasClassName;
// ---------------------------------------------------------------------------
EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged)
EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog)
EVT_IDLE(wxWindowMSW::OnIdle)
- EVT_SET_FOCUS(wxWindowMSW::OnSetFocus)
END_EVENT_TABLE()
// ===========================================================================
wxWindow *wxWindowMSW::FindItem(long id) const
{
#if wxUSE_CONTROLS
- wxControl *item = wxDynamicThisCast(this, wxControl);
+ wxControl *item = wxDynamicCastThis(wxControl);
if ( item )
{
// is it we or one of our "internal" children?
{
wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
+#if wxUSE_STATBOX
+ // wxGTK doesn't allow to create controls with static box as the parent so
+ // this will result in a crash when the program is ported to wxGTK - warn
+ // about it
+ //
+ // the correct solution is to create the controls as siblings of the
+ // static box
+ wxASSERT_MSG( !wxDynamicCastThis(wxStaticBox),
+ _T("wxStaticBox can't be used as a window parent!") );
+#endif // wxUSE_STATBOX
+
if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
return FALSE;
#endif // WXWIN_COMPATIBILITY
+inline int GetScrollPosition(HWND hWnd, int wOrient)
+{
+#ifdef __WXMICROWIN__
+ return ::GetScrollPosWX(hWnd, wOrient);
+#else
+ return ::GetScrollPos(hWnd, wOrient);
+#endif
+}
+
int wxWindowMSW::GetScrollPos(int orient) const
{
int wOrient;
wOrient = SB_HORZ;
else
wOrient = SB_VERT;
+
HWND hWnd = GetHwnd();
- if ( hWnd )
- {
-#ifdef __WXMICROWIN__
- return ::GetScrollPosWX(hWnd, wOrient);
-#else
- return ::GetScrollPos(hWnd, wOrient);
-#endif
- }
- else
- return 0;
+ wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") );
+
+ return GetScrollPosition(hWnd, wOrient);
}
// This now returns the whole range, not just the number
::ScrollWindow(GetHwnd(), dx, dy, prect ? &rect : NULL, NULL);
}
+static bool ScrollVertically(HWND hwnd, int kind, int count)
+{
+ int posStart = GetScrollPosition(hwnd, SB_VERT);
+
+ int pos = posStart;
+ for ( int n = 0; n < count; n++ )
+ {
+ ::SendMessage(hwnd, WM_VSCROLL, kind, 0);
+
+ int posNew = GetScrollPosition(hwnd, SB_VERT);
+ if ( posNew == pos )
+ {
+ // don't bother to continue, we're already at top/bottom
+ break;
+ }
+
+ pos = posNew;
+ }
+
+ return pos != posStart;
+}
+
+bool wxWindowMSW::ScrollLines(int lines)
+{
+ bool down = lines > 0;
+
+ return ScrollVertically(GetHwnd(),
+ down ? SB_LINEDOWN : SB_LINEUP,
+ down ? lines : -lines);
+}
+
+bool wxWindowMSW::ScrollPages(int pages)
+{
+ bool down = pages > 0;
+
+ return ScrollVertically(GetHwnd(),
+ down ? SB_PAGEDOWN : SB_PAGEUP,
+ down ? pages : -pages);
+}
+
// ---------------------------------------------------------------------------
// subclassing
// ---------------------------------------------------------------------------
dc.Clear();
}
+static inline void SendSetRedraw(HWND hwnd, bool on)
+{
+ ::SendMessage(hwnd, WM_SETREDRAW, (WPARAM)on, 0);
+}
+
+void wxWindowMSW::Freeze()
+{
+ SendSetRedraw(GetHwnd(), FALSE);
+}
+
+void wxWindowMSW::Thaw()
+{
+ SendSetRedraw(GetHwnd(), TRUE);
+
+ // we need to refresh everything or otherwise he invalidated area is not
+ // repainted
+ Refresh();
+}
+
void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
{
HWND hWnd = GetHwnd();
bProcess = FALSE;
}
-#if wxUSE_BUTTON
+ // FIXME: this should be handled by
+ // wxNavigationKeyEvent handler and not here!!
else
{
- wxPanel *panel = wxDynamicThisCast(this, wxPanel);
- wxButton *btn = NULL;
- if ( panel )
- {
- // panel may have a default button which should
- // be activated by Enter
- btn = panel->GetDefaultItem();
- }
-
+#if wxUSE_BUTTON
+ wxButton *btn = wxDynamicCast(GetDefaultItem(),
+ wxButton);
if ( btn && btn->IsEnabled() )
{
// if we do have a default button, do press it
return TRUE;
}
- // else: but if it does not it makes sense to make
- // it work like a TAB - and that's what we do.
- // Note that Ctrl-Enter always works this way.
- }
+ else // no default button
#endif // wxUSE_BUTTON
+ {
+ // no special function for enter and don't even
+ // let IsDialogMessage() have it: it seems to
+ // do something really strange with it
+ return FALSE;
+ }
+ }
}
break;
if ( GetEventHandler()->ProcessEvent(event) )
{
-#if wxUSE_BUTTON
- wxButton *btn = wxDynamicCast(FindFocus(), wxButton);
- if ( btn )
- {
- // the button which has focus should be default
- btn->SetDefault();
- }
-#endif // wxUSE_BUTTON
-
return TRUE;
}
}
}
-#else
+#else // 0
// let ::IsDialogMessage() do almost everything and handle just the
// things it doesn't here: Ctrl-TAB for switching notebook pages
if ( msg->message == WM_KEYDOWN )
}
}
}
-#endif // 0
+#endif // 1/0
if ( ::IsDialogMessage(GetHwnd(), msg) )
{
#endif // wxUSE_ACCEL
}
+bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* pMsg)
+{
+ // preprocess all messages by default
+ return TRUE;
+}
+
// ---------------------------------------------------------------------------
// message params unpackers (different for Win16 and Win32)
// ---------------------------------------------------------------------------
// activation/focus
// ---------------------------------------------------------------------------
-void wxWindowMSW::OnSetFocus(wxFocusEvent& event)
-{
- // panel wants to track the window which was the last to have focus in it,
- // so we want to set ourselves as the window which last had focus
- //
- // notice that it's also important to do it upwards the tree becaus
- // otherwise when the top level panel gets focus, it won't set it back to
- // us, but to some other sibling
- wxWindow *win = (wxWindow *)this;
- while ( win )
- {
- wxWindow *parent = win->GetParent();
- wxPanel *panel = wxDynamicCast(parent, wxPanel);
- if ( panel )
- {
- panel->SetLastFocus(win);
- }
-
- win = parent;
- }
-
- wxLogTrace(_T("focus"), _T("%s (0x%08x) gets focus"),
- GetClassInfo()->GetClassName(), GetHandle());
-
- event.Skip();
-}
-
bool wxWindowMSW::HandleActivate(int state,
bool WXUNUSED(minimized),
WXHWND WXUNUSED(activate))
bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
{
+ // notify the parent keeping track of focus for the kbd navigation
+ // purposes that we got it
+ wxChildFocusEvent eventFocus(this);
+ (void)GetEventHandler()->ProcessEvent(eventFocus);
+
#if wxUSE_CARET
// Deal with caret
if ( m_caret )
}
#endif // wxUSE_CARET
+#if wxUSE_TEXTCTRL
+ // If it's a wxTextCtrl don't send the event as it will be done
+ // after the control gets to process it from EN_FOCUS handler
+ if ( wxDynamicCastThis(wxTextCtrl) )
+ {
+ return FALSE;
+ }
+#endif // wxUSE_TEXTCTRL
+
wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
event.SetEventObject(this);
}
#endif // wxUSE_CARET
+#if wxUSE_TEXTCTRL
+ // If it's a wxTextCtrl don't send the event as it will be done
+ // after the control gets to process it.
+ wxTextCtrl *ctrl = wxDynamicCastThis(wxTextCtrl);
+ if ( ctrl )
+ {
+ return FALSE;
+ }
+#endif
+
wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
event.SetEventObject(this);
case VK_NUMPAD7: id = WXK_NUMPAD7; break;
case VK_NUMPAD8: id = WXK_NUMPAD8; break;
case VK_NUMPAD9: id = WXK_NUMPAD9; break;
- case VK_MULTIPLY: id = WXK_MULTIPLY; break;
- case 0xBB: // VK_OEM_PLUS
- case VK_ADD: id = WXK_ADD; break;
- case 0xBD: // VK_OEM_MINUS
- case VK_SUBTRACT: id = WXK_SUBTRACT; break;
- case 0xBE: // VK_OEM_PERIOD
- case VK_DECIMAL: id = WXK_DECIMAL; break;
- case VK_DIVIDE: id = WXK_DIVIDE; break;
+ case VK_MULTIPLY: id = WXK_NUMPAD_MULTIPLY; break;
+ case VK_ADD: id = WXK_NUMPAD_ADD; break;
+ case VK_SUBTRACT: id = WXK_NUMPAD_SUBTRACT; break;
+ case VK_DECIMAL: id = WXK_NUMPAD_DECIMAL; break;
+ case VK_DIVIDE: id = WXK_NUMPAD_DIVIDE; break;
case VK_F1: id = WXK_F1; break;
case VK_F2: id = WXK_F2; break;
case VK_F3: id = WXK_F3; break;
case WXK_NUMPAD7: keySym = VK_NUMPAD7; break;
case WXK_NUMPAD8: keySym = VK_NUMPAD8; break;
case WXK_NUMPAD9: keySym = VK_NUMPAD9; break;
- case WXK_MULTIPLY: keySym = VK_MULTIPLY; break;
- case WXK_ADD: keySym = VK_ADD; break;
- case WXK_SUBTRACT: keySym = VK_SUBTRACT; break;
- case WXK_DECIMAL: keySym = VK_DECIMAL; break;
- case WXK_DIVIDE: keySym = VK_DIVIDE; break;
+ case WXK_NUMPAD_MULTIPLY: keySym = VK_MULTIPLY; break;
+ case WXK_NUMPAD_ADD: keySym = VK_ADD; break;
+ case WXK_NUMPAD_SUBTRACT: keySym = VK_SUBTRACT; break;
+ case WXK_NUMPAD_DECIMAL: keySym = VK_DECIMAL; break;
+ case WXK_NUMPAD_DIVIDE: keySym = VK_DIVIDE; break;
case WXK_F1: keySym = VK_F1; break;
case WXK_F2: keySym = VK_F2; break;
case WXK_F3: keySym = VK_F3; break;
#endif // wxUSE_SPINCTRL
#endif // Win32
-
- if ( !win )
- {
- // hwnd is not a wxWindow, try its parent next below
- hwnd = ::GetParent(hwnd);
- }
}
}
while ( hwnd && !win )
{
- win = wxFindWinFromHandle((WXHWND)hwnd);
+ // this is a really ugly hack needed to avoid mistakenly returning the
+ // parent frame wxWindow for the find/replace modeless dialog HWND -
+ // this, in turn, is needed to call IsDialogMessage() from
+ // wxApp::ProcessMessage() as for this we must return NULL from here
+ //
+ // FIXME: this is clearly not the best way to do it but I think we'll
+ // need to change HWND <-> wxWindow code more heavily than I can
+ // do it now to fix it
+ if ( ::GetWindow(hwnd, GW_OWNER) )
+ {
+ // it's a dialog box, don't go upwards
+ break;
+ }
+
hwnd = ::GetParent(hwnd);
+ win = wxFindWinFromHandle((WXHWND)hwnd);
}
return win;