wxWidgets初始化分析-应用定义和初始化

1. 一个wxWidgets的基本结构是:一个App类+一个Frame类,代码如:

class MyApp: public wxApp
{
public:
    bool OnInit();
};
IMPLEMENT_APP(MyApp)


2. IMPLEMENT_APP(MyApp) 这个宏包含了入口,抽象了不同平台入口的差异,分析如下:

IMPLEMENT_APP展开如下:

#define IMPLEMENT_APP(appname)              \
    IMPLEMENT_APP_NO_THEMES(appname)        \
    IMPLEMENT_WX_THEME_SUPPORT

 

IMPLEMENT_APP_NO_THEMES展开如下:

#define IMPLEMENT_APP_NO_THEMES(appname)    \
    IMPLEMENT_APP_NO_MAIN(appname)          \
    IMPLEMENT_WXWIN_MAIN

 

IMPLEMENT_APP_NO_MAIN展开如下:

#define IMPLEMENT_APP_NO_MAIN(appname)                                      \
    wxAppConsole *wxCreateApp()                                             \
    {                                                                       \
        wxAppConsole::CheckBuildOptions(WX_BUILD_OPTIONS_SIGNATURE,         \
                                        "your program");                    \
        return new appname;                                                 \
    }                                                                       \
    wxAppInitializer                                                        \
        wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp);        \
    DECLARE_APP(appname)                                                    \
    appname& wxGetApp() { return *wx_static_cast(appname*, wxApp::GetInstance()); }

实际上IMPLEMENT_APP_NO_MAIN定义了wxCreateApp函数new appname创建出应用类的实例.   

wxAppInitializer  wxTheAppInitializer((wxAppInitializerFunction) wxCreateApp);实际上把创建函数wxCreateApp用接口wxApp::SetInitializerFunction(fn);设置进了系统,都静态变量保存的.

appname& wxGetApp() { return *wx_static_cast(appname*, wxApp::GetInstance()); }这个获取App实例的接口也在此定义.

 

IMPLEMENT_WXWIN_MAIN展开如下:

#define IMPLEMENT_WXWIN_MAIN \
    extern "C" int WINAPI WinMain(HINSTANCE hInstance,                    \
                                  HINSTANCE hPrevInstance,                \
                                  wxCmdLineArgType lpCmdLine,             \
                                  int nCmdShow)                           \
    {                                                                     \
        return wxEntry(hInstance, hPrevInstance, lpCmdLine, nCmdShow);    \
    }                                                                     \
    IMPLEMENT_WXWIN_MAIN_BORLAND_NONSTANDARD

WinMain是Windows平台Win32应用的入口函数,WinMain包含了C/C++的main函数实现.

多参WXDLLEXPORT int wxEntry(HINSTANCE hInstance,HINSTANCE WXUNUSED(hPrevInstance),wxCmdLineArgType WXUNUSED(pCmdLine),int nCmdShow),会在最后调用2参的int wxEntry(int& argc, char **argv),此函数实现有3处,Unicode版本的也是要转换成非Unicode版本的函数调用,最终会调用到wxEntryReal,此接口是真正的库初始化入口:分析如下

wxEntryReal定义如下:

int wxEntryReal(int& argc, wxChar **argv)
{
    // library initialization
    wxInitializer initializer(argc, argv);

    if ( !initializer.IsOk() )
    {
#if wxUSE_LOG
        // flush any log messages explaining why we failed
        delete wxLog::SetActiveTarget(NULL);
#endif
        return -1;
    }

    wxTRY
    {

        // app initialization
        if ( !wxTheApp->CallOnInit() )
        {
            // don't call OnExit() if OnInit() failed
            return -1;
        }

        // ensure that OnExit() is called if OnInit() had succeeded
        class CallOnExit
        {
        public:
            ~CallOnExit() { wxTheApp->OnExit(); }
        } callOnExit;

        WX_SUPPRESS_UNUSED_WARN(callOnExit);

        // app execution
        return wxTheApp->OnRun();
    }
    wxCATCH_ALL( wxTheApp->OnUnhandledException(); return -1; )
}

