锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 3.1 static_cast 娉ㄦ剰錛?strong style="color: black; background-color: #ffff66;">static_cast涓嶈兘杞崲鎺塭xdivssion鐨刢onst銆乿olitale銆佹垨鑰卂_unaligned灞炴с?/p>
dynamic_cast涓昏鐢ㄤ簬綾誨眰嬈¢棿鐨勪笂琛岃漿鎹㈠拰涓嬭杞崲錛岃繕鍙互鐢ㄤ簬綾諱箣闂寸殑浜ゅ弶杞崲銆?br>鍦ㄧ被灞傛闂磋繘琛屼笂琛岃漿鎹㈡椂錛宒ynamic_cast鍜?strong style="color: black; background-color: #ffff66;">static_cast鐨勬晥鏋滄槸涓鏍風殑錛?br>鍦ㄨ繘琛屼笅琛岃漿鎹㈡椂錛宒ynamic_cast鍏鋒湁綾誨瀷媯鏌ョ殑鍔熻兘錛屾瘮static_cast鏇村畨鍏ㄣ?br>class B{ class D:public B{ void func(B *pb){ 鍦ㄤ笂闈㈢殑浠g爜孌典腑錛屽鏋減b鎸囧悜涓涓狣綾誨瀷鐨勫璞★紝pd1鍜宲d2鏄竴鏍風殑錛屽茍涓斿榪欎袱涓寚閽堟墽琛孌綾誨瀷鐨勪換浣曟搷浣滈兘鏄畨鍏ㄧ殑錛?br>浣嗘槸錛屽鏋減b鎸囧悜鐨勬槸涓涓狟綾誨瀷鐨勫璞★紝閭d箞pd1灝嗘槸涓涓寚鍚戣瀵硅薄鐨勬寚閽堬紝瀵瑰畠榪涜D綾誨瀷鐨勬搷浣滃皢鏄笉瀹夊叏鐨勶紙濡傝闂甿_szName錛夛紝 鍙﹀瑕佹敞鎰忥細B瑕佹湁铏氬嚱鏁幫紝鍚﹀垯浼氱紪璇戝嚭閿欙紱static_cast鍒欐病鏈夎繖涓檺鍒躲?br>榪欐槸鐢變簬榪愯鏃剁被鍨嬫鏌ラ渶瑕佽繍琛屾椂綾誨瀷淇℃伅錛岃岃繖涓俊鎭瓨鍌ㄥ湪綾葷殑铏氬嚱鏁拌〃錛?br>鍏充簬铏氬嚱鏁拌〃鐨勬蹇碉紝璇︾粏鍙 鍙﹀錛宒ynamic_cast榪樻敮鎸佷氦鍙夎漿鎹紙cross cast錛夈傚涓嬩唬鐮佹墍紺恒?br>class A{ class B:public A{ class D:public A{ void foo(){ D *pd1 = static_cast 鍦ㄥ嚱鏁癴oo涓紝浣跨敤static_cast榪涜杞崲鏄笉琚厑璁哥殑錛屽皢鍦ㄧ紪璇戞椂鍑洪敊錛涜屼嬌鐢?dynamic_cast鐨勮漿鎹㈠垯鏄厑璁哥殑錛岀粨鏋滄槸絀烘寚閽堛?/p>
璇ヨ繍綆楃鐨勭敤娉曟瘮杈冨銆?/p>
3.4 const_cast Voiatile鍜宑onst綾昏瘯銆備婦濡備笅涓渚嬶細 == =========================================== == dynamic_cast .vs. static_cast D* pd1 = dynamic_cast(pb); D* pd2 = static_cast(pb); If
pb really points to an object of type D, then pd1 and pd2 will get the
same value. They will also get the same value if pb == 0. If
pb points to an object of type B and not to the complete D class, then
dynamic_cast will know enough to return zero. However, static_cast
relies on the programmer’s assertion that pb points to an object of
type D and simply returns a pointer to that supposed D object. 鍗?/span>dynamic_cast鍙敤浜庣戶鎵夸綋緋諱腑鐨勫悜涓嬭漿鍨嬶紝鍗沖皢鍩虹被鎸囬拡杞崲涓烘淳鐢熺被鎸囬拡錛屾瘮static_cast鏇翠弗鏍兼洿瀹夊叏銆?/span>dynamic_cast鍦ㄦ墽琛屾晥鐜囦笂姣?/span>static_cast瑕佸樊涓浜涳紝浣?/span>static_cast鍦ㄦ洿瀹戒笂鑼冨洿鍐呭彲浠ュ畬鎴愭槧灝勶紝榪欑涓嶅姞闄愬埗鐨勬槧灝勪即闅忕潃涓嶅畨鍏ㄦс?/span>static_cast瑕嗙洊鐨勫彉鎹㈢被鍨嬮櫎綾誨眰嬈$殑闈欐佸鑸互澶栵紝榪樺寘鎷棤鏄犲皠鍙樻崲銆佺獎鍖栧彉鎹?/span>(榪欑鍙樻崲浼氬鑷村璞″垏鐗?/span>,涓㈠け淇℃伅)銆佺敤VOID*鐨勫己鍒跺彉鎹€侀殣寮忕被鍨嬪彉鎹㈢瓑... reinterdivt_cast鏄負浜嗘槧灝勫埌涓涓畬鍏ㄤ笉鍚岀被鍨嬬殑鎰忔濓紝榪欎釜鍏抽敭璇嶅湪鎴戜滑闇瑕佹妸綾誨瀷鏄犲皠鍥炲師鏈夌被鍨嬫椂鐢ㄥ埌瀹冦傛垜浠槧灝勫埌鐨勭被鍨嬩粎浠呮槸涓轟簡鏁呭紕鐜勮櫄鍜屽叾浠栫洰鐨勶紝榪欐槸鎵鏈夋槧灝勪腑鏈鍗遍櫓鐨勩?/span>(榪欏彞璇濇槸C++緙栫▼鎬濇兂涓殑鍘熻瘽) static_cast 鍜?/span> reinterdivt_cast 鎿嶄綔絎︿慨鏀逛簡鎿嶄綔鏁扮被鍨嬨傚畠浠笉鏄簰閫嗙殑錛?/span> static_cast 鍦ㄧ紪璇戞椂浣跨敤綾誨瀷淇℃伅鎵ц杞崲錛屽湪杞崲鎵ц蹇呰鐨勬嫻?/span>(璇稿鎸囬拡瓚婄晫璁$畻, 綾誨瀷媯鏌?/span>). 鍏舵搷浣滄暟鐩稿鏄畨鍏ㄧ殑銆傚彟涓鏂歸潰錛?/span>reinterdivt_cast 浠呬粎鏄噸鏂拌В閲婁簡緇欏嚭鐨勫璞$殑姣旂壒妯″瀷鑰屾病鏈夎繘琛屼簩榪涘埗杞崲錛?/span> 渚嬪瓙濡備笅錛?/span> int n=9; double d=static_cast < double > (n); 涓婇潰鐨勪緥瀛愪腑, 鎴戜滑灝嗕竴涓彉閲忎粠 int 杞崲鍒?/span> double銆?/span> 榪欎簺綾誨瀷鐨勪簩榪涘埗琛ㄨ揪寮忔槸涓嶅悓鐨勩?/span> 瑕佸皢鏁存暟 9 杞崲鍒?/span> 鍙岀簿搴︽暣鏁?/span> 9錛?/span>static_cast 闇瑕佹紜湴涓哄弻綺懼害鏁存暟 d 琛ヨ凍姣旂壒浣嶃傚叾緇撴灉涓?/span> 9.0銆傝?/span>reinterdivt_cast 鐨勮涓哄嵈涓嶅悓: int n=9; double d=reinterdivt_cast
榪欐, 緇撴灉鏈夋墍涓嶅悓. 鍦ㄨ繘琛岃綆椾互鍚?/span>, d 鍖呭惈鏃犵敤鍊?/span>. 榪欐槸鍥犱負 reinterdivt_cast 浠呬粎鏄鍒?/span> n 鐨勬瘮鐗逛綅鍒?/span> d, 娌℃湁榪涜蹇呰鐨勫垎鏋?/span>. 鍥犳, 浣犻渶瑕佽皚鎱庝嬌鐢?/span> reinterdivt_cast. Seeing as this is my first ever post to CodeProject, let me do a quick introduction as to who I am and what I do. I have been working in one form of C and C++ or another for as long as I can remember (among the other myriad of languages that I've run into). Nowadays, most of my development is focused on Microsoft Windows platforms, and is done in VC6, VC2002.NET. I am heavily entrenched in BI (Business Intelligence) development, and in my spare time develop little ActiveX controls and games etc... Having learnt COM a while ago, I made the obvious progression to ATL to ease the development of boilerplate code, and to leverage off Microsoft's template library. As my experience grew, I ventured into creating ActiveX controls using the ATL framework ... and life was good. I could spew out a fairly useful (albeit not overly complex) control within a short period of time. Recently, I was asked to create a KPI (Key Performance Indicator) control that could be embedded in a web page and an Excel document. Obviously based on my experience (which was obviously not vast) I thought that this would be no problem and off I went, creating code that would meet the functional spec (we all work to these don't we :)). A couple of days later the control was finished and the final tests were being run when someone asked me to print a hardcopy of an example spreadsheet with the embedded control. This is where my nightmares began. Not only did my control not print, but there was no clear indication as to why it didn't print. And so my exploration into this apparent mystery began. Have you ever tried to include 3rd party ActiveX controls into an Office document? They sure seem to work fine, but most (apart from the Microsoft controls) don't seem to render themselves when you request a Print Preview or a simple Print of the worksheet or document. So, if any of you have ever had this problem, or have never dabbled with this, but think that you may be heading this way, take note of this, cos it might save you hours of frustration and frantic searching on MSDN and Google. The first thing one needs to realize is that even though we have been blessed with Office 2000 and Office XP, the printing architecture still uses the old Windows-format metafile for its printing operations. This metafile format was used in 16-bit Windows-based applications (thinks back to Win3.1). Now, this becomes a major problem for ActiveX developers who wish their controls to be printable from within Office applications, because this old metafile format only supported a limited set of GDI functionality. The list of supported GDI functions can be found here. Now that you are armed with your limited function set, you cringe with the realization that you can no longer create memory DC's, you can no longer use your lovely For interest, the opposite of Now that we know if we're drawing to an old metafile format or not, we can write adaptive code to cater for each instance or we can just write all our drawing logic using the limited set of functionality that is supported by the old metafile DC. As any ATL ActiveX developer knows, using fonts in AX controls provides for limited amount of fun. The typical piece of code would probably look something like this: The Bolded lines of code are ones that I didn't use regularly, due to the fact that I didn't really need to know about the breakdown of my font's details because I had access to Having said this, there are many other functions that I use a lot that I can't use if I want my ActiveX control to be printable by Office, but as with When creating an ActiveX control that you know will be used inside Office applications, and will most probably be printed, remember to stick to these guidelines when developing your drawing logic. I was fairly shocked by how little information was available in the MSDN and online in general, while I was searching for information on how to enable my ActiveX control to print from within an Office application. There are hundreds of documents on ActiveX controls being printed from within Internet Explorer, but none address this particular issue. Perhaps I was looking in the wrong places. Hopefully this article will help one or more of you one day ;) Many thanks to Igor Tandetnik for pointing me in the right direction on this.
鐢ㄦ硶錛?strong style="color: black; background-color: #ffff66;">static_cast < type-id > ( exdivssion )
璇ヨ繍綆楃鎶奺xdivssion杞崲涓簍ype-id綾誨瀷錛屼絾娌℃湁榪愯鏃剁被鍨嬫鏌ユ潵淇濊瘉杞崲鐨勫畨鍏ㄦс傚畠涓昏鏈夊涓嬪嚑縐嶇敤娉曪細
鈶犵敤浜庣被灞傛緇撴瀯涓熀綾誨拰瀛愮被涔嬮棿鎸囬拡鎴栧紩鐢ㄧ殑杞崲銆?br>銆銆榪涜涓婅杞崲錛堟妸瀛愮被鐨勬寚閽堟垨寮曠敤杞崲鎴愬熀綾昏〃紺猴級鏄畨鍏ㄧ殑錛?br>銆銆榪涜涓嬭杞崲錛堟妸鍩虹被鎸囬拡鎴栧紩鐢ㄨ漿鎹㈡垚瀛愮被琛ㄧず錛夋椂錛岀敱浜庢病鏈夊姩鎬佺被鍨嬫鏌ワ紝鎵浠ユ槸涓嶅畨鍏ㄧ殑銆?br>鈶$敤浜庡熀鏈暟鎹被鍨嬩箣闂寸殑杞崲錛屽鎶奿nt杞崲鎴恈har錛屾妸int杞崲鎴恊num銆傝繖縐嶈漿鎹㈢殑瀹夊叏鎬т篃瑕佸紑鍙戜漢鍛樻潵淇濊瘉銆?br>鈶㈡妸絀烘寚閽堣漿鎹㈡垚鐩爣綾誨瀷鐨勭┖鎸囬拡銆?br>鈶f妸浠諱綍綾誨瀷鐨勮〃杈懼紡杞崲鎴恦oid綾誨瀷銆?/p>
3.2 dynamic_cast
鐢ㄦ硶錛歞ynamic_cast < type-id > ( exdivssion )
璇ヨ繍綆楃鎶奺xdivssion杞崲鎴恡ype-id綾誨瀷鐨勫璞°俆ype-id蹇呴』鏄被鐨勬寚閽堛佺被鐨勫紩鐢ㄦ垨鑰卾oid *錛?br>濡傛灉type-id鏄被鎸囬拡綾誨瀷錛岄偅涔坋xdivssion涔熷繀欏繪槸涓涓寚閽堬紝濡傛灉type-id鏄竴涓紩鐢紝閭d箞exdivssion涔熷繀欏繪槸涓涓紩鐢ㄣ?/p>
public:
int m_iNum;
virtual void foo();
};
public:
char *m_szName[100];
};
D *pd1 = static_cast
D *pd2 = dynamic_cast
}
鑰宲d2灝嗘槸涓涓┖鎸囬拡銆?/p>
娌℃湁瀹氫箟铏氬嚱鏁扮殑綾繪槸娌℃湁铏氬嚱鏁拌〃鐨勩?/p>
public:
int m_iNum;
virtual void f(){}
};
};
};
B *pb = new B;
pb->m_iNum = 100;
D *pd2 = dynamic_cast
delete pb;
}
3.3 reindivter_cast
鐢ㄦ硶錛歳eindivter_cast
type-id蹇呴』鏄竴涓寚閽堛佸紩鐢ㄣ佺畻鏈被鍨嬨佸嚱鏁版寚閽堟垨鑰呮垚鍛樻寚閽堛?br>瀹冨彲浠ユ妸涓涓寚閽堣漿鎹㈡垚涓涓暣鏁幫紝涔熷彲浠ユ妸涓涓暣鏁拌漿鎹㈡垚涓涓寚閽堬紙鍏堟妸涓涓寚閽堣漿鎹㈡垚涓涓暣鏁幫紝
鍦ㄦ妸璇ユ暣鏁拌漿鎹㈡垚鍘熺被鍨嬬殑鎸囬拡錛岃繕鍙互寰楀埌鍘熷厛鐨勬寚閽堝鹼級銆?/p>
鐢ㄦ硶錛歝onst_cast
璇ヨ繍綆楃鐢ㄦ潵淇敼綾誨瀷鐨刢onst鎴杤olatile灞炴с傞櫎浜哻onst 鎴杤olatile淇グ涔嬪錛?type_id鍜宔xdivssion鐨勭被鍨嬫槸涓鏍風殑銆?br>甯擱噺鎸囬拡琚漿鍖栨垚闈炲父閲忔寚閽堬紝騫朵笖浠嶇劧鎸囧悜鍘熸潵鐨勫璞★紱
甯擱噺寮曠敤琚漿鎹㈡垚闈炲父閲忓紩鐢紝騫朵笖浠嶇劧鎸囧悜鍘熸潵鐨勫璞★紱甯擱噺瀵硅薄琚漿鎹㈡垚闈炲父閲忓璞°?/p>
class B{
public:
int m_iNum;
}
void foo(){
const B b1;
b1.m_iNum = 100; //comile error
B b2 = const_cast(b1);
b2. m_iNum = 200; //fine
}
涓婇潰鐨勪唬鐮佺紪璇戞椂浼氭姤閿欙紝鍥犱負b1鏄竴涓父閲忓璞★紝涓嶈兘瀵瑰畠榪涜鏀瑰彉錛?br>浣跨敤const_cast鎶婂畠杞崲鎴愪竴涓父閲忓璞★紝灝卞彲浠ュ瀹冪殑鏁版嵁鎴愬憳浠繪剰鏀瑰彉銆傛敞鎰忥細b1鍜宐2鏄袱涓笉鍚岀殑瀵硅薄銆?br>
== ===========================================
class B { ... };
class D : public B { ... };
void f(B* pb)
{
}
== ===========================================
== static_cast .vs. reinterdivt_cast
== ================================================
]]>offsetof(s,m)瑙f瀽 offsetof(s,m)瑙f瀽
2
3浠婂ぉ鐪嬩唬鐮佹椂錛屽彂鐜頒竴涓湁鐢ㄧ殑涓滀笢錛宱ffsetof(s,m)錛岃繖鏄竴涓畯錛屽畾涔夊涓嬶細
4
5 #define offsetof(s,m) (size_t)&(((s *)0)->m)
6
7 鐒跺悗鍒扮綉涓婃煡浜嗕竴涓嬶紝鍙戠幇榪樼湡鐨勬槸寰堟湁鐢紝闄勫甫涓浣嶅ぇ渚犵殑瑙h錛?br> 8
9 struct AAA
10
{
11 int i;
12 int j;
13 };
14
15 struct AAA *pAAA;
16 pAAA=new AAA;
17 榪欐椂錛宲AAA瀹為檯涓婃槸涓涓狿ointer, 鎸囧悜鏌愪竴紜畾鐨勫唴瀛樺湴鍧錛屾瘮濡?x1234;
18 鑰?nbsp;pAAA->i 鏁翠綋鏄竴涓猧nt鍨嬪彉閲忥紝鍏跺湴鍧鏄?/span>&(pAAA->i) ,'&'涓哄彇鍧榪愮畻絎︼紱
19 閭d箞&(pAAA->i)涓瀹氱瓑浜?x1234,鍥犱負i鏄粨鏋勪綋AAA鐨勭涓涓厓绱犮?nbsp;
20 鑰?/span>&(pAAA->j)涓瀹氭槸0x1234 + 0x4 = 0x1238; 鍥犱負sizeof(int) = 4;
21
22 榪欎釜鍋氭硶鐨勫閥濡欎箣澶勫氨鏄細瀹冩妸“0”浣滀負涓婁緥涓殑pAAA,閭d箞 &(pAAA->j)灝辨槸j鐨?nbsp;
23 offset鍟?br>24
25 瑙f瀽緇撴灉鏄細
26 (s *)0 ,灝?nbsp;0 寮哄埗杞崲涓篜ointer to "s"
27 鍙互璁?nbsp;pS = (s *)0 錛宲S鏄寚鍚憇鐨勬寚閽堬紝瀹冪殑鍊兼槸0;
28 閭d箞pS->m灝辨槸m榪欎釜鍏冪礌浜嗭紝鑰?/span>&(pS->m)灝辨槸m鐨勫湴鍧錛岃屽湪鏈緥涓氨鏄痮ffset鍟?nbsp;
29
30 鍐嶆妸緇撴灉寮哄埗杞崲涓簊ize_t鍨嬬殑灝監K 浜嗭紝size_t鍏跺疄涔熷氨鏄痠nt鍟︼紒錛?nbsp;
31
32
33
]]>
]]>
閫氳繃VARIANT;聽聽聽
聽2
聽聽VARIANT聽聽聽varData;(鍑哄弬)聽聽聽
聽3
聽聽聽聽
聽4
聽聽MYSTRUCT聽聽聽
*
pMyData聽聽聽
=
聽聽聽NULL;聽聽聽
聽5
聽聽聽聽
聽6
聽聽pMyData聽聽聽
=
聽聽聽(MYSTRUCT
*
)CoTaskMemAlloc(
sizeof
(MYSTRUCT));聽聽聽
聽7
聽聽
.聽聽聽
聽8
聽聽聽聽
聽9
聽聽varData.byref聽聽聽
=
聽聽聽(LPVOID)pMyData;聽聽聽
10
聽聽聽聽
11
聽聽鍦ㄨ皟鐢ㄦ枃浠墮噷錛屽悓鏍峰畾涔壜犅犅?br />
12
聽聽VARIANT聽聽聽varData(鍏ュ弬錛壜犅犅?br />
13
聽聽聽聽
14
聽聽MYSTRUCT聽聽聽
*
pMyData聽聽聽
=
聽聽聽NULL;聽聽聽
15
聽聽聽聽
16
聽聽pMyData聽聽聽
=
聽聽聽(MYSTRUCT
*
)varData.byref;聽聽聽
17
聽聽聽聽
18
聽聽CoTaskMemFree((LPVOID)pMyData);
]]>
13 votes for this article.
Popularity: 4.73. Rating: 4.25 out of 5.
Introduction
The plot
So what now?
DrawText()
functions and you can definitely no longer call GetTextExtentPoint32()
function. However, those realizations only hold true for the instance of when your control is being rendered to an old format metafile. So how do we empower our control to know that its being rendered to an old format metafile? Simple, we use the GetObjectType()
function and check if the result is equal to OBJ_METADC
(old metafile format):HRESULT Cxxxxx::OnDraw(ATL_DRAWINFO& di)
{
HDC hdc = di.hdcDraw;
bool bMetaFile = false;
//// lets check if we're drawing to an old// metafile format.. (like Office printing)//if ( GetObjectType(hdc) == OBJ_METADC )
bOldMetaFile = true;
//// the rest of your code...//
}
OBJ_METADC
is OBJ_ENHMETADC
(refer to this MSDN document).What about fonts and text extents?
//
// ... some code
//
CComQIPtr<IFont, &IID_IFont> pFont(m_pFont);
TEXTMETRICOLE tm;if ( pFont != NULL )
{
pFont->get_hFont(&newFont);
pFont->AddRefHfont(newFont);
pFont->QueryTextMetrics(&tm);
oldFont = (HFONT) SelectObject(dc, newFont);
}
GetTextExtentPoint32()
function. Unfortunately, in this scenario, we don't have access to that function to determine how wide (in pixels) our text is going to be. But there is another way to calculate this fairly accurately, as is demonstrated in the code below:
//
// assume that we have called QueryTextMetrics() and
// have a filled TEXTMETRICOLE structure called tm
//
CComBSTR strText(_T("Hello, world"));
SIZE sz;
sz.cx = strText.Length() * tm.tmAveCharWidth;
sz.cy = tm.tmHeight;
GetTextExtentPoint32()
and its respective replacement, there is always a way to replace these functions using Old-Metafile-Safe-Drawing-Code (OMSDC). *maybe that acronym will catch on*Conclusion
Acknowledgment
About Peter Mares
]]>