wxWidgets的资源读取

来源:互联网 发布:bing 每日壁纸软件 编辑:程序博客网 时间:2024/04/29 14:22

 

快乐虾

http://blog.csdn.net/lights_joy/

lights@hb165.com

  

本文适用于

wxWidgets-2.8.8

vs2008

Windows XP

  

欢迎转载,但请保留作者信息

 

在VC下使用资源,通常都是先在resource.h中定义一个整数,比如:

#define IDI_LIGHTNING_R          200   // 程序图标

然后在resource.rc中定义这个图标:

IDI_LIGHTNING_R             ICON                   "icons//lightning_r.ico"

读取图标的时候则用:

::LoadIcon(h, MAKEINTRESOURCE(IDI_LIGHTNING_R));

这样的形式。用wxWidgets也想当然地这样做了,结果用

     pMainWnd->SetIcon(wxICON(IDI_LIGHTNING_R));

无论如何不起作用。

看了下wxWidgetes代码:

    #define wxICON(X) wxIcon(wxT(#X))

直接将IDI_LIGHTNING_R转换成了一个字符串,调用wxIcon的构造函数。

wxIcon::wxIcon(const wxString& iconfile,

               long flags,

               int desiredWidth,

               int desiredHeight)

 

{

    LoadFile(iconfile, flags, desiredWidth, desiredHeight);

}

往下看LoadFile

bool wxIcon::LoadFile(const wxString& filename,

                      long type,

                      int desiredWidth, int desiredHeight)

{

    UnRef();

 

    wxGDIImageHandler *handler = FindHandler(type);

 

    if ( !handler )

    {

        // load via wxBitmap which, in turn, uses wxImage allowing us to

        // support more formats

        wxBitmap bmp;

        if ( !bmp.LoadFile(filename, type) )

            return false;

 

        CopyFromBitmap(bmp);

        return true;

    }

 

    return handler->Load(this, filename, type, desiredWidth, desiredHeight);

}

嗯,查找读取图标的Handler,然后用它来完成实际操作,图标的HandlerwxICOResourceHandler这个类来完成,看其Load方法:

    virtual bool Load(wxGDIImage *image,

                      const wxString& name,

                      long flags,

                      int desiredWidth, int desiredHeight)

    {

        wxIcon *icon = wxDynamicCast(image, wxIcon);

        wxCHECK_MSG( icon, false, _T("wxIconHandler only works with icons") );

 

        return LoadIcon(icon, name, flags, desiredWidth, desiredHeight);

    }

转为LoadIcon

bool wxICOResourceHandler::LoadIcon(wxIcon *icon,

                                    const wxString& name,

                                    long WXUNUSED(flags),

                                    int desiredWidth, int desiredHeight)

{

    HICON hicon;

 

    // do we need the icon of the specific size or would any icon do?

    bool hasSize = desiredWidth != -1 || desiredHeight != -1;

 

    wxASSERT_MSG( !hasSize || (desiredWidth != -1 && desiredHeight != -1),

                  _T("width and height should be either both -1 or not") );

 

    // try to load the icon from this program first to allow overriding the

    // standard icons (although why one would want to do it considering that

    // we already have wxApp::GetStdIcon() is unclear)

 

    // note that we can't just always call LoadImage() because it seems to do

    // some icon rescaling internally which results in very ugly 16x16 icons

    if ( hasSize )

    {

        hicon = (HICON)::LoadImage(wxGetInstance(), name, IMAGE_ICON,

                                    desiredWidth, desiredHeight,

                                    LR_DEFAULTCOLOR);

    }

    else

    {

        hicon = ::LoadIcon(wxGetInstance(), name);

    }

…………………..

    wxSize size = wxGetHiconSize(hicon);

    icon->SetSize(size.x, size.y);

 

    icon->SetHICON((WXHICON)hicon);

 

    return icon->Ok();

}

最终的读取操作同样将由LoadIcon这个windows api完成,它必须接受一个字符串做为参数,在wxWidgets中,从开始传递进来的就是”IDI_LIGHTNING_R”这样一个字符串,它并没有使用MAKEINTRESOURCE转换得到的字符串,因而自然无法正常读取资源。

比较wxWidgets自己的resource.rc文件,它并没有使用resource.h,自然也没有将这个资源标志定义为整数。呵呵,原来如此。

resource.rc中修改图标的定义:

lightning_r            ICON                   "icons//lightning_r.ico"

这里lightning_r是一个未定义的符号,这样vc的资源编译将把它做为一个字符串处理,并以此为这个图标的标识,最后读取图标的时候用:

     pMainWnd->SetIcon(wxICON(lightning_r));

一切OK!

 

 

参考资料

dll方式编译wxWidgets-2.8.8(2008-9-6)

wxWidgetsMFC动态类型信息比较2008-9-7

wxWidgets程序链接错误解决(2008-10-24)

animate示例看wxWidgets的程序结构(2008-10-25)

重载wxArtProvider改写wxWidgets图标(2008-10-25)

vs2008下使用wxWidgets的诡异问题(2008-10-28)

 

 

 

原创粉丝点击