C基礎(wxWidgets的資源讀取)

字號:

在VC下使用資源,通常都是先在resource.h中定義一個整數(shù),比如:
    #define IDI_LIGHTNING_R 200 // 程序圖標
    然后在resource.rc中定義這個圖標:
    IDI_LIGHTNING_R ICON "icons\\lightning_r.ico"
    讀取圖標的時候則用:
    ::LoadIcon(h, MAKEINTRESOURCE(IDI_LIGHTNING_R));
    這樣的形式。用wxWidgets也想當然地這樣做了,結(jié)果用
    pMainWnd->SetIcon(wxICON(IDI_LIGHTNING_R));
    無論如何不起作用。
    看了下wxWidgetes代碼:
    #define wxICON(X) wxIcon(wxT(#X))
    直接將IDI_LIGHTNING_R轉(zhuǎn)換成了一個字符串,調(diào)用wxIcon的構(gòu)造函數(shù)。
    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,然后用它來完成實際操作,圖標的Handler由wxICOResourceHandler這個類來完成,看其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);
    }
    轉(zhuǎn)為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完成,它必須接受一個字符串做為參數(shù),在wxWidgets中,從開始傳遞進來的就是”IDI_LIGHTNING_R”這樣一個字符串,它并沒有使用MAKEINTRESOURCE轉(zhuǎn)換得到的字符串,因而自然無法正常讀取資源。
    比較wxWidgets自己的resource.rc文件,它并沒有使用resource.h,自然也沒有將這個資源標志定義為整數(shù)。呵呵,原來如此。
    在resource.rc中修改圖標的定義:
    lightning_r ICON "icons\\lightning_r.ico"
    這里lightning_r是一個未定義的符號,這樣vc的資源編譯將把它做為一個字符串處理,并以此為這個圖標的標識,最后讀取圖標的時候用:
    pMainWnd->SetIcon(wxICON(lightning_r));
    一切OK!