]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/os2/app.cpp
Added a couple more numeric character references
[wxWidgets.git] / src / os2 / app.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: app.cpp
3// Purpose: wxApp
4// Author: David Webster
5// Modified by:
6// Created: 10/13/99
7// RCS-ID: $Id$
8// Copyright: (c) David Webster
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifndef WX_PRECOMP
16 #include "wx/frame.h"
17 #include "wx/app.h"
18 #include "wx/utils.h"
19 #include "wx/gdicmn.h"
20 #include "wx/pen.h"
21 #include "wx/brush.h"
22 #include "wx/cursor.h"
23 #include "wx/icon.h"
24 #include "wx/palette.h"
25 #include "wx/dc.h"
26 #include "wx/dialog.h"
27 #include "wx/msgdlg.h"
28 #include "wx/intl.h"
29 #include "wx/dynarray.h"
30 #include "wx/wxchar.h"
31 #include "wx/icon.h"
32 #include "wx/timer.h"
33#endif
34
35#include "wx/log.h"
36#include "wx/module.h"
37
38#include "wx/os2/private.h"
39
40#if wxUSE_THREADS
41 #include "wx/thread.h"
42
43 // define the array of QMSG strutures
44 WX_DECLARE_OBJARRAY(QMSG, wxMsgArray);
45
46 #include "wx/arrimpl.cpp"
47
48 WX_DEFINE_OBJARRAY(wxMsgArray);
49#endif // wxUSE_THREADS
50
51#if wxUSE_WX_RESOURCES
52 #include "wx/resource.h"
53#endif
54
55#if wxUSE_TOOLTIPS
56 #include "wx/tooltip.h"
57#endif // wxUSE_TOOLTIPS
58
59#include <string.h>
60#include <ctype.h>
61
62// ---------------------------------------------------------------------------
63// global variables
64// ---------------------------------------------------------------------------
65
66extern wxChar* wxBuffer;
67extern wxList* wxWinHandleList;
68extern wxList WXDLLEXPORT wxPendingDelete;
69extern wxCursor* g_globalCursor;
70
71HAB vHabmain = NULLHANDLE;
72QMSG svCurrentMsg;
73wxApp* wxTheApp = NULL;
74
75// NB: all "NoRedraw" classes must have the same names as the "normal" classes
76// with NR suffix - wxWindow::OS2Create() supposes this
77wxChar wxFrameClassName[] = wxT("wxFrameClass");
78wxChar wxFrameClassNameNoRedraw[] = wxT("wxFrameClassNR");
79wxChar wxMDIFrameClassName[] = wxT("wxMDIFrameClass");
80wxChar wxMDIFrameClassNameNoRedraw[] = wxT("wxMDIFrameClassNR");
81wxChar wxMDIChildFrameClassName[] = wxT("wxMDIChildFrameClass");
82wxChar wxMDIChildFrameClassNameNoRedraw[] = wxT("wxMDIChildFrameClassNR");
83wxChar wxPanelClassName[] = wxT("wxPanelClass");
84wxChar wxCanvasClassName[] = wxT("wxCanvasClass");
85
86HICON wxSTD_FRAME_ICON = (HICON) NULL;
87HICON wxSTD_MDICHILDFRAME_ICON = (HICON) NULL;
88HICON wxSTD_MDIPARENTFRAME_ICON = (HICON) NULL;
89
90HICON wxDEFAULT_FRAME_ICON = (HICON) NULL;
91HICON wxDEFAULT_MDICHILDFRAME_ICON = (HICON) NULL;
92HICON wxDEFAULT_MDIPARENTFRAME_ICON = (HICON) NULL;
93
94HBRUSH wxDisableButtonBrush = (HBRUSH) 0;
95
96MRESULT EXPENTRY wxWndProc( HWND hWnd,ULONG message,MPARAM mp1,MPARAM mp2);
97MRESULT EXPENTRY wxFrameWndProc( HWND hWnd,ULONG message,MPARAM mp1,MPARAM mp2);
98
99// ===========================================================================
100// implementation
101// ===========================================================================
102
103// ---------------------------------------------------------------------------
104// wxApp
105// ---------------------------------------------------------------------------
106
107 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
108
109 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
110 EVT_IDLE(wxApp::OnIdle)
111 EVT_END_SESSION(wxApp::OnEndSession)
112 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
113 END_EVENT_TABLE()
114
115//
116// Initialize
117//
118bool wxApp::Initialize(
119 HAB vHab
120)
121{
122#if defined(wxUSE_CONSOLEDEBUG)
123 #if wxUSE_CONSOLEDEBUG
124/***********************************************/
125/* Code for using stdout debug */
126/* To use it you mast link app as "Window" - EK*/
127/***********************************************/
128 {
129 PPIB pib;
130 PTIB tib;
131
132 printf("In console\n");
133
134 DosGetInfoBlocks(&tib, &pib);
135/* Try morphing into a PM application. */
136// if(pib->pib_ultype == 2) /* VIO */
137 pib->pib_ultype = 3;
138 }
139/**********************************************/
140/**********************************************/
141 #endif //wxUSE_CONSOLEDEBUG
142#endif
143
144 //
145 // OS2 has to have an anchorblock
146 //
147 vHab = WinInitialize(0);
148
149 if (!vHab)
150 return FALSE;
151 else
152 vHabmain = vHab;
153
154 // Some people may wish to use this, but
155 // probably it shouldn't be here by default.
156#ifdef __WXDEBUG__
157 // wxRedirectIOToConsole();
158#endif
159
160 wxBuffer = new wxChar[1500]; // FIXME; why?
161
162 wxClassInfo::InitializeClasses();
163
164#if wxUSE_THREADS
165 wxPendingEventsLocker = new wxCriticalSection;
166#endif
167
168 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
169 wxTheColourDatabase->Initialize();
170
171 wxInitializeStockLists();
172 wxInitializeStockObjects();
173
174#if wxUSE_WX_RESOURCES
175 wxInitializeResourceSystem();
176#endif
177
178 wxBitmap::InitStandardHandlers();
179
180 RegisterWindowClasses(vHab);
181 wxWinHandleList = new wxList(wxKEY_INTEGER);
182
183 // This is to foil optimizations in Visual C++ that throw out dummy.obj.
184 // PLEASE DO NOT ALTER THIS.
185#if !defined(WXMAKINGDLL) && defined(__VISAGECPP__)
186 extern char wxDummyChar;
187 if (wxDummyChar) wxDummyChar++;
188#endif
189
190 // wxSetKeyboardHook(TRUE);
191
192 wxModule::RegisterModules();
193 if (!wxModule::InitializeModules())
194 return FALSE;
195 return TRUE;
196} // end of wxApp::Initialize
197
198const char* CANTREGISTERCLASS = " Can't register Class ";
199// ---------------------------------------------------------------------------
200// RegisterWindowClasses
201// ---------------------------------------------------------------------------
202
203bool wxApp::RegisterWindowClasses(
204 HAB vHab
205)
206{
207 APIRET rc;
208 ERRORID vError = 0L;
209 wxString sError;
210
211 if (!::WinRegisterClass( vHab
212 ,wxFrameClassName
213 ,wxFrameWndProc
214 ,CS_SIZEREDRAW | CS_MOVENOTIFY | CS_SYNCPAINT | CS_CLIPCHILDREN
215 ,sizeof(ULONG)
216 ))
217 {
218 vError = ::WinGetLastError(vHab);
219 sError = wxPMErrorToStr(vError);
220 wxLogLastError(sError);
221 return FALSE;
222 }
223
224 if (!::WinRegisterClass( vHab
225 ,wxFrameClassNameNoRedraw
226 ,wxWndProc
227 ,0
228 ,sizeof(ULONG)
229 ))
230 {
231 vError = ::WinGetLastError(vHab);
232 sError = wxPMErrorToStr(vError);
233 wxLogLastError(sError);
234 return FALSE;
235 }
236
237 if (!::WinRegisterClass( vHab
238 ,wxMDIFrameClassName
239 ,wxWndProc
240 ,CS_SIZEREDRAW | CS_MOVENOTIFY | CS_SYNCPAINT
241 ,sizeof(ULONG)
242 ))
243 {
244 vError = ::WinGetLastError(vHab);
245 sError = wxPMErrorToStr(vError);
246 wxLogLastError(sError);
247 return FALSE;
248 }
249
250 if (!::WinRegisterClass( vHab
251 ,wxMDIFrameClassNameNoRedraw
252 ,wxWndProc
253 ,0
254 ,sizeof(ULONG)
255 ))
256 {
257 vError = ::WinGetLastError(vHab);
258 sError = wxPMErrorToStr(vError);
259 wxLogLastError(sError);
260 return FALSE;
261 }
262
263 if (!::WinRegisterClass( vHab
264 ,wxMDIChildFrameClassName
265 ,wxWndProc
266 ,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_SYNCPAINT | CS_HITTEST
267 ,sizeof(ULONG)
268 ))
269 {
270 vError = ::WinGetLastError(vHab);
271 sError = wxPMErrorToStr(vError);
272 wxLogLastError(sError);
273 return FALSE;
274 }
275
276 if (!::WinRegisterClass( vHab
277 ,wxMDIChildFrameClassNameNoRedraw
278 ,wxWndProc
279 ,CS_HITTEST
280 ,sizeof(ULONG)
281 ))
282 {
283 vError = ::WinGetLastError(vHab);
284 sError = wxPMErrorToStr(vError);
285 wxLogLastError(sError);
286 return FALSE;
287 }
288
289 if (!::WinRegisterClass( vHab
290 ,wxPanelClassName
291 ,wxWndProc
292 ,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_HITTEST | CS_SAVEBITS | CS_SYNCPAINT
293 ,sizeof(ULONG)
294 ))
295 {
296 vError = ::WinGetLastError(vHab);
297 sError = wxPMErrorToStr(vError);
298 wxLogLastError(sError);
299 return FALSE;
300 }
301
302 if (!::WinRegisterClass( vHab
303 ,wxCanvasClassName
304 ,wxWndProc
305 ,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_HITTEST | CS_SAVEBITS | CS_SYNCPAINT | CS_CLIPCHILDREN
306 ,sizeof(ULONG)
307 ))
308 {
309 vError = ::WinGetLastError(vHab);
310 sError = wxPMErrorToStr(vError);
311 wxLogLastError(sError);
312 return FALSE;
313 }
314 return TRUE;
315} // end of wxApp::RegisterWindowClasses
316
317//
318// Cleans up any wxWindows internal structures left lying around
319//
320void wxApp::CleanUp()
321{
322 //
323 // COMMON CLEANUP
324 //
325
326#if wxUSE_LOG
327
328 //
329 // Flush the logged messages if any and install a 'safer' log target: the
330 // default one (wxLogGui) can't be used after the resources are freed just
331 // below and the user suppliedo ne might be even more unsafe (using any
332 // wxWindows GUI function is unsafe starting from now)
333 //
334 wxLog::DontCreateOnDemand();
335
336 //
337 // This will flush the old messages if any
338 //
339 delete wxLog::SetActiveTarget(new wxLogStderr);
340#endif // wxUSE_LOG
341
342 //
343 // One last chance for pending objects to be cleaned up
344 //
345 wxTheApp->DeletePendingObjects();
346
347 wxModule::CleanUpModules();
348
349#if wxUSE_WX_RESOURCES
350 wxCleanUpResourceSystem();
351#endif
352
353 wxDeleteStockObjects();
354
355 //
356 // Destroy all GDI lists, etc.
357 //
358 wxDeleteStockLists();
359
360 delete wxTheColourDatabase;
361 wxTheColourDatabase = NULL;
362
363 wxBitmap::CleanUpHandlers();
364
365 delete[] wxBuffer;
366 wxBuffer = NULL;
367
368 //
369 // PM-SPECIFIC CLEANUP
370 //
371
372 // wxSetKeyboardHook(FALSE);
373
374 if (wxSTD_FRAME_ICON)
375 ::WinFreeFileIcon(wxSTD_FRAME_ICON);
376 if (wxSTD_MDICHILDFRAME_ICON)
377 ::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON);
378 if (wxSTD_MDIPARENTFRAME_ICON)
379 ::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON);
380
381 if (wxDEFAULT_FRAME_ICON)
382 ::WinFreeFileIcon(wxDEFAULT_FRAME_ICON);
383 if (wxDEFAULT_MDICHILDFRAME_ICON)
384 ::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON);
385 if (wxDEFAULT_MDIPARENTFRAME_ICON)
386 ::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON);
387
388 if ( wxDisableButtonBrush )
389 {
390// TODO: ::DeleteObject( wxDisableButtonBrush );
391 }
392
393 if (wxWinHandleList)
394 delete wxWinHandleList;
395
396 delete wxPendingEvents;
397#if wxUSE_THREADS
398 delete wxPendingEventsLocker;
399 // If we don't do the following, we get an apparent memory leak.
400 ((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
401#endif
402
403 wxClassInfo::CleanUpClasses();
404
405 // Delete Message queue
406 if (wxTheApp->m_hMq)
407 ::WinDestroyMsgQueue(wxTheApp->m_hMq);
408
409 delete wxTheApp;
410 wxTheApp = NULL;
411
412#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
413 // At this point we want to check if there are any memory
414 // blocks that aren't part of the wxDebugContext itself,
415 // as a special case. Then when dumping we need to ignore
416 // wxDebugContext, too.
417 if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
418 {
419 wxLogDebug(wxT("There were memory leaks."));
420 wxDebugContext::Dump();
421 wxDebugContext::PrintStatistics();
422 }
423 // wxDebugContext::SetStream(NULL, NULL);
424#endif
425
426#if wxUSE_LOG
427 // do it as the very last thing because everything else can log messages
428 delete wxLog::SetActiveTarget(NULL);
429#endif // wxUSE_LOG
430} // end of wxApp::CleanUp
431
432//----------------------------------------------------------------------
433// Main wxWindows entry point
434//----------------------------------------------------------------------
435int wxEntry(
436 int argc
437, char* argv[]
438)
439{
440 HAB vHab = 0;
441
442 if (!wxApp::Initialize(vHab))
443 return 0;
444
445 //
446 // create the application object or ensure that one already exists
447 //
448 if (!wxTheApp)
449 {
450 // The app may have declared a global application object, but we recommend
451 // the IMPLEMENT_APP macro is used instead, which sets an initializer
452 // function for delayed, dynamic app object construction.
453 wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
454 wxT("No initializer - use IMPLEMENT_APP macro.") );
455 wxTheApp = (*wxApp::GetInitializerFunction()) ();
456 }
457 wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") );
458 wxTheApp->argc = argc;
459
460#if wxUSE_UNICODE
461 wxTheApp->argv = new wxChar*[argc+1];
462
463 int nArgc = 0;
464
465 while (nArgc < argc)
466 {
467 wxTheApp->argv[nArgc] = wxStrdup(wxConvLibc.cMB2WX(argv[nArgc]));
468 nArgc++;
469 }
470 wxTheApp->argv[nArgc] = (wxChar *)NULL;
471#else
472 wxTheApp->argv = argv;
473#endif
474
475 wxString sName(wxFileNameFromPath(argv[0]));
476
477 wxStripExtension(sName);
478 wxTheApp->SetAppName(sName);
479
480 int nRetValue = 0;
481
482 if (!wxTheApp->OnInitGui())
483 nRetValue = -1;
484
485 if (nRetValue == 0)
486 {
487 if (wxTheApp->OnInit())
488 {
489 nRetValue = wxTheApp->OnRun();
490 }
491 // Normal exit
492 wxWindow* pTopWindow = wxTheApp->GetTopWindow();
493 if (pTopWindow)
494 {
495 // Forcibly delete the window.
496 if (pTopWindow->IsKindOf(CLASSINFO(wxFrame)) ||
497 pTopWindow->IsKindOf(CLASSINFO(wxDialog)) )
498 {
499 pTopWindow->Close(TRUE);
500 wxTheApp->DeletePendingObjects();
501 }
502 else
503 {
504 delete pTopWindow;
505 wxTheApp->SetTopWindow(NULL);
506 }
507 }
508 }
509 else // app initialization failed
510 {
511 wxLogLastError(" Gui initialization failed, exitting");
512 }
513#if wxUSE_CONSOLEDEBUG
514 printf("wxTheApp->OnExit ");
515 fflush(stdout);
516#endif
517 wxTheApp->OnExit();
518#if wxUSE_CONSOLEDEBUG
519 printf("wxApp::CleanUp ");
520 fflush(stdout);
521#endif
522 wxApp::CleanUp();
523#if wxUSE_CONSOLEDEBUG
524 printf("return %i ", nRetValue);
525 fflush(stdout);
526#endif
527 return(nRetValue);
528} // end of wxEntry
529
530bool wxApp::OnInitGui()
531{
532 ERRORID vError;
533 wxString sError;
534
535 m_hMq = ::WinCreateMsgQueue(vHabmain, 0);
536 if (!m_hMq)
537 {
538 vError = ::WinGetLastError(vHabmain);
539 sError = wxPMErrorToStr(vError);
540 wxLogDebug(sError);
541 return FALSE;
542 }
543 return TRUE;
544} // end of wxApp::OnInitGui
545
546//
547// Static member initialization
548//
549wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
550
551wxApp::wxApp()
552{
553 m_topWindow = NULL;
554 wxTheApp = this;
555 m_wantDebugOutput = TRUE;
556
557 argc = 0;
558 argv = NULL;
559 m_nPrintMode = wxPRINT_WINDOWS;
560 m_exitOnFrameDelete = TRUE;
561 m_bAuto3D = TRUE;
562 m_hMq = 0;
563} // end of wxApp::wxApp
564
565wxApp::~wxApp()
566{
567 //
568 // Delete command-line args
569 //
570#if wxUSE_UNICODE
571 int i;
572
573 for (i = 0; i < argc; i++)
574 {
575 delete[] argv[i];
576 }
577 delete[] argv;
578#endif
579} // end of wxApp::~wxApp
580
581bool wxApp::Initialized()
582{
583 if (GetTopWindow())
584 return TRUE;
585 else
586 return FALSE;
587} // end of wxApp::Initialized
588
589//
590// Get and process a message, returning FALSE if WM_QUIT
591// received (and also set the flag telling the app to exit the main loop)
592//
593bool wxApp::DoMessage()
594{
595 BOOL bRc = ::WinGetMsg(vHabmain, &svCurrentMsg, HWND(NULL), 0, 0);
596
597 if (bRc == 0)
598 {
599 // got WM_QUIT
600 m_bKeepGoing = FALSE;
601 return FALSE;
602 }
603 else if (bRc == -1)
604 {
605 // should never happen, but let's test for it nevertheless
606 wxLogLastError("GetMessage");
607 }
608 else
609 {
610#if wxUSE_THREADS
611 wxASSERT_MSG( wxThread::IsMain()
612 ,wxT("only the main thread can process Windows messages")
613 );
614
615 static bool sbHadGuiLock = TRUE;
616 static wxMsgArray svSavedMessages;
617
618 //
619 // If a secondary thread owns is doing GUI calls, save all messages for
620 // later processing - we can't process them right now because it will
621 // lead to recursive library calls (and we're not reentrant)
622 //
623 if (!wxGuiOwnedByMainThread())
624 {
625 sbHadGuiLock = FALSE;
626
627 //
628 // Leave out WM_COMMAND messages: too dangerous, sometimes
629 // the message will be processed twice
630 //
631 if ( !wxIsWaitingForThread() ||
632 svCurrentMsg.msg != WM_COMMAND )
633 {
634 svSavedMessages.Add(svCurrentMsg);
635 }
636 return TRUE;
637 }
638 else
639 {
640 //
641 // Have we just regained the GUI lock? if so, post all of the saved
642 // messages
643 //
644 if (!sbHadGuiLock )
645 {
646 sbHadGuiLock = TRUE;
647
648 size_t nCount = svSavedMessages.Count();
649
650 for (size_t n = 0; n < nCount; n++)
651 {
652 QMSG vMsg = svSavedMessages[n];
653
654 if ( !ProcessMessage((WXMSG *)&vMsg) )
655 {
656 ::WinDispatchMsg(vHabmain, &vMsg);
657 }
658 }
659 svSavedMessages.Empty();
660 }
661 }
662#endif // wxUSE_THREADS
663
664 // Process the message
665 if (!ProcessMessage((WXMSG *)&svCurrentMsg))
666 {
667 ::WinDispatchMsg(vHabmain, (PQMSG)&svCurrentMsg);
668 }
669 }
670 return TRUE;
671} // end of wxApp::DoMessage
672
673//////////////////////////////////////////////////////////////////////////////
674//
675// Keep trying to process messages until WM_QUIT
676// received.
677//
678// If there are messages to be processed, they will all be
679// processed and OnIdle will not be called.
680// When there are no more messages, OnIdle is called.
681// If OnIdle requests more time,
682// it will be repeatedly called so long as there are no pending messages.
683// A 'feature' of this is that once OnIdle has decided that no more processing
684// is required, then it won't get processing time until further messages
685// are processed (it'll sit in DoMessage).
686//
687//////////////////////////////////////////////////////////////////////////////
688int wxApp::MainLoop()
689{
690 m_bKeepGoing = TRUE;
691
692 while (m_bKeepGoing)
693 {
694#if wxUSE_THREADS
695 wxMutexGuiLeaveOrEnter();
696#endif // wxUSE_THREADS
697 while (/*Pending() &&*/ ProcessIdle())
698 {
699// wxUsleep(10000);
700 }
701 DoMessage();
702 }
703 return (int)svCurrentMsg.mp1;
704} // end of wxApp::MainLoop
705
706//
707// Returns TRUE if more time is needed.
708//
709bool wxApp::ProcessIdle()
710{
711 wxIdleEvent vEvent;
712
713 vEvent.SetEventObject(this);
714 ProcessEvent(vEvent);
715 return vEvent.MoreRequested();
716} // end of wxApp::ProcessIdle
717
718void wxApp::ExitMainLoop()
719{
720 m_bKeepGoing = FALSE;
721}
722
723bool wxApp::Pending()
724{
725 return (::WinPeekMsg(vHabmain, (PQMSG)&svCurrentMsg, (HWND)NULL, 0, 0, PM_NOREMOVE) != 0);
726}
727
728void wxApp::Dispatch()
729{
730 DoMessage();
731}
732
733//////////////////////////////////////////////////////////////////////////////
734//
735// Give all windows a chance to preprocess
736// the message. Some may have accelerator tables, or have
737// MDI complications.
738//
739//////////////////////////////////////////////////////////////////////////////
740bool wxApp::ProcessMessage(
741 WXMSG* pWxmsg
742)
743{
744 QMSG* pMsg = (PQMSG)pWxmsg;
745 HWND hWnd = pMsg->hwnd;
746 wxWindow* pWndThis = wxFindWinFromHandle((WXHWND)hWnd);
747 wxWindow* pWnd;
748
749#if wxUSE_TOOLTIPS
750 //
751 // We must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to
752 // popup the tooltip bubbles
753 //
754 if (pWndThis && (pMsg->msg == WM_MOUSEMOVE))
755 {
756 wxToolTip* pToolTip = pWndThis->GetToolTip();
757 if (pToolTip)
758 {
759 pToolTip->RelayEvent(pWxmsg);
760 }
761 }
762#endif // wxUSE_TOOLTIPS
763
764 //
765 // We must relay Timer events to wxTimer's processing function
766 //
767 if (pMsg->msg == WM_TIMER)
768 wxTimerProc(NULL, 0, (int)pMsg->mp1, 0);
769
770 //
771 // For some composite controls (like a combobox), wndThis might be NULL
772 // because the subcontrol is not a wxWindow, but only the control itself
773 // is - try to catch this case
774 //
775 while (hWnd && !pWndThis)
776 {
777 hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
778 pWndThis = wxFindWinFromHandle((WXHWND)hWnd);
779 }
780
781 //
782 // Try translations first; find the youngest window with
783 // a translation table. OS/2 has case sensative accels, so
784 // this block, coded by BK, removes that and helps make them
785 // case insensative.
786 //
787 if(pMsg->msg == WM_CHAR)
788 {
789 PBYTE pChmsg = (PBYTE)&(pMsg->msg);
790 USHORT uSch = CHARMSG(pChmsg)->chr;
791 bool bRc;
792
793 //
794 // Do not process keyup events
795 //
796 if(!(CHARMSG(pChmsg)->fs & KC_KEYUP))
797 {
798 if((CHARMSG(pChmsg)->fs & (KC_ALT | KC_CTRL)) && CHARMSG(pChmsg)->chr != 0)
799 CHARMSG(pChmsg)->chr = (USHORT)wxToupper((UCHAR)uSch);
800
801
802 for(pWnd = pWndThis; pWnd; pWnd = pWnd->GetParent() )
803 {
804 if((bRc = pWnd->OS2TranslateMessage(pWxmsg)) == TRUE)
805 break;
806 }
807
808 if(!bRc) // untranslated, should restore original value
809 CHARMSG(pChmsg)->chr = uSch;
810 }
811 }
812 //
813 // Anyone for a non-translation message? Try youngest descendants first.
814 //
815// for (pWnd = pWndThis; pWnd; pWnd = pWnd->GetParent())
816// {
817// if (pWnd->OS2ProcessMessage(pWxmsg))
818// return TRUE;
819// }
820 return FALSE;
821} // end of wxApp::ProcessMessage
822
823void wxApp::OnIdle(
824 wxIdleEvent& rEvent
825)
826{
827 static bool sbInOnIdle = FALSE;
828
829 //
830 // Avoid recursion (via ProcessEvent default case)
831 //
832 if (sbInOnIdle)
833 return;
834
835 sbInOnIdle = TRUE;
836
837 //
838 // If there are pending events, we must process them: pending events
839 // are either events to the threads other than main or events posted
840 // with wxPostEvent() functions
841 //
842 ProcessPendingEvents();
843
844 //
845 // 'Garbage' collection of windows deleted with Close().
846 //
847 DeletePendingObjects();
848
849#if wxUSE_LOG
850 //
851 // Flush the logged messages if any
852 //
853 wxLog::FlushActive();
854#endif // wxUSE_LOG
855
856 //
857 // Send OnIdle events to all windows
858 //
859 if (SendIdleEvents())
860 {
861 //
862 // SendIdleEvents() returns TRUE if at least one window requested more
863 // idle events
864 //
865 rEvent.RequestMore(TRUE);
866 }
867 sbInOnIdle = FALSE;
868} // end of wxApp::OnIdle
869
870// Send idle event to all top-level windows
871bool wxApp::SendIdleEvents()
872{
873 bool bNeedMore = FALSE;
874 wxWindowList::Node* pNode = wxTopLevelWindows.GetFirst();
875
876 while (pNode)
877 {
878 wxWindow* pWin = pNode->GetData();
879
880 if (SendIdleEvents(pWin))
881 bNeedMore = TRUE;
882 pNode = pNode->GetNext();
883 }
884 return bNeedMore;
885} // end of wxApp::SendIdleEvents
886
887//
888// Send idle event to window and all subwindows
889//
890bool wxApp::SendIdleEvents(
891 wxWindow* pWin
892)
893{
894 bool bNeedMore = FALSE;
895 wxIdleEvent vEvent;
896
897 vEvent.SetEventObject(pWin);
898 pWin->GetEventHandler()->ProcessEvent(vEvent);
899
900 if (vEvent.MoreRequested())
901 bNeedMore = TRUE;
902
903 wxNode* pNode = pWin->GetChildren().First();
904
905 while (pNode)
906 {
907 wxWindow* pWin = (wxWindow*) pNode->Data();
908
909 if (SendIdleEvents(pWin))
910 bNeedMore = TRUE;
911 pNode = pNode->Next();
912 }
913 return bNeedMore;
914} // end of wxApp::SendIdleEvents
915
916void wxApp::DeletePendingObjects()
917{
918 wxNode* pNode = wxPendingDelete.First();
919
920 while (pNode)
921 {
922 wxObject* pObj = (wxObject *)pNode->Data();
923
924 delete pObj;
925
926 if (wxPendingDelete.Member(pObj))
927 delete pNode;
928
929 //
930 // Deleting one object may have deleted other pending
931 // objects, so start from beginning of list again.
932 //
933 pNode = wxPendingDelete.First();
934 }
935} // end of wxApp::DeletePendingObjects
936
937void wxApp::OnEndSession(
938 wxCloseEvent& WXUNUSED(rEvent))
939{
940 if (GetTopWindow())
941 GetTopWindow()->Close(TRUE);
942} // end of wxApp::OnEndSession
943
944//
945// Default behaviour: close the application with prompts. The
946// user can veto the close, and therefore the end session.
947//
948void wxApp::OnQueryEndSession(
949 wxCloseEvent& rEvent
950)
951{
952 if (GetTopWindow())
953 {
954 if (!GetTopWindow()->Close(!rEvent.CanVeto()))
955 rEvent.Veto(TRUE);
956 }
957} // end of wxApp::OnQueryEndSession
958
959void wxExit()
960{
961 wxLogError(_("Fatal error: exiting"));
962
963 wxApp::CleanUp();
964} // end of wxExit
965
966static bool gs_inYield = FALSE;
967
968//
969// Yield to incoming messages
970//
971bool wxYield()
972{
973 HAB vHab = 0;
974 QMSG vMsg;
975
976 //
977 // Disable log flushing from here because a call to wxYield() shouldn't
978 // normally result in message boxes popping up &c
979 //
980 wxLog::Suspend();
981
982 gs_inYield = TRUE;
983
984 //
985 // We want to go back to the main message loop
986 // if we see a WM_QUIT. (?)
987 //
988 while (::WinPeekMsg(vHab, &vMsg, (HWND)NULL, 0, 0, PM_NOREMOVE) && vMsg.msg != WM_QUIT)
989 {
990#if wxUSE_THREADS
991 wxMutexGuiLeaveOrEnter();
992#endif // wxUSE_THREADS
993 if (!wxTheApp->DoMessage())
994 break;
995 }
996 //
997 // If they are pending events, we must process them.
998 //
999 if (wxTheApp)
1000 wxTheApp->ProcessPendingEvents();
1001
1002 //
1003 // Let the logs be flashed again
1004 //
1005 wxLog::Resume();
1006 gs_inYield = FALSE;
1007 return TRUE;
1008} // end of wxYield
1009
1010// Yield to incoming messages; but fail silently if recursion is detected.
1011bool wxYieldIfNeeded()
1012{
1013 if (gs_inYield)
1014 return FALSE;
1015
1016 return wxYield();
1017}
1018
1019wxIcon wxApp::GetStdIcon(
1020 int nWhich
1021) const
1022{
1023 switch(nWhich)
1024 {
1025 case wxICON_INFORMATION:
1026 return wxIcon("wxICON_INFO");
1027
1028 case wxICON_QUESTION:
1029 return wxIcon("wxICON_QUESTION");
1030
1031 case wxICON_EXCLAMATION:
1032 return wxIcon("wxICON_WARNING");
1033
1034 default:
1035 wxFAIL_MSG(wxT("requested non existent standard icon"));
1036 // still fall through
1037
1038 case wxICON_HAND:
1039 return wxIcon("wxICON_ERROR");
1040 }
1041 return wxIcon("wxICON_ERROR");
1042} // end of wxApp::GetStdIcon
1043
1044//-----------------------------------------------------------------------------
1045// wxWakeUpIdle
1046//-----------------------------------------------------------------------------
1047
1048void wxWakeUpIdle()
1049{
1050 //
1051 // Send the top window a dummy message so idle handler processing will
1052 // start up again. Doing it this way ensures that the idle handler
1053 // wakes up in the right thread (see also wxWakeUpMainThread() which does
1054 // the same for the main app thread only)
1055 //
1056 wxWindow* pTopWindow = wxTheApp->GetTopWindow();
1057
1058 if (pTopWindow)
1059 {
1060 if ( !::WinPostMsg(GetHwndOf(pTopWindow), WM_NULL, (MPARAM)0, (MPARAM)0))
1061 {
1062 //
1063 // Should never happen
1064 //
1065 wxLogLastError("PostMessage(WM_NULL)");
1066 }
1067 }
1068} // end of wxWakeUpIdle
1069
1070HAB wxGetInstance()
1071{
1072 return vHabmain;
1073}
1074
1075void wxSetInstance(
1076 HAB vHab
1077)
1078{
1079 vHabmain = vHab;
1080}
1081