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