]> git.saurik.com Git - wxWidgets.git/blame - src/msw/app.cpp
removed compilation warning about "switch with default but no case" (no
[wxWidgets.git] / src / msw / app.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: app.cpp
3// Purpose: wxApp
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "app.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#define IN_WX_MAIN_CPP
18#include "wx/wxprec.h"
19
20#if defined(__BORLANDC__)
21#pragma hdrstop
22#endif
23
24#ifndef WX_PRECOMP
25#include "wx/frame.h"
26#include "wx/app.h"
27#include "wx/utils.h"
28#include "wx/gdicmn.h"
29#include "wx/pen.h"
30#include "wx/brush.h"
31#include "wx/cursor.h"
32#include "wx/icon.h"
33#include "wx/palette.h"
34#include "wx/dc.h"
35#include "wx/dialog.h"
36#include "wx/msgdlg.h"
37#endif
38
39#include "wx/msw/private.h"
40#include "wx/postscrp.h"
41#include "wx/log.h"
42#include "wx/module.h"
43
44#if USE_WX_RESOURCES
45#include "wx/resource.h"
46#endif
47
48
49#include <string.h>
50
51#if defined(__WIN95__) && !defined(__GNUWIN32__)
52#include <commctrl.h>
53#endif
54
55extern char *wxBuffer;
56extern char *wxOsVersion;
57extern wxList *wxWinHandleList;
58extern wxList wxPendingDelete;
59extern void wxSetKeyboardHook(bool doIt);
60extern wxCursor *g_globalCursor;
61
62HANDLE wxhInstance = 0;
63static MSG s_currentMsg;
64wxApp *wxTheApp = NULL;
65
66char wxFrameClassName[] = "wxFrameClass";
67char wxMDIFrameClassName[] = "wxMDIFrameClass";
68char wxMDIChildFrameClassName[] = "wxMDIChildFrameClass";
69char wxPanelClassName[] = "wxPanelClass";
70char wxCanvasClassName[] = "wxCanvasClass";
71
72HICON wxSTD_FRAME_ICON = NULL;
73HICON wxSTD_MDICHILDFRAME_ICON = NULL;
74HICON wxSTD_MDIPARENTFRAME_ICON = NULL;
75
76HICON wxDEFAULT_FRAME_ICON = NULL;
77HICON wxDEFAULT_MDICHILDFRAME_ICON = NULL;
78HICON wxDEFAULT_MDIPARENTFRAME_ICON = NULL;
79
80HBRUSH wxDisableButtonBrush = 0;
81
82LRESULT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
83
84#if !USE_SHARED_LIBRARY
85IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
86BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
87 EVT_IDLE(wxApp::OnIdle)
88END_EVENT_TABLE()
89#endif
90
91long wxApp::sm_lastMessageTime = 0;
92
93#ifdef __WIN95__
94static HINSTANCE gs_hRichEdit = NULL;
95#endif
96
97bool wxApp::Initialize(WXHANDLE instance)
98{
99 HANDLE hInstance = (HANDLE)instance;
100
101 CommonInit();
102
103#if defined(__WIN95__)
104 InitCommonControls();
105 gs_hRichEdit = LoadLibrary("RICHED32.DLL");
106
107 if (gs_hRichEdit == NULL)
108 {
109 wxMessageBox("Could not initialise Rich Edit DLL");
110 }
111#endif
112
113#if defined(WX_DRAG_DROP)
114 // we need to initialize OLE library
115 if ( FAILED(::OleInitialize(NULL)) )
116 wxFatalError(_("Cannot initialize OLE"));
117#endif
118
119#if CTL3D
120 if (!Ctl3dRegister(hInstance))
121 wxFatalError("Cannot register CTL3D");
122
123 Ctl3dAutoSubclass(hInstance);
124#endif
125
126 wxSTD_FRAME_ICON = LoadIcon(hInstance, "wxSTD_FRAME");
127 wxSTD_MDIPARENTFRAME_ICON = LoadIcon(hInstance, "wxSTD_MDIPARENTFRAME");
128 wxSTD_MDICHILDFRAME_ICON = LoadIcon(hInstance, "wxSTD_MDICHILDFRAME");
129
130 wxDEFAULT_FRAME_ICON = LoadIcon(hInstance, "wxDEFAULT_FRAME");
131 wxDEFAULT_MDIPARENTFRAME_ICON = LoadIcon(hInstance, "wxDEFAULT_MDIPARENTFRAME");
132 wxDEFAULT_MDICHILDFRAME_ICON = LoadIcon(hInstance, "wxDEFAULT_MDICHILDFRAME");
133
134 RegisterWindowClasses();
135
136 // Create the brush for disabling bitmap buttons
137
138 LOGBRUSH lb ;
139 lb.lbStyle = BS_PATTERN;
140 lb.lbHatch = (int)LoadBitmap( hInstance, "wxDISABLE_BUTTON_BITMAP" ) ;
141 wxDisableButtonBrush = ::CreateBrushIndirect( & lb ) ;
142 ::DeleteObject( (HGDIOBJ)lb.lbHatch ) ;
143
144#if USE_PENWINDOWS
145 wxRegisterPenWin();
146#endif
147
148 wxWinHandleList = new wxList(wxKEY_INTEGER);
149
150 // This is to foil optimizations in Visual C++ that
151 // throw out dummy.obj.
152#if (_MSC_VER >= 800) && !defined(WXMAKINGDLL)
153 extern char wxDummyChar;
154 if (wxDummyChar) wxDummyChar++;
155#endif
156 wxSetKeyboardHook(TRUE);
157
158 wxModule::RegisterModules();
159 if (!wxModule::InitializeModules())
160 return FALSE;
161 return TRUE;
162}
163
164bool wxApp::RegisterWindowClasses(void)
165{
166///////////////////////////////////////////////////////////////////////
167// Register the frame window class.
168 WNDCLASS wndclass; // Structure used to register Windows class.
169
170 wndclass.style = CS_HREDRAW | CS_VREDRAW;
171 wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
172 wndclass.cbClsExtra = 0;
173 wndclass.cbWndExtra = sizeof( DWORD ); // was 4
174 wndclass.hInstance = wxhInstance;
175 wndclass.hIcon = NULL; // wxSTD_FRAME_ICON;
176 wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
177 wndclass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1) ;
178// wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
179 wndclass.lpszMenuName = NULL;
180#ifdef _MULTIPLE_INSTANCES
181 sprintf( wxFrameClassName,"wxFrameClass%d", hInstance );
182#endif
183 wndclass.lpszClassName = wxFrameClassName;
184
185 if (!RegisterClass( &wndclass ))
186 {
187 // wxFatalError("Can't register Frame Window class");
188 }
189
190///////////////////////////////////////////////////////////////////////
191// Register the MDI frame window class.
192 WNDCLASS wndclass1; // Structure used to register Windows class.
193
194 wndclass1.style = CS_HREDRAW | CS_VREDRAW;
195 wndclass1.lpfnWndProc = (WNDPROC)wxWndProc;
196 wndclass1.cbClsExtra = 0;
197 wndclass1.cbWndExtra = sizeof( DWORD ); // was 4
198 wndclass1.hInstance = wxhInstance;
199 wndclass1.hIcon = NULL; // wxSTD_MDIPARENTFRAME_ICON;
200 wndclass1.hCursor = LoadCursor( NULL, IDC_ARROW );
201// wndclass1.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE+1) ;
202 wndclass1.hbrBackground = NULL;
203 wndclass1.lpszMenuName = NULL;
204
205 wndclass1.lpszClassName = wxMDIFrameClassName;
206 if (!RegisterClass( &wndclass1 ))
207 {
208// wxFatalError("Can't register MDI Frame window class");
209// return FALSE;
210 }
211
212///////////////////////////////////////////////////////////////////////
213// Register the MDI child frame window class.
214 WNDCLASS wndclass4; // Structure used to register Windows class.
215
216 wndclass4.style = CS_HREDRAW | CS_VREDRAW;
217 wndclass4.lpfnWndProc = (WNDPROC)wxWndProc;
218 wndclass4.cbClsExtra = 0;
219 wndclass4.cbWndExtra = sizeof( DWORD ); // was 4
220 wndclass4.hInstance = wxhInstance;
221 wndclass4.hIcon = NULL; // wxSTD_MDICHILDFRAME_ICON;
222 wndclass4.hCursor = LoadCursor( NULL, IDC_ARROW );
223 // TODO: perhaps this should be NULL so that Windows doesn't
224 // paint the background itself (would OnEraseBackground duplicate
225 // this?)
226 wndclass4.hbrBackground = (HBRUSH)(COLOR_WINDOW+1) ;
227// wndclass4.hbrBackground = NULL;
228 wndclass4.lpszMenuName = NULL;
229 wndclass4.lpszClassName = wxMDIChildFrameClassName;
230
231 if (!RegisterClass( &wndclass4 ))
232 {
233// wxFatalError("Can't register MDI child frame window class");
234// return FALSE;
235 }
236
237///////////////////////////////////////////////////////////////////////
238// Register the panel window class.
239 WNDCLASS wndclass2; // Structure used to register Windows class.
240 memset(&wndclass2, 0, sizeof(WNDCLASS)); // start with NULL defaults
241 // Use CS_OWNDC to avoid messing about restoring the context
242 // for every graphic operation.
243 wndclass2.style = CS_HREDRAW | CS_VREDRAW;
244 wndclass2.lpfnWndProc = (WNDPROC)wxWndProc;
245 wndclass2.cbClsExtra = 0;
246 wndclass2.cbWndExtra = sizeof( DWORD ); // was 4
247 wndclass2.hInstance = wxhInstance;
248 wndclass2.hIcon = NULL;
249 wndclass2.hCursor = NULL;
250// wndclass2.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1) ;
251 wndclass2.hbrBackground = GetStockObject( LTGRAY_BRUSH );
252 wndclass2.lpszMenuName = NULL;
253 wndclass2.lpszClassName = wxPanelClassName;
254 if (!RegisterClass( &wndclass2 ))
255 {
256// wxFatalError("Can't register Panel Window class");
257// return FALSE;
258 }
259
260///////////////////////////////////////////////////////////////////////
261// Register the canvas and textsubwindow class name
262 WNDCLASS wndclass3; // Structure used to register Windows class.
263 memset(&wndclass3, 0, sizeof(WNDCLASS)); // start with NULL defaults
264 // Use CS_OWNDC to avoid messing about restoring the context
265 // for every graphic operation.
266// wndclass3.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS ;
267 // wxWin 2.0
268 wndclass3.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
269 wndclass3.lpfnWndProc = (WNDPROC)wxWndProc;
270 wndclass3.cbClsExtra = 0;
271 wndclass3.cbWndExtra = sizeof( DWORD ); // was 4
272 wndclass3.hInstance = wxhInstance;
273 wndclass3.hIcon = NULL;
274 wndclass3.hCursor = NULL;
275// wndclass3.hbrBackground = (HBRUSH)(COLOR_WINDOW+1) ;
276 wndclass3.hbrBackground = NULL;
277 wndclass3.lpszMenuName = NULL;
278 wndclass3.lpszClassName = wxCanvasClassName;
279 if (!RegisterClass( &wndclass3))
280 {
281// wxFatalError("Can't register Canvas class");
282// return FALSE;
283 }
284
285 return TRUE;
286}
287
288// Cleans up any wxWindows internal structures left lying around
289void wxApp::CleanUp(void)
290{
291 wxModule::CleanUpModules();
292
293 CommonCleanUp();
294
295 wxSetKeyboardHook(FALSE);
296
297#ifdef __WIN95__
298 if (gs_hRichEdit != NULL)
299 FreeLibrary(gs_hRichEdit);
300#endif
301
302#if USE_PENWINDOWS
303 wxCleanUpPenWin();
304#endif
305
306 if (wxSTD_FRAME_ICON)
307 DestroyIcon(wxSTD_FRAME_ICON);
308 if (wxSTD_MDICHILDFRAME_ICON)
309 DestroyIcon(wxSTD_MDICHILDFRAME_ICON);
310 if (wxSTD_MDIPARENTFRAME_ICON)
311 DestroyIcon(wxSTD_MDIPARENTFRAME_ICON);
312
313 if (wxDEFAULT_FRAME_ICON)
314 DestroyIcon(wxDEFAULT_FRAME_ICON);
315 if (wxDEFAULT_MDICHILDFRAME_ICON)
316 DestroyIcon(wxDEFAULT_MDICHILDFRAME_ICON);
317 if (wxDEFAULT_MDIPARENTFRAME_ICON)
318 DestroyIcon(wxDEFAULT_MDIPARENTFRAME_ICON);
319
320 if ( wxDisableButtonBrush )
321 ::DeleteObject( wxDisableButtonBrush ) ;
322
323#if defined(WX_DRAG_DROP)
324 ::OleUninitialize();
325#endif
326
327#if CTL3D
328 Ctl3dUnregister(wxhInstance);
329#endif
330
331 if (wxWinHandleList)
332 delete wxWinHandleList ;
333
c54f78a2
VZ
334 // do it as the very last thing because everything else can log messages
335 delete wxLog::SetActiveTarget(NULL);
2bda0e17
KB
336}
337
338void wxApp::CommonInit(void)
339{
340#ifdef __WINDOWS__
341 wxBuffer = new char[1500];
342#else
343 wxBuffer = new char[BUFSIZ + 512];
344#endif
345
346 wxClassInfo::InitializeClasses();
347
348#ifdef __X__
349 wxTheFontNameDirectory.Initialize();
350#endif
351
352#if defined(__X__) && USE_RESOURCES
353 // Read standard font names from .Xdefaults
354
355 extern char *wxDecorativeFontName;
356 extern char *wxRomanFontName;
357 extern char *wxModernFontName;
358 extern char *wxSwissFontName;
359 extern char *wxScriptFontName;
360 extern char *wxTeletypeFontName;
361 extern char *wxDefaultFontName;
362
363 (void) wxGetResource("wxWindows", "defaultFamily", &wxDefaultFontName);
364 (void) wxGetResource("wxWindows", "decorativeFamily", &wxDecorativeFontName);
365 (void) wxGetResource("wxWindows", "romanFamily", &wxRomanFontName);
366 (void) wxGetResource("wxWindows", "modernFamily", &wxModernFontName);
367 (void) wxGetResource("wxWindows", "swissFamily", &wxSwissFontName);
368 (void) wxGetResource("wxWindows", "scriptFamily", &wxScriptFontName);
369 (void) wxGetResource("wxWindows", "teletypeFamily", &wxTeletypeFontName);
370#endif
371
372#if USE_RESOURCES
373 (void) wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
374#endif
375
376 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
377 wxTheColourDatabase->Initialize();
378 wxInitializeStockObjects();
379
380#if USE_WX_RESOURCES
381 wxInitializeResourceSystem();
382#endif
383
384 // For PostScript printing
385#if USE_POSTSCRIPT
386 wxInitializePrintSetupData();
387 wxThePrintPaperDatabase = new wxPrintPaperDatabase;
388 wxThePrintPaperDatabase->CreateDatabase();
389#endif
390
391 wxBitmap::InitStandardHandlers();
392
393 g_globalCursor = new wxCursor;
394}
395
396void wxApp::CommonCleanUp(void)
397{
398#if USE_WX_RESOURCES
399 wxCleanUpResourceSystem();
400
401// wxDefaultResourceTable->ClearTable();
402#endif
403 // Indicate that the cursor can be freed,
404 // so that cursor won't be deleted by deleting
405 // the bitmap list before g_globalCursor goes out
406 // of scope (double deletion of the cursor).
407 wxSetCursor(wxNullCursor);
408 delete g_globalCursor;
409
410 wxDeleteStockObjects() ;
411
412 // Destroy all GDI lists, etc.
413 delete wxTheBrushList;
414 wxTheBrushList = NULL;
415
416 delete wxThePenList;
417 wxThePenList = NULL;
418
419 delete wxTheFontList;
420 wxTheFontList = NULL;
421
422 delete wxTheBitmapList;
423 wxTheBitmapList = NULL;
424
425 delete wxTheColourDatabase;
426 wxTheColourDatabase = NULL;
427
428#if USE_POSTSCRIPT
429 wxInitializePrintSetupData(FALSE);
430 delete wxThePrintPaperDatabase;
431 wxThePrintPaperDatabase = NULL;
432#endif
433
434 wxBitmap::CleanUpHandlers();
435
436 delete[] wxBuffer;
437 wxBuffer = NULL;
438}
439
440#if !defined(_WINDLL) || (defined(_WINDLL) && defined(WXMAKINGDLL))
441
442// Main wxWindows entry point
443
444int wxEntry(WXHINSTANCE hInstance, WXHINSTANCE WXUNUSED(hPrevInstance), char *m_lpCmdLine,
445 int nCmdShow, bool enterLoop)
446{
447 wxhInstance = (HINSTANCE) hInstance;
448
449#if (DEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
450
451#if !defined(_WINDLL)
452 streambuf* sBuf = new wxDebugStreamBuf;
453#else
454 streambuf* sBuf = NULL;
455#endif
456 ostream* oStr = new ostream(sBuf) ;
457 wxDebugContext::SetStream(oStr, sBuf);
458
459#endif
460
461 if (!wxApp::Initialize((WXHINSTANCE) wxhInstance))
462 return 0;
463
464 // The app may have declared a global application object, but we recommend
465 // the IMPLEMENT_APP macro is used instead, which sets an initializer function
466 // for delayed, dynamic app object construction.
467 if (!wxTheApp)
468 {
469 if (!wxApp::GetInitializerFunction())
470 {
471 MessageBox(NULL, "No initializer - use IMPLEMENT_APP macro.", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
472 return 0;
473 }
474
475 wxTheApp = (* wxApp::GetInitializerFunction()) ();
476 }
477
478 if (!wxTheApp) {
479 MessageBox(NULL, "You have to define an instance of wxApp!", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
480 return 0;
481 }
482
483 // Split command line into tokens, as in usual main(argc, argv)
484 char **command = new char*[50];
485
486 int count = 0;
487 char *buf = new char[strlen(m_lpCmdLine) + 1];
488
489 // Hangs around until end of app. in case
490 // user carries pointers to the tokens
491
492 /* Model independent strcpy */
493 int i;
494 for (i = 0; (buf[i] = m_lpCmdLine[i]) != 0; i++)
495 {
496 /* loop */;
497 }
498
499 // Get application name
500 char name[200];
501 ::GetModuleFileName(wxhInstance, name, 199);
502
503 // Is it only 16-bit Borland that already copies the program name
504 // to the first argv index?
505#if !defined(__GNUWIN32__)
506// #if ! (defined(__BORLANDC__) && !defined(__WIN32__))
507 command[count++] = copystring(name);
508// #endif
509#endif
510
511 strcpy(name, wxFileNameFromPath(name));
512 wxStripExtension(name);
513 wxTheApp->SetAppName(name);
514
515 /* Break up string */
516 // Treat strings enclosed in double-quotes as single arguments
517 char* str = buf;
518 while (*str)
519 {
520 while (*str && *str <= ' ') str++; // skip whitespace
521 if (*str == '"')
522 {
523 str++;
524 command[count++] = str;
525 while (*str && *str != '"') str++;
526 }
527 else if (*str)
528 {
529 command[count++] = str;
530 while (*str && *str > ' ') str++;
531 }
532 if (*str) *str++ = '\0';
533 }
534 command[count] = NULL; /* argv[] is NULL terminated list! */
535
536 wxTheApp->argc = count;
537 wxTheApp->argv = command;
538 wxTheApp->m_nCmdShow = nCmdShow;
539
540 // GUI-specific initialisation. In fact on Windows we don't have any,
541 // but this call is provided for compatibility across platforms.
542 wxTheApp->OnInitGui() ;
543
544 if (!wxTheApp->OnInit())
545 {
546 wxTheApp->DeletePendingObjects();
547 wxTheApp->OnExit();
548 wxApp::CleanUp();
549
550 delete wxTheApp;
551 wxTheApp = NULL;
552
553 delete [] buf ;
554
555 // TODO: This should really be cleaned up in ~wxApp
556 delete [] command[0] ;
557 delete [] command ;
558 return 0;
559 }
560
561 if (!enterLoop)
562 return 0;
563
564 int retValue = 1;
565
566/* New behaviour - leave it to the app to show the top window
567 if (wxTheApp->GetTopWindow()) {
568 // show the toplevel frame, only if we are not iconized (from MS-Windows)
569 if(wxTheApp->GetShowFrameOnInit() && (nCmdShow!=SW_HIDE)) wxTheApp->GetTopWindow()->Show(TRUE);
570 }
571*/
572
573 retValue = wxTheApp->OnRun();
574
575 if (wxTheApp->GetTopWindow())
576 {
577 // Forcibly delete the window.
578 if (wxTheApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)) ||
579 wxTheApp->GetTopWindow()->IsKindOf(CLASSINFO(wxDialog)))
580 {
581 wxTheApp->GetTopWindow()->Close(TRUE);
582 wxTheApp->DeletePendingObjects();
583 }
584 else
585 {
586 delete wxTheApp->GetTopWindow();
587 wxTheApp->SetTopWindow(NULL);
588 }
589 }
590
591 wxTheApp->OnExit();
592 wxApp::CleanUp();
593
594 delete wxTheApp;
595 wxTheApp = NULL;
596
597 delete [] buf ;
598 delete [] command[0] ;
599 delete [] command ;
600
601#if (DEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
602 // At this point we want to check if there are any memory
603 // blocks that aren't part of the wxDebugContext itself,
604 // as a special case. Then when dumping we need to ignore
605 // wxDebugContext, too.
606 if (wxDebugContext::CountObjectsLeft() > 0)
607 {
608 wxTrace("There were memory leaks.\n");
609 wxDebugContext::Dump();
610 wxDebugContext::PrintStatistics();
611 }
612 wxDebugContext::SetStream(NULL, NULL);
613#endif
614
615 return retValue;
616}
617
618#else /* _WINDLL */
619
620int wxEntry(WXHINSTANCE hInstance)
621{
622 wxhInstance = (HINSTANCE) hInstance;
623 wxApp::Initialize((WXHINSTANCE) wxhInstance);
624
625 // The app may have declared a global application object, but we recommend
626 // the IMPLEMENT_APP macro is used instead, which sets an initializer function
627 // for delayed, dynamic app object construction.
628
629 if (!wxTheApp)
630 {
631 if (!wxApp::GetInitializerFunction())
632 {
633 MessageBox(NULL, "No initializer - use IMPLEMENT_APP macro.", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
634 return 0;
635 }
636
637 wxTheApp = (* wxApp::GetInitializerFunction()) ();
638 }
639
640 if (!wxTheApp) {
641 MessageBox(NULL, "You have to define an instance of wxApp!", "wxWindows Error", MB_APPLMODAL | MB_ICONSTOP | MB_OK);
642 return 0;
643 }
644
645 wxTheApp->argc = 0;
646 wxTheApp->argv = NULL;
647
648 wxTheApp->OnInitGui();
649
650 wxTheApp->OnInit();
651
652 if (wxTheApp->GetTopWindow() && wxTheApp->GetTopWindow()->GetHWND()) {
653 wxTheApp->GetTopWindow()->Show(TRUE);
654 }
655
656 return 1;
657}
658#endif // _WINDLL
659
660// Static member initialization
661wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
662
663wxApp::wxApp(void)
664{
665 m_topWindow = NULL;
666 wxTheApp = this;
667// work_proc = NULL ;
668 m_className = "";
669// m_resourceCollection = TRUE;
670// m_pendingCleanup = FALSE;
671 m_wantDebugOutput = TRUE ;
672 m_appName = "";
673 argc = 0;
674 argv = NULL;
675#ifdef __WINDOWS__
676 m_printMode = wxPRINT_WINDOWS;
677#else
678 m_printMode = wxPRINT_POSTSCRIPT;
679#endif
680// work_proc = NULL;
681 m_exitOnFrameDelete = TRUE;
682// m_showOnInit = TRUE;
683 m_auto3D = TRUE;
684}
685
686bool wxApp::Initialized(void)
687{
688#ifndef _WINDLL
689 if (GetTopWindow())
690 return TRUE;
691 else
692 return FALSE;
693#endif
694#ifdef _WINDLL // Assume initialized if DLL (no way of telling)
695 return TRUE;
696#endif
697}
698
699/*
700 * Get and process a message, returning FALSE if WM_QUIT
701 * received.
702 *
703 */
704bool wxApp::DoMessage(void)
705{
706 if (!::GetMessage(&s_currentMsg, (HWND) NULL, 0, 0))
707 {
708 return FALSE;
709 }
710
711 // Process the message
712 if (!ProcessMessage((WXMSG *)&s_currentMsg))
713 {
714 ::TranslateMessage(&s_currentMsg);
715 wxApp::sm_lastMessageTime = s_currentMsg.time; /* MATTHEW: timeStamp impl. */
716 ::DispatchMessage(&s_currentMsg);
717 }
718 return TRUE;
719}
720
721/*
722 * Keep trying to process messages until WM_QUIT
723 * received.
724 *
725 * If there are messages to be processed, they will all be
726 * processed and OnIdle will not be called.
727 * When there are no more messages, OnIdle is called.
728 * If OnIdle requests more time,
729 * it will be repeatedly called so long as there are no pending messages.
730 * A 'feature' of this is that once OnIdle has decided that no more processing
731 * is required, then it won't get processing time until further messages
732 * are processed (it'll sit in DoMessage).
733 */
734
735int wxApp::MainLoop(void)
736{
737 m_keepGoing = TRUE;
738 while (m_keepGoing)
739 {
740 while (!::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) &&
741 ProcessIdle()) {}
742 if (!DoMessage())
743 m_keepGoing = FALSE;
744 }
745
746 return s_currentMsg.wParam;
747}
748
749// Returns TRUE if more time is needed.
750bool wxApp::ProcessIdle(void)
751{
752 wxIdleEvent event;
753 event.SetEventObject(this);
754 ProcessEvent(event);
755
756 return event.MoreRequested();
757}
758
759void wxApp::ExitMainLoop(void)
760{
761 m_keepGoing = FALSE;
762}
763
764bool wxApp::Pending(void)
765{
766 return (::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) != 0) ;
767}
768
769void wxApp::Dispatch(void)
770{
771 if (!DoMessage())
772 m_keepGoing = FALSE;
773}
774
775/*
776 * Give all windows a chance to preprocess
777 * the message. Some may have accelerator tables, or have
778 * MDI complications.
779 */
780bool wxApp::ProcessMessage(WXMSG *Msg)
781{
782 MSG *msg = (MSG *)Msg;
783
784 HWND hWnd;
785
786 // Anyone for a message? Try youngest descendants first.
787 for (hWnd = msg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
788 {
789 wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd);
790 if (wnd)
791 {
792 if (wnd->MSWProcessMessage(Msg))
793 return TRUE;
794
795 // STOP if we've reached the top of the hierarchy!
796// if (m_topWindow && (wnd == m_topWindow))
797// return FALSE;
798 }
799 }
800
801 // TODO: Is this now obsolete, given that m_topWindow may not be defined?
802 // Does it do anything useful anyway?
803// if (m_topWindow && m_topWindow->MSWProcessMessage(Msg))
804// return TRUE;
805 return FALSE;
806}
807
808void wxApp::OnIdle(wxIdleEvent& event)
809{
810 static bool inOnIdle = FALSE;
811
812 // Avoid recursion (via ProcessEvent default case)
813 if (inOnIdle)
814 return;
815
816 inOnIdle = TRUE;
817
818 // 'Garbage' collection of windows deleted with Close().
819 DeletePendingObjects();
820
c54f78a2
VZ
821 // flush the logged messages if any
822 wxLog *pLog = wxLog::GetActiveTarget();
823 if ( pLog != NULL && pLog->HasPendingMessages() )
824 pLog->Flush();
825
2bda0e17
KB
826 // Send OnIdle events to all windows
827 bool needMore = SendIdleEvents();
828
829 if (needMore)
830 event.RequestMore(TRUE);
831
832 inOnIdle = FALSE;
833}
834
835// Send idle event to all top-level windows
836bool wxApp::SendIdleEvents(void)
837{
838 bool needMore = FALSE;
839 wxNode* node = wxTopLevelWindows.First();
840 while (node)
841 {
842 wxWindow* win = (wxWindow*) node->Data();
843 if (SendIdleEvents(win))
844 needMore = TRUE;
845
846 node = node->Next();
847 }
848 return needMore;
849}
850
851// Send idle event to window and all subwindows
852bool wxApp::SendIdleEvents(wxWindow* win)
853{
854 bool needMore = FALSE;
855
856 wxIdleEvent event;
857 event.SetEventObject(win);
858 win->ProcessEvent(event);
859
860 if (event.MoreRequested())
861 needMore = TRUE;
862
863 wxNode* node = win->GetChildren()->First();
864 while (node)
865 {
866 wxWindow* win = (wxWindow*) node->Data();
867 if (SendIdleEvents(win))
868 needMore = TRUE;
869
870 node = node->Next();
871 }
872 return needMore ;
873}
874
875// Windows specific. Intercept keyboard input: by default,
876// route it to the active frame or dialog box.
877#if WXWIN_COMPATIBILITY == 2
878bool wxApp::OldOnCharHook(wxKeyEvent& event)
879{
880 wxWindow *win = wxGetActiveWindow();
881 if (win)
882 return win->GetEventHandler()->OldOnCharHook(event);
883 else
884 return FALSE;
885}
886#endif
887
888void wxApp::DeletePendingObjects(void)
889{
890 wxNode *node = wxPendingDelete.First();
891 while (node)
892 {
893 wxObject *obj = (wxObject *)node->Data();
894
895 delete obj;
896
897 if (wxPendingDelete.Member(obj))
898 delete node;
899
900 // Deleting one object may have deleted other pending
901 // objects, so start from beginning of list again.
902 node = wxPendingDelete.First();
903 }
904}
905
906/*
907// Free up font objects that are not being used at present.
908bool wxApp::DoResourceCleanup(void)
909{
910// wxDebugMsg("ResourceCleanup\n");
911
912 if (wxTheFontList)
913 {
914 wxNode *node = wxTheFontList->First();
915 while (node)
916 {
917 wxGDIObject *obj = (wxGDIObject *)node->Data();
918 if ((obj->GetResourceHandle() != 0) && (obj->GetResourceUsage() == 0))
919 {
920// wxDebugMsg("Freeing font %ld (GDI object %d)\n", (long)obj, (int)obj->GetResourceHandle());
921 obj->FreeResource();
922 }
923 node = node->Next();
924 }
925 }
926 if (wxThePenList)
927 {
928 wxNode *node = wxThePenList->First();
929 while (node)
930 {
931 wxGDIObject *obj = (wxGDIObject *)node->Data();
932 if ((obj->GetResourceHandle() != 0) && (obj->GetResourceUsage() == 0))
933 {
934// wxDebugMsg("Freeing pen %ld (GDI object %d)\n", (long)obj, (int)obj->GetResourceHandle());
935 obj->FreeResource();
936 }
937 node = node->Next();
938 }
939 }
940 if (wxTheBrushList)
941 {
942 wxNode *node = wxTheBrushList->First();
943 while (node)
944 {
945 wxGDIObject *obj = (wxGDIObject *)node->Data();
946 if ((obj->GetResourceHandle() != 0) && (obj->GetResourceUsage() == 0))
947 {
948// wxDebugMsg("Freeing brush %ld (GDI object %d)\n", (long)obj, (int)obj->GetResourceHandle());
949 obj->FreeResource();
950 }
951 node = node->Next();
952 }
953 }
954
955 SetPendingCleanup(FALSE);
956 return FALSE;
957}
958*/
959
960wxLog* wxApp::CreateLogTarget(void)
961{
962 return new wxLogGui;
963}
964
965wxWindow* wxApp::GetTopWindow(void) const
966{
967 if (m_topWindow)
968 return m_topWindow;
969 else if (wxTopLevelWindows.Number() > 0)
970 return (wxWindow*) wxTopLevelWindows.First()->Data();
971 else
972 return NULL;
973}
974
975void wxExit(void)
976{
977 wxApp::CleanUp();
978 FatalAppExit(0, "Fatal error: exiting");
979}
980
981// Yield to incoming messages
982bool wxYield(void)
983{
984 MSG msg;
985 // We want to go back to the main message loop
986 // if we see a WM_QUIT. (?)
987 while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) && msg.message != WM_QUIT)
988 {
989 if (!wxTheApp->DoMessage())
990 break;
991 }
992
993 return TRUE;
994}
995
996HINSTANCE wxGetInstance()
997{
998 return wxhInstance;
999}
1000
1001// For some reason, with MSVC++ 1.5, WinMain isn't linked in properly
1002// if in a separate file. So include it here to ensure it's linked.
1003#if (defined(_MSC_VER) && !defined(__WIN32__)) || defined(__GNUWIN32__)
1004#include "main.cpp"
1005#endif
1006
1007#undef IN_WX_MAIN_CPP
1008