Files
wxWidgets/src/os2/app.cpp
David Webster 8df85a6123 Some changes to fix event processing
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6661 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2000-03-13 23:29:44 +00:00

989 lines
26 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: app.cpp
// Purpose: wxApp
// Author: David Webster
// Modified by:
// Created: 10/13/99
// RCS-ID: $Id$
// Copyright: (c) David Webster
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/frame.h"
#include "wx/app.h"
#include "wx/utils.h"
#include "wx/gdicmn.h"
#include "wx/pen.h"
#include "wx/brush.h"
#include "wx/cursor.h"
#include "wx/icon.h"
#include "wx/palette.h"
#include "wx/dc.h"
#include "wx/dialog.h"
#include "wx/msgdlg.h"
#include "wx/intl.h"
#include "wx/dynarray.h"
# include "wx/wxchar.h"
# include "wx/icon.h"
#endif
#include "wx/log.h"
#include "wx/module.h"
#include "wx/os2/private.h"
#if wxUSE_THREADS
#include "wx/thread.h"
// define the array of QMSG strutures
WX_DECLARE_OBJARRAY(QMSG, wxMsgArray);
#include "wx/arrimpl.cpp"
WX_DEFINE_OBJARRAY(wxMsgArray);
#endif // wxUSE_THREADS
#if wxUSE_WX_RESOURCES
#include "wx/resource.h"
#endif
#if wxUSE_TOOLTIPS
#include "wx/tooltip.h"
#endif // wxUSE_TOOLTIPS
#include <string.h>
#include <ctype.h>
// ---------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
extern wxChar* wxBuffer;
extern wxChar* wxOsVersion;
extern wxList* wxWinHandleList;
extern wxList WXDLLEXPORT wxPendingDelete;
extern wxCursor* g_globalCursor;
HAB vHabmain = NULLHANDLE;
QMSG svCurrentMsg;
wxApp* wxTheApp = NULL;
// NB: all "NoRedraw" classes must have the same names as the "normal" classes
// with NR suffix - wxWindow::OS2Create() supposes this
wxChar wxFrameClassName[] = wxT("wxFrameClass");
wxChar wxFrameClassNameNoRedraw[] = wxT("wxFrameClassNR");
wxChar wxMDIFrameClassName[] = wxT("wxMDIFrameClass");
wxChar wxMDIFrameClassNameNoRedraw[] = wxT("wxMDIFrameClassNR");
wxChar wxMDIChildFrameClassName[] = wxT("wxMDIChildFrameClass");
wxChar wxMDIChildFrameClassNameNoRedraw[] = wxT("wxMDIChildFrameClassNR");
wxChar wxPanelClassName[] = wxT("wxPanelClass");
wxChar wxCanvasClassName[] = wxT("wxCanvasClass");
HICON wxSTD_FRAME_ICON = (HICON) NULL;
HICON wxSTD_MDICHILDFRAME_ICON = (HICON) NULL;
HICON wxSTD_MDIPARENTFRAME_ICON = (HICON) NULL;
HICON wxDEFAULT_FRAME_ICON = (HICON) NULL;
HICON wxDEFAULT_MDICHILDFRAME_ICON = (HICON) NULL;
HICON wxDEFAULT_MDIPARENTFRAME_ICON = (HICON) NULL;
HBRUSH wxDisableButtonBrush = (HBRUSH) 0;
MRESULT EXPENTRY wxWndProc( HWND
,ULONG
,MPARAM
,MPARAM
);
// ===========================================================================
// implementation
// ===========================================================================
// ---------------------------------------------------------------------------
// wxApp
// ---------------------------------------------------------------------------
IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
EVT_IDLE(wxApp::OnIdle)
EVT_END_SESSION(wxApp::OnEndSession)
EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
END_EVENT_TABLE()
//
// Initialize
//
bool wxApp::Initialize(
HAB vHab
)
{
//
// OS2 has to have an anchorblock
//
vHab = WinInitialize(0);
if (!vHab)
return FALSE;
else
vHabmain = vHab;
// Some people may wish to use this, but
// probably it shouldn't be here by default.
#ifdef __WXDEBUG__
// wxRedirectIOToConsole();
#endif
wxBuffer = new wxChar[1500]; // FIXME; why?
wxClassInfo::InitializeClasses();
#if wxUSE_RESOURCES
wxGetResource(wxT("wxWindows"), wxT("OsVersion"), &wxOsVersion);
#endif
#if wxUSE_THREADS
wxPendingEventsLocker = new wxCriticalSection;
#endif
wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
wxTheColourDatabase->Initialize();
wxInitializeStockLists();
wxInitializeStockObjects();
#if wxUSE_WX_RESOURCES
wxInitializeResourceSystem();
#endif
wxBitmap::InitStandardHandlers();
RegisterWindowClasses(vHab);
wxWinHandleList = new wxList(wxKEY_INTEGER);
// This is to foil optimizations in Visual C++ that throw out dummy.obj.
// PLEASE DO NOT ALTER THIS.
#if !defined(WXMAKINGDLL) && defined(__VISAGECPP__)
extern char wxDummyChar;
if (wxDummyChar) wxDummyChar++;
#endif
// wxSetKeyboardHook(TRUE);
wxModule::RegisterModules();
if (!wxModule::InitializeModules())
return FALSE;
return TRUE;
} // end of wxApp::Initialize
// ---------------------------------------------------------------------------
// RegisterWindowClasses
// ---------------------------------------------------------------------------
bool wxApp::RegisterWindowClasses(
HAB vHab
)
{
APIRET rc;
ERRORID vError = 0L;
wxString sError;
if (!::WinRegisterClass( vHab
,wxFrameClassName
,(PFNWP)wxWndProc
,CS_SIZEREDRAW | CS_SYNCPAINT
,sizeof(ULONG)
))
{
vError = ::WinGetLastError(vHab);
sError = wxPMErrorToStr(vError);
wxLogLastError(sError);
return FALSE;
}
if (!::WinRegisterClass( vHab
,wxFrameClassNameNoRedraw
,(PFNWP)wxWndProc
,0
,0
))
{
vError = ::WinGetLastError(vHab);
sError = wxPMErrorToStr(vError);
wxLogLastError(sError);
return FALSE;
}
if (!::WinRegisterClass( vHab
,wxMDIFrameClassName
,(PFNWP)wxWndProc
,CS_SIZEREDRAW | CS_SYNCPAINT
,0
))
{
vError = ::WinGetLastError(vHab);
sError = wxPMErrorToStr(vError);
wxLogLastError(sError);
return FALSE;
}
if (!::WinRegisterClass( vHab
,wxMDIFrameClassNameNoRedraw
,(PFNWP)wxWndProc
,0
,0
))
{
vError = ::WinGetLastError(vHab);
sError = wxPMErrorToStr(vError);
wxLogLastError(sError);
return FALSE;
}
if (!::WinRegisterClass( vHab
,wxMDIChildFrameClassName
,(PFNWP)wxWndProc
,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_SYNCPAINT | CS_HITTEST
,0
))
{
vError = ::WinGetLastError(vHab);
sError = wxPMErrorToStr(vError);
wxLogLastError(sError);
return FALSE;
}
if (!::WinRegisterClass( vHab
,wxMDIChildFrameClassNameNoRedraw
,(PFNWP)wxWndProc
,CS_HITTEST
,0
))
{
vError = ::WinGetLastError(vHab);
sError = wxPMErrorToStr(vError);
wxLogLastError(sError);
return FALSE;
}
if (!::WinRegisterClass( vHab
,wxPanelClassName
,(PFNWP)wxWndProc
,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_HITTEST | CS_SAVEBITS | CS_SYNCPAINT
,0
))
{
vError = ::WinGetLastError(vHab);
sError = wxPMErrorToStr(vError);
wxLogLastError(sError);
return FALSE;
}
if (!::WinRegisterClass( vHab
,wxCanvasClassName
,(PFNWP)wxWndProc
,CS_MOVENOTIFY | CS_SIZEREDRAW | CS_HITTEST | CS_SAVEBITS | CS_SYNCPAINT
,0
))
{
vError = ::WinGetLastError(vHab);
sError = wxPMErrorToStr(vError);
wxLogLastError(sError);
return FALSE;
}
return TRUE;
} // end of wxApp::RegisterWindowClasses
//
// Cleans up any wxWindows internal structures left lying around
//
void wxApp::CleanUp()
{
//
// COMMON CLEANUP
//
#if wxUSE_LOG
//
// Flush the logged messages if any and install a 'safer' log target: the
// default one (wxLogGui) can't be used after the resources are freed just
// below and the user suppliedo ne might be even more unsafe (using any
// wxWindows GUI function is unsafe starting from now)
//
wxLog::DontCreateOnDemand();
//
// This will flush the old messages if any
//
delete wxLog::SetActiveTarget(new wxLogStderr);
#endif // wxUSE_LOG
//
// One last chance for pending objects to be cleaned up
//
wxTheApp->DeletePendingObjects();
wxModule::CleanUpModules();
#if wxUSE_WX_RESOURCES
wxCleanUpResourceSystem();
#endif
wxDeleteStockObjects();
//
// Destroy all GDI lists, etc.
//
wxDeleteStockLists();
delete wxTheColourDatabase;
wxTheColourDatabase = NULL;
wxBitmap::CleanUpHandlers();
delete[] wxBuffer;
wxBuffer = NULL;
//
// PM-SPECIFIC CLEANUP
//
// wxSetKeyboardHook(FALSE);
if (wxSTD_FRAME_ICON)
::WinFreeFileIcon(wxSTD_FRAME_ICON);
if (wxSTD_MDICHILDFRAME_ICON)
::WinFreeFileIcon(wxSTD_MDICHILDFRAME_ICON);
if (wxSTD_MDIPARENTFRAME_ICON)
::WinFreeFileIcon(wxSTD_MDIPARENTFRAME_ICON);
if (wxDEFAULT_FRAME_ICON)
::WinFreeFileIcon(wxDEFAULT_FRAME_ICON);
if (wxDEFAULT_MDICHILDFRAME_ICON)
::WinFreeFileIcon(wxDEFAULT_MDICHILDFRAME_ICON);
if (wxDEFAULT_MDIPARENTFRAME_ICON)
::WinFreeFileIcon(wxDEFAULT_MDIPARENTFRAME_ICON);
if ( wxDisableButtonBrush )
{
// TODO: ::DeleteObject( wxDisableButtonBrush );
}
if (wxWinHandleList)
delete wxWinHandleList;
delete wxPendingEvents;
#if wxUSE_THREADS
delete wxPendingEventsLocker;
// If we don't do the following, we get an apparent memory leak.
((wxEvtHandler&) wxDefaultValidator).ClearEventLocker();
#endif
wxClassInfo::CleanUpClasses();
delete wxTheApp;
wxTheApp = NULL;
#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
// At this point we want to check if there are any memory
// blocks that aren't part of the wxDebugContext itself,
// as a special case. Then when dumping we need to ignore
// wxDebugContext, too.
if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
{
wxLogDebug(wxT("There were memory leaks."));
wxDebugContext::Dump();
wxDebugContext::PrintStatistics();
}
// wxDebugContext::SetStream(NULL, NULL);
#endif
#if wxUSE_LOG
// do it as the very last thing because everything else can log messages
delete wxLog::SetActiveTarget(NULL);
#endif // wxUSE_LOG
} // end of wxApp::CleanUp
int wxEntry(
int argc
, char* argv[]
)
{
HAB vHab = 0;
if (!wxApp::Initialize(vHab))
return 0;
//
// create the application object or ensure that one already exists
//
if (!wxTheApp)
{
// The app may have declared a global application object, but we recommend
// the IMPLEMENT_APP macro is used instead, which sets an initializer
// function for delayed, dynamic app object construction.
wxCHECK_MSG( wxApp::GetInitializerFunction(), 0,
wxT("No initializer - use IMPLEMENT_APP macro.") );
wxTheApp = (*wxApp::GetInitializerFunction()) ();
}
wxCHECK_MSG( wxTheApp, 0, wxT("You have to define an instance of wxApp!") );
wxTheApp->argc = argc;
#if wxUSE_UNICODE
wxTheApp->argv = new wxChar*[argc+1];
int nArgc = 0;
while (nArgc < argc)
{
wxTheApp->argv[nArgc] = wxStrdup(wxConvLibc.cMB2WX(argv[nArgc]));
nArgc++;
}
wxTheApp->argv[nArgc] = (wxChar *)NULL;
#else
wxTheApp->argv = argv;
#endif
wxString sName(wxFileNameFromPath(argv[0]));
wxStripExtension(sName);
wxTheApp->SetAppName(sName);
int nRetValue = 0;
if (!wxTheApp->OnInitGui())
nRetValue = -1;
if (nRetValue == 0)
{
if (wxTheApp->OnInit())
{
nRetValue = wxTheApp->OnRun();
// nRetValue = -1;
}
}
wxWindow* pTopWindow = wxTheApp->GetTopWindow();
if (pTopWindow)
{
// Forcibly delete the window.
if (pTopWindow->IsKindOf(CLASSINFO(wxFrame)) ||
pTopWindow->IsKindOf(CLASSINFO(wxDialog)) )
{
pTopWindow->Close(TRUE);
wxTheApp->DeletePendingObjects();
}
else
{
delete pTopWindow;
wxTheApp->SetTopWindow(NULL);
}
}
wxTheApp->OnExit();
wxApp::CleanUp();
return(nRetValue);
} // end of wxEntry
bool wxApp::OnInitGui()
{
ERRORID vError;
wxString sError;
m_hMq = ::WinCreateMsgQueue(vHabmain, 0);
if (!m_hMq)
{
vError = ::WinGetLastError(vHabmain);
sError = wxPMErrorToStr(vError);
wxLogDebug(sError);
return FALSE;
}
return TRUE;
} // end of wxApp::OnInitGui
//
// Static member initialization
//
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
wxApp::wxApp()
{
m_topWindow = NULL;
wxTheApp = this;
m_wantDebugOutput = TRUE;
argc = 0;
argv = NULL;
m_nPrintMode = wxPRINT_WINDOWS;
m_exitOnFrameDelete = TRUE;
m_bAuto3D = TRUE;
} // end of wxApp::wxApp
wxApp::~wxApp()
{
//
// Delete command-line args
//
int i;
for (i = 0; i < argc; i++)
{
delete[] argv[i];
}
delete[] argv;
#endif
} // end of wxApp::~wxApp
bool wxApp::Initialized()
{
if (GetTopWindow())
return TRUE;
else
return FALSE;
} // end of wxApp::Initialized
//
// Get and process a message, returning FALSE if WM_QUIT
// received (and also set the flag telling the app to exit the main loop)
//
bool wxApp::DoMessage()
{
BOOL bRc = ::WinGetMsg(vHabmain, &m_vMsg, HWND(NULL), 0, 0);
if (bRc == 0)
{
// got WM_QUIT
m_bKeepGoing = FALSE;
return FALSE;
}
else if (bRc == -1)
{
// should never happen, but let's test for it nevertheless
wxLogLastError("GetMessage");
}
else
{
#if wxUSE_THREADS
wxASSERT_MSG( wxThread::IsMain()
,wxT("only the main thread can process Windows messages")
);
static bool sbHadGuiLock = TRUE;
static wxMsgArray svSavedMessages;
//
// If a secondary thread owns is doing GUI calls, save all messages for
// later processing - we can't process them right now because it will
// lead to recursive library calls (and we're not reentrant)
//
if (!wxGuiOwnedByMainThread())
{
sbHadGuiLock = FALSE;
//
// Leave out WM_COMMAND messages: too dangerous, sometimes
// the message will be processed twice
//
if ( !wxIsWaitingForThread() ||
svCurrentMsg.msg != WM_COMMAND )
{
svSavedMessages.Add(svCurrentMsg);
}
return TRUE;
}
else
{
//
// Have we just regained the GUI lock? if so, post all of the saved
// messages
//
if (!sbHadGuiLock )
{
sbHadGuiLock = TRUE;
size_t nCount = svSavedMessages.Count();
for (size_t n = 0; n < nCount; n++)
{
QMSG vMsg = svSavedMessages[n];
if ( !ProcessMessage((WXMSG *)&vMsg) )
{
::WinDispatchMsg(vHabmain, &vMsg);
}
}
svSavedMessages.Empty();
}
}
#endif // wxUSE_THREADS
// Process the message
if (!ProcessMessage((WXMSG *)&svCurrentMsg) )
{
::WinDispatchMsg(vHabmain, (PQMSG)&svCurrentMsg);
}
}
return TRUE;
} // end of wxApp::DoMessage
//////////////////////////////////////////////////////////////////////////////
//
// Keep trying to process messages until WM_QUIT
// received.
//
// If there are messages to be processed, they will all be
// processed and OnIdle will not be called.
// When there are no more messages, OnIdle is called.
// If OnIdle requests more time,
// it will be repeatedly called so long as there are no pending messages.
// A 'feature' of this is that once OnIdle has decided that no more processing
// is required, then it won't get processing time until further messages
// are processed (it'll sit in DoMessage).
//
//////////////////////////////////////////////////////////////////////////////
int wxApp::MainLoop()
{
m_bKeepGoing = TRUE;
while (m_bKeepGoing)
{
#if wxUSE_THREADS
wxMutexGuiLeaveOrEnter();
#endif // wxUSE_THREADS
while (!Pending() && ProcessIdle())
{
}
DoMessage();
}
return (int)svCurrentMsg.mp1;
} // end of wxApp::MainLoop
//
// Returns TRUE if more time is needed.
//
bool wxApp::ProcessIdle()
{
wxIdleEvent vEvent;
vEvent.SetEventObject(this);
ProcessEvent(vEvent);
return vEvent.MoreRequested();
} // end of wxApp::ProcessIdle
void wxApp::ExitMainLoop()
{
m_bKeepGoing = FALSE;
}
bool wxApp::Pending()
{
return (::WinPeekMsg(vHabmain, (PQMSG)&svCurrentMsg, (HWND)NULL, 0, 0, PM_NOREMOVE) != 0);
}
void wxApp::Dispatch()
{
DoMessage();
}
//////////////////////////////////////////////////////////////////////////////
//
// Give all windows a chance to preprocess
// the message. Some may have accelerator tables, or have
// MDI complications.
//
//////////////////////////////////////////////////////////////////////////////
bool wxApp::ProcessMessage(
WXMSG* pWxmsg
)
{
QMSG* vMsg = (PQMSG)pWxmsg;
HWND hWnd = vMsg->hwnd;
wxWindow* pWndThis = wxFindWinFromHandle((WXHWND)hWnd);
wxWindow* pWnd;
#if wxUSE_TOOLTIPS
//
// We must relay WM_MOUSEMOVE events to the tooltip ctrl if we want it to
// popup the tooltip bubbles
//
if (pWndThis && (vMsg->msg == WM_MOUSEMOVE))
{
wxToolTip* pToolTip = pWndThis->GetToolTip();
if (pToolTip)
{
pToolTip->RelayEvent(pWxmsg);
}
}
#endif // wxUSE_TOOLTIPS
//
// For some composite controls (like a combobox), wndThis might be NULL
// because the subcontrol is not a wxWindow, but only the control itself
// is - try to catch this case
//
while (hWnd && !pWndThis)
{
hWnd = ::WinQueryWindow(hWnd, QW_PARENT);
pWndThis = wxFindWinFromHandle((WXHWND)hWnd);
}
//
// Anyone for a non-translation message? Try youngest descendants first.
//
for (pWnd = pWndThis; pWnd; pWnd = pWnd->GetParent())
{
if (pWnd->OS2ProcessMessage(pWxmsg))
return TRUE;
}
return FALSE;
} // end of wxApp::ProcessMessage
void wxApp::OnIdle(
wxIdleEvent& rEvent
)
{
static bool sbInOnIdle = FALSE;
//
// Avoid recursion (via ProcessEvent default case)
//
if (sbInOnIdle )
return;
sbInOnIdle = TRUE;
//
// If there are pending events, we must process them: pending events
// are either events to the threads other than main or events posted
// with wxPostEvent() functions
//
ProcessPendingEvents();
//
// 'Garbage' collection of windows deleted with Close().
//
DeletePendingObjects();
#if wxUSE_LOG
//
// Flush the logged messages if any
//
wxLog::FlushActive();
#endif // wxUSE_LOG
//
// Send OnIdle events to all windows
//
if (SendIdleEvents())
{
//
// SendIdleEvents() returns TRUE if at least one window requested more
// idle events
//
rEvent.RequestMore(TRUE);
}
sbInOnIdle = FALSE;
} // end of wxApp::OnIdle
// Send idle event to all top-level windows
bool wxApp::SendIdleEvents()
{
bool bNeedMore = FALSE;
wxWindowList::Node* pNode = wxTopLevelWindows.GetFirst();
while (pNode)
{
wxWindow* pWin = pNode->GetData();
if (SendIdleEvents(pWin))
bNeedMore = TRUE;
pNode = pNode->GetNext();
}
return bNeedMore;
} // end of wxApp::SendIdleEvents
//
// Send idle event to window and all subwindows
//
bool wxApp::SendIdleEvents(
wxWindow* pWin
)
{
bool bNeedMore = FALSE;
wxIdleEvent vEvent;
vEvent.SetEventObject(pWin);
pWin->GetEventHandler()->ProcessEvent(vEvent);
if (vEvent.MoreRequested())
bNeedMore = TRUE;
wxNode* pNode = pWin->GetChildren().First();
while (pNode)
{
wxWindow* pWin = (wxWindow*) pNode->Data();
if (SendIdleEvents(pWin))
bNeedMore = TRUE;
pNode = pNode->Next();
}
return bNeedMore;
} // end of wxApp::SendIdleEvents
void wxApp::DeletePendingObjects()
{
wxNode* pNode = wxPendingDelete.First();
while (pNode)
{
wxObject* pObj = (wxObject *)pNode->Data();
delete pObj;
if (wxPendingDelete.Member(pObj))
delete pNode;
//
// Deleting one object may have deleted other pending
// objects, so start from beginning of list again.
//
pNode = wxPendingDelete.First();
}
} // end of wxApp::DeletePendingObjects
void wxApp::OnEndSession(
wxCloseEvent& WXUNUSED(rEvent))
{
if (GetTopWindow())
GetTopWindow()->Close(TRUE);
} // end of wxApp::OnEndSession
//
// Default behaviour: close the application with prompts. The
// user can veto the close, and therefore the end session.
//
void wxApp::OnQueryEndSession(
wxCloseEvent& rEvent
)
{
if (GetTopWindow())
{
if (!GetTopWindow()->Close(!rEvent.CanVeto()))
rEvent.Veto(TRUE);
}
} // end of wxApp::OnQueryEndSession
void wxExit()
{
wxLogError(_("Fatal error: exiting"));
wxApp::CleanUp();
} // end of wxExit
//
// Yield to incoming messages
//
bool wxYield()
{
HAB vHab = 0;
QMSG vMsg;
//
// Disable log flushing from here because a call to wxYield() shouldn't
// normally result in message boxes popping up &c
//
wxLog::Suspend();
//
// We want to go back to the main message loop
// if we see a WM_QUIT. (?)
//
while (::WinPeekMsg(vHab, &vMsg, (HWND)NULL, 0, 0, PM_NOREMOVE) && vMsg.msg != WM_QUIT)
{
#if wxUSE_THREADS
wxMutexGuiLeaveOrEnter();
#endif // wxUSE_THREADS
if (!wxTheApp->DoMessage())
break;
}
//
// If they are pending events, we must process them.
//
if (wxTheApp)
wxTheApp->ProcessPendingEvents();
//
// Let the logs be flashed again
//
wxLog::Resume();
return TRUE;
} // end of wxYield
wxIcon wxApp::GetStdIcon(
int nWhich
) const
{
switch(nWhich)
{
case wxICON_INFORMATION:
return wxIcon("wxICON_INFO");
case wxICON_QUESTION:
return wxIcon("wxICON_QUESTION");
case wxICON_EXCLAMATION:
return wxIcon("wxICON_WARNING");
default:
wxFAIL_MSG(wxT("requested non existent standard icon"));
// still fall through
case wxICON_HAND:
return wxIcon("wxICON_ERROR");
}
return wxIcon("wxICON_ERROR");
} // end of wxApp::GetStdIcon
//-----------------------------------------------------------------------------
// wxWakeUpIdle
//-----------------------------------------------------------------------------
void wxWakeUpIdle()
{
//
// Send the top window a dummy message so idle handler processing will
// start up again. Doing it this way ensures that the idle handler
// wakes up in the right thread (see also wxWakeUpMainThread() which does
// the same for the main app thread only)
//
wxWindow* pTopWindow = wxTheApp->GetTopWindow();
if (pTopWindow)
{
if ( !::WinPostMsg(GetHwndOf(pTopWindow), WM_NULL, (MPARAM)0, (MPARAM)0))
{
//
// Should never happen
//
wxLogLastError("PostMessage(WM_NULL)");
}
}
} // end of wxWakeUpIdle
HINSTANCE wxGetInstance()
{
return wxhInstance;
}
void wxSetInstance(HINSTANCE hInst)
{
wxhInstance = hInst;
}