switch ( msg->wParam )
{
case VK_TAB:
- // assume that nobody wants Shift-TAB for himself - if we
- // don't do it there is no easy way for a control to grab
- // TABs but still let Shift-TAB work as navugation key
- if ( (lDlgCode & DLGC_WANTTAB) && !bShiftDown ) {
+ if ( lDlgCode & DLGC_WANTTAB ) {
bProcess = FALSE;
}
else {
bProcess = FALSE;
break;
+ case VK_ESCAPE:
+ {
+#if wxUSE_BUTTON
+ wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),
+ wxButton);
+ if ( btn && btn->IsEnabled() )
+ {
+ // if we do have a cancel button, do press it
+ btn->MSWCommand(BN_CLICKED, 0 /* unused */);
+
+ // we consumed the message
+ return TRUE;
+ }
+#endif // wxUSE_BUTTON
+
+ bProcess = FALSE;
+ }
+ break;
+
case VK_RETURN:
{
if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown )
}
#endif // 1/0
- // we handle VK_ESCAPE ourselves in wxDialog::OnCharHook() and we
- // shouldn't let IsDialogMessage() get it as it _always_ eats the
+ // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the
// message even when there is no cancel button and when the message is
// needed by the control itself: in particular, it prevents the tree in
// place edit control from being closed with Escape in a dialog
wxPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
- evtCtx.SetEventObject(this);
- processed = GetEventHandler()->ProcessEvent(evtCtx);
+
+ // we could have got an event from our child, reflect it back
+ // to it if this is the case
+ wxWindow *win = NULL;
+ if ( wParam != m_hWnd )
+ {
+ win = FindItemByHWND((WXHWND)wParam);
+ }
+
+ if ( !win )
+ win = this;
+
+ evtCtx.SetEventObject(win);
+ processed = win->GetEventHandler()->ProcessEvent(evtCtx);
}
break;
#endif
int& x, int& y,
int& w, int& h) const
{
+ // yes, those are just some arbitrary hardcoded numbers
static const int DEFAULT_Y = 200;
+ static const int DEFAULT_W = 400;
static const int DEFAULT_H = 250;
bool nonDefault = FALSE;
if ( pos.x == -1 )
{
- // if set x to CW_USEDEFAULT, y parameter is ignored anyhow so we can
- // just as well set it to CW_USEDEFAULT as well
+ // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we
+ // can just as well set it to CW_USEDEFAULT as well
x =
y = CW_USEDEFAULT;
}
*/
if ( size.x == -1 )
{
- // as above, h is not used at all in this case anyhow
- w =
- h = CW_USEDEFAULT;
+ // we don't use CW_USEDEFAULT here for several reasons:
+ //
+ // 1. it results in huge frames on modern screens (1000*800 is not
+ // uncommon on my 1280*1024 screen) which is way too big for a half
+ // empty frame of most of wxWindows samples for example)
+ //
+ // 2. it is buggy for frames with wxFRAME_TOOL_WINDOW style for which
+ // the default is for whatever reason 8*8 which breaks client <->
+ // window size calculations (it would be nice if it didn't, but it
+ // does and the simplest way to fix it seemed to change the broken
+ // default size anyhow)
+ //
+ // 3. there is just no advantage in doing it: with x and y it is
+ // possible that [future versions of] Windows position the new top
+ // level window in some smart way which we can't do, but we can
+ // guess a reasonably good size for a new window just as well
+ // ourselves
+ w = DEFAULT_W;
+ h = DEFAULT_H;
}
else
{
#endif // wxUSE_HOTKEY
-// Not verified for WinCE
+// Not tested under WinCE
#ifndef __WXWINCE__
-/*
- * wxEventFixModule (needs a better name) allows message handling to continute while a menu
- * is being shown - ie, to continue processing messages from a worker thread.
- *
- * Code originally by Jason W. from wx-dev, reworked into a wxModule by Chris Mellon
- */
-class wxEventFixModule : public wxModule {
+// this class installs a message hook which really wakes up our idle processing
+// each time a WM_NULL is received (wxWakeUpIdle does this), even if we're
+// sitting inside a local modal loop (e.g. a menu is opened or scrollbar is
+// being dragged or even inside ::MessageBox()) and so don't control message
+// dispatching otherwise
+class wxIdleWakeUpModule : public wxModule
+{
public:
- //base class virtuals
- virtual bool OnInit() {
- wxEventFixModule::s_hMsgHookProc = SetWindowsHookEx(
- WH_GETMESSAGE,
- &wxEventFixModule::MsgHookProc,
- NULL,
- GetCurrentThreadId());
- wxLogDebug(_T("Loaded event fix module"));
- return true;
- };
- virtual void OnExit() {
- UnhookWindowsHookEx(wxEventFixModule::s_hMsgHookProc);
+ virtual bool OnInit()
+ {
+ ms_hMsgHookProc = ::SetWindowsHookEx
+ (
+ WH_GETMESSAGE,
+ &wxIdleWakeUpModule::MsgHookProc,
+ NULL,
+ GetCurrentThreadId()
+ );
- };
- static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam) {
+ if ( !ms_hMsgHookProc )
+ {
+ wxLogLastError(_T("SetWindowsHookEx(WH_GETMESSAGE)"));
+
+ return false;
+ }
+
+ return true;
+ }
+
+ virtual void OnExit()
+ {
+ ::UnhookWindowsHookEx(wxIdleWakeUpModule::ms_hMsgHookProc);
+ }
+
+ static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
+ {
MSG *msg = (MSG*)lParam;
- switch (msg->message)
+ if ( msg->message == WM_NULL )
{
- case WM_NULL:
- static bool bInHookProc = false;
- if (!bInHookProc)
- {
- bInHookProc = true;
- wxTheApp->ProcessPendingEvents();
- bInHookProc = false;
- }
- break;
+ wxTheApp->ProcessPendingEvents();
}
- return CallNextHookEx(wxEventFixModule::s_hMsgHookProc, nCode, wParam, lParam);
+
+ return CallNextHookEx(ms_hMsgHookProc, nCode, wParam, lParam);
};
+
private:
- static HHOOK s_hMsgHookProc;
-DECLARE_DYNAMIC_CLASS(wxEventFixModule)
+ static HHOOK ms_hMsgHookProc;
+
+ DECLARE_DYNAMIC_CLASS(wxIdleWakeUpModule)
};
-HHOOK wxEventFixModule::s_hMsgHookProc = 0;
-IMPLEMENT_DYNAMIC_CLASS(wxEventFixModule, wxModule)
-#endif
- // __WXWINCE__
+HHOOK wxIdleWakeUpModule::ms_hMsgHookProc = 0;
+
+IMPLEMENT_DYNAMIC_CLASS(wxIdleWakeUpModule, wxModule)
+
+#endif // __WXWINCE__