1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
19 #include "wx/gdicmn.h"
22 #include "wx/cursor.h"
24 #include "wx/palette.h"
26 #include "wx/dialog.h"
27 #include "wx/msgdlg.h"
29 #include "wx/dynarray.h"
30 # include "wx/wxchar.h"
35 #include "wx/module.h"
37 #include "wx/os2/private.h"
40 #include "wx/thread.h"
42 // define the array of QMSG strutures
43 WX_DECLARE_OBJARRAY(QMSG
, wxMsgArray
);
45 #include "wx/arrimpl.cpp"
47 WX_DEFINE_OBJARRAY(wxMsgArray
);
48 #endif // wxUSE_THREADS
50 #if wxUSE_WX_RESOURCES
51 #include "wx/resource.h"
55 #include "wx/tooltip.h"
56 #endif // wxUSE_TOOLTIPS
61 // ---------------------------------------------------------------------------
63 // ---------------------------------------------------------------------------
65 extern wxChar
* wxBuffer
;
66 extern wxList
* wxWinHandleList
;
67 extern wxList WXDLLEXPORT wxPendingDelete
;
68 extern wxCursor
* g_globalCursor
;
70 HAB vHabmain
= NULLHANDLE
;
72 wxApp
* wxTheApp
= NULL
;
74 // NB: all "NoRedraw" classes must have the same names as the "normal" classes
75 // with NR suffix - wxWindow::OS2Create() supposes this
76 wxChar wxFrameClassName
[] = wxT("wxFrameClass");
77 wxChar wxFrameClassNameNoRedraw
[] = wxT("wxFrameClassNR");
78 wxChar wxMDIFrameClassName
[] = wxT("wxMDIFrameClass");
79 wxChar wxMDIFrameClassNameNoRedraw
[] = wxT("wxMDIFrameClassNR");
80 wxChar wxMDIChildFrameClassName
[] = wxT("wxMDIChildFrameClass");
81 wxChar wxMDIChildFrameClassNameNoRedraw
[] = wxT("wxMDIChildFrameClassNR");
82 wxChar wxPanelClassName
[] = wxT("wxPanelClass");
83 wxChar wxCanvasClassName
[] = wxT("wxCanvasClass");
85 HICON wxSTD_FRAME_ICON
= (HICON
) NULL
;
86 HICON wxSTD_MDICHILDFRAME_ICON
= (HICON
) NULL
;
87 HICON wxSTD_MDIPARENTFRAME_ICON
= (HICON
) NULL
;
89 HICON wxDEFAULT_FRAME_ICON
= (HICON
) NULL
;
90 HICON wxDEFAULT_MDICHILDFRAME_ICON
= (HICON
) NULL
;
91 HICON wxDEFAULT_MDIPARENTFRAME_ICON
= (HICON
) NULL
;
93 HBRUSH wxDisableButtonBrush
= (HBRUSH
) 0;
95 MRESULT EXPENTRY
wxWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
);
96 MRESULT EXPENTRY
wxFrameWndProc( HWND hWnd
,ULONG message
,MPARAM mp1
,MPARAM mp2
);
98 // ===========================================================================
100 // ===========================================================================
102 // ---------------------------------------------------------------------------
104 // ---------------------------------------------------------------------------
106 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
108 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
109 EVT_IDLE(wxApp::OnIdle
)
110 EVT_END_SESSION(wxApp::OnEndSession
)
111 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
117 bool wxApp::Initialize(
121 #if defined(wxUSE_CONSOLEDEBUG)
122 #if wxUSE_CONSOLEDEBUG
123 /***********************************************/
124 /* Code for using stdout debug */
125 /* To use it you mast link app as "Window" - EK*/
126 /***********************************************/
131 printf("In console\n");
133 DosGetInfoBlocks(&tib
, &pib
);
134 /* Try morphing into a PM application. */
135 // if(pib->pib_ultype == 2) /* VIO */
138 /**********************************************/
139 /**********************************************/
140 #endif //wxUSE_CONSOLEDEBUG
144 // OS2 has to have an anchorblock
146 vHab
= WinInitialize(0);
153 // Some people may wish to use this, but
154 // probably it shouldn't be here by default.
156 // wxRedirectIOToConsole();
159 wxBuffer
= new wxChar
[1500]; // FIXME; why?
161 wxClassInfo::InitializeClasses();
164 wxPendingEventsLocker
= new wxCriticalSection
;
167 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
168 wxTheColourDatabase
->Initialize();
170 wxInitializeStockLists();
171 wxInitializeStockObjects();
173 #if wxUSE_WX_RESOURCES
174 wxInitializeResourceSystem();
177 wxBitmap::InitStandardHandlers();
179 RegisterWindowClasses(vHab
);
180 wxWinHandleList
= new wxList(wxKEY_INTEGER
);
182 // This is to foil optimizations in Visual C++ that throw out dummy.obj.
183 // PLEASE DO NOT ALTER THIS.
184 #if !defined(WXMAKINGDLL) && defined(__VISAGECPP__)
185 extern char wxDummyChar
;
186 if (wxDummyChar
) wxDummyChar
++;
189 // wxSetKeyboardHook(TRUE);
191 wxModule::RegisterModules();
192 if (!wxModule::InitializeModules())
195 } // end of wxApp::Initialize
197 const char* CANTREGISTERCLASS
= " Can't register Class ";
198 // ---------------------------------------------------------------------------
199 // RegisterWindowClasses
200 // ---------------------------------------------------------------------------
202 bool wxApp::RegisterWindowClasses(
210 if (!::WinRegisterClass( vHab
213 ,CS_SIZEREDRAW
| CS_MOVENOTIFY
| CS_SYNCPAINT
| CS_CLIPCHILDREN
217 vError
= ::WinGetLastError(vHab
);
218 sError
= wxPMErrorToStr(vError
);
219 wxLogLastError(sError
);
223 if (!::WinRegisterClass( vHab
224 ,wxFrameClassNameNoRedraw
230 vError
= ::WinGetLastError(vHab
);
231 sError
= wxPMErrorToStr(vError
);
232 wxLogLastError(sError
);
236 if (!::WinRegisterClass( vHab
239 ,CS_SIZEREDRAW
| CS_MOVENOTIFY
| CS_SYNCPAINT
243 vError
= ::WinGetLastError(vHab
);
244 sError
= wxPMErrorToStr(vError
);
245 wxLogLastError(sError
);
249 if (!::WinRegisterClass( vHab
250 ,wxMDIFrameClassNameNoRedraw
256 vError
= ::WinGetLastError(vHab
);
257 sError
= wxPMErrorToStr(vError
);
258 wxLogLastError(sError
);
262 if (!::WinRegisterClass( vHab
263 ,wxMDIChildFrameClassName
265 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_SYNCPAINT
| CS_HITTEST
269 vError
= ::WinGetLastError(vHab
);
270 sError
= wxPMErrorToStr(vError
);
271 wxLogLastError(sError
);
275 if (!::WinRegisterClass( vHab
276 ,wxMDIChildFrameClassNameNoRedraw
282 vError
= ::WinGetLastError(vHab
);
283 sError
= wxPMErrorToStr(vError
);
284 wxLogLastError(sError
);
288 if (!::WinRegisterClass( vHab
291 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_HITTEST
| CS_SAVEBITS
| CS_SYNCPAINT
295 vError
= ::WinGetLastError(vHab
);
296 sError
= wxPMErrorToStr(vError
);
297 wxLogLastError(sError
);
301 if (!::WinRegisterClass( vHab
304 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_HITTEST
| CS_SAVEBITS
| CS_SYNCPAINT
308 vError
= ::WinGetLastError(vHab
);
309 sError
= wxPMErrorToStr(vError
);
310 wxLogLastError(sError
);
314 } // end of wxApp::RegisterWindowClasses
317 // Cleans up any wxWindows internal structures left lying around
319 void wxApp::CleanUp()
328 // Flush the logged messages if any and install a 'safer' log target: the
329 // default one (wxLogGui) can't be used after the resources are freed just
330 // below and the user suppliedo ne might be even more unsafe (using any
331 // wxWindows GUI function is unsafe starting from now)
333 wxLog::DontCreateOnDemand();
336 // This will flush the old messages if any
338 delete wxLog::SetActiveTarget(new wxLogStderr
);
342 // One last chance for pending objects to be cleaned up
344 wxTheApp
->DeletePendingObjects();
346 wxModule::CleanUpModules();
348 #if wxUSE_WX_RESOURCES
349 wxCleanUpResourceSystem();
352 wxDeleteStockObjects();
355 // Destroy all GDI lists, etc.
357 wxDeleteStockLists();
359 delete wxTheColourDatabase
;
360 wxTheColourDatabase
= NULL
;
362 wxBitmap::CleanUpHandlers();
368 // PM-SPECIFIC CLEANUP
371 // wxSetKeyboardHook(FALSE);
373 if (wxSTD_FRAME_ICON
)
374 ::WinFreeFileIcon(wxSTD_FRAME_ICON
);
375 if (wxSTD_MDICHILDFRAME_ICON
)
376 ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON
);
377 if (wxSTD_MDIPARENTFRAME_ICON
)
378 ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON
);
380 if (wxDEFAULT_FRAME_ICON
)
381 ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON
);
382 if (wxDEFAULT_MDICHILDFRAME_ICON
)
383 ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON
);
384 if (wxDEFAULT_MDIPARENTFRAME_ICON
)
385 ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON
);
387 if ( wxDisableButtonBrush
)
389 // TODO: ::DeleteObject( wxDisableButtonBrush );
393 delete wxWinHandleList
;
395 delete wxPendingEvents
;
397 delete wxPendingEventsLocker
;
398 // If we don't do the following, we get an apparent memory leak.
399 ((wxEvtHandler
&) wxDefaultValidator
).ClearEventLocker();
402 wxClassInfo::CleanUpClasses();
404 // Delete Message queue
406 ::WinDestroyMsgQueue(wxTheApp
->m_hMq
);
411 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
412 // At this point we want to check if there are any memory
413 // blocks that aren't part of the wxDebugContext itself,
414 // as a special case. Then when dumping we need to ignore
415 // wxDebugContext, too.
416 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
418 wxLogDebug(wxT("There were memory leaks."));
419 wxDebugContext::Dump();
420 wxDebugContext::PrintStatistics();
422 // wxDebugContext::SetStream(NULL, NULL);
426 // do it as the very last thing because everything else can log messages
427 delete wxLog::SetActiveTarget(NULL
);
429 } // end of wxApp::CleanUp
431 //----------------------------------------------------------------------
432 // Main wxWindows entry point
433 //----------------------------------------------------------------------
441 if (!wxApp::Initialize(vHab
))
445 // create the application object or ensure that one already exists
449 // The app may have declared a global application object, but we recommend
450 // the IMPLEMENT_APP macro is used instead, which sets an initializer
451 // function for delayed, dynamic app object construction.
452 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
453 wxT("No initializer - use IMPLEMENT_APP macro.") );
454 wxTheApp
= (*wxApp::GetInitializerFunction()) ();
456 wxCHECK_MSG( wxTheApp
, 0, wxT("You have to define an instance of wxApp!") );
457 wxTheApp
->argc
= argc
;
460 wxTheApp
->argv
= new wxChar
*[argc
+1];
466 wxTheApp
->argv
[nArgc
] = wxStrdup(wxConvLibc
.cMB2WX(argv
[nArgc
]));
469 wxTheApp
->argv
[nArgc
] = (wxChar
*)NULL
;
471 wxTheApp
->argv
= argv
;
474 wxString
sName(wxFileNameFromPath(argv
[0]));
476 wxStripExtension(sName
);
477 wxTheApp
->SetAppName(sName
);
481 if (!wxTheApp
->OnInitGui())
486 if (wxTheApp
->OnInit())
488 nRetValue
= wxTheApp
->OnRun();
491 wxWindow
* pTopWindow
= wxTheApp
->GetTopWindow();
494 // Forcibly delete the window.
495 if (pTopWindow
->IsKindOf(CLASSINFO(wxFrame
)) ||
496 pTopWindow
->IsKindOf(CLASSINFO(wxDialog
)) )
498 pTopWindow
->Close(TRUE
);
499 wxTheApp
->DeletePendingObjects();
504 wxTheApp
->SetTopWindow(NULL
);
508 else // app initialization failed
510 wxLogLastError(" Gui initialization failed, exitting");
512 #if wxUSE_CONSOLEDEBUG
513 printf("wxTheApp->OnExit ");
517 #if wxUSE_CONSOLEDEBUG
518 printf("wxApp::CleanUp ");
522 #if wxUSE_CONSOLEDEBUG
523 printf("return %i ", nRetValue
);
529 bool wxApp::OnInitGui()
534 m_hMq
= ::WinCreateMsgQueue(vHabmain
, 0);
537 vError
= ::WinGetLastError(vHabmain
);
538 sError
= wxPMErrorToStr(vError
);
543 } // end of wxApp::OnInitGui
546 // Static member initialization
548 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
554 m_wantDebugOutput
= TRUE
;
558 m_nPrintMode
= wxPRINT_WINDOWS
;
559 m_exitOnFrameDelete
= TRUE
;
562 } // end of wxApp::wxApp
567 // Delete command-line args
572 for (i
= 0; i
< argc
; i
++)
578 } // end of wxApp::~wxApp
580 bool wxApp::Initialized()
586 } // end of wxApp::Initialized
589 // Get and process a message, returning FALSE if WM_QUIT
590 // received (and also set the flag telling the app to exit the main loop)
592 bool wxApp::DoMessage()
594 BOOL bRc
= ::WinGetMsg(vHabmain
, &svCurrentMsg
, HWND(NULL
), 0, 0);
599 m_bKeepGoing
= FALSE
;
604 // should never happen, but let's test for it nevertheless
605 wxLogLastError("GetMessage");
610 wxASSERT_MSG( wxThread::IsMain()
611 ,wxT("only the main thread can process Windows messages")
614 static bool sbHadGuiLock
= TRUE
;
615 static wxMsgArray svSavedMessages
;
618 // If a secondary thread owns is doing GUI calls, save all messages for
619 // later processing - we can't process them right now because it will
620 // lead to recursive library calls (and we're not reentrant)
622 if (!wxGuiOwnedByMainThread())
624 sbHadGuiLock
= FALSE
;
627 // Leave out WM_COMMAND messages: too dangerous, sometimes
628 // the message will be processed twice
630 if ( !wxIsWaitingForThread() ||
631 svCurrentMsg
.msg
!= WM_COMMAND
)
633 svSavedMessages
.Add(svCurrentMsg
);
640 // Have we just regained the GUI lock? if so, post all of the saved
647 size_t nCount
= svSavedMessages
.Count();
649 for (size_t n
= 0; n
< nCount
; n
++)
651 QMSG vMsg
= svSavedMessages
[n
];
653 if ( !ProcessMessage((WXMSG
*)&vMsg
) )
655 ::WinDispatchMsg(vHabmain
, &vMsg
);
658 svSavedMessages
.Empty();
661 #endif // wxUSE_THREADS
663 // Process the message
664 if (!ProcessMessage((WXMSG
*)&svCurrentMsg
))
666 ::WinDispatchMsg(vHabmain
, (PQMSG
)&svCurrentMsg
);
670 } // end of wxApp::DoMessage
672 //////////////////////////////////////////////////////////////////////////////
674 // Keep trying to process messages until WM_QUIT
677 // If there are messages to be processed, they will all be
678 // processed and OnIdle will not be called.
679 // When there are no more messages, OnIdle is called.
680 // If OnIdle requests more time,
681 // it will be repeatedly called so long as there are no pending messages.
682 // A 'feature' of this is that once OnIdle has decided that no more processing
683 // is required, then it won't get processing time until further messages
684 // are processed (it'll sit in DoMessage).
686 //////////////////////////////////////////////////////////////////////////////
687 int wxApp::MainLoop()
694 wxMutexGuiLeaveOrEnter();
695 #endif // wxUSE_THREADS
696 while (/*Pending() &&*/ ProcessIdle())
702 return (int)svCurrentMsg
.mp1
;
703 } // end of wxApp::MainLoop
706 // Returns TRUE if more time is needed.
708 bool wxApp::ProcessIdle()
712 vEvent
.SetEventObject(this);
713 ProcessEvent(vEvent
);
714 return vEvent
.MoreRequested();
715 } // end of wxApp::ProcessIdle
717 void wxApp::ExitMainLoop()
719 m_bKeepGoing
= FALSE
;
722 bool wxApp::Pending()
724 return (::WinPeekMsg(vHabmain
, (PQMSG
)&svCurrentMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) != 0);
727 void wxApp::Dispatch()
732 //////////////////////////////////////////////////////////////////////////////
734 // Give all windows a chance to preprocess
735 // the message. Some may have accelerator tables, or have
736 // MDI complications.
738 //////////////////////////////////////////////////////////////////////////////
739 bool wxApp::ProcessMessage(
743 QMSG
* pMsg
= (PQMSG
)pWxmsg
;
744 HWND hWnd
= pMsg
->hwnd
;
745 wxWindow
* pWndThis
= wxFindWinFromHandle((WXHWND
)hWnd
);
750 // We must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to
751 // popup the tooltip bubbles
753 if (pWndThis
&& (pMsg
->msg
== WM_MOUSEMOVE
))
755 wxToolTip
* pToolTip
= pWndThis
->GetToolTip();
758 pToolTip
->RelayEvent(pWxmsg
);
761 #endif // wxUSE_TOOLTIPS
764 // We must relay Timer events to wxTimer's processing function
766 if (pMsg
->msg
== WM_TIMER
)
767 wxTimerProc(NULL
, 0, pMsg
->mp1
, 0);
770 // For some composite controls (like a combobox), wndThis might be NULL
771 // because the subcontrol is not a wxWindow, but only the control itself
772 // is - try to catch this case
774 while (hWnd
&& !pWndThis
)
776 hWnd
= ::WinQueryWindow(hWnd
, QW_PARENT
);
777 pWndThis
= wxFindWinFromHandle((WXHWND
)hWnd
);
781 // Try translations first; find the youngest window with
782 // a translation table. OS/2 has case sensative accels, so
783 // this block, coded by BK, removes that and helps make them
786 if(pMsg
->msg
== WM_CHAR
)
788 PBYTE pChmsg
= (PBYTE
)&(pMsg
->msg
);
789 USHORT uSch
= CHARMSG(pChmsg
)->chr
;
793 // Do not process keyup events
795 if(!(CHARMSG(pChmsg
)->fs
& KC_KEYUP
))
797 if((CHARMSG(pChmsg
)->fs
& (KC_ALT
| KC_CTRL
)) && CHARMSG(pChmsg
)->chr
!= 0)
798 CHARMSG(pChmsg
)->chr
= (USHORT
)wxToupper((UCHAR
)uSch
);
801 for(pWnd
= pWndThis
; pWnd
; pWnd
= pWnd
->GetParent() )
803 if((bRc
= pWnd
->OS2TranslateMessage(pWxmsg
)) == TRUE
)
807 if(!bRc
) // untranslated, should restore original value
808 CHARMSG(pChmsg
)->chr
= uSch
;
812 // Anyone for a non-translation message? Try youngest descendants first.
814 // for (pWnd = pWndThis; pWnd; pWnd = pWnd->GetParent())
816 // if (pWnd->OS2ProcessMessage(pWxmsg))
820 } // end of wxApp::ProcessMessage
826 static bool sbInOnIdle
= FALSE
;
829 // Avoid recursion (via ProcessEvent default case)
837 // If there are pending events, we must process them: pending events
838 // are either events to the threads other than main or events posted
839 // with wxPostEvent() functions
841 ProcessPendingEvents();
844 // 'Garbage' collection of windows deleted with Close().
846 DeletePendingObjects();
850 // Flush the logged messages if any
852 wxLog::FlushActive();
856 // Send OnIdle events to all windows
858 if (SendIdleEvents())
861 // SendIdleEvents() returns TRUE if at least one window requested more
864 rEvent
.RequestMore(TRUE
);
867 } // end of wxApp::OnIdle
869 // Send idle event to all top-level windows
870 bool wxApp::SendIdleEvents()
872 bool bNeedMore
= FALSE
;
873 wxWindowList::Node
* pNode
= wxTopLevelWindows
.GetFirst();
877 wxWindow
* pWin
= pNode
->GetData();
879 if (SendIdleEvents(pWin
))
881 pNode
= pNode
->GetNext();
884 } // end of wxApp::SendIdleEvents
887 // Send idle event to window and all subwindows
889 bool wxApp::SendIdleEvents(
893 bool bNeedMore
= FALSE
;
896 vEvent
.SetEventObject(pWin
);
897 pWin
->GetEventHandler()->ProcessEvent(vEvent
);
899 if (vEvent
.MoreRequested())
902 wxNode
* pNode
= pWin
->GetChildren().First();
906 wxWindow
* pWin
= (wxWindow
*) pNode
->Data();
908 if (SendIdleEvents(pWin
))
910 pNode
= pNode
->Next();
913 } // end of wxApp::SendIdleEvents
915 void wxApp::DeletePendingObjects()
917 wxNode
* pNode
= wxPendingDelete
.First();
921 wxObject
* pObj
= (wxObject
*)pNode
->Data();
925 if (wxPendingDelete
.Member(pObj
))
929 // Deleting one object may have deleted other pending
930 // objects, so start from beginning of list again.
932 pNode
= wxPendingDelete
.First();
934 } // end of wxApp::DeletePendingObjects
936 void wxApp::OnEndSession(
937 wxCloseEvent
& WXUNUSED(rEvent
))
940 GetTopWindow()->Close(TRUE
);
941 } // end of wxApp::OnEndSession
944 // Default behaviour: close the application with prompts. The
945 // user can veto the close, and therefore the end session.
947 void wxApp::OnQueryEndSession(
953 if (!GetTopWindow()->Close(!rEvent
.CanVeto()))
956 } // end of wxApp::OnQueryEndSession
960 wxLogError(_("Fatal error: exiting"));
966 // Yield to incoming messages
974 // Disable log flushing from here because a call to wxYield() shouldn't
975 // normally result in message boxes popping up &c
980 // We want to go back to the main message loop
981 // if we see a WM_QUIT. (?)
983 while (::WinPeekMsg(vHab
, &vMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) && vMsg
.msg
!= WM_QUIT
)
986 wxMutexGuiLeaveOrEnter();
987 #endif // wxUSE_THREADS
988 if (!wxTheApp
->DoMessage())
992 // If they are pending events, we must process them.
995 wxTheApp
->ProcessPendingEvents();
998 // Let the logs be flashed again
1004 wxIcon
wxApp::GetStdIcon(
1010 case wxICON_INFORMATION
:
1011 return wxIcon("wxICON_INFO");
1013 case wxICON_QUESTION
:
1014 return wxIcon("wxICON_QUESTION");
1016 case wxICON_EXCLAMATION
:
1017 return wxIcon("wxICON_WARNING");
1020 wxFAIL_MSG(wxT("requested non existent standard icon"));
1021 // still fall through
1024 return wxIcon("wxICON_ERROR");
1026 return wxIcon("wxICON_ERROR");
1027 } // end of wxApp::GetStdIcon
1029 //-----------------------------------------------------------------------------
1031 //-----------------------------------------------------------------------------
1036 // Send the top window a dummy message so idle handler processing will
1037 // start up again. Doing it this way ensures that the idle handler
1038 // wakes up in the right thread (see also wxWakeUpMainThread() which does
1039 // the same for the main app thread only)
1041 wxWindow
* pTopWindow
= wxTheApp
->GetTopWindow();
1045 if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0))
1048 // Should never happen
1050 wxLogLastError("PostMessage(WM_NULL)");
1053 } // end of wxWakeUpIdle