wxInitializer initializer(argc, argv);这句隐含了库的初始化过程,wxInitializer类的构造函数进行了初始化:

    wxInitializer(int argc, char **argv) //构造函数
    {
        m_ok = wxInitialize(argc, argv);  //调用了初始化wxInitialize
    }

wxInitialize调用了wxEntryStart,此函数也2个版本,unicode的版本也是经过转换调用的非unicode版本,如下:

    wxAppPtr app(wxTheApp);
    if ( !app.get() )
    {
        // if not, he might have used IMPLEMENT_APP() to give us a function to
        // create it
        wxAppInitializerFunction fnCreate = wxApp::GetInitializerFunction(); // 注意此句取得了上边设置的创建App的函数

        if ( fnCreate )
        {
            // he did, try to create the custom wxApp object
            app.Set((*fnCreate)()); // 此处构造了应用App类,app变量保存了此指针,这个赋值实际调用wxApp::SetInstance(ptr);赋值了ms_appInstance,

                                              //通过wxTheApp宏访问,上边定义的wxGetApp接口,也是获取此变量.
    }

    if ( !app.get() )
    {
        // either IMPLEMENT_APP() was not used at all or it failed -- in any
        // case we still need something
        app.Set(new wxDummyConsoleApp);
    }


    // wxApp initialization: this can be customized
    // --------------------------------------------

    if ( !app->Initialize(argc, argv) ) // 调用app初始化接口,bool wxApp::Initialize(int& argc, wxChar **argv)此接口被调用,进而初始化了系统

    {
        return false;
    }

 

wxEntryReal调用了系统初始化后,又调用了应用App的OnInit接口,给App初始化的时机:

        // app initialization
        if ( !wxTheApp->CallOnInit() )
        {
            // don't call OnExit() if OnInit() failed
            return -1;
        }
此调用会多态到应用的OnInit接口,应用在此接口中初始化了Frame主窗口之类的窗口组件.wxTheApp宏用的比较多.CallOnInit接口调用了 CallOnInit() { return OnInit(); }接口。

 

-----------------------------------------------------------------------

以上基本完成了库和用户的App初始化过程,在wxEntryReal接口的最后,return wxTheApp->OnRun();进入:

int wxAppBase::OnRun()
{
    // see the comment in ctor: if the initial value hasn't been changed, use
    // the default Yes from now on
    if ( m_exitOnFrameDelete == Later )
    {
        m_exitOnFrameDelete = Yes;
    }
    //else: it has been changed, assume the user knows what he is doing

    return MainLoop();
}
//进入了程序主循环,开始了事件接收、分发、处理的过程,指导程序结束.

 

本文完.

转载于:https://www.cnblogs.com/linucos/archive/2012/08/19/2646543.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
wxWidgets初始化是通过调用wxInitializer类的构造函数来完成的。在构造函数中,会调用wxInitialize函数来进行初始化。该函数的参数是argc和argv,这些参数通常是由主函数传递给应用程序的命令行参数。通过调用wxInitialize函数来初始化wxWidgets库,可以确保在使用wxWidgets之前,所有必要的初始化工作都已完成。 在使用wxWidgets的样本程序时,如果遇到了无法运行的问题,可以尝试在构建新的wxWidgets项目时勾选"use dynamic wxWidgets libs"选项。这个选项的前提是按照动态库构建的wxWidgets。这样可以确保程序能够正确链接和加载wxWidgets库,并进行正确的初始化。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [wxWidgets初始化分析-应用定义初始化](https://blog.csdn.net/weixin_30376083/article/details/96446977)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [linux下code::blocks开发wxWidgets项目的初始化工作](https://blog.csdn.net/weixin_30244681/article/details/96767073)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值