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 // ===========================================================================
97 // ===========================================================================
99 // ---------------------------------------------------------------------------
101 // ---------------------------------------------------------------------------
103 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
105 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
106 EVT_IDLE(wxApp::OnIdle
)
107 EVT_END_SESSION(wxApp::OnEndSession
)
108 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
114 bool wxApp::Initialize(
118 #if defined(wxUSE_CONSOLEDEBUG)
119 #if wxUSE_CONSOLEDEBUG
120 /***********************************************/
121 /* Code for using stdout debug */
122 /* To use it you mast link app as "Window" - EK*/
123 /***********************************************/
128 printf("In console\n");
130 DosGetInfoBlocks(&tib
, &pib
);
131 /* Try morphing into a PM application. */
132 // if(pib->pib_ultype == 2) /* VIO */
135 /**********************************************/
136 /**********************************************/
137 #endif //wxUSE_CONSOLEDEBUG
141 // OS2 has to have an anchorblock
143 vHab
= WinInitialize(0);
150 // Some people may wish to use this, but
151 // probably it shouldn't be here by default.
153 // wxRedirectIOToConsole();
156 wxBuffer
= new wxChar
[1500]; // FIXME; why?
158 wxClassInfo::InitializeClasses();
161 wxPendingEventsLocker
= new wxCriticalSection
;
164 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
165 wxTheColourDatabase
->Initialize();
167 wxInitializeStockLists();
168 wxInitializeStockObjects();
170 #if wxUSE_WX_RESOURCES
171 wxInitializeResourceSystem();
174 wxBitmap::InitStandardHandlers();
176 RegisterWindowClasses(vHab
);
177 wxWinHandleList
= new wxList(wxKEY_INTEGER
);
179 // This is to foil optimizations in Visual C++ that throw out dummy.obj.
180 // PLEASE DO NOT ALTER THIS.
181 #if !defined(WXMAKINGDLL) && defined(__VISAGECPP__)
182 extern char wxDummyChar
;
183 if (wxDummyChar
) wxDummyChar
++;
186 // wxSetKeyboardHook(TRUE);
188 wxModule::RegisterModules();
189 if (!wxModule::InitializeModules())
192 } // end of wxApp::Initialize
194 const char* CANTREGISTERCLASS
= " Can't register Class ";
195 // ---------------------------------------------------------------------------
196 // RegisterWindowClasses
197 // ---------------------------------------------------------------------------
199 bool wxApp::RegisterWindowClasses(
207 if (!::WinRegisterClass( vHab
210 ,CS_SIZEREDRAW
| CS_MOVENOTIFY
| CS_SYNCPAINT
214 vError
= ::WinGetLastError(vHab
);
215 sError
= wxPMErrorToStr(vError
);
216 wxLogLastError(sError
);
220 if (!::WinRegisterClass( vHab
221 ,wxFrameClassNameNoRedraw
227 vError
= ::WinGetLastError(vHab
);
228 sError
= wxPMErrorToStr(vError
);
229 wxLogLastError(sError
);
233 if (!::WinRegisterClass( vHab
236 ,CS_SIZEREDRAW
| CS_MOVENOTIFY
| CS_SYNCPAINT
240 vError
= ::WinGetLastError(vHab
);
241 sError
= wxPMErrorToStr(vError
);
242 wxLogLastError(sError
);
246 if (!::WinRegisterClass( vHab
247 ,wxMDIFrameClassNameNoRedraw
253 vError
= ::WinGetLastError(vHab
);
254 sError
= wxPMErrorToStr(vError
);
255 wxLogLastError(sError
);
259 if (!::WinRegisterClass( vHab
260 ,wxMDIChildFrameClassName
262 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_SYNCPAINT
| CS_HITTEST
266 vError
= ::WinGetLastError(vHab
);
267 sError
= wxPMErrorToStr(vError
);
268 wxLogLastError(sError
);
272 if (!::WinRegisterClass( vHab
273 ,wxMDIChildFrameClassNameNoRedraw
279 vError
= ::WinGetLastError(vHab
);
280 sError
= wxPMErrorToStr(vError
);
281 wxLogLastError(sError
);
285 if (!::WinRegisterClass( vHab
288 ,CS_MOVENOTIFY
| CS_SIZEREDRAW
| CS_HITTEST
| CS_SAVEBITS
| CS_SYNCPAINT
292 vError
= ::WinGetLastError(vHab
);
293 sError
= wxPMErrorToStr(vError
);
294 wxLogLastError(sError
);
298 if (!::WinRegisterClass( vHab
301 ,0 // CS_MOVENOTIFY | CS_SIZEREDRAW | CS_HITTEST | CS_SAVEBITS | CS_SYNCPAINT
305 vError
= ::WinGetLastError(vHab
);
306 sError
= wxPMErrorToStr(vError
);
307 wxLogLastError(sError
);
311 } // end of wxApp::RegisterWindowClasses
314 // Cleans up any wxWindows internal structures left lying around
316 void wxApp::CleanUp()
325 // Flush the logged messages if any and install a 'safer' log target: the
326 // default one (wxLogGui) can't be used after the resources are freed just
327 // below and the user suppliedo ne might be even more unsafe (using any
328 // wxWindows GUI function is unsafe starting from now)
330 wxLog::DontCreateOnDemand();
333 // This will flush the old messages if any
335 delete wxLog::SetActiveTarget(new wxLogStderr
);
339 // One last chance for pending objects to be cleaned up
341 wxTheApp
->DeletePendingObjects();
343 wxModule::CleanUpModules();
345 #if wxUSE_WX_RESOURCES
346 wxCleanUpResourceSystem();
349 wxDeleteStockObjects();
352 // Destroy all GDI lists, etc.
354 wxDeleteStockLists();
356 delete wxTheColourDatabase
;
357 wxTheColourDatabase
= NULL
;
359 wxBitmap::CleanUpHandlers();
365 // PM-SPECIFIC CLEANUP
368 // wxSetKeyboardHook(FALSE);
370 if (wxSTD_FRAME_ICON
)
371 ::WinFreeFileIcon(wxSTD_FRAME_ICON
);
372 if (wxSTD_MDICHILDFRAME_ICON
)
373 ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON
);
374 if (wxSTD_MDIPARENTFRAME_ICON
)
375 ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON
);
377 if (wxDEFAULT_FRAME_ICON
)
378 ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON
);
379 if (wxDEFAULT_MDICHILDFRAME_ICON
)
380 ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON
);
381 if (wxDEFAULT_MDIPARENTFRAME_ICON
)
382 ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON
);
384 if ( wxDisableButtonBrush
)
386 // TODO: ::DeleteObject( wxDisableButtonBrush );
390 delete wxWinHandleList
;
392 delete wxPendingEvents
;
394 delete wxPendingEventsLocker
;
395 // If we don't do the following, we get an apparent memory leak.
396 ((wxEvtHandler
&) wxDefaultValidator
).ClearEventLocker();
399 wxClassInfo::CleanUpClasses();
401 // Delete Message queue
403 ::WinDestroyMsgQueue(wxTheApp
->m_hMq
);
408 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
409 // At this point we want to check if there are any memory
410 // blocks that aren't part of the wxDebugContext itself,
411 // as a special case. Then when dumping we need to ignore
412 // wxDebugContext, too.
413 if (wxDebugContext::CountObjectsLeft(TRUE
) > 0)
415 wxLogDebug(wxT("There were memory leaks."));
416 wxDebugContext::Dump();
417 wxDebugContext::PrintStatistics();
419 // wxDebugContext::SetStream(NULL, NULL);
423 // do it as the very last thing because everything else can log messages
424 delete wxLog::SetActiveTarget(NULL
);
426 } // end of wxApp::CleanUp
428 //----------------------------------------------------------------------
429 // Main wxWindows entry point
430 //----------------------------------------------------------------------
438 if (!wxApp::Initialize(vHab
))
442 // create the application object or ensure that one already exists
446 // The app may have declared a global application object, but we recommend
447 // the IMPLEMENT_APP macro is used instead, which sets an initializer
448 // function for delayed, dynamic app object construction.
449 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
450 wxT("No initializer - use IMPLEMENT_APP macro.") );
451 wxTheApp
= (*wxApp::GetInitializerFunction()) ();
453 wxCHECK_MSG( wxTheApp
, 0, wxT("You have to define an instance of wxApp!") );
454 wxTheApp
->argc
= argc
;
457 wxTheApp
->argv
= new wxChar
*[argc
+1];
463 wxTheApp
->argv
[nArgc
] = wxStrdup(wxConvLibc
.cMB2WX(argv
[nArgc
]));
466 wxTheApp
->argv
[nArgc
] = (wxChar
*)NULL
;
468 wxTheApp
->argv
= argv
;
471 wxString
sName(wxFileNameFromPath(argv
[0]));
473 wxStripExtension(sName
);
474 wxTheApp
->SetAppName(sName
);
478 if (!wxTheApp
->OnInitGui())
483 if (wxTheApp
->OnInit())
485 nRetValue
= wxTheApp
->OnRun();
490 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
);
507 else // app initialization failed
509 wxLogLastError(" Gui initialization failed, exitting");
511 #if wxUSE_CONSOLEDEBUG
512 printf("wxTheApp->OnExit ");
516 #if wxUSE_CONSOLEDEBUG
517 printf("wxApp::CleanUp ");
521 #if wxUSE_CONSOLEDEBUG
522 printf("return %i ", nRetValue
);
528 bool wxApp::OnInitGui()
533 m_hMq
= ::WinCreateMsgQueue(vHabmain
, 0);
536 vError
= ::WinGetLastError(vHabmain
);
537 sError
= wxPMErrorToStr(vError
);
542 } // end of wxApp::OnInitGui
545 // Static member initialization
547 wxAppInitializerFunction
wxAppBase::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
553 m_wantDebugOutput
= TRUE
;
557 m_nPrintMode
= wxPRINT_WINDOWS
;
558 m_exitOnFrameDelete
= TRUE
;
561 } // end of wxApp::wxApp
566 // Delete command-line args
571 for (i
= 0; i
< argc
; i
++)
577 } // end of wxApp::~wxApp
579 bool wxApp::Initialized()
585 } // end of wxApp::Initialized
588 // Get and process a message, returning FALSE if WM_QUIT
589 // received (and also set the flag telling the app to exit the main loop)
591 bool wxApp::DoMessage()
593 BOOL bRc
= ::WinGetMsg(vHabmain
, &svCurrentMsg
, HWND(NULL
), 0, 0);
598 m_bKeepGoing
= FALSE
;
603 // should never happen, but let's test for it nevertheless
604 wxLogLastError("GetMessage");
609 wxASSERT_MSG( wxThread::IsMain()
610 ,wxT("only the main thread can process Windows messages")
613 static bool sbHadGuiLock
= TRUE
;
614 static wxMsgArray svSavedMessages
;
617 // If a secondary thread owns is doing GUI calls, save all messages for
618 // later processing - we can't process them right now because it will
619 // lead to recursive library calls (and we're not reentrant)
621 if (!wxGuiOwnedByMainThread())
623 sbHadGuiLock
= FALSE
;
626 // Leave out WM_COMMAND messages: too dangerous, sometimes
627 // the message will be processed twice
629 if ( !wxIsWaitingForThread() ||
630 svCurrentMsg
.msg
!= WM_COMMAND
)
632 svSavedMessages
.Add(svCurrentMsg
);
639 // Have we just regained the GUI lock? if so, post all of the saved
646 size_t nCount
= svSavedMessages
.Count();
648 for (size_t n
= 0; n
< nCount
; n
++)
650 QMSG vMsg
= svSavedMessages
[n
];
652 if ( !ProcessMessage((WXMSG
*)&vMsg
) )
654 ::WinDispatchMsg(vHabmain
, &vMsg
);
657 svSavedMessages
.Empty();
660 #endif // wxUSE_THREADS
662 // Process the message
663 if (!ProcessMessage((WXMSG
*)&svCurrentMsg
))
665 ::WinDispatchMsg(vHabmain
, (PQMSG
)&svCurrentMsg
);
669 } // end of wxApp::DoMessage
671 //////////////////////////////////////////////////////////////////////////////
673 // Keep trying to process messages until WM_QUIT
676 // If there are messages to be processed, they will all be
677 // processed and OnIdle will not be called.
678 // When there are no more messages, OnIdle is called.
679 // If OnIdle requests more time,
680 // it will be repeatedly called so long as there are no pending messages.
681 // A 'feature' of this is that once OnIdle has decided that no more processing
682 // is required, then it won't get processing time until further messages
683 // are processed (it'll sit in DoMessage).
685 //////////////////////////////////////////////////////////////////////////////
686 int wxApp::MainLoop()
693 wxMutexGuiLeaveOrEnter();
694 #endif // wxUSE_THREADS
695 while (/*Pending() &&*/ ProcessIdle())
701 return (int)svCurrentMsg
.mp1
;
702 } // end of wxApp::MainLoop
705 // Returns TRUE if more time is needed.
707 bool wxApp::ProcessIdle()
711 vEvent
.SetEventObject(this);
712 ProcessEvent(vEvent
);
713 return vEvent
.MoreRequested();
714 } // end of wxApp::ProcessIdle
716 void wxApp::ExitMainLoop()
718 m_bKeepGoing
= FALSE
;
721 bool wxApp::Pending()
723 return (::WinPeekMsg(vHabmain
, (PQMSG
)&svCurrentMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) != 0);
726 void wxApp::Dispatch()
731 //////////////////////////////////////////////////////////////////////////////
733 // Give all windows a chance to preprocess
734 // the message. Some may have accelerator tables, or have
735 // MDI complications.
737 //////////////////////////////////////////////////////////////////////////////
738 bool wxApp::ProcessMessage(
742 QMSG
* pMsg
= (PQMSG
)pWxmsg
;
743 HWND hWnd
= pMsg
->hwnd
;
744 wxWindow
* pWndThis
= wxFindWinFromHandle((WXHWND
)hWnd
);
749 // We must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to
750 // popup the tooltip bubbles
752 if (pWndThis
&& (pMsg
->msg
== WM_MOUSEMOVE
))
754 wxToolTip
* pToolTip
= pWndThis
->GetToolTip();
757 pToolTip
->RelayEvent(pWxmsg
);
760 #endif // wxUSE_TOOLTIPS
763 // For some composite controls (like a combobox), wndThis might be NULL
764 // because the subcontrol is not a wxWindow, but only the control itself
765 // is - try to catch this case
767 while (hWnd
&& !pWndThis
)
769 hWnd
= ::WinQueryWindow(hWnd
, QW_PARENT
);
770 pWndThis
= wxFindWinFromHandle((WXHWND
)hWnd
);
774 // Try translations first; find the youngest window with
775 // a translation table. OS/2 has case sensative accels, so
776 // this block, coded by BK, removes that and helps make them
779 if(pMsg
->msg
== WM_CHAR
)
781 PBYTE pChmsg
= (PBYTE
)&(pMsg
->msg
);
782 USHORT uSch
= CHARMSG(pChmsg
)->chr
;
786 // Do not process keyup events
788 if(!(CHARMSG(pChmsg
)->fs
& KC_KEYUP
))
790 if((CHARMSG(pChmsg
)->fs
& (KC_ALT
| KC_CTRL
)) && CHARMSG(pChmsg
)->chr
!= 0)
791 CHARMSG(pChmsg
)->chr
= (USHORT
)wxToupper((UCHAR
)uSch
);
794 for(pWnd
= pWndThis
; pWnd
; pWnd
= pWnd
->GetParent() )
796 if((bRc
= pWnd
->OS2TranslateMessage(pWxmsg
)) == TRUE
)
800 if(!bRc
) // untranslated, should restore original value
801 CHARMSG(pChmsg
)->chr
= uSch
;
805 // Anyone for a non-translation message? Try youngest descendants first.
807 // for (pWnd = pWndThis; pWnd; pWnd = pWnd->GetParent())
809 // if (pWnd->OS2ProcessMessage(pWxmsg))
813 } // end of wxApp::ProcessMessage
819 static bool sbInOnIdle
= FALSE
;
822 // Avoid recursion (via ProcessEvent default case)
830 // If there are pending events, we must process them: pending events
831 // are either events to the threads other than main or events posted
832 // with wxPostEvent() functions
834 ProcessPendingEvents();
837 // 'Garbage' collection of windows deleted with Close().
839 DeletePendingObjects();
843 // Flush the logged messages if any
845 wxLog::FlushActive();
849 // Send OnIdle events to all windows
851 if (SendIdleEvents())
854 // SendIdleEvents() returns TRUE if at least one window requested more
857 rEvent
.RequestMore(TRUE
);
860 } // end of wxApp::OnIdle
862 // Send idle event to all top-level windows
863 bool wxApp::SendIdleEvents()
865 bool bNeedMore
= FALSE
;
866 wxWindowList::Node
* pNode
= wxTopLevelWindows
.GetFirst();
870 wxWindow
* pWin
= pNode
->GetData();
872 if (SendIdleEvents(pWin
))
874 pNode
= pNode
->GetNext();
877 } // end of wxApp::SendIdleEvents
880 // Send idle event to window and all subwindows
882 bool wxApp::SendIdleEvents(
886 bool bNeedMore
= FALSE
;
889 vEvent
.SetEventObject(pWin
);
890 pWin
->GetEventHandler()->ProcessEvent(vEvent
);
892 if (vEvent
.MoreRequested())
895 wxNode
* pNode
= pWin
->GetChildren().First();
899 wxWindow
* pWin
= (wxWindow
*) pNode
->Data();
901 if (SendIdleEvents(pWin
))
903 pNode
= pNode
->Next();
906 } // end of wxApp::SendIdleEvents
908 void wxApp::DeletePendingObjects()
910 wxNode
* pNode
= wxPendingDelete
.First();
914 wxObject
* pObj
= (wxObject
*)pNode
->Data();
918 if (wxPendingDelete
.Member(pObj
))
922 // Deleting one object may have deleted other pending
923 // objects, so start from beginning of list again.
925 pNode
= wxPendingDelete
.First();
927 } // end of wxApp::DeletePendingObjects
929 void wxApp::OnEndSession(
930 wxCloseEvent
& WXUNUSED(rEvent
))
933 GetTopWindow()->Close(TRUE
);
934 } // end of wxApp::OnEndSession
937 // Default behaviour: close the application with prompts. The
938 // user can veto the close, and therefore the end session.
940 void wxApp::OnQueryEndSession(
946 if (!GetTopWindow()->Close(!rEvent
.CanVeto()))
949 } // end of wxApp::OnQueryEndSession
953 wxLogError(_("Fatal error: exiting"));
959 // Yield to incoming messages
967 // Disable log flushing from here because a call to wxYield() shouldn't
968 // normally result in message boxes popping up &c
973 // We want to go back to the main message loop
974 // if we see a WM_QUIT. (?)
976 while (::WinPeekMsg(vHab
, &vMsg
, (HWND
)NULL
, 0, 0, PM_NOREMOVE
) && vMsg
.msg
!= WM_QUIT
)
979 wxMutexGuiLeaveOrEnter();
980 #endif // wxUSE_THREADS
981 if (!wxTheApp
->DoMessage())
985 // If they are pending events, we must process them.
988 wxTheApp
->ProcessPendingEvents();
991 // Let the logs be flashed again
997 wxIcon
wxApp::GetStdIcon(
1003 case wxICON_INFORMATION
:
1004 return wxIcon("wxICON_INFO");
1006 case wxICON_QUESTION
:
1007 return wxIcon("wxICON_QUESTION");
1009 case wxICON_EXCLAMATION
:
1010 return wxIcon("wxICON_WARNING");
1013 wxFAIL_MSG(wxT("requested non existent standard icon"));
1014 // still fall through
1017 return wxIcon("wxICON_ERROR");
1019 return wxIcon("wxICON_ERROR");
1020 } // end of wxApp::GetStdIcon
1022 //-----------------------------------------------------------------------------
1024 //-----------------------------------------------------------------------------
1029 // Send the top window a dummy message so idle handler processing will
1030 // start up again. Doing it this way ensures that the idle handler
1031 // wakes up in the right thread (see also wxWakeUpMainThread() which does
1032 // the same for the main app thread only)
1034 wxWindow
* pTopWindow
= wxTheApp
->GetTopWindow();
1038 if ( !::WinPostMsg(GetHwndOf(pTopWindow
), WM_NULL
, (MPARAM
)0, (MPARAM
)0))
1041 // Should never happen
1043 wxLogLastError("PostMessage(WM_NULL)");
1046 } // end of wxWakeUpIdle