锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
騫村墠錛孞effrey鎵炬垜璋堣繃錛屽叧浜庤亴涓氬彇鍚戜笂鐨勬兂娉曘備粩緇嗘兂浜嗘兂錛屾垜浠嶇劧鎯沖湪鎶鏈亾璺笂璧板緱鏇磋繙錛屽湪搴曞眰鎶鏈笂璧板緱鏇磋繙銆傚敖綆″悇縐嶅弽闈㈢殑鎯蟲硶鍜岀幇瀹炴憜鍦ㄧ溂鍓嶏紝浣嗘槸錛屾垜甯屾湜鑷繁濮嬬粓鑳芥湁涓棰楀媷浜庡垱閫犵殑鍐呭績銆?br>
鏂扮殑涓騫達紝鑷繁瑕佹洿鍔犲姫鍔涳紝榪樻槸璁╄嚜宸辯戶緇啓涓嬪幓鍚э紝璁╁啓浣滄垚涓轟竴縐嶅潥鎸侊紝璁╁涔犳垚涓轟竴縐嶄範鎯紝璁╁垎浜垚涓轟竴縐嶅揩涔愶紝璁╄矗浠繪垚涓轟竴縐嶇幇瀹炪?/p>
]]>
]]>
DKP璁板綍閲屾垜浠緣鐓岀殑鐬棿錛屾兂璧蜂簡浠ュ線鐨勭縐嶇殑鎰熷姩錛屽敖綆¤繖縐嶆劅瑙変笉鑳芥案椹誨績闂達紝鍗村湪鎴戝績閲屽垝涓婁簡涓鍒頒激鐥曘?span lang="EN-US">
聽聽聽
聽聽聽
聽聽聽
聽聽聽
聽聽聽
聽聽聽
聽聽聽
鍦∕FC鐨勬秷鎭槧灝勮〃鐨勫緩绔嬩腑錛岄氳繃涓緇勫畯錛屼綘灝卞彲浠ヨ鑷繁鐨勭被鍏堜簬鐖剁被澶勭悊鏌愪簺Windows娑堟伅錛岃繖縐嶈涓哄緢鍍忚櫄鍑芥暟錛屽彧鏄垜浠噸杞界殑鍐呭涓嶆槸铏氬嚱鏁幫紝鑰屾槸娑堟伅銆?/font>
鎺ㄥ姩娑堟伅鐨勬車
絎竴闃舵 紿楀彛榪囩▼
鍦ㄤ駭鐢熶竴涓獥鍙g殑鏃跺欙紝浼氳皟鐢–FrameWnd::Create錛屾墍鏈夌殑鏁呬簨涔熼兘浠庤繖閲屽睍寮銆備笅闈㈢殑浠g爜涓轟簡綆媧侊紝鍘繪帀浜嗕笉鐩稿叧鐨勪唬鐮?br />
BOOL聽CFrameWnd::Create(鈥?聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽
if
聽(
!
CreateEx(鈥?)聽
{
聽聽聽聽聽聽聽聽
//
聽鈥?/span>
聽聽聽聽}
聽聽聽聽
//
聽鈥?/span>
}
BOOL聽CWnd::CreateEx(鈥?聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽AfxHookWindowCreate(
this
);
聽聽聽聽HWND聽hWnd聽
=
聽::CreateWindowEx(鈥?;
聽聽聽聽
//
聽鈥?/span>
}
void
聽AFXAPI聽AfxHookWindowCreate(CWnd
*
聽pWnd)聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽
if
聽(pThreadState
->
m_hHookOldCbtFilter聽
==
聽NULL)聽
{
聽聽聽聽聽聽聽聽pThreadState
->
m_hHookOldCbtFilter聽
=
聽::SetWindowsHookEx(WH_CBT,
聽聽聽聽聽聽聽聽_AfxCbtFilterHook,聽NULL,聽::GetCurrentThreadId());
聽聽聽聽聽聽聽聽
//
聽鈥?/span>
聽聽聽聽}
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽pThreadState
->
m_pWndInit聽
=
聽pWnd;
}
榪欐牱錛岄氳繃AfxHookWindowCreate錛屽湪褰撳墠綰跨▼涓畨瑁呬簡涓涓挬瀛愶紝鐢ㄦ潵鎷︽埅鍜岀獥鍙g浉鍏崇殑浜嬩歡錛屾瘡褰擄細
1. 鍙︿竴涓獥鍙f垚涓篴ctive錛?br />2. 浜х敓鎴栨懅姣佷竴涓獥鍙?br />3. Minimize鎴杕aximize涓涓獥鍙o紱
4. 縐誨姩鎴栫緝鏀句竴涓獥鍙o紱
5. 瀹屾垚涓涓潵鑷郴緇熻彍鍗曠殑鍛戒護錛?br />6. 浠庣郴緇熼槦鍒椾腑鍙栧嚭涓涓秷鎭紱
鏃訛紝閮戒細鍏堣皟鐢╛AfxCbtFilterHook錛屾帴涓嬫潵鐪嬬湅閽╁瓙鍑芥暟浣滀簡浠涔堬細
LRESULT聽CALLBACK
_AfxCbtFilterHook(
int
聽code,聽WPARAM聽wParam,聽LPARAM聽lParam)聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽WNDPROC聽afxWndProc聽
=
聽AfxGetAfxWndProc();
聽聽聽聽oldWndProc聽
=
聽(WNDPROC)SetWindowLongPtr(hWnd,聽GWLP_WNDPROC,(DWORD_PTR)afxWndProc);
聽聽聽聽
//
聽鈥?/span>
}
WNDPROC聽AFXAPI聽AfxGetAfxWndProc()聽
{
聽聽聽聽
//
聽鈥?/span>
聽聽聽聽
return
聽
&
AfxWndProc;
}
榪欐牱錛宊AfxCbtFilterHook鐨勫伐浣滄葷粨璧鋒潵灝辨槸閫氳繃紿楀彛瀛愮被鍖栵紝鎶婃柊寤虹殑紿楀彛鐨勭獥鍙h繃紼嬭緗垚AfxWndProc銆?br />鍒拌繖閲岋紝鎴戜滑緇堜簬鎵懼埌浜嗙獥鍙h繃紼嬨?br />
緇撹
CFrameWnd::Create鍒涘緩紿楀彛璋冪敤CWnd::CreateEx
CWnd::CreateEx璋冪敤AfxHookWindowCreate鍑嗗涓虹獥鍙h緗挬瀛?br />AfxHookWindowCreate璋冪敤::SetWindowHookEx涓虹獥鍙h緗簡涓涓猈H_CBT綾誨瀷鐨勯挬瀛愭潵榪囨護娑堟伅錛屽茍鎶婅繃婊ゅ嚱鏁拌緗垚_AfxCbtFilterHook
_AfxCbtFilterHook閫氳繃紿楀彛瀛愮被鍖栬緗獥鍙g殑紿楀彛榪囩▼涓篈fxWndProc
榪欐牱錛岄氳繃::DispatchMessage鍙戦佺粰紿楀彛鐨勬秷鎭氨浼氭簮婧愪笉鏂湴閫佸埌AfxWndProc涓潵錛屽彲浠ユ兂鍒幫紝AfxWndProc鍒╃敤MFC鐨勬秷鎭槧灝勮〃錛屽垎闂ㄥ埆綾葷殑瀵規秷鎭繘琛屽垎嫻併?br />
錛堝緟緇︹︼級
struct
聽AFX_MSGMAP_ENTRY
{
銆銆UINT聽nMessage;聽聽聽
//
聽windows聽message
銆銆UINT聽nCode;聽聽聽聽聽聽銆
//
聽control聽code聽or聽WM_NOTIFY聽code
銆銆UINT聽nID;聽聽聽聽聽聽聽聽銆銆
//
聽control聽ID聽(or聽0聽for聽windows聽messages)
銆銆UINT聽nLastID;聽聽聽聽銆
//
聽used聽for聽entries聽specifying聽a聽range聽of聽control聽id's
銆銆UINT_PTR聽nSig;聽聽聽銆
//
聽signature聽type聽(action)聽or聽pointer聽to聽message聽#
銆銆AFX_PMSG聽pfn;聽聽聽聽
//
聽routine聽to聽call聽(or聽special聽value)
}
;
鍏朵腑銆typedef void (AFX_MSG_CALL CCmdTarget::*AFX_PMSG)(void);
涔嬪悗錛岄氳繃涓涓摼琛紝鎶婅繖浜涙弿榪版秷鎭殑緇撴瀯緇勭粐璧鋒潵錛屾瀯鎴愭秷鎭槧灝勮〃鐨勭粨鏋勬槸AFX_MSGMAP
struct
聽AFX_MSGMAP銆
{
銆銆
const
聽AFX_MSGMAP
*
聽pBaseMap;
銆銆
const
聽AFX_MSGMAP_ENTRY
*
聽lpEntries;
}
;
榪欐牱涓涓狝FX_MSGMAP瀵硅薄灝辨垚浜嗘瀯寤烘秷鎭槧灝勮〃鐨勫叧閿漢鐗╋紝瀹冧竴鍙墜鎷夌潃鍩虹被鐨凙FX_MSGMAP瀵硅薄錛屽彟涓鍙墜鎷夌潃綾繪湰韜殑娑堟伅鏄犲皠琛紝榪欐牱鍙姝g‘鍦板湪姣忎竴涓被涓兘瀹夋彃涓涓狝FX_MSGMAP瀵硅薄錛岄偅涔堟暣涓秷鎭槧灝勮〃灝卞緩绔嬭搗鏉ヤ簡銆傞偅涔堬紝浣曚負姝g‘鍛紵鍚箟鏈?錛氫竴鏄紜殑璁劇疆pBaseMap錛屼護瀹冩寚鍚戝熀綾伙紝浜屾槸姝g‘鐨勫緩绔嬬被鑷韓鐨勬秷鎭槧灝勮〃銆傝繖涓や釜宸ヤ綔鏄敱4涓畯瀹屾垚鐨勶紝
瀹冧滑鏄細DECLARE_MEMSSAGE_MAP() / BEGIN_MESSAGE_MAP() / ON_COMMAND()錛堟敞錛歄N_COMMAND瀹忓彧鏄負浜嗗鐞嗗懡浠ゆ秷鎭紝瀵逛簬鍏跺畠鐨勬秷鎭繕鏈夊搴旂殑瀹忥紝浣嗘槸鍘熺悊鏄浉鍚岀殑錛?/ END_MESSAGE_MAP()銆?br />璁╂垜浠竴涓釜鐨勭湅鐪嬶細
#define
聽DECLARE_MESSAGE_MAP()聽\
private
:聽\
銆銆
static
聽
const
聽AFX_MSGMAP_ENTRY聽_messageEntries[];聽\
protected
:聽\
銆銆
static
聽
const
聽AFX_MSGMAP聽messageMap;聽\
銆銆
virtual
聽
const
聽AFX_MSGMAP
*
聽GetMessageMap()聽
const
;聽\
榪欎釜瀹忕殑浣滅敤鏈?錛?br />聽1. 鍦ㄧ被涓彃鍏ヤ竴涓潤鎬佹垚鍛榑messageEntries錛岃繖鏄敤鏉ュ瓨鏀劇被瑕佸鐞嗙殑娑堟伅鐨勬暟緇勶紙鍗崇被鏈韓鐨勬秷鎭槧灝勮〃錛?br />聽2.聽 鍙︿竴涓潤鎬佹垚鍛榤assageMap鐢ㄦ潵鎸囧悜鍩虹被鐨勬秷鎭槧灝勮〃
聽3. 瀹夋彃涓涓櫄鍑芥暟錛屽叾鍐呭鏈夊緟瀹炵幇
鎺ヤ笅鏉ワ紝_messageEntries鐨勫垵濮嬪寲錛宮essageMap鐨勬紜寚鍚戯紝GetMessageMap鍑芥暟鐨勫疄鐜拌繖浜涘伐浣滆繕閮芥病鍋氾紝閭f鏄悗涓変釜瀹忕殑璐d換錛屽畠浠欏哄簭浣跨敤錛屾柟鑳藉伐浣滄甯搞?
#define
聽BEGIN_MESSAGE_MAP(theClass,聽baseClass)聽\
聽聽
const
聽AFX_MSGMAP
*
聽theClass::GetMessageMap()聽
const
聽\
聽聽
{聽
return
聽
&
theClass::messageMap;聽}
聽\
聽聽AFX_COMDAT聽
const
聽AFX_MSGMAP聽theClass::messageMap聽
=
聽\
聽聽
{聽
&
baseClass::messageMap,聽
&
theClass::_messageEntries[
0
]聽}
;聽\
聽聽AFX_COMDAT聽
const
聽AFX_MSGMAP_ENTRY聽theClass::_messageEntries[]聽
=
聽\
聽
{聽\
榪欎釜瀹忕殑浣滅敤鏈?錛?br />1. 瀹氫箟浜嗗畨鎻掑湪綾諱腑鐨勮櫄鍑芥暟GetMessageMap()錛屽彧鏄畝鍗曠殑榪斿洖messageMap瀵硅薄鐨勫湴鍧
2. 鍒濆鍖杕essageMap錛屾妸媧劇敓綾誨拰鍩虹被鑱旂郴璧鋒潵鏋勬垚涓涓ぇ鐨勬秷鎭槧灝勮〃
3. 涓虹被鏈韓鐨勬秷鎭槧灝勮〃鐨勫垵濮嬪寲鍋氳娉曞噯澶?/font>
ON_COMMAND榪欎釜瀹忕殑浣滅敤灝辨槸鍚慱messageEntries鏁扮粍涓坊鍔犵被鏈韓瑕佸鐞嗙殑鍛戒護娑堟伅錛屽叾瀹炲湪MFC涓繕鏈夊緢澶氭洿鏂逛究鐨勫畯鍙互鍚戠被涓坊鍔犳秷鎭紝渚嬪OM_WM_PAINT絳夛紝榪欓噷錛屾垜浠富瑕佽璁篛N_COMMAND錛屾瘯绔熷師鐞嗛兘鏄浉鍚岀殑銆?br />
#define
聽ON_COMMAND(id,聽memberFxn)聽\
{聽WM_COMMAND,聽CN_COMMAND,聽(WORD)id,聽(WORD)id,聽AfxSigCmd_v,聽\
聽聽static_cast
<
AFX_PMSG
>
聽(memberFxn)聽}
,
鏃犻潪鏄AFX_MSG_ENTRY緇撴瀯鐨勫垵濮嬪寲錛岃繖鏍峰湪綾諱腑涓烘瘡涓涓兂瑕佸鐞嗙殑娑堟伅閮芥槸鐢ㄤ竴涓狾N_COMMAND瀹忥紝灝辮嚜鍔ㄧ殑鍒濆鍖栦簡綾繪湰韜殑娑堟伅鏄犲皠琛ㄣ?/font>
鏈鍚庯紝褰撳叏閮ㄧ殑淇℃伅娣誨姞瀹屾瘯鍚庯紝浣跨敤END_MESSAGE_MAP()瀹忛氱煡MFC涓涓被娑堟伅鏄犲皠琛ㄧ粨鏉熶簡銆?br />
#define
聽END_MESSAGE_MAP()聽\
聽聽
{
0
,聽
0
,聽
0
,聽
0
,聽AfxSig_end,聽(AFX_PMSG)
0
聽}
聽\
聽};聽\
瀹炵幇鎵嬫硶鍗曠函寰楀緢錛屾棤闈炴槸涓涓叏0鐨凙FX_MESSAGE_MAP瀵硅薄銆?br />
緇撹
鎯寵璁╀綘鐨勭被澶勭悊鏌愪釜娑堟伅錛屼嬌鐢ㄤ笅闈㈢殑緇勫悎錛?/font>
BEGIN_MESSAGE_MAP(theClass,聽the聽
base
聽Class)
//
娑堟伅澶勭悊瀹?/span>
END_MESSAGE_MAP()
鍦∕FC涓紝瀵硅薄鐨勫姩鎬佸垱寤鴻渚濊禆浜嶳TTI鎵寤虹珛璧鋒潵鐨勭被鍒瀷褰曪紝鍜屽姩鎬佸垱寤烘湁鍏崇殑CRuntimeClass鎴愬憳鏈変袱涓細
CObject*聽(PASCAL*聽m_pfnCreateObject)();聽//聽鎸囧悜鐢ㄤ簬鍒涘緩瀵硅薄鐨勫嚱鏁?/span>
CObject*聽CreateObject();聽//聽鍒╃敤m_pfnCreateObject鍒涘緩瀵硅薄鍒╃敤RTTI寤虹珛鐨勭被鍒瀷褰曪紝DECLARE_DYNCREATE / IMPLEMENT_DYNCREATE緇х畫涓虹被娣誨姞浜嗗姩鎬佸垱寤虹殑鍔熻兘銆?/p>
#define聽DECLARE_DYNCREATE聽(class_name)聽\
銆銆銆銆DECLARE_DYNAMIC聽(class_name)聽\聽
銆銆銆銆static聽CObject*聽PASCAL聽CreateObject();榪欎釜瀹忓悓鏍風敤鍦ㄧ被澹版槑涓紝瀹冧笉浣嗕負綾繪坊鍔犱簡class##class_name瀵硅薄鍜孏etRuntimeClass()錛岃繕涓虹被鍔犲叆浜嗕竴涓潤鎬佸嚱鏁癈reateObject,鐢ㄦ潵榪涜瀵硅薄鐨勫姩鎬佸垱寤恒傚悓鏍稩MPLEMENT_DYNCREATE鐢ㄦ潵瀵逛笂闈㈡坊鍔犵殑鍐呭浣滃畾涔夊拰鍒濆鍖栧伐浣溿?/p>
#define聽IMPLEMENT_DYNCREATE聽(class_name,聽base_class_name)聽\
銆銆銆銆CObject*聽PASCAL聽class_name::CreateObject()聽\
銆銆銆銆
{聽return聽new聽class_name;聽}聽\
銆銆銆銆IMPLEMENT_RUNTIMECLASS聽(class_name,聽base_class_name,聽0xFFFF,聽\
銆銆銆銆class_name::CreateObject,聽NULL)鍜孖MPLEMENT_DYNAMIC涓嶅悓鐨勬槸錛岃繖閲岀殑IMPLEMENT_RUNTIMECLASS涓殑絎?涓弬鏁板茍涓嶄負NULL錛岃屾槸class_name::CreateObject錛岃繖鏍峰氨鎸囧畾浜嗙敤浜庡垱寤哄璞$殑鍑芥暟錛岃嚦浜庡叾瀹冪殑鍐呭錛屼笌RTTI娌℃湁浠涔堜笉鍚屻?br />
浜庢槸錛屾暣涓璞$殑鍔ㄦ佸垱寤鴻繃紼嬪氨鍙樺緱闈炲父綆鍗曚簡錛屽彧瑕佹垜浠壘鍒版煇涓壒瀹氱被鐨凜RuntimeClass瀵硅薄錛屽埄鐢╟lass##class_name.CreateObject()灝卞彲浠ヤ簡銆?/p>
CObject*聽CRuntimeClass::CreateObject()

