在VC下使用资源,通常都是先在resource.h中定义一个整数,比如:) j& X2 `$ ?9 J! ^- f5 B+ x
#define IDI_LIGHTNING_R 200 // 程序图标
$ \ S2 U' c# Q$ t R 然后在resource.rc中定义这个图标:/ D' U' [6 ?& c- t. t7 W% o1 Y
IDI_LIGHTNING_R ICON "icons\\lightning_r.ico"
' n! }: Y. A9 C# J l 读取图标的时候则用:9 ~9 ?$ G- a7 T& B
::LoadIcon(h, MAKEINTRESOURCE(IDI_LIGHTNING_R));
1 v$ Z$ A% a( B) J* P 这样的形式。用wxWidgets也想当然地这样做了,结果用
, a0 S4 V) S/ e$ [ pMainWnd->SetIcon(wxICON(IDI_LIGHTNING_R));
p0 G6 N2 ]7 J 无论如何不起作用。/ q7 j( `! T1 ^( p: ?
看了下wxWidgetes代码:! |$ d. L# d3 _' ^
#define wxICON(X) wxIcon(wxT(#X))
$ `+ y/ y% F) s* Q, d 直接将IDI_LIGHTNING_R转换成了一个字符串,调用wxIcon的构造函数。
- i* r2 i9 g1 Q7 d: A2 L. } wxIcon::wxIcon(const wxString& iconfile,
! j; ? u1 L; y8 d0 G+ `" f- S long flags,
+ k6 a; Z, v' l: K8 E, ? int desiredWidth,& F% y: Q" A4 P3 o1 U% E" w4 s* }
int desiredHeight)
. M( W) A$ M2 ] j3 a {
& a' L$ F: g ^1 {7 t LoadFile(iconfile, flags, desiredWidth, desiredHeight);
5 U2 e4 j7 c( w. }: v }4 l X4 w& B8 u7 C3 K. Z. V
往下看LoadFile:
! y# \: p m0 } bool wxIcon::LoadFile(const wxString& filename,
1 G4 O4 J' \3 M' \ long type, {- e2 l4 _ q4 _* e: F0 A
int desiredWidth, int desiredHeight)6 g# Z! q! m2 ]$ s- s9 c) F. _3 Z
{* q& q/ K( }' V- f B& t: A* k
UnRef();; ]5 k" E- e! s4 i. l3 v" \6 i0 [) J
wxGDIImageHandler *handler = FindHandler(type);& C4 F; Z' v7 T* @6 ?
if ( !handler )
* |3 e# J2 C( B( c4 p {
- V% g% z, }# Q4 S // load via wxBitmap which, in turn, uses wxImage allowing us to5 D9 ~1 ^$ T$ }8 ~# T% ?3 ^! ]* S
// support more formats
3 a9 G/ M) _ S- C* e$ @& }, g+ h wxBitmap bmp;
v8 B) Z0 c( X F if ( !bmp.LoadFile(filename, type) )
9 g* }( _3 }4 j% ?" I0 \ F% u/ [ return false;
; P4 k% c6 W) [9 P# N$ ?+ I CopyFromBitmap(bmp);$ [3 t! ~1 U$ l
return true;+ Z* H% f$ g9 o" j
}
5 o+ N$ K# ?7 x3 M5 N return handler->Load(this, filename, type, desiredWidth, desiredHeight);
- ]" a/ X; \& v' O6 Z0 q* I }
- s; N8 v+ \/ m, x8 L, ]) ? 嗯,查找读取图标的Handler,然后用它来完成实际操作,图标的Handler由wxICOResourceHandler这个类来完成,看其Load方法:
' r5 i6 B% m$ @0 w7 f# M$ c virtual bool Load(wxGDIImage *image,
2 K6 J+ {" h3 r1 l const wxString& name,
' O5 c- y$ X0 ^9 g' g long flags,
5 H2 S6 j, F$ y4 I1 W int desiredWidth, int desiredHeight)
) z% b6 P0 H2 v" p3 _/ @ {
* L* h5 ~/ E0 U: y' q! B% K" Z, H wxIcon *icon = wxDynamicCast(image, wxIcon);! n r1 y) r! Y+ f& o
wxCHECK_MSG( icon, false, _T("wxIconHandler only works with icons") );
* b" t( S+ b% x2 m9 \9 B return LoadIcon(icon, name, flags, desiredWidth, desiredHeight);
S4 |% e' ^3 ]; K) ?, p% R }
& O. V2 c: x( {5 v* m' J" ^ 转为LoadIcon:
1 \: D8 J7 O( ^ bool wxICOResourceHandler::LoadIcon(wxIcon *icon,
8 F8 I4 S9 u6 E7 j0 _7 c3 A5 o& @ const wxString& name,* A0 ~# G% |% Q- V! }
long WXUNUSED(flags),
3 H) J6 ]9 m+ T int desiredWidth, int desiredHeight)
9 y6 U% y% X) o2 N! B& i7 Z { y$ v% X/ T6 S: u. {* x
HICON hicon;. w0 u* ]7 m6 G* I% S, N
// do we need the icon of the specific size or would any icon do?
- T+ R4 a& n$ C bool hasSize = desiredWidth != -1 || desiredHeight != -1;
( B( d- x2 C( Q3 x' _4 c wxASSERT_MSG( !hasSize || (desiredWidth != -1 && desiredHeight != -1),
7 j U4 _' x! c P+ ~" m _T("width and height should be either both -1 or not") );
! s: X$ V9 e2 N+ F // try to load the icon from this program first to allow overriding the& e+ f1 a: J# J7 E- D8 d
// standard icons (although why one would want to do it considering that+ K: p5 L" c0 i* o% Z+ ]( i6 w
// we already have wxApp::GetStdIcon() is unclear)# J) G1 B- u+ \% ^- {+ c6 G
// note that we can't just always call LoadImage() because it seems to do' r7 X6 Y8 U p& O
// some icon rescaling internally which results in very ugly 16x16 icons9 w8 d) ]$ H4 B
if ( hasSize )7 g+ g# Y8 z8 {! W- ^9 A
{ E) M, M" j/ m; c9 e9 P; h* }7 X
hicon = (HICON)::LoadImage(wxGetInstance(), name, IMAGE_ICON,; l" `3 r+ h D l
desiredWidth, desiredHeight,
: h# a* D1 w: ]1 L7 C LR_DEFAULTCOLOR);
- x" g6 G7 p6 \% m2 O, Y }+ o+ }5 B! s, J8 i' K
else
! {& i! S' @4 K5 K/ J2 t {; e& {/ W0 k. g+ {7 w
hicon = ::LoadIcon(wxGetInstance(), name);
6 z# g8 k* \6 x; X& M! w) @3 Z }
) n) ~" z8 `0 P- x2 J% V! b …………………..
% K0 I6 A) U) n. B! C wxSize size = wxGetHiconSize(hicon);
* ?: N, e- T C2 F6 } icon->SetSize(size.x, size.y);8 S6 y! N* q( K( `* g$ s
icon->SetHICON((WXHICON)hicon);
( J8 r A: a* k% a( v return icon->Ok();) [) _' z9 q, m2 ]# H! E. ~* `
}: m& K, `$ [" [* z( ~& b! ]
最终的读取操作同样将由LoadIcon这个windows api完成,它必须接受一个字符串做为参数,在wxWidgets中,从开始传递进来的就是”IDI_LIGHTNING_R”这样一个字符串,它并没有使用MAKEINTRESOURCE转换得到的字符串,因而自然无法正常读取资源。
! b/ `- a) j, u V 比较wxWidgets自己的resource.rc文件,它并没有使用resource.h,自然也没有将这个资源标志定义为整数。呵呵,原来如此。! }& [3 f" A. C8 [/ g( [
在resource.rc中修改图标的定义:
5 ?7 ^& c" l3 W2 R9 W9 `8 ? lightning_r ICON "icons\\lightning_r.ico". C1 I' Y# b4 s4 a
这里lightning_r是一个未定义的符号,这样vc的资源编译将把它做为一个字符串处理,并以此为这个图标的标识,最后读取图标的时候用:* I }6 e" W, `' V2 f, {( t
pMainWnd->SetIcon(wxICON(lightning_r));+ A- C" C( D; v9 J" R
一切OK! |