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