{
銆銆CObject*聽pObject聽=聽NULL;
銆銆pObject聽=聽(*m_pfnCreateObject)();
銆銆return聽pObject;
}緇撹
鎯寵浣犵殑綾誨湪MFC涓敮鎸佸姩鎬佸垱寤猴紝
1.聽鍦ㄧ被澹版槑涓嬌鐢―ECLARE_DYNAMIC
2. 鍦ㄧ被瀹氫箟鏂囦歡涓嬌鐢↖MPLEMENT_DYNAMIC錛屾鏃?br />聽聽聽 class##class_name.m_pfnCreateObject = class_name::CreateObject;銆
聽聽聽 CRuntimeClass::CreateObject鍒╃敤m_pfnCreateObject灝卞彲浠ヨ繘琛屽璞$殑鍔ㄦ佸垱寤轟簡
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 錛堝緟緇︹︼級
LPCSTR聽m_lpszClassName;聽聽聽聽//聽鐢ㄤ簬璁板綍綾誨悕
//聽鐢ㄤ簬鎸囧悜鍩虹被鐨凜RuntimeClass緇撴瀯
CRuntimeClass*聽m_pBaseClass;聽聽
//聽鐢ㄤ簬鎸囧悜閾捐〃涓墠涓涓被鐨凜RuntimeClass緇撴瀯
CRuntimeClass*聽m_pNextClass;
//聽鐢ㄤ簬寤虹珛綾誨埆鍨嬪綍
const聽AFX_CLASSINIT*聽m_pClassInit;聽
#define聽DECLARE_DYNAMIC聽(class_name)聽\
public:聽\
聽聽聽聽static聽const聽CRuntimeClass聽class##class_name;聽\
聽聽聽聽virtual聽CRuntimeClass*聽GetRuntimeClass()聽const;聽\
#define聽IMPLEMENT_DYNAMIC聽(class_name,聽base_class_name)聽\
聽聽聽聽IMPLEMENT_RUNTIMECLASS聽(class_name,聽base_class_name,聽0xFFFF,聽NULL,聽NULL)
#define聽IMPLEMENT_RUNTIMECLASS聽(class_name,聽base_class_name,聽wSchema,聽pfnNew,聽class_init)聽\
聽聽聽聽AFX_COMDAT聽const聽CRuntimeClass聽class_name::class##class_name聽=聽
{聽\
聽聽聽聽聽聽聽聽銆銆#class_name,聽sizeof(class聽class_name),聽wSchema,聽pfnNew,聽\
聽聽聽聽聽聽聽聽銆銆RUNTIME_CLASS(base_class_name),聽NULL,聽class_init聽};聽\
聽聽聽聽CRuntimeClass*聽class_name::GetRuntimeClass()聽const聽\
聽聽聽聽
{聽return聽RUNTIME_CLASS聽(class_name);聽}聽\鍙﹀錛孯UNTIME_CLASS灝辨槸鐢ㄦ潵鑾峰緱class##class_name瀵硅薄鍦板潃鐨勫畯錛?br />
#define聽RUNTIME_CLASS聽(class_name)聽_RUNTIME_CLASS聽(class_name)
#define聽_RUNTIME_CLASS聽(class_name)聽\
聽聽聽聽((CRuntimeClass*)聽(&class_name::class##class_name))榪欐牱錛屽綋瀵圭▼搴忎腑鐨勬瘡涓涓被閮戒嬌鐢ㄤ簡DECLARE_DYNAMIC / IMPLEMENT_DYNAMIC瀹忎箣鍚庯紝灝變負璇ョ被鍦ㄧ被鍒瀷褰曚腑榪涜浜嗙櫥璁板伐浣溿傚綋鐒訛紝MFC涓墍鏈夌殑綾婚兘媧劇敓浜嶤Object錛屾墍浠ユ墍鏈夌殑璺嚎鏈緇堥兘瑕佸湪CObject澶勪細鍚堬紝鐢變簬CObject娌℃湁鍩虹被錛屾墍浠ュ畠鐨凜RuntimeClass瀵硅薄騫朵笉鑳界敤涓婇潰鐨勪袱涓畯鏉ュ疄鐜幫紝鍦╫bjcore.cpp涓紝涓篊Object鐨刢lassCObject瀵硅薄鍗曠嫭浣滀簡鍒濆鍖栫殑宸ヤ綔錛?/p>
const聽struct聽CRuntimeClass聽CObject::classCObject聽=
聽
{聽"CObject",聽sizeof(CObject),聽0xffff,聽NULL,聽NULL,聽NULL聽};鎴戜滑鍙互鐪嬪埌m_pBaseClass琚垵濮嬪寲涓篘ULL銆傚彟澶栵紝涔熷崟鐙疄鐜頒簡GetRuntimeClass():

CRuntimeClass*聽CObject::GetRuntimeClass()聽const聽
{
聽聽聽聽return聽_RUNTIME_CLASS聽(CObject);
}鑷充簬_RUNTIME_CLASS錛屽墠闈㈠凡緇忚榪囦簡銆傝繖鏍鳳紝濡傛灉鎯寵鎶婅嚜宸辯殑綾諱粙緇嶇粰MFC錛屽彧瑕佸湪綾誨0鏄庝腑浣跨敤DECLARE_DYNAMIC錛屽湪綾葷殑瀹炵幇涓姞鍏MPLEMENT_DYNAMIC
錛屽氨鍙互鎶婅嚜宸辨敞鍐屽埌綾誨埆鍨嬪綍涓簡銆傝嚦姝わ紝涓轟簡瀹炵幇綾誨璞$殑RTTI錛屾垜浠凡緇忓仛濂戒簡鎵鏈夌殑鍑嗗宸ヤ綔錛屼笅闈㈠氨鏉ョ湅涓涓嬪畠鐨勫疄鐜幫紝瀹冧富瑕佹槸闈燙Object涓殑IsKindOf鍑芥暟瀹屾垚鐨勩?/p>
BOOL聽CObject::IsKindOf(const聽CRuntimeClass*聽pClass)聽const

{
聽銆銆//聽涓轟簡綆媧侊紝鐣ュ幓浜嗕笉鐩稿叧鐨勪唬鐮?/span>
聽銆銆CRuntimeClass*聽pClassThis聽=聽GetRuntimeClass();
聽銆銆return聽pClassThis->IsDerivedFrom(pClass);
}榪欓噷錛岀敱浜嶨etRuntimeClass鏄櫄鍑芥暟錛屾墍浠ClassThis浼氭寚鍚戣皟鐢↖sKindOf鍑芥暟鐨勭被瀵硅薄鐨刢lass##class_name錛屼箣鍚庡埄鐢ㄦ寚鍚戣瀵硅薄鐨勬寚閽堣皟鐢↖sDerivedFrom錛?/p>

BOOL聽CRuntimeClass::IsDerivedFrom(const聽CRuntimeClass*聽pBaseClass)聽const聽
{
聽聽聽聽//涓轟簡綆媧侊紝鐣ュ幓浜嗕笉鐩稿叧鐨勪唬鐮?/span>
聽聽聽聽if聽(pBaseClass聽==聽NULL)
聽聽聽聽聽聽聽聽return聽FALSE;
聽聽聽聽//聽simple聽SI聽case
聽聽聽聽const聽CRuntimeClass*聽pClassThis聽=聽this;
聽聽聽聽while聽(pClassThis聽!=聽NULL)聽
{
聽聽聽聽聽聽聽聽if聽(pClassThis聽==聽pBaseClass)
聽聽聽聽聽聽聽聽銆return聽TRUE;
聽聽聽聽聽聽聽聽pClassThis聽=聽pClassThis->m_pBaseClass;
聽聽聽聽}聽聽聽聽
聽聽聽聽return聽FALSE;聽聽聽聽聽聽聽//聽walked聽to聽the聽top,聽no聽match
}
2涓換鎰忕被鍨?span lang="EN-US">U鍜?span lang="EN-US">T錛屽浣曠‘瀹?span lang="EN-US">T鑳藉惁鑷姩杞崲鎴?span lang="EN-US">U鍛紵
sizeof鐢ㄥ湪浠諱綍澶嶆潅鐨勮〃杈懼紡涓婏紝 sizeof鍙互榪斿洖榪欎釜琛ㄨ揪寮忓肩殑澶у皬錛岃屼笉浼氬湪榪愯鏃惰瘎浼拌〃杈懼紡鐨勫箋傝繖涔熷氨鎰忓懗鐫錛屼綘鍙互鎶婂嚱鏁伴噸杞姐佹ā鐗堝疄渚嬪寲銆佽漿鎹㈣鍒欑瓑絳夋墍鏈変綘鍙互鍦?span lang="EN-US">C++琛ㄨ揪寮忎腑浣跨敤鐨勮鏂界粺緇熷鍒?span lang="EN-US">sizeof涓潵銆傚疄闄呬笂錛?span lang="EN-US">sizeof闅愯棌浜嗕竴涓彲浠ユ紨緇庤〃杈懼紡綾誨瀷鐨勮鏂斤紝鏈緇堬紝sizeof浼氳繑鍥炶〃杈懼紡緇撴灉鐨勭被鍨嬨?span lang="EN-US">
sizeof鍜岄噸杞藉嚱鏁版潵瑙e喅鍒ゆ柇綾誨瀷涔嬮棿鐨勫彲杞崲鎬х殑闂銆傛濊礬寰堢畝鍗曪細鎴戜滑鎻愪緵2涓噸杞藉嚱鏁幫紝涓涓嚱鏁扮殑鍙傛暟鏄垜浠杞崲鎴愮殑綾誨瀷錛堟垜浠敤U琛ㄧず錛夛紝鑰屽彟涓涓垯鐢ㄦ潵鎺ユ敹鍏朵粬鎵鏈夌被鍨嬬殑鍙傛暟銆傜劧鍚庢垜浠妸瑕佹嫻嬬殑綾誨瀷錛堢敤T琛ㄧず錛変紶閫掔粰閲嶈澆鍑芥暟銆傚鏋滄帴鍙楃被鍨?span lang="EN-US">U涓哄弬鏁扮殑鍑芥暟琚皟鐢ㄤ簡錛屾垜浠氨璁や負T鍙互杞崲涓?span lang="EN-US">U錛屽弽涔嬪垯涓嶅彲浠ャ傚浣曠‘瀹氬摢涓嚱鏁拌璋冪敤浜嗗憿錛熸垜浠埄鐢?span lang="EN-US">sizeof鍑洪┈錛屾垜浠彧瑕佽閲嶈澆鍑芥暟榪斿洖涓嶅悓鐨勭被鍨嬶紝鐒跺悗媯鏌ヤ竴涓嬭繑鍥炲煎氨鍙互浜嗐?span lang="EN-US">
2涓笉鍚岀殑綾誨瀷錛?span lang="EN-US">
typedef聽
char
聽Small;
class
聽Big聽
{聽
char
聽dummy[
2
];聽}
;
榛樿鎯呭喌涓嬶紝
sizeof(Small)
鏄?/span>
1
錛岃?/span>
Big
鐨勫ぇ灝忓垯鏃犲叧绱ц錛屾垜浠彧瑕佺煡閬撹偗瀹氫笉鏄?/span>
1
灝卞ソ浜嗐?/span>
鍏舵錛屽畾涔?/span>
2
涓噸杞藉嚱鏁幫紝涓涓帴鏀惰杞崲鎴愮殑綾誨瀷錛?/span>
Small Test(U);
鍙︿竴涓敤鏉ユ帴鏀垛滃叾浠栫殑鎵鏈夌被鍨嬧濓紝鎴戜滑瑕佷繚璇佸湪鎺掗櫎鎵鏈夌殑杞崲涔嬪悗鎵嶈皟鐢ㄨ繖涓嚱鏁幫紝
OK,
鐢ㄧ渷鐣ュ彿琛ㄧず鐨勫弬鏁板垪琛ㄧ湡濂芥弧瓚抽渶姹?/span>
Big Test(...);
灝界鎶婁竴涓?/span>
C++
瀵硅薄浼犻掔粰
...
鍙傛暟綾誨瀷鐨勫嚱鏁幫紝鍏剁粨鏋滄湭瀹氫箟錛屼絾鏄疄闄呬笂鎴戜滑騫舵病鏈夎皟鐢ㄨ繖涓嚱鏁般傛垜浠敋鑷沖彲浠ヤ笉鐢ㄥ疄鐜板畠銆?/span>
鏈鍚庯紝鎴戜滑鐢?/span>
sizeof
鍒ゆ柇涓涓嬪氨瀹屾垚浠誨姟浜嗭細
const
聽
bool
聽convExist聽
=
聽
sizeof
(Test(T()))聽
==
聽
sizeof
(Small);
浣犱篃璁鎬細璇達紝灝辨槸瀹冧簡錛?/span>
Test
鐨勮皟鐢ㄤ細鍒涘緩涓涓復鏃跺璞?/span>
T
錛屼箣鍚庡彲鑳界殑緇撴灉鍙兘鏄?/span>
sizeof(Small)
鎴?/span>
sizeof(Big)
銆傚叴濂嬩箣浣欙紝鎴戜滑榪樿鐪嬪埌涓涓棶棰樸傚鏋?/span>
T
鐨勬瀯閫犲嚱鏁拌璁捐鎴?/span>
private
錛屾垜浠氨鍓嶅姛灝藉純浜嗐傚綋鐒惰В鍐崇殑鏂規硶涔熷緢綆鍗曪紝瀹氫箟涓涓嚱鏁幫紝璁╀粬榪斿洖綾誨瀷涓?/span>
T
鐨勫璞°?/span>
T聽MakeT();
const
聽
bool
聽convExist聽
=
聽
sizeof
(Test(MakeT()))聽
==
聽
sizeof
(Small);
鏈鍚庯紝鎶婂垰鎵嶇殑涓滆タ灝佽鍒頒竴涓被閲岋細
template聽
<
class
聽T,聽
class
聽U
>
class
聽Conversion聽
{
聽聽聽聽typedef聽
char
聽Small;
聽聽聽聽
class
聽Big聽
{聽
char
聽dummy[
2
];聽}
;
聽聽聽聽
static
聽Small聽Test(U);
聽聽聽聽
static
聽Big聽Test(
);
聽聽聽聽
static
聽T聽MakeT();
public
:
聽聽聽聽
enum
聽
{聽exist聽
=
聽
sizeof
(Test(MakeT()))聽
==
聽
sizeof
(Small)聽}
;
}
;
鍙﹀錛屾垜浠繕鍙互璁劇疆鍙﹀涓涓父閲?/span>
Conversion::SameType
錛屽鏋?/span>
T
鍜?/span>
U
琛ㄧず鍚屼竴涓被鍨嬶紝閭d箞榪斿洖
true
錛?/span>
template聽
<
class
聽T,聽
class
聽U
>
class
聽Conversion聽
{
聽聽聽聽..聽
as
聽above..
聽聽聽聽
enum
聽
{聽sameType聽
=
聽
false
}
}
;
涔嬪悗涓哄悓涓涓被鍨嬭璁′竴涓亸鐗瑰寲鐗堟湰錛?/span>
template聽
<
class
聽T
>
class
聽Conversion
<
T,聽T
>
聽
{
聽聽聽聽
enum
聽
{聽exists聽
=
聽
1
,聽sameType聽
=
聽
1
聽}
;
}
;
鏈鍚庯紝鍥炲埌鎴戜滑鐨勪富棰橈紝閫氳繃
Conversion
鐨勫府鍔╋紝鎴戜滑鍙互鏉ュ喅瀹氫袱涓被鍨嬬殑緇ф壙鎬т簡銆?/span>
#define
聽SUPERSUBCLASS(T,聽U)聽\
聽聽聽聽(Conversion
<
const
聽U
*
,聽
const
聽T
*
)::exists聽
&&
聽\
聽聽聽聽
!
Conversion
<
const
聽T
*
,聽
const
聽
void
*>
::sameType)
褰?/span>
U
緇ф壙浜?/span>
T
鎴栬?/span>
U
鍜?/span>
T
鏄悓涓涓被鍨嬬殑鏃跺欙紝
SUPERSUBCLASS
榪斿洖
true
銆傛葷粨涓涓嬶紝鍙湁涓嬮潰榪?/span>
3
縐嶆儏褰?/span>
const U*
鍙互闅愬紡杞崲鍒?/span>
const T*
錛?/span>
1.聽聽聽聽聽
T
鍜?/span>
U
鏄悓涓涓被鍨?/span>
2.聽聽聽聽聽
T
鏄?/span>
U
鐨勪換鎰忎竴涓熀綾?/span>
3.聽聽聽聽聽
T
鏄?/span>
void
鎴戜滑閫氳繃絎?/span>
2
涓祴璇曞睆钄戒簡鏈鍚庝竴縐嶆儏褰€傚綋鐒訛紝濡傛灉浣犺涓哄悓涓縐嶇被鍨嬩篃涓嶇畻鏄戶鎵垮叧緋葷殑璇濓紝鍙互榪涗竴姝ヤ弗鏍煎叾鏉′歡錛?/span>
#define
聽SUPERSUBCLASS_STRICT(T,聽U)聽\
聽聽聽聽(SUPERSUBCLASS(T,聽U)聽
&&
聽\
聽聽聽聽
!
Conversion(
const
聽T,聽
const
聽U)::sameType)