app.cpp
来自「A*算法 A*算法 A*算法 A*算法A*算法A*算法」· C++ 代码 · 共 789 行 · 第 1/2 页
CPP
789 行
/////////////////////////////////////////////////////////////////////////////
// Name: app.cpp
// Purpose: wxApp
// Author: Julian Smart
// Modified by:
// Created: 04/01/98
// RCS-ID: $Id: app.cpp,v 1.238.2.2 2006/02/11 14:57:10 JS Exp $
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ===========================================================================
// declarations
// ===========================================================================
// ---------------------------------------------------------------------------
// headers
// ---------------------------------------------------------------------------
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
#pragma implementation "app.h"
#endif
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#if defined(__BORLANDC__)
#pragma hdrstop
#endif
#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"
#include "wx/log.h"
#endif
#include "wx/apptrait.h"
#include "wx/filename.h"
#include "wx/module.h"
#include "wx/dynlib.h"
#include "wx/msw/private.h"
#include "wx/msw/ole/oleutils.h"
#if wxUSE_TOOLTIPS
#include "wx/tooltip.h"
#endif // wxUSE_TOOLTIPS
// OLE is used for drag-and-drop, clipboard, OLE Automation..., but some
// compilers don't support it (missing headers, libs, ...)
#if defined(__GNUWIN32_OLD__) || defined(__SYMANTEC__) || defined(__SALFORDC__)
#undef wxUSE_OLE
#define wxUSE_OLE 0
#endif // broken compilers
#if defined(__POCKETPC__) || defined(__SMARTPHONE__)
#include <ole2.h>
#include <aygshell.h>
#endif
#if wxUSE_OLE
#include <ole2.h>
#endif
#include <string.h>
#include <ctype.h>
#include "wx/msw/wrapcctl.h"
// For MB_TASKMODAL
#ifdef __WXWINCE__
#include "wx/msw/wince/missing.h"
#endif
// instead of including <shlwapi.h> which is not part of the core SDK and not
// shipped at all with other compilers, we always define the parts of it we
// need here ourselves
//
// NB: DLLVER_PLATFORM_WINDOWS will be defined if shlwapi.h had been somehow
// included already
#ifndef DLLVER_PLATFORM_WINDOWS
// hopefully we don't need to change packing as DWORDs should be already
// correctly aligned
struct DLLVERSIONINFO
{
DWORD cbSize;
DWORD dwMajorVersion; // Major version
DWORD dwMinorVersion; // Minor version
DWORD dwBuildNumber; // Build number
DWORD dwPlatformID; // DLLVER_PLATFORM_*
};
typedef HRESULT (CALLBACK* DLLGETVERSIONPROC)(DLLVERSIONINFO *);
#endif // defined(DLLVERSIONINFO)
// ---------------------------------------------------------------------------
// global variables
// ---------------------------------------------------------------------------
extern wxList WXDLLEXPORT wxPendingDelete;
#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
extern void wxSetKeyboardHook(bool doIt);
#endif
// NB: all "NoRedraw" classes must have the same names as the "normal" classes
// with NR suffix - wxWindow::MSWCreate() supposes this
#ifdef __WXWINCE__
WXDLLIMPEXP_CORE wxChar *wxCanvasClassName;
WXDLLIMPEXP_CORE wxChar *wxCanvasClassNameNR;
#else
WXDLLIMPEXP_CORE const wxChar *wxCanvasClassName = wxT("wxWindowClass");
WXDLLIMPEXP_CORE const wxChar *wxCanvasClassNameNR = wxT("wxWindowClassNR");
#endif
WXDLLIMPEXP_CORE const wxChar *wxMDIFrameClassName = wxT("wxMDIFrameClass");
WXDLLIMPEXP_CORE const wxChar *wxMDIFrameClassNameNoRedraw = wxT("wxMDIFrameClassNR");
WXDLLIMPEXP_CORE const wxChar *wxMDIChildFrameClassName = wxT("wxMDIChildFrameClass");
WXDLLIMPEXP_CORE const wxChar *wxMDIChildFrameClassNameNoRedraw = wxT("wxMDIChildFrameClassNR");
// ----------------------------------------------------------------------------
// private functions
// ----------------------------------------------------------------------------
LRESULT WXDLLEXPORT APIENTRY wxWndProc(HWND, UINT, WPARAM, LPARAM);
// ===========================================================================
// wxGUIAppTraits implementation
// ===========================================================================
// private class which we use to pass parameters from BeforeChildWaitLoop() to
// AfterChildWaitLoop()
struct ChildWaitLoopData
{
ChildWaitLoopData(wxWindowDisabler *wd_, wxWindow *winActive_)
{
wd = wd_;
winActive = winActive_;
}
wxWindowDisabler *wd;
wxWindow *winActive;
};
void *wxGUIAppTraits::BeforeChildWaitLoop()
{
/*
We use a dirty hack here to disable all application windows (which we
must do because otherwise the calls to wxYield() could lead to some very
unexpected reentrancies in the users code) but to avoid losing
focus/activation entirely when the child process terminates which would
happen if we simply disabled everything using wxWindowDisabler. Indeed,
remember that Windows will never activate a disabled window and when the
last childs window is closed and Windows looks for a window to activate
all our windows are still disabled. There is no way to enable them in
time because we don't know when the childs windows are going to be
closed, so the solution we use here is to keep one special tiny frame
enabled all the time. Then when the child terminates it will get
activated and when we close it below -- after reenabling all the other
windows! -- the previously active window becomes activated again and
everything is ok.
*/
wxBeginBusyCursor();
// first disable all existing windows
wxWindowDisabler *wd = new wxWindowDisabler;
// then create an "invisible" frame: it has minimal size, is positioned
// (hopefully) outside the screen and doesn't appear on the taskbar
wxWindow *winActive = new wxFrame
(
wxTheApp->GetTopWindow(),
wxID_ANY,
wxEmptyString,
wxPoint(32600, 32600),
wxSize(1, 1),
wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR
);
winActive->Show();
return new ChildWaitLoopData(wd, winActive);
}
void wxGUIAppTraits::AlwaysYield()
{
wxYield();
}
void wxGUIAppTraits::AfterChildWaitLoop(void *dataOrig)
{
wxEndBusyCursor();
ChildWaitLoopData * const data = (ChildWaitLoopData *)dataOrig;
delete data->wd;
// finally delete the dummy frame and, as wd has been already destroyed and
// the other windows reenabled, the activation is going to return to the
// window which had had it before
data->winActive->Destroy();
// also delete the temporary data object itself
delete data;
}
bool wxGUIAppTraits::DoMessageFromThreadWait()
{
// we should return false only if the app should exit, i.e. only if
// Dispatch() determines that the main event loop should terminate
return !wxTheApp || wxTheApp->Dispatch();
}
wxToolkitInfo& wxGUIAppTraits::GetToolkitInfo()
{
static wxToolkitInfo info;
wxToolkitInfo& baseInfo = wxAppTraits::GetToolkitInfo();
info.versionMajor = baseInfo.versionMajor;
info.versionMinor = baseInfo.versionMinor;
info.os = baseInfo.os;
info.shortName = _T("msw");
info.name = _T("wxMSW");
#ifdef __WXUNIVERSAL__
info.shortName << _T("univ");
info.name << _T("/wxUniversal");
#endif
return info;
}
// ===========================================================================
// wxApp implementation
// ===========================================================================
int wxApp::m_nCmdShow = SW_SHOWNORMAL;
// ---------------------------------------------------------------------------
// wxWin macros
// ---------------------------------------------------------------------------
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()
// class to ensure that wxAppBase::CleanUp() is called if our Initialize()
// fails
class wxCallBaseCleanup
{
public:
wxCallBaseCleanup(wxApp *app) : m_app(app) { }
~wxCallBaseCleanup() { if ( m_app ) m_app->wxAppBase::CleanUp(); }
void Dismiss() { m_app = NULL; }
private:
wxApp *m_app;
};
//// Initialize
bool wxApp::Initialize(int& argc, wxChar **argv)
{
if ( !wxAppBase::Initialize(argc, argv) )
return false;
// ensure that base cleanup is done if we return too early
wxCallBaseCleanup callBaseCleanup(this);
#ifdef __WXWINCE__
wxString tmp = GetAppName();
tmp += wxT("ClassName");
wxCanvasClassName = wxStrdup( tmp.c_str() );
tmp += wxT("NR");
wxCanvasClassNameNR = wxStrdup( tmp.c_str() );
HWND hWnd = FindWindow( wxCanvasClassNameNR, NULL );
if (hWnd)
{
SetForegroundWindow( (HWND)(((DWORD)hWnd)|0x01) );
return false;
}
#endif
#if defined(__WIN95__) && !defined(__WXMICROWIN__)
InitCommonControls();
#endif // __WIN95__
#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
SHInitExtraControls();
#endif
#ifndef __WXWINCE__
// Don't show a message box if a function such as SHGetFileInfo
// fails to find a device.
SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
#endif
wxOleInitialize();
RegisterWindowClasses();
wxWinHandleHash = new wxWinHashTable(wxKEY_INTEGER, 100);
#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
wxSetKeyboardHook(true);
#endif
callBaseCleanup.Dismiss();
return true;
}
// ---------------------------------------------------------------------------
// RegisterWindowClasses
// ---------------------------------------------------------------------------
// TODO we should only register classes really used by the app. For this it
// would be enough to just delay the class registration until an attempt
// to create a window of this class is made.
bool wxApp::RegisterWindowClasses()
{
WNDCLASS wndclass;
wxZeroMemory(wndclass);
// for each class we register one with CS_(V|H)REDRAW style and one
// without for windows created with wxNO_FULL_REDRAW_ON_REPAINT flag
static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
static const long styleNoRedraw = CS_DBLCLKS;
// the fields which are common to all classes
wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
wndclass.hInstance = wxhInstance;
wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
// register the class for all normal windows
wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndclass.lpszClassName = wxCanvasClassName;
wndclass.style = styleNormal;
if ( !RegisterClass(&wndclass) )
{
wxLogLastError(wxT("RegisterClass(frame)"));
}
// "no redraw" frame
wndclass.lpszClassName = wxCanvasClassNameNR;
wndclass.style = styleNoRedraw;
if ( !RegisterClass(&wndclass) )
{
wxLogLastError(wxT("RegisterClass(no redraw frame)"));
}
// Register the MDI frame window class.
wndclass.hbrBackground = (HBRUSH)NULL; // paint MDI frame ourselves
wndclass.lpszClassName = wxMDIFrameClassName;
wndclass.style = styleNormal;
if ( !RegisterClass(&wndclass) )
{
wxLogLastError(wxT("RegisterClass(MDI parent)"));
}
// "no redraw" MDI frame
wndclass.lpszClassName = wxMDIFrameClassNameNoRedraw;
wndclass.style = styleNoRedraw;
if ( !RegisterClass(&wndclass) )
{
wxLogLastError(wxT("RegisterClass(no redraw MDI parent frame)"));
}
// Register the MDI child frame window class.
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszClassName = wxMDIChildFrameClassName;
wndclass.style = styleNormal;
if ( !RegisterClass(&wndclass) )
{
wxLogLastError(wxT("RegisterClass(MDI child)"));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?