锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
騫朵笖涓鴻繖浜涘嚱鏁伴氬悜 com 搴撴彁渚涗簡 com 鐨勪簩榪涘埗鎸囬拡銆傜劧鍚?/span> com 浣胯繖浜涘嚱鏁拌繍琛屽湪
璇鋒眰浜嗕竴涓寚鍚戣鎺ュ彛鐨勪換浣曞鎴風銆?/font>
聽
Interfaces and Interface Implementations
聽
COM 鍦ㄦ帴鍙g殑瀹氫箟鍜屽疄鐜頒笂鏈夋牴鏈殑宸埆銆備竴涓帴鍙e疄闄呬笂鏄敱涓緇勫畾涔変簡鐢ㄦ硶鐨勭浉
鑱旂郴鐨勫嚱鏁板師鍨嬬粍鎴愶紝鍙槸浠栦笉鑳藉琚疄鐜般傝繖浜涘嚱鏁板師鍨嬪氨鐩稿綋浜?/span> C++ 涓惈鏈夌函铏氭嫙鍑芥暟鐨勫熀綾匯備竴涓帴鍙e畾涔夊埗瀹氫簡鎺ュ彛鐨勬垚鍛樺嚱鏁般佽皟鐢ㄦ柟娉曘佽繑鍥炵被鍨嬨佷粬浠殑鍙傛暟鐨勬暟閲忓拰綾誨瀷錛岃繖浜涘嚱鏁拌騫蹭粈涔堛備絾鏄繖閲屽茍娌℃湁涓庢帴鍙e疄鐜扮浉鍏崇殑涓滆タ銆備竴涓帴鍙g殑瀹炵幇灝辨槸紼嬪簭鍛樺湪涓涓熷彛瀹氫箟涓婃彁渚涚殑鎵ц鐩稿叧鍔ㄤ綔鐨勪唬鐮併?/span>
聽聽聽聽 涓涓帴鍙g殑瀹炵幇灝辨槸紼嬪簭鍛樺湪涓涓熷彛瀹氫箟涓婃彁渚涚殑鎵ц鐩稿叧鍔ㄤ綔鐨勪唬鐮併傚鎴瘋皟鐢ㄥ畬鍏ㄦ槸鍐沖畾浜庢帴鍙g殑瀹氫箟銆?/span>
聽
Interface Pointers and Interfaces
鎺ュ彛瀹炵幇鐨勪竴涓疄渚嬶紝瀹為檯涓婂氨鏄竴涓寚鍚戜竴緇勬柟娉曠殑鎸囬拡錛屽嵆鏄寚鎸囧悜涓涓帴鍙g殑鍑?/font> 鏁拌〃錛岃鍑芥暟琛ㄥ紩鐢ㄤ簡璇ユ帴鍙f墍鏈夋柟娉曠殑瀹炵幇銆?/font>
聽聽聽聽 姣忎釜鎺ュ彛錛屾槸涓涓浐瀹氱殑涓緇勬柟娉曠殑闆嗗悎錛屽湪榪愯鏃墮氳繃 globally unique interface identifier (IID) 鏉ュ畾浣嶃傝繖閲岋紝 IID 鏄?/span> com 鏀寔鐨?/span> globally unique identifier (GUID) 鐨勭壒孌婄殑瀹炰緥銆傝繖鏍峰仛灝變笉浼氫駭鐢熷崟涓緋葷粺涓婄浉鍚屽悕瀛椼佹帴鍙g殑澶氫釜鐗堟湰鐨?/span> COM 涔嬮棿鐨勫啿紿佷簡銆?/span>
路聽聽聽聽聽聽聽聽 COM鎺ュ彛鐨勪笉鍙樻р斺斾綘涓嶈兘澶熺敤鑰佺増鏈殑鎺ュ彛鏍囪瘑絎﹀畾涔夋柊鐨勭増鏈紝鎺ュ彛鐨処ID瀹氫箟鐨勬帴鍙e悎鍚屾槸鏄庣‘鐨勩佸敮涓鐨?/span> 銆?/span>
IUnknown and Interface Inheritance
聽聽聽聽
緇ф壙鍦?/span>
COM
閲屽茍涓嶆剰鍛崇潃浠g爜鐨勯噸鐢ㄣ傚洜涓烘帴鍙f病鏈夊疄鐜板叧鑱旓紝鍊熷彛緇ф壙騫舵剰鍛崇潃浠g爜緇ф壙銆備粬鐨勬剰鎬濅粎浠呮槸錛屼竴涓帴鍙e悓涓涓悎鍚屽叧鑱旓紝灝卞儚
C++
鐨勭函铏氭嫙鍩虹被鐨勫垱寤哄拰淇敼鏍鳳紝鍙互娣誨姞鏂規(guī)硶鎴栬呮洿榪涗竴姝ョ殑鍔犲己鏂規(guī)硶鐨勪嬌鐢ㄣ傚湪
COM
閲屾病鏈夐夋嫨鎬х戶鎵褲傚鏋滀竴涓帴鍙g敱鍙︿竴涓帴鍙g戶鎵跨殑璇濓紝浠栧氨鍖呭惈浜嗗彟涓涓帴鍙e畾涔夌殑鎵鏈夌殑鏂規(guī)硶銆?/span>
Using and Implementing IUnknown
聽聽聽 COM 涓哄疄鐜板拰浣跨敤瀵硅薄鍜屽璞$殑鍐呴儴閫氫俊鎻愪緵浜嗕竴涓赴瀵岀殑鏍囧噯闆嗗悎銆傚IUnknown鎺ュ彛鐨勫疄鐜板拰浣跨敤鐨勭粏鑺傦紝璇峰弬瑙佷笅闈富棰橈細QueryInterface: Navigating in an Object 銆偮?o:p>
聽聽聽
Rules for Implementing QueryInterface
聽
綆$悊瀹炵幇涓涓?span lang="EN-US">COM瀵硅薄鐨?/span>
IUnknown::QueryInterface
鏂規(guī)硶鐨勪笁涓富瑕佽鍒欙細
聽聽聽 1錛庡璞″繀欏昏鏈変竴涓爣璇嗙錛?/font> 聽
聽聽聽 2錛庝竴涓璞″疄渚嬬殑鎺ュ彛闆嗗悎蹇呴』鏄潤鎬佺殑錛?b style="mso-bidi-font-weight: normal">static錛夛紱 聽
聽聽聽 3錛庡湪瀵硅薄涓粠浠諱綍涓涓叾浠栫殑鎺ュ彛鏌ヨ姝ゆ帴鍙i兘搴旇鎴愬姛銆?/span>
聽
閫氳繃寮曠敤璁℃暟鏉ョ鐞嗗璞$殑鐢熷懡鍛ㄦ湡
聽聽聽聽
浣跨敤
AddRef
錛堬級
聽聽聽 //澧炲姞寮曠敤聽
聽聽聽聽聽聽聽聽聽聽聽聽聽 聽 Realase錛堬級聽聽 //鍑忓皯寮曠敤
BEGIN_MSG_MAP( CMyMainWindow )
COMMAND_ID_HANDLER( ID_HELP_ABOUT, onHelpAbout )
...
LRESULT onHelpAbout( WORD, WORD, HWND, BOOL& )
{
CSimpleDialog<IDD_DIALOG1> dlg;
int ret = dlg.DoModal();
return 0;
}鎴戜滑鍙互鐪嬪埌瀵硅瘽妗嗚祫婧愮殑ID錛圛DD_DIALOG1錛夎浣滀負涓涓ā鐗堝弬鏁頒紶閫掔粰CSimpleDialog綾伙紝DoModal鏂規(guī)硶鏄劇ず瀵硅瘽妗嗐傚綋鐢ㄦ埛鐐瑰嚮OK鎸夐挳鏃訛紝CSimpleDialog綾誨叧闂璇濇騫惰繑鍥炴寜閽殑ID銆傦紙CSimpleDialog綾誨疄鐜頒簡瀵規(guī)寜閽甀DOK錛孖DCANCEL錛孖DABORT錛孖DRETRY錛孖DIGNORE錛孖DYES鍜孖DNO鐨勫搷搴斻傦級 class CMyModelessDialog: public CDialogImpl鍜孋SimpleDialog涓嶅悓錛屾垜浠笉闇瑕佸皢瀵硅瘽妗嗚祫婧愮殑ID浣滀負妯℃澘鍙傛暟浼犻掔粰瀹冿紝浣嗘槸鎴戜滑蹇呴』灝嗚繖涓被鍜屽璇濇璧勬簮鑱旂郴璧鋒潵錛屾垜浠氳繃鍦ㄧ被涓畾涔変竴涓灇涓懼彉閲忓疄鐜幫細{
public:
enum { IDD = IDD_DIALOG1 };
鐒跺悗瀹氫箟娑堟伅鏄犲皠琛細 BEGIN_MSG_MAP( CMyDialog ) MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog ) MESSAGE_HANDLER( WM_CLOSE, OnClose ) ... END_MSG_MAP()鍝嶅簲鍑芥暟鐨勫畾涔夊拰鍓嶉潰鐨勪竴鏍鳳紝浣嗘槸鏈変竴鐐歸渶瑕佹敞鎰忥紝濡傛灉浣犲疄鐜扮殑鏄竴涓潪妯″紡瀵硅瘽妗嗭紝閭d箞鍦╓M_CLOSE娑堟伅鐨勫搷搴斿嚱鏁頒腑蹇呴』璋冪敤DestroyWindow錛?pre>LRESULT OnClose( UINT, WPARAM, LPARAM, BOOL& ) { DestroyWindow(); return 0; } ... }; // CMyModelessDialog 瑕佸湪灞忓箷涓婂垱寤鴻繖鏍蜂竴涓璇濇錛岄渶瑕佸垱寤鴻繖涓被鐨勪竴涓疄渚嬪茍璋冪敤Create鏂規(guī)硶錛?
CMyModelessDialog dlg; dlg.Create( wndParent );濡傛灉瀵硅瘽妗嗚祫婧愭病鏈夐変腑WS_VISIBLE灞炴э紝鎴戜滑闇瑕佽繖鏍瘋瀵硅瘽妗嗘樉紺哄嚭鏉ワ細
dlg.ShowWindow( SW_SHOW );涓嬮潰鐨勪緥瀛愭湁涓涓潪妯″紡鐨勫璇濇鍙互鎺ュ彈鐢ㄦ埛杈撳叆鐨勫瓧絎︿覆錛岀劧鍚庡湪涓葷獥鍙d腑鏄劇ず榪欎釜瀛楃涓層傚璇濇涓湁涓涓紪杈戞鎺т歡鍜屼竴涓寜閽紱褰撴寜閽鐐瑰嚮鏃訛紝瀵硅瘽妗嗚皟鐢ㄥ畠鎵灞炵獥鍙g殑DoSomething鏂規(guī)硶瀵圭紪杈戞涓殑瀛楃涓茶繘琛屽鐞嗭紝瀹冩墍灞炵殑紿楀彛鏄竴涓秴綾誨寲鐨勫垪琛ㄦ鎺т歡錛孌oSomething鏂規(guī)硶鐨勫姛鑳芥槸灝嗗瓧絎︿覆娣誨姞鍒板垪琛ㄦ涓?
#include "atlbase.h"
CComModule _Module;
#include "atlwin.h"
#include "resource.h"
class CMyWindow: public CWindowImpl<CMyWindow>
{
public:
DECLARE_WND_SUPERCLASS( "MyWindow", "listbox" )
BEGIN_MSG_MAP( CMyWindow )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
END_MSG_MAP()
LRESULT OnDestroy( UINT, WPARAM, LPARAM, BOOL& )
{
PostQuitMessage( 0 );
return 0;
}
void DoSomething( LPCTSTR s )
{
SendMessage( LB_ADDSTRING, 0, reinterpret_cast<LPARAM>(s) );
}
};
class CMyDialog: public CDialogImpl<CMyDialog>
{
public:
enum { IDD = IDD_DIALOG1 };
BEGIN_MSG_MAP( CMyDialog )
COMMAND_ID_HANDLER( IDC_BUTTON1, OnButton )
MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog )
MESSAGE_HANDLER( WM_CLOSE, OnClose )
END_MSG_MAP()
LRESULT OnButton(WORD, WORD, HWND, BOOL&)
{
char buf[100];
m_ed.GetWindowText( buf, 100 );
m_owner.DoSomething( buf );
return 0;
}
LRESULT OnInitDialog( UINT, WPARAM, LPARAM, BOOL& )
{
m_owner.Attach( GetParent() );
CenterWindow( m_owner );
m_ed = GetDlgItem( IDC_EDIT1 );
return TRUE;
}
LRESULT OnClose( UINT, WPARAM, LPARAM, BOOL& )
{
DestroyWindow();
m_owner.Detach();
return 0;
}
CMyWindow m_owner;
CWindow m_ed;
};
CMyDialog dlg;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
_Module.Init( NULL, hInstance );
CMyWindow win;
win.Create( NULL, CWindow::rcDefault, _T("modeless dialog test"),
WS_OVERLAPPEDWINDOW|WS_VISIBLE );
dlg.Create( win );
dlg.ShowWindow( SW_SHOW );
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) ){
if( !IsWindow(dlg) || !dlg.IsDialogMessage( &msg ) ){
DispatchMessage( &msg );
}
}
_Module.Term();
return 0;
}
鎸囧畾紿楀彛綾葷殑淇℃伅錛?/strong>CMyWindow wnd;
wnd.Create( NULL, CWindow::rcDefault, _T("Hello"),
WS_OVERLAPPEDWINDOW|WS_VISIBLE );
濡傛灉浣犱笉鎸囧畾浠諱綍鏍峰紡鍜屾墿灞曟牱寮忥紝ATL灝嗕嬌鐢ㄩ粯璁ょ殑鏍峰紡錛涜繖浜涢粯璁ょ殑鏍峰紡鏄綔涓虹獥鍙g殑鐗瑰緛瀹氫箟鐨勶紝榛樿鐗瑰緛鏄疌ControlWinTraits錛屽畾涔夊涓嬶細typedef CWinTraits<WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN |WS_CLIPSIBLINGS, 0> CControlWinTraits;CWinTraits鏄竴涓ā鏉跨被錛屽畠闇瑕?涓弬鏁幫細紿楀彛鏍峰紡銆佹墿灞曠獥鍙f牱寮忋?
template <class T,
class TBase = CWindow,
class TWinTraits = CControlWinTraits>
class CWindowImpl : public ...
鎵浠ュ湪榛樿鎯呭喌涓嬶紝浠嶤WindowImpl媧劇敓鐨勭獥鍙i兘鍏鋒湁鍙銆佸瓙紿楀彛銆佽鍓厔寮熺獥鍙c佽鍑忓瓙紿楀彛鐨勫睘鎬с?typedef CWinTraits<WS_OVERLAPPEDWINDOW|WS_VISIBLE,0> MyTraits;鐒跺悗錛屼粠CWindowImpl媧劇敓涓涓獥鍙g被錛屾寚瀹氳嚜宸辯殑紿楀彛鐗瑰緛錛?
class CMyWindow: public CWindowImpl<CMyWindow,CWindow,MyTraits>
{...};
鎴栬呰薄涓嬮潰榪欐牱鏇村姞鐩存帴錛?class CMyWindow: public CWindowImpl<
CMyWindow,
CWindow,
CWinTraits<WS_OVERLAPPEDWINDOW|WS_VISIBLE,0>
>
{...};娉ㄦ剰錛屾垜浠繀欏繪彁渚涘叏閮ㄧ殑涓変釜妯℃澘鍙傛暟錛氭淳鐢熺被錛屽熀綾伙紙CWindow錛夊拰鐗瑰緛綾匯?CMyWindow wnd;
wnd.Create( NULL, CWindow::rcDefault, _T("Hello") );
// style: WS_OVERLAPPEDWINDOW|WS_VISIBLE
鎴戜滑涔熷彲浠ラ噸鍐欑獥鍙g壒寰侊細ovwnd.Create( NULL, CWindow::rcDefault, _T("Hello"),
WS_OVERLAPPEDWINDOW ); // not visible
紿楀彛鐗瑰緛涔熷彲浠ュ寘鍚墿灞曟牱寮忥細class CClientWindow: public CWindowImpl<CClientWindow, CWindow,
CWinTraits< WS_OVERLAPPEDWINDOW|WS_VISIBLE, WS_EX_CLIENTEDGE > >
{...};
DECLARE_WND_CLASS DECLARE_WND_CLASS("my window class");榪欑瓑浠蜂簬錛?pre>DECLARE_WND_CLASS_EX(
"my window class",
CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, // default style
COLOR_WINDOW // default color
);
DECLARE_WND_CLASS_EX class CMyWindow: public CWindowImpl<CMyWindow>
{
public:
DECLARE_WND_CLASS_EX(
"my window class", // class name
CS_HREDRAW|CS_VREDRAW, // class style
COLOR_WINDOW // background color
);
BEGIN_MSG_MAP(CMyWindow)
...
鎵璋撶殑紿楀彛綾誨悕鏄寚娉ㄥ唽鐨勭獥鍙g被鐨勫悕瀛楋紝濡傛灉鎴戜滑涓嶆寚瀹氱獥鍙g被鍚嶏紝ATL灝嗚嚜鍔ㄧ敓鎴愪竴涓紝浣嗘槸褰撴垜浠嬌鐢⊿py++涔嬬被鐨勫伐鍏風殑鏃跺欙紝浣犲皢浼氬彂鐜版垜浠嚜宸卞彇鐨勭被鍚嶆瘮"ATL:00424bd0"涔嬬被鐨勫悕瀛楄鏈夌敤寰楀銆?#define DECLARE_WND_CLASS(WndClassName) \
static CWndClassInfo& GetWndClassInfo() \
{ \
static CWndClassInfo wc = \
{ \
{ sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, \
StartWindowProc, \
0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, \
WndClassName, NULL }, \
NULL, NULL, IDC_ARROW, TRUE, 0, _T("") \
}; \
return wc; \
}
CWndClassInfo緇撴瀯鎻愪緵浜嗘洿鐏墊椿鐨勮嚜瀹氫箟鐨勫彲鑳斤紝瀹冩槸榪欐牱瀹氫箟鐨勶細 struct CWndClassInfo
{
struct WNDCLASSEX
{
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCSTR lpszMenuName;
LPCSTR lpszClassName;
HICON hIconSm;
} m_wc;
LPCSTR m_lpszOrigName;
WNDPROC pWndProc;
LPCSTR m_lpszCursorID;
BOOL m_bSystemCursor;
ATOM m_atom;
CHAR m_szAutoName[13];
ATOM Register(WNDPROC* p);
};
渚嬪錛岃鎸囧畾涓涓獥鍙g殑鎸囬拡錛屾垜浠彲浠ュ皢m_lpszCursorID璁劇疆涓烘寚閽堢殑鍚嶅瓧錛屽鏋滃畠鏄竴涓郴緇熸寚閽堬紝灝唌_bSystemCursor璁劇疆涓篢RUE錛屽惁鍒欒緗負FALSE銆傛敞鎰廌ECLARE_WND_CLASS瀹忔槸鎬庢牱灝嗚繖涓や釜鎴愬憳鍙橀噺鍒嗗埆璁劇疆涓篒DC_ARROW 鍜?TRUE鐨勩傛棦鐒禗ECLARE_WND_瀹忎笉鑳借鎴戜滑鏀瑰啓榪欎簺榛樿鐨勫鹼紝鎴戜滑鍙互榪欐牱鍋氾細 class CMyWindow: public CWindowImpl<CMyWindow>
{
public:
static CWndClassInfo& GetWndClassInfo()
{
// a manual DECLARE_WND_CLASS macro expansion
// modified to specify an application-defined cursor:
static CWndClassInfo wc =
{
{ sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS,
StartWindowProc,
0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL,
"MyWindow", NULL },
NULL, NULL, MAKEINTRESOURCE(IDC_CURSOR1), FALSE, 0, _T("")
};
return wc;
}
...
緇撹錛?/strong>class CMyWindow: public CWindowImplCmyWindow鏄竴涓鍣ㄧ獥鍙g被錛屽畠鐨勬瀯閫犲嚱鏁板CcontainedWindow綾誨瀷鐨勬垚鍛樺仛榪欐牱鐨勫垵濮嬪寲錛氳鍖呭惈鐨勭獥鍙f槸緙栬緫妗嗭紝鍙戦佸畠鐨勬秷鎭埌鈥渢his鈥濓紙瀹冪殑鐖剁獥鍙o級錛屼嬌鐢ㄥ彲閫夋秷鎭槧灝勮〃99銆?pre>BEGIN_MSG_MAP( CMyWindow ) MESSAGE_HANDLER( WM_CREATE, OnCreate ) MESSAGE_HANDLER( WM_DESTROY, OnDestroy ) ALT_MSG_MAP( 99 ) // contained window''s messages come here... MESSAGE_HANDLER( WM_CHAR, OnChar ) END_MSG_MAP() 褰撶埗紿楀彛琚垱寤虹殑鏃跺欙紝琚寘鍚殑紿楀彛涔熻鍒涘緩錛堝湪WM_CREATE娑堟伅鐨勫搷搴斿嚱鏁頒腑錛夈傚洜涓鴻鍖呭惈鐨勬帶浠舵槸浠ョ紪杈戞涓哄熀紜鐨勶紝鎵浠ュ畠鍦ㄥ睆騫曚笂鐪嬭搗鏉ヨ薄涓涓紪杈戞錛?{ CContainedWindow m_contained; public: CMyWindow(): m_contained( _T("edit"), this, 99 ) { } ...
LRESULT OnCreate( UINT, WPARAM, LPARAM, BOOL& )
{
RECT rc = { 10, 10, 200, 35 };
m_contained.Create( *this, rc, _T("non-numeric edit"),
WS_CHILD|WS_VISIBLE|WS_BORDER, 0, 666 );
return 0;
}
鍦ㄨ繖涓緥瀛愪腑錛屽鍣ㄧ獥鍙e悓鏃朵篃鏄鍖呭惈紿楀彛鐨勭埗紿楀彛銆?LRESULT OnChar( UINT, WPARAM wParam, LPARAM, BOOL& bHandled )
{
TCHAR ch = wParam;
if( _T(''0'') <= ch && ch <= _T(''9'') )
MessageBeep( 0 );
else
bHandled = FALSE;
return 0;
}
LRESULT OnDestroy( UINT, WPARAM, LPARAM, BOOL& )
{
PostQuitMessage( 0 );
return 0;
}
};
鎴戜滑鍚屾牱涔熷彲浠ョ敤琚寘鍚殑紿楀彛鏉ュ瓙綾誨寲瀵硅瘽妗嗕腑宸茬粡瀛樺湪鐨勬帶浠訛紝鍜屾瑙勭殑瀛愮被鍖栦笉鍚岋紝琚瓙綾誨寲鐨勭獥鍙g殑娑堟伅鏃惰瀹瑰櫒紿楀彛鎹曡幏鐨勩傚湪涓嬮潰鐨勪緥瀛愪腑錛屼竴涓璇濇瀛愮被鍖栦簡涓涓紪杈戞鎺т歡錛屾妸瀹冭漿鍖栨垚浜嗚鍖呭惈鐨勭獥鍙o紱閭d釜瀵硅瘽妗嗭紙瀹瑰櫒錛夋崟鑾稺M_CHAR娑堟伅騫跺拷鐣ユ帀鏁板瓧瀛楃錛岀劧鍚庡湪鍙戦佸埌緙栬緫妗嗘帶浠躲傦紙CdialogImpl鍦ˋTL涓殑瀵硅瘽妗嗙被涓鑺傝榪般傦級 class CMyDialog: public CDialogImpl<CMyDialog>
{
public:
enum { IDD = IDD_DIALOG1 };
// contained window is an edit control:
CMyDialog(): m_contained( "edit", this, 123 )
{
}
BEGIN_MSG_MAP( CMyDialog )
MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog )
ALT_MSG_MAP( 123 ) // contained window''s messages come here...
MESSAGE_HANDLER( WM_CHAR, OnChar )
END_MSG_MAP()
LRESULT OnInitDialog( UINT, WPARAM, LPARAM, BOOL& bHandled )
{
// when the dialog box is created, subclass its edit control:
m_contained.SubclassWindow( GetDlgItem(IDC_EDIT1) );
bHandled = FALSE;
return 0;
}
LRESULT OnChar( UINT, WPARAM wParam, LPARAM, BOOL& bHandled )
{
TCHAR ch = wParam;
if( _T(''0'') <= ch && ch <= _T(''9'') )
MessageBeep( 0 );
else
bHandled = FALSE;
return 0;
}
CContainedWindow m_contained;
};
娑堟伅鍙嶅皠錛?/strong>class CParentWindow: CWindowImpl<CParentWindow>
{
// 鍋囪榪欎釜紿楀彛鏈変竴涓寜閽瀷鐨勫瓙紿楀彛錛?
// 騫朵笖鍏?ID 涓?ID_BUTTON
BEGIN_MSG_MAP( CParentWindow )
COMMAND_ID_HANDLER( ID_BUTTON, OnButton )
MESSAGE_HANDLER( WM_CTLCOLORBUTTON, OnColorButton )
...
褰撴寜閽鎸変笅鐨勬椂鍊欙紝瀹冨彂閫佷竴涓懡浠ゆ秷鎭粰鐖剁獥鍙o紝鐒跺悗CParentWindow::OnButton琚皟鐢ㄣ傚悓鐞嗭紝褰撴寜閽渶瑕佽緇樺埗鐨勬椂鍊欙紝瀹冨彂閫乄M_CTLCOLORBUTTON娑堟伅緇欑埗紿楀彛錛孋ParentWindow::OnColorButton鍝嶅簲榪欎釜娑堟伅錛屽畠浣跨敤鐗瑰畾鐨勭敾鍒風粯鍒舵帶浠躲?class CParentWindow: CWindowImpl褰撶埗紿楀彛鏀跺埌涓涓秷鎭紝鍏堟煡鎵懼畠鐨勬秷鎭槧灝勮〃錛屽鏋滄病鏈夊拰榪欎釜娑堟伅鐩稿尮閰嶇殑鍏ュ彛錛屽垯REFLECT_NOTIFICATIONS瀹忎嬌寰楄娑堟伅琚弽灝勭粰鍙戦佽繖涓秷鎭殑鎺т歡銆傛帶浠跺彲浠ユ彁渚涘搷搴斿弽灝勬秷鎭殑澶勭悊鍑芥暟錛屽涓嬶細{ BEGIN_MSG_MAP( CParentWindow ) MESSAGE_HANDLER( WM_CREATE, OnCreate ) MESSAGE_HANDLER( WM_DESTROY, OnDestroy ) ...other messages that CParentWindow will handle... REFLECT_NOTIFICATIONS() END_MSG_MAP() ...
class CHandlesItsOwnMessages: CWindowImpl<CHandlesItsOwnMessage>
{
public:
DECLARE_WND_SUPERCLASS( _T("Superbutton"), _T("button") )
BEGIN_MSG_MAP( CHandlesItsOwnMessage )
MESSAGE_HANDLER( OCM_COMMAND, OnCommand )
MESSAGE_HANDLER( OCM_CTLCOLORBUTTON, OnColorButton )
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
...
娉ㄦ剰錛屽弽灝勬秷鎭殑娑堟伅鏍囧織浠CM_寮澶達紝鑰屼笉鏄疻M_銆傝繖鍙互璁╀綘鍖哄垎榪欎釜娑堟伅絀剁珶鏄惁鏄鍙嶅皠鍥炴潵鐨勩?// in CParentWindow:
CHandlesItsOwnMessages m_button;
LRESULT OnCreate( UINT, WPARAM, LPARAM, BOOL& )
{
RECT rc; // initialize appropriately
m_button.Create( *this, rc, _T("click me"), WS_CHILD|WS_VISIBLE );
...
鎴栬咃紝濡傛灉榪欎釜鎸夐挳鎺т歡鏄凡瀛樺湪鐨勶紙渚嬪錛岀埗紿楀彛鏄竴涓璇濇錛夛細m_button.SubclassWindow( GetDlgItem(ID_BUTTON) );涓嬮潰鐨勪緥瀛愬畾涔変簡涓涓狢staticLink綾伙紝瀹冩槸涓涓猄tatic鎺т歡錛屽綋鐐瑰嚮瀹冪殑鏃跺欙紝灝嗘墦寮涓涓寚瀹氱殑緗戦〉銆傛墍鏈変粠CstaticLink鍙戦佸嚭鍘葷殑娑堟伅閮借瀹冪殑鐖剁獥鍙e弽灝勫洖鏉ワ紙鍦ㄨ繖涓緥瀛愪腑錛岀敤鍒板璇濇錛岃鐪婣TL涓殑瀵硅瘽妗嗙被榪欎竴鑺傦級銆傞櫎浜嗗搷搴斿弽灝勫洖鐨勫懡浠ゆ秷鎭紝CstaticLink榪樺鐞嗗弽灝勫洖鐨刉M_CTLCOLORSTATIC娑堟伅浠ヤ究瀹冭兘澶熻鑷繁鍦ㄧ偣鍑誨墠鍜岀偣鍑誨悗鏄劇ず涓嶅悓鐨勯鑹層?
#include "stdafx.h"
#include "resource.h"
CComModule _Module;
class CStaticLink : public CWindowImpl<CStaticLink> {
/*
Based on CStaticLink by Paul DiLascia, C++ Q&A, Microsoft Systems
Journal 12/1997.
Turns static controls into clickable "links" -- when the control is
clicked, the file/program/webpage named in the control''s text (or
set by SetLinkText()) is opened via ShellExecute(). Static control
can be either text or graphic (bitmap, icon, etc.).
*/
public:
DECLARE_WND_SUPERCLASS( _T("StaticLink"), _T("Static") )
CStaticLink() :
m_colorUnvisited( RGB(0,0,255) ),
m_colorVisited( RGB(128,0,128) ),
m_bVisited( FALSE ),
m_hFont( NULL )
{
}
void SetLinkText( LPCTSTR szLink ) {
USES_CONVERSION;
m_bstrLink = T2OLE( szLink );
}
BEGIN_MSG_MAP(CStaticLink)
// uses message reflection: WM_* comes back as OCM_*
MESSAGE_HANDLER( OCM_COMMAND, OnCommand )
MESSAGE_HANDLER( OCM_CTLCOLORSTATIC, OnCtlColor )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy ) // not a reflected message
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
LRESULT OnDestroy( UINT, WPARAM, LPARAM, BOOL& ) {
if( m_hFont ) DeleteObject( m_hFont );
return 0;
}
LRESULT OnCommand( UINT, WPARAM wParam, LPARAM, BOOL& ) {
USES_CONVERSION;
int code = HIWORD( wParam );
if( code == STN_CLICKED || code == STN_DBLCLK ){
if( m_bstrLink.Length() == 0 ){
GetWindowText( &m_bstrLink );
}
if( (int)ShellExecute( *this, _T("open"),
OLE2T(m_bstrLink), NULL, NULL, SW_SHOWNORMAL ) > 32 ){
m_bVisited = TRUE; // return codes > 32 => success
Invalidate();
}else{
MessageBeep( 0 );
ATLTRACE( _T("Error: CStaticLink couldn''t open file") );
}
}
return 0;
}
LRESULT OnCtlColor( UINT, WPARAM wParam, LPARAM, BOOL& ) {
// notify bit must be set to get STN_* notifications
ModifyStyle( 0, SS_NOTIFY );
HBRUSH hBr = NULL;
if( (GetStyle() & 0xff) <= SS_RIGHT ){
// it''s a text control: set up font and colors
if( !m_hFont ){
LOGFONT lf;
GetObject( GetFont(), sizeof(lf), &lf );
lf.lfUnderline = TRUE;
m_hFont = CreateFontIndirect( &lf );
}
HDC hDC = (HDC)wParam;
SelectObject( hDC, m_hFont );
SetTextColor( hDC, m_bVisited ? m_colorVisited
: m_colorUnvisited );
SetBkMode( hDC, TRANSPARENT );
hBr = (HBRUSH)GetStockObject( HOLLOW_BRUSH );
}
return (LRESULT)hBr;
}
private:
COLORREF m_colorUnvisited;
COLORREF m_colorVisited;
BOOL m_bVisited;
HFONT m_hFont;
CComBSTR m_bstrLink;
}; // CStaticLink
class CReflectDlg : public CDialogImpl<CReflectDlg> {
public:
enum { IDD = IDD_DIALOG1 };
BEGIN_MSG_MAP(CReflectDlg)
COMMAND_RANGE_HANDLER( IDOK, IDCANCEL, OnClose )
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
REFLECT_NOTIFICATIONS() // reflect messages back to static links
END_MSG_MAP()
LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&)
{
CenterWindow( GetParent() );
// a textual static control:
s1.SubclassWindow( GetDlgItem(IDS_TEST1) );
// a static control displaying an icon
s2.SubclassWindow( GetDlgItem(IDS_TEST2) );
// set the icon''s link
s2.SetLinkText( _T("http://www.microsoft.com") );
return 1;
}
LRESULT OnClose(UINT, WPARAM wID, HWND, BOOL& )
{
::EndDialog( m_hWnd, wID );
return 0;
}
private:
CStaticLink s1, s2;
}; // CReflectDlg
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow)
{
_Module.Init( NULL, hInstance );
CReflectDlg dlg;
dlg.DoModal();
_Module.Term();
return 0;
}
HWND hWnd = ::CreateWindow( "button", "Click me", WS_CHILD, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); ::ShowWindow( hWnd, nCmdShow ); ::UpdateWindow( hWnd );浣跨敤ATL涓殑CWindow綾誨悗錛岀瓑鏁堜唬鐮佸涓嬶細
CWindow win; win.Create( "button", NULL, CWindow::rcDefault, "Click me", WS_CHILD ); win.ShowWindow( nCmdShow ); win.UpdateWindow();鎴戜滑搴旇鍦ㄦ垜浠殑澶ц剳涓垜浠簲璇ヤ繚鎸佽繖鏍蜂竴涓蹇碉細ATL鐨勭獥鍙e璞′笌Windows緋葷粺涓殑紿楀彛鏄笉鍚岀殑銆俉indows緋葷粺涓殑紿楀彛鎸囩殑鏄搷浣滅郴緇熶腑緇存寔鐨勪竴鍧楁暟鎹紝鎿嶄綔緋葷粺闈犺繖鍧楁暟鎹潵鎿嶄綔灞忓箷涓婄殑涓鍧楀尯鍩熴傝屼竴涓狝TL紿楀彛瀵硅薄錛屾槸CWindow綾葷殑涓涓疄渚嬶紝瀹冩槸涓涓狢++瀵硅薄錛屽畠鐨勫唴閮ㄦ病鏈変繚瀛樹換浣曟湁鍏沖睆騫曞尯鍩熸垨鑰呯獥鍙f暟鎹粨鏋勭殑鍐呭錛屽彧淇濆瓨浜嗕竴涓獥鍙g殑鍙ユ焺錛岃繖涓彞鏌勪繚瀛樺湪瀹冪殑鏁版嵁鎴愬憳m_hWnd涓紝CWindow瀵硅薄鍜屽畠鍦ㄥ睆騫曚笂鏄劇ず鍑烘潵鐨勭獥鍙e氨鏄潬榪欎釜鍙ユ焺鑱旂郴璧鋒潵鐨勩?br />鐞嗚В浜咥TL涓殑紿楀彛瀵硅薄鍜學indows緋葷粺涓獥鍙g殑鍖哄埆錛屽氨鏇村姞瀹規(guī)槗鐞嗚ВCWindow瀵硅薄鐨勬瀯閫犱笌紿楀彛鐨勫垱寤烘槸涓や釜鍒嗗紑鐨勮繃紼嬨傛垜浠啀鐪嬬湅鍓嶉潰鐨勪唬鐮侊紝灝變細鍙戠幇錛岄鍏堟槸涓涓狢Window瀵硅薄琚瀯閫狅細
CWindow win;鐒跺悗鍒涘緩瀹冪殑紿楀彛錛?pre>win.Create( "button", NULL, CWindow::rcDefault, "Click me", WS_CHILD ); 鎴戜滑涔熷彲浠ユ瀯閫犱竴涓狢Window瀵硅薄錛岀劧鍚庢妸瀹冨拰涓涓凡緇忓瓨鍦ㄧ殑紿楀彛鍏寵仈璧鋒潵錛岃繖鏍鋒垜浠氨鍙互閫氳繃CWindow綾葷殑鎴愬憳鍑芥暟鏉ユ搷浣滆繖涓凡緇忓瓨鍦ㄧ殑紿楀彛銆傝繖縐嶆柟娉曢潪甯告湁鐢紝鍥犱負CWindow綾繪彁渚涚殑鍑芥暟閮芥槸灝佽濂戒簡鐨勶紝鐢ㄨ搗鏉ュ緢鏂逛究錛屾瘮濡侰Window綾諱腑鐨凜enterWindow, GetDescendantWindow絳夊嚱鏁扮敤璧鋒潵灝辨瘮鐩存帴浣跨敤Windows API鏂逛究寰楀銆?
HWND hWnd = CreateWindow( szWndClass, "Main window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL ); // 涓嬮潰鐨勬柟娉曚腑鍙互浠婚変竴縐嶏細 // CWindow win( hWnd ); // 閫氳繃鏋勯犲嚱鏁板叧鑱? // 鎴? // CWindow win; // win = hWnd; // 閫氳繃璧嬪兼搷浣滅鍏寵仈 // 鎴? // CWindow win; // win.Attach( hWnd ); // 浣跨敤Attach()鏂規(guī)硶鍏寵仈 win.CenterWindow(); // 鐜板湪鍙互浣跨敤win瀵硅薄鏉ヤ唬鏇縣Wnd榪涜鎿嶄綔 win.ShowWindow( nCmdShow ); win.UpdateWindow();CWindow綾諱篃鎻愪緵浜嗕竴涓狧WND鎿嶄綔絎︼紝鍙互鎶奀Window綾葷殑瀵硅薄杞寲涓虹獥鍙e彞鏌勶紝榪欐牱錛屼換浣曡姹備嬌鐢℉WND鐨勫湴鏂歸兘鍙互浣跨敤CWindow綾葷殑瀵硅薄浠f浛錛?
::ShowWindow( win, nCmdShow ); // 姝PI鍑芥暟鏈潵瑕佹眰HWND綾誨瀷鐨勫弬鏁?/pre>CWindow綾諱嬌寰楀紿楀彛鐨勬搷浣滄洿綆鍗曪紝鑰屼笖涓嶄細澧炲姞緋葷粺寮閿鈥斺斿畠緇忚繃緙栬瘧鍜屼紭鍖栧悗鐨勪唬鐮佷笌浣跨敤綰疉PI緙栫▼鐨勪唬鐮佹槸絳変環(huán)鐨勩?br />
涓嶅垢鐨勬槸錛孋Window綾諱笉鑳借鎴戜滑鑷繁鍐沖畾紿楀彛濡備綍鍝嶅簲娑堟伅銆傚綋鐒訛紝鎴戜滑鍙互浣跨敤CWindow綾繪彁渚涚殑鏂規(guī)硶鏉ヤ嬌涓涓獥鍙e眳涓垨闅愯棌錛岀敋鑷沖彲浠ュ悜涓涓獥鍙e彂閫佹秷鎭紝浣嗘槸褰撶獥鍙f敹鍒版秷鎭悗鎬庝箞澶勭悊鍒欏彇鍐充簬鍒涘緩榪欎釜紿楀彛鏃朵嬌鐢ㄧ殑紿楀彛綾伙紝濡傛灉鎴戜滑鏄垱寤虹殑鏄漛utton鈥濈被鐨勭獥鍙o紝閭d箞瀹冪殑琛ㄧ幇灝辮薄涓寜閽紝濡傛灉鐢ㄢ漧istbox鈥濈被鍒涘緩錛岄偅瀹冨氨鍏鋒湁璺熷垪琛ㄦ鐩稿悓鐨勮涓猴紝浣跨敤CWindow綾繪垜浠病鏈夊姙娉曟敼鍙樿繖鐐廣傚垢濂斤紝ATL涓烘垜浠彁渚涗簡鍙﹀涓涓被CWindowImpl錛屽畠鍏佽鎴戜滑鎸囧畾紿楀彛鐨勬柊琛屼負銆?
CWindowImpl:
CWindowImpl綾繪槸浠嶤Window綾繪淳鐢熺殑錛屾墍浠ユ垜浠緷鐒跺彲浠ヤ嬌鐢–Window綾諱腑鐨勬垚鍛樺嚱鏁幫紝浣嗘槸CWindowImpl綾葷殑鍔熻兘鏇村己澶э紝瀹冨厑璁告垜浠寚瀹氱獥鍙f庢牱澶勭悊娑堟伅銆傚湪浼犵粺鐨勭獥鍙g紪紼嬩腑錛屽鏋滄垜浠澶勭悊紿楀彛娑堟伅錛屾垜浠繀欏諱嬌鐢ㄧ獥鍙e嚱鏁幫紱浣嗘槸浣跨敤ATL錛屾垜浠彧闇瑕佸湪鎴戜滑鐨凙TL紿楀彛綾諱腑瀹氫箟涓涓秷鎭槧灝勩?
棣栧厛錛屼粠CWindowImpl綾繪淳鐢熻嚜宸辯殑紿楀彛綾伙紝濡備笅錛?class CMyWindow : public CWindowImpl娉ㄦ剰錛屾垜浠嚜宸辯殑綾誨悕蹇呴』浣滀負涓涓ā鐗堝弬鏁頒紶閫掔粰CWindowImpl綾匯?{
鐒跺悗鍦ㄧ被鐨勫畾涔夐噷闈㈠畾涔夊涓嬬殑娑堟伅鏄犲皠錛?BEGIN_MSG_MAP(CMyWindow) MESSAGE_HANDLER(WM_PAINT,OnPaint) MESSAGE_HANDLER(WM_CREATE,OnCreate) MESSAGE_HANDLER(WM_DESTROY,OnDestroy) END_MSG_MAP()涓嬮潰榪欏彞MESSAGE_HANDLER(WM_PAINT,OnPaint)鐨勬剰鎬濇槸錛屽綋WM_PAINT娑堟伅鍒拌揪鏃訛紝灝嗚皟鐢–MyWindow::OnPaint鎴愬憳鍑芥暟銆?
鏈鍚庡氨鏄畾涔夊鐞嗘秷鎭殑鍑芥暟浜嗭紝濡備笅錛?LRESULT OnPaint( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { ... } LRESULT OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { ... } LRESULT OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { ... } }; // CmyWindow榪欎簺鍑芥暟涓殑鍙傛暟鎰忎箟涓猴細絎竴涓槸娑堟伅ID錛屼腑闂寸殑涓や釜鍙傛暟鐨勬剰涔夊彇鍐充簬娑堟伅綾誨瀷錛岀鍥涗釜鍙傛暟鏄竴涓爣蹇楋紝鐢ㄥ畠鏉ュ喅瀹氳繖涓秷鎭槸宸茬粡澶勭悊瀹屼簡榪樻槸闇瑕佽繘涓姝ョ殑澶勭悊銆傚叧浜庤繖浜涘弬鏁幫紝鎴戜滑鍦∕essage Map灝忕粨鏈夋洿璇︾粏鐨勮璁恒?
褰撶獥鍙f敹鍒頒竴涓秷鎭紝瀹冨皢浠庢秷鎭槧灝勮〃鐨勯《閮ㄥ紑濮嬫煡鎵懼尮閰嶇殑娑堟伅澶勭悊鍑芥暟錛屽洜姝ゆ妸鏈甯哥敤鐨勬秷鎭斁鍦ㄦ秷鎭槧灝勮〃鐨勫墠闈㈡槸涓笉閿欑殑娉ㄦ剰銆傚鏋滄病鏈夋壘鍒板尮閰嶇殑娑堟伅澶勭悊鍑芥暟錛屽垯榪欎釜娑堟伅琚彂閫佸埌榛樿鐨勭獥鍙h繃紼嬭繘琛屽鐞嗐?
ATL鐨勬秷鎭槧灝勮〃灝佽浜哤indows鐨勬秷鎭鐞嗚繃紼嬶紝瀹冩瘮浼犵粺鐨勭獥鍙e嚱鏁頒腑鐨勫ぇ閲弒witch鍒嗘敮鎴栬卛f璇彞鐪嬭搗鏉ユ洿鍔犵洿瑙傘?
瑕佸垱寤轟竴涓熀浜嶤WindowImpl媧劇敓綾葷殑紿楀彛錛岃璋冪敤CWindowImpl綾葷殑Create鏂規(guī)硶錛?CMyWindow wnd; // 鏋勯犱竴涓?CMyWindow 綾葷殑瀵硅薄 wnd.Create( NULL, CWindow::rcDefault, _T("Hello"), WS_OVERLAPPEDWINDOW|WS_VISIBLE );娉ㄦ剰錛孋WindowImpl綾葷殑Create鏂規(guī)硶涓嶤Window綾葷殑Create鏂規(guī)硶鐣ユ湁涓嶅悓錛屽湪CWindow綾葷殑Create涓紝鎴戜滑蹇呴』鎸囧畾涓涓敞鍐屼簡鐨勭獥鍙g被錛屼絾鏄疌WindowImpl鍒欎笉鍚岋紝瀹冨垱寤轟竴涓柊鐨勭獥鍙g被錛屽洜姝わ紝涓嶉渶瑕佷負瀹冩寚瀹氱獥鍙g被銆?
涓涓畝鍗曡屽畬鏁寸殑紺轟緥錛?br />
榪欑瘒鏂囩珷涓殑澶ч儴鍒嗙ず渚嬮兘鍙槸浠g爜鐗囨錛屼絾鏄笅闈㈠垪鍑虹殑鏄竴涓畬鏁寸殑Hello world鐨勭ず渚嬬▼搴忋傝櫧鐒舵垜浠嬌鐢ㄧ殑鏄疉TL錛屼絾鏄病鏈夋秹鍙婂埌COM錛屽洜姝ゅ湪浣跨敤Visual C++®寤虹珛欏圭洰鐨勬椂鍊欙紝鎴戜滑閫夋嫨Win32® application鑰屼笉鏄疉TL COM錛?
鍦╯tdafx.h鏂囦歡涓紝鍔犲叆涓嬮潰鍑犺錛?#include <atlbase.h> extern CComModule _Module; #include <atlwin.h>鍦╤ello.cpp鏂囦歡涓紝鍐欏涓嬩唬鐮侊細#include "stdafx.h" CComModule _Module; class CMyWindow : public CWindowImpl<CMyWindow> { BEGIN_MSG_MAP( CMyWindow ) MESSAGE_HANDLER( WM_PAINT, OnPaint ) MESSAGE_HANDLER( WM_DESTROY, OnDestroy ) END_MSG_MAP() LRESULT OnPaint( UINT, WPARAM, LPARAM, BOOL& ){ PAINTSTRUCT ps; HDC hDC = GetDC(); BeginPaint( &ps ); TextOut( hDC, 0, 0, _T("Hello world"), 11 ); EndPaint( &ps ); return 0; } LRESULT OnDestroy( UINT, WPARAM, LPARAM, BOOL& ){ PostQuitMessage( 0 ); return 0; } }; int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR, int ) { _Module.Init( NULL, hInstance ); CMyWindow wnd; wnd.Create( NULL, CWindow::rcDefault, _T("Hello"), WS_OVERLAPPEDWINDOW|WS_VISIBLE ); MSG msg; while( GetMessage( &msg, NULL, 0, 0 ) ){ TranslateMessage( &msg ); DispatchMessage( &msg ); } _Module.Term(); return msg.wParam; }鍦ㄨ繖涓ず渚嬬▼搴忎腑錛孋myWindow鏄粠CWindowImpl媧劇敓鐨勶紝瀹冪殑娑堟伅鏄犲皠鎹曡幏浜嗕袱涓秷鎭疻M_PAINT鍜學M_DESTROY錛屽綋鏀跺埌WM_PAINT娑堟伅鏃訛紝瀹冪殑鎴愬憳鍑芥暟OnPaint澶勭悊榪欎釜娑堟伅騫跺湪紿楀彛涓婅緭鍑衡淗ello world鈥濓紝褰撴敹鍒癢M_DESTROY娑堟伅鏃訛紝涔熷氨鏄綋鐢ㄦ埛鍏抽棴榪欎釜紿楀彛鐨勬椂鍊欙紝璋冪敤OnDestroy鍑芥暟澶勭悊榪欎釜娑堟伅錛屽湪OnDestroy鍑芥暟涓皟鐢≒ostQuitMessage鏉ョ粨鏉熸秷鎭驚鐜?
WinMain鍑芥暟涓垱寤轟簡涓涓狢myWindow綾葷殑瀹炰緥騫跺疄鐜頒簡涓涓爣鍑嗙殑娑堟伅寰幆銆傦紙鏈変竴浜涘湴鏂癸紝鎴戜滑蹇呴』閬靛驚ATL鐨勮鑼冿紝姣斿鍦ㄨ繖閲屾垜浠繀欏諱嬌鐢╛Module銆傦級
娑堟伅鏄犲皠錛?
鏈変笁緇勭敤浜庢秷鎭槧灝勭殑瀹忥紝浠栦滑鍒嗗埆鏄細
紿楀彛娑堟伅鏄犲皠瀹忥細
鏈変袱涓獥鍙f秷鎭槧灝勫畯錛屼粬浠垎鍒槸錛?/p>
絎竴涓畯灝嗕竴涓壒瀹氱殑娑堟伅鏄犲皠鍒扮浉搴旂殑澶勭悊鍑芥暟錛涚浜屼釜瀹忓皢涓緇勬秷鎭槧灝勫埌涓涓鐞嗗嚱鏁般傛秷鎭鐞嗗嚱鏁伴兘瑕佹眰鍏鋒湁濡備笅鐨勫師褰細
LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
鍏朵腑錛屽弬鏁皍Msg鏄秷鎭爣璇嗭紝wParam鍜宭Param鏄袱涓檮鍔犱笌娑堟伅鐨勫弬鏁幫紝錛堜粬浠殑鍏蜂綋鎰忎箟鍙栧喅涓庢秷鎭被鍒傦級
娑堟伅澶勭悊鍑芥暟浣跨敤bHandled鏉ユ爣蹇楁秷鎭槸鍚﹀凡緇忚瀹屽叏鎹曡幏錛屽鏋渂Handled琚緗垚FALSE錛岀▼搴忓皢緇х畫鍦ㄦ秷鎭槧灝勮〃鐨勫悗緇儴鍒嗘煡鎵捐繖涓秷鎭殑鍏跺畠澶勭悊鍑芥暟銆傝繖涓壒鎬т嬌寰楁垜浠涓涓秷鎭嬌鐢ㄥ涓鐞嗗嚱鏁版垚涓哄彲鑳姐備粈涔堟椂鍊欓渶瑕佸涓涓秷鎭嬌鐢ㄥ涓鐞嗗嚱鏁板憿錛熷彲鑳芥槸鍦ㄥ澶氫釜綾婚摼鎺ユ椂錛屼篃鍙兘鏄垜浠彧鎯沖涓涓秷鎭仛鍑哄搷搴斾絾鏄茍涓嶇湡姝f崟鑾峰畠銆傚湪澶勭悊鍑芥暟琚皟鐢ㄤ箣鍓嶏紝bHandled琚疆涓篢RUE錛屾墍浠ュ鏋滄垜浠笉鍦ㄥ嚱鏁扮殑緇撳熬鏄懼紡鍦板皢瀹冪疆涓篎ALSE錛屽垯娑堟伅鏄犲皠琛ㄧ殑鍚庣畫閮ㄥ垎涓嶄細琚戶緇煡鎵撅紝涔熶笉浼氭湁鍏跺畠鐨勫鐞嗗嚱鏁拌璋冪敤銆?
鍛戒護娑堟伅鏄犲皠瀹忥細
鍛戒護娑堟伅鏄犲皠瀹忓彧澶勭悊鍛戒護娑堟伅錛圵M_COMMAND娑堟伅錛夛紝浣嗘槸瀹冭兘璁╂垜浠牴鎹秷鎭被鍨嬫垨鑰呭彂閫佸懡浠ゆ秷鎭殑鎺т歡ID鏉ユ寚瀹氭秷鎭鐞嗗嚱鏁般?
鍛戒護娑堟伅澶勭悊鍑芥暟搴旇鍏鋒湁濡備笅鐨勫師褰細
LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
鍏朵腑錛屽弬鏁皐NotifyCode浠h〃娑堟伅浠g爜錛寃ID浠h〃鍙戦佹秷鎭殑鎺т歡鐨処D錛宧WndCtl浠h〃鍙戦佹秷鎭殑鎺т歡鐨勭獥鍙e彞鏌勶紝bHandled鐨勬剰涔夊鍓嶆墍榪般?
閫氱煡娑堟伅鏄犲皠瀹忥細
閫氱煡娑堟伅鏄犲皠瀹忕敤鏉ュ鐞嗛氱煡娑堟伅錛圵M_NOTUFY娑堟伅錛夛紝瀹冩牴鎹氱煡娑堟伅鐨勭被鍨嬪拰鍙戦侀氱煡娑堟伅鐨勬帶浠剁殑涓嶅悓灝嗘秷鎭槧灝勫埌涓嶅悓鐨勫鐞嗗嚱鏁幫紝榪欎簺瀹忎笌鍓嶉潰璁茬殑鍛戒護娑堟伅鏄犲皠瀹忔槸絳変環(huán)鐨勶紝鍞竴鐨勪笉鍚屽氨鏄畠澶勭悊鐨勬槸閫氱煡娑堟伅鑰屼笉鏄懡浠ゆ秷鎭?
閫氱煡娑堟伅澶勭悊鍑芥暟閮介渶瑕佸涓嬬殑鍘熷艦錛?/p>
LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);鍏朵腑錛屽弬鏁癷dCtrl浠h〃鍙戦侀氱煡娑堟伅鐨勬帶浠剁殑ID錛屽弬鏁皃nmh鏄寚鍚戜竴涓狽MHDR緇撴瀯鐨勬寚閽堬紝bHandled鐨勬剰涔夊鍓嶆墍榪般?
NOTIFY_HANDLER( ID_LISTVIEW, LVN_ENDLABELEDIT, OnEndLabelEdit)榪欎釜閫氱煡娑堟伅闄勫甫鐨勯澶栦俊鎭寘鍚湪涓涓狽MLVDISPINFO緇撴瀯涓紝鍥犳錛屾秷鎭鐞嗗嚱鏁扮湅璧鋒潵搴旇璞′笅闈㈣繖涓牱瀛愶細
LRESULT OnEndLabelEdit(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
{
// The item is -1 if editing is being canceled.
if ( ((NMLVDISPINFO*)pnmh)->item.iItem == -1) return FALSE;
...
鍙互鐪嬪嚭錛宲nmh鎸囬拡琚漿鍖栨垚NMLVDISPINFO*綾誨瀷錛屼互渚胯闂ご閮ㄧ粨鏋勪互澶栫殑鏁版嵁銆?class CBase: public CWindowImpl< CBase >
// simple base window class: shuts down app when closed
{
BEGIN_MSG_MAP( CBase )
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
END_MSG_MAP()
LRESULT OnDestroy( UINT, WPARAM, LPARAM, BOOL& )
{
PostQuitMessage( 0 );
return 0;
}
};
class CDerived: public CBase
// derived from CBase; handles mouse button events
{
BEGIN_MSG_MAP( CDerived )
MESSAGE_HANDLER( WM_LBUTTONDOWN, OnButtonDown )
END_MSG_MAP()
LRESULT OnButtonDown( UINT, WPARAM, LPARAM, BOOL& )
{
ATLTRACE( "button down\n" );
return 0;
}
};
// in WinMain():
...
CDerived win;
win.Create( NULL, CWindow::rcDefault, "derived window" );
鍙槸錛屼笂闈㈢殑浠g爜鏈変竴涓棶棰樸傚綋鎴戜滑鍦ㄨ皟璇曟ā寮忎笅榪愯榪欎釜紼嬪簭錛屼竴涓獥鍙e嚭鐜頒簡錛屽鏋滄垜浠湪榪欎釜紿楀彛涓崟鍑伙紝鈥渂utton down鈥濆皢鍑虹幇鍦ㄨ緭鍑虹獥鍙d腑錛岃繖鏄疌Drived綾葷殑鍔熻兘錛屽彲鏄紝褰撴垜浠叧闂繖涓獥鍙g殑鏃跺欙紝紼嬪簭騫朵笉閫鍑猴紝灝界CBase綾誨鐞嗕簡WM_DESTROY娑堟伅騫朵笖CDrived綾繪槸浠嶤Base綾繪淳鐢熺殑銆?BEGIN_MSG_MAP( CDerived ) MESSAGE_HANDLER( WM_LBUTTONDOWN, OnButtonDown ) CHAIN_MSG_MAP( CBase ) // 閾炬帴鍒板熀綾? END_MSG_MAP()鐜板湪錛屼換浣曞湪CDrived綾諱腑娌℃湁琚鐞嗙殑娑堟伅閮戒細琚紶鍒癈Base綾諱腑銆?
// in class CBase:
BEGIN_MSG_MAP( CBase )
MESSAGE_HANDLER( WM_CREATE, OnCreate1 )
MESSAGE_HANDLER( WM_PAINT, OnPaint1 )
ALT_MSG_MAP( 100 )
MESSAGE_HANDLER( WM_CREATE, OnCreate2 )
MESSAGE_HANDLER( WM_PAINT, OnPaint2 )
ALT_MSG_MAP( 101)
MESSAGE_HANDLER( WM_CREATE, OnCreate3 )
MESSAGE_HANDLER( WM_PAINT, OnPaint3 )
END_MSG_MAP()
濡備笂錛屽熀綾葷殑娑堟伅鏄犲皠琛ㄧ敱3鑺傜粍鎴愶細涓涓粯璁ょ殑娑堟伅鏄犲皠琛紙闅愬惈鐨勬爣璇嗕負0錛夊拰涓や釜鍙夌殑娑堟伅鏄犲皠琛紙鏍囪瘑涓?00鍜?01錛夈?class CDerived: public CBase {
BEGIN_MSG_MAP( CDerived )
CHAIN_MSG_MAP_ALT( CBase, 100 )
END_MSG_MAP()
...
CDrived綾葷殑娑堟伅鏄犲皠琛ㄩ摼鎺ュ埌CBase綾諱腑鏍囪瘑鍙蜂負100鐨勫彲閫夎妭錛屽洜姝ゅ綋WM_PAINT鍒拌揪鏃訛紝CBase::OnPaint2琚皟鐢ㄣ?class CBeepButton: public CWindowImpl< CBeepButton >
{
public:
DECLARE_WND_SUPERCLASS( _T("BeepButton"), _T("Button") )
BEGIN_MSG_MAP( CBeepButton )
MESSAGE_HANDLER( WM_LBUTTONDOWN, OnLButtonDown )
END_MSG_MAP()
LRESULT OnLButtonDown( UINT, WPARAM, LPARAM, BOOL& bHandled )
{
MessageBeep( MB_ICONASTERISK );
bHandled = FALSE; // alternatively: DefWindowProc()
return 0;
}
}; // CBeepButton
DECLARE_WND_SUPERCLASS瀹忓0鏄庝簡榪欎釜紿楀彛鐨勭被鍚嶏紙鈥淏eepButton鈥濓級鍜岃瓚呯被鍖栫殑綾誨悕錛堚淏utton鈥濓級銆傚畠鐨勬秷鎭槧灝勮〃鍙湁涓涓叆鍙i」錛屽皢WM_LBUTTONDOWN娑堟伅鏄犲皠鍒癘nLButtonDown鍑芥暟銆傚叾浣欑殑娑堟伅閮借榛樿鐨勭獥鍙h繃紼嬪鐞嗭紝闄や簡鍙互鍙戝嚭铚傞福澶栵紝CbeepButton闇瑕佸拰鍏跺畠鐨勬寜閽〃鐜扮浉鍚岋紝鍥犳鍦∣nLButtonDown鍑芥暟鐨勬渶鍚庯紝闇瑕佸皢bHandled璁劇疆涓篎ALSE錛岃榛樿鐨勭獥鍙h繃紼嬪湪OnLButtonDown鍑芥暟瀹屾垚鍚庡WM_LBUTTONDOWN娑堟伅榪涜鍏跺畠鐨勫鐞嗐傦紙鍙﹀鐨勪竴縐嶆柟娉曟槸鐩存帴璋冪敤DefWindowProc鍑芥暟銆傦級 const int ID_BUTTON1 = 101;
const int ID_BUTTON2 = 102;
class CMyWindow: public CWindowImpl< CMyWindow, CWindow,
CWinTraits<WS_OVERLAPPEDWINDOW|WS_VISIBLE> >
{
CBeepButton b1, b2;
BEGIN_MSG_MAP( CMyWindow )
MESSAGE_HANDLER( WM_CREATE, OnCreate )
COMMAND_CODE_HANDLER( BN_CLICKED, onClick )
END_MSG_MAP()
LRESULT onClick(WORD wNotifyCode, WORD wID, HWND hWndCtl,
BOOL& bHandled)
{
ATLTRACE( "Control %d clicked\n", wID );
return 0;
}
LRESULT OnCreate( UINT, WPARAM, LPARAM, BOOL& )
{
RECT r1 = { 10, 10, 250, 80 };
b1.Create(*this, r1, "beep1", WS_CHILD|WS_VISIBLE, 0, ID_BUTTON1);
RECT r2 = { 10, 110, 250, 180 };
b2.Create(*this, r2, "beep2", WS_CHILD|WS_VISIBLE, 0, ID_BUTTON2);
return 0;
}
}; // CMyWindow
紿楀彛鐨勫瓙綾誨寲錛?/strong>class CNoNumEdit: public CWindowImpl< CNoNumEdit >
{
BEGIN_MSG_MAP( CNoNumEdit )
MESSAGE_HANDLER( WM_CHAR, OnChar )
END_MSG_MAP()
LRESULT OnChar( UINT, WPARAM wParam, LPARAM, BOOL& bHandled )
{
TCHAR ch = wParam;
if( _T(''0'') <= ch && ch <= _T(''9'') )
MessageBeep( 0 );
else
bHandled = FALSE;
return 0;
}
};
榪欎釜綾誨彧澶勭悊涓涓秷鎭疻M_CHAR錛屽鏋滆繖涓瓧絎︽槸鏁板瓧鐨勮瘽錛屽垯璋冪敤MessageBeep( 0 )騫惰繑鍥烇紝榪欐牱鍙互鏈夋晥鍦板拷鐣ヨ繖涓瓧絎︺傚鏋滀笉鏄暟瀛楋紝鍒欏皢bHandled璁劇疆涓篎ALSE錛屾寚鏄庨粯璁ょ殑紿楀彛榪囩▼榪欎釜娑堟伅闇瑕佽繘涓姝ュ鐞嗐?class CMyDialog: public CDialogImpl<CMyDialog>
{
public:
enum { IDD = IDD_DIALOG1 };
BEGIN_MSG_MAP( CMyDialog )
MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog )
END_MSG_MAP()
LRESULT OnInitDialog( UINT, WPARAM, LPARAM, BOOL& )
{
ed.SubclassWindow( GetDlgItem( IDC_EDIT1 ) );
return 0;
}
CNoNumEdit ed;
};
void f(void) {
IUnknown *pUnk = 0;
// 璋冪敤
HRESULT hr = GetSomeObject(&pUnk);
if (SUCCEEDED(hr)) {
// 浣跨敤
UseSomeObject(pUnk);
// 閲婃斁
pUnk->Release();
}
}
聽聽聽 榪欎釜妯″紡鍦–OM紼嬪簭鍛樺績涓槸濡傛鏍規(guī)繁钂傚浐錛屼互鑷充簬浠栦滑甯稿父涓嶅啓瀹為檯浣跨敤鎸囬拡鐨勮鍙ワ紝鑰屾槸鍏堝湪浠g爜鍧楁湯灝炬暡鍏elease璇彞銆傝繖寰堝儚C紼嬪簭鍛樹嬌鐢╯witch璇彞鏃剁殑鏉′歡鍙嶅皠涓鏍鳳紝鍏堟暡鍏reak鍐嶈銆?br />聽聽聽 鍏跺疄璋冪敤Release瀹炲湪涓嶆槸浠涔堝彲鎬曠殑璐熸媴錛屼絾鏄紝瀹㈡埛绔▼搴忓憳闈復涓や釜鐩稿綋涓ラ噸鐨勯棶棰樸傜涓涓棶棰樹笌鑾峰緱澶氭帴鍙f寚閽堟湁鍏熾傚鏋滄煇涓嚱鏁伴渶瑕佸湪鍋氫換浣曞疄闄呭伐浣滀箣鍓嶈幏寰椾笁涓帴鍙f寚閽堬紝涔熷氨鏄鍦ㄧ涓涓嬌鐢ㄦ寚閽堢殑璇彞涔嬪墠蹇呴』瑕佺敱涓変釜璋冪敤璇彞銆傚湪涔﹀啓浠g爜鏃訛紝榪欏父甯告剰鍛崇潃紼嬪簭鍛橀渶瑕佸啓璁稿宓屽鏉′歡璇彞錛屽錛?br />void f(void) {
IUnknown *rgpUnk[3];
HRESULT hr = GetObject(rgpUnk);
if (SUCCEEDED(hr)) {
hr = GetObject(rgpUnk + 1);
if (SUCCEEDED(hr)) {
hr = GetObject(rgpUnk + 2);
if (SUCCEEDED(hr)) {
UseObjects(rgpUnk[0], rgpUnk[1],
rgpUnk[2]);
rgpUnk[2]->Release();
}
rgpUnk[1]->Release();
}
rgpUnk[0]->Release();
}
}
聽聽聽 鍍忚繖鏍風殑璇彞甯稿父淇冧嬌紼嬪簭鍛樺皢TAB閿緗垚涓涓垨涓や釜絀烘牸錛岀敋鑷蟲儏鎰夸嬌鐢ㄥぇ涓鐐圭殑鏄劇ず鍣ㄣ備絾浜嬫儏騫朵笉鎬繪槸鎸変綘鎯寵薄鐨勯偅鏍鳳紝鐢變簬縐嶇鍘熷洜欏圭洰鍥㈤槦涓殑COM緇勪歡緙栫▼浜哄憳寰寰寰椾笉鍒?鎵鎯崇殑紜歡鏀寔錛岃屼笖鍦ㄥ叕鍙哥‘瀹氬叧浜嶵AB閿殑浣跨敤鏍囧噯涔嬪墠錛岀▼搴忓憳甯稿父姹傚姪浜庝嬌鐢ㄦ湁寰堝ぇ浜夎浣嗕粛鐒舵湁鏁堢殑鈥淕OTO鈥濊鍙ワ細void f(void) {
IUnknown *rgpUnk[3];
ZeroMemory(rgpUnk, sizeof(rgpUnk));
if (FAILED(GetObject(rgpUnk)))
goto cleanup;
if (FAILED(GetObject(rgpUnk+1)))
goto cleanup;
if (FAILED(GetObject(rgpUnk+2)))
goto cleanup;
UseObjects(rgpUnk[0], rgpUnk[1], rgpUnk[2]);
cleanup:
if (rgpUnk[0]) rgpUnk[0]->Release();
if (rgpUnk[1]) rgpUnk[1]->Release();
if (rgpUnk[2]) rgpUnk[2]->Release();
} 榪欐牱鐨勪唬鐮佽櫧鐒朵笉閭d箞涓撲笟錛屼絾鑷沖皯鍑忓皯浜嗗睆騫曠殑姘村鉤婊氬姩銆?br />浣跨敤浠ヤ笂榪欎簺浠g爜孌墊綔鍦ㄧ潃鏇村姞媯樻墜鐨勯棶棰橈紝閭e氨鏄湪紕板埌C++寮傚父鏃躲傚鏋滃嚱鏁癠seObjects涓㈠嚭寮傚父錛屽垯閲婃斁鎸囬拡鐨勪唬鐮佽瀹屽叏灞忚斀鎺変簡銆?瑙e喅榪欎釜闂鐨勪竴涓柟娉曟槸浣跨敤Win32鐨勭粨鏋勫寲寮傚父澶勭悊錛圫EH錛夎繘琛岀粓緇撴搷浣滐細void f(void) {
IUnknown *rgpUnk[3];
ZeroMemory(rgpUnk, sizeof(rgpUnk));
__try {
if (FAILED(GetObject(rgpUnk))) leave;
if (FAILED(GetObject(rgpUnk+1))) leave;
if (FAILED(GetObject(rgpUnk+2))) leave;
UseObjects(rgpUnk[0], rgpUnk[1], rgpUnk[2]);
} __finally {
if (rgpUnk[0]) rgpUnk[0]->Release();
if (rgpUnk[1]) rgpUnk[1]->Release();
if (rgpUnk[2]) rgpUnk[2]->Release();
}
聽聽聽 鍙儨Win32 SHE鍦–++涓殑琛ㄧ幇騫朵笉濡傛兂璞″緱閭d箞濂姐傝緝濂界殑鏂規(guī)硶鏄嬌鐢ㄥ唴寤虹殑C++寮傚父澶勭悊妯″瀷錛屽悓鏃跺仠姝嬌鐢ㄦ病鏈夊姞宸ヨ繃鐨勬寚閽堛傛爣鍑咰++搴撴湁涓涓被錛歛uto_ptr錛屽湪鍏舵瀽鏋勫嚱鏁頒腑瀹?姝諱簡涓涓搷浣滄寚閽堢殑delete璋冪敤錛堝嵆浣垮湪鍑虹幇寮傚父鏃朵篃鑳戒繚璇佽皟鐢級銆備笌涔嬬被浼鹼紝ATL鏈変竴涓狢OM鏅鴻兘鎸囬拡錛孋ComPtr錛屽畠鐨勬瀽鏋勫嚱鏁頒細姝g‘璋冪敤Release銆?br />聽聽聽 CComPtr綾誨疄鐜板鎴風鍩烘湰鐨凜OM寮曠敤璁℃暟妯″瀷銆侰ComPtr鏈変竴涓暟鎹垚鍛橈紝瀹冩槸涓涓湭緇忚繃浠諱綍鍔犲伐鐨凜OM鎺ュ彛鎸囬拡銆傚叾綾誨瀷琚綔涓烘ā鏉垮弬鏁頒紶閫掞細 CComPtr<IUnknown> unk;
CComPtr<IClassFactory> cf;
聽聽聽 緙虹渷鐨勬瀯閫犲嚱鏁板皢榪欎釜鍘熷鎸囬拡鏁版嵁鎴愬憳鍒濆鍖栦負NULL銆傛櫤鑳芥寚閽堜篃鏈夋瀯閫犲嚱鏁幫紝瀹冪殑鍙傛暟瑕佷箞鏄師濮嬫寚閽堬紝瑕佷箞鏄浉鍚岀被鍨嬬殑鏅鴻兘鍙傛暟銆備笉璁哄摢縐嶆儏鍐碉紝鏅鴻兘鎸囬拡閮借皟鐢ˋddRef鎺у埗寮曠敤銆侰ComPtr鐨勮祴鍊兼搷浣滅 鏃㈠彲浠ュ鐞嗗師濮嬫寚閽堬紝涔熷彲浠ュ鐞嗘櫤鑳芥寚閽堬紝騫朵笖鍦ㄨ皟鐢ㄦ柊鍒嗛厤鎸囬拡鐨凙ddRef涔嬪墠鑷姩閲婃斁淇濆瓨鐨勬寚閽堛傛渶閲嶈鐨勬槸錛孋ComPtr鐨勬瀽鏋勫嚱鏁伴噴鏀句繚瀛樼殑鎺ュ彛錛堝鏋滈潪絀猴級銆傝鐪嬩笅鍒椾唬鐮侊細void f(IUnknown *pUnk1, IUnknown *pUnk2) {
// 濡傛灉闈炵┖錛屾瀯閫犲嚱鏁拌皟鐢╬Unk1鐨凙ddRef
CComPtr unk1(pUnk1);
// 濡傛灉闈炵┖錛屾瀯閫犲嚱鏁拌皟鐢╱nk1.p鐨凙ddRef
CComPtr unk2 = unk1;
// 濡傛灉闈炵┖錛宱perator= 璋冪敤unk1.p鐨凴elease騫朵笖
//濡傛灉闈炵┖錛岃皟鐢╱nk2.p鐨凙ddRef
unk1 = unk2;
//濡傛灉闈炵┖錛屾瀽鏋勫嚱鏁伴噴鏀緐nk1 鍜?unk2
}
聽聽聽 闄や簡姝g‘瀹炵幇COM鐨凙ddRef 鍜?Release瑙勫垯涔嬪錛孋ComPtr榪樺厑璁稿疄鐜板師濮嬪拰鏅鴻兘鎸囬拡鐨勯忔槑鎿嶄綔錛屽弬瑙?a >闄勮〃浜?/a>鎵紺恒備篃灝辨槸璇翠笅闈㈢殑浠g爜鎸夌収浣犳墍鎯寵薄鐨勬柟寮忚繍琛岋細void f(IUnknown *pUnkCO) {
CComPtr cf;
HRESULT hr;
// 浣跨敤鎿嶄綔絎?& 鑾峰緱瀵?&cf.p 鐨勫瓨鍙?
hr = pUnkCO->QueryInterface(IID_IClassFactory,(void**)&cf);
if (FAILED(hr)) throw hr;
CComPtr unk;
// 鎿嶄綔絎?-> 鑾峰緱瀵筩f.p鐨勫瓨鍙?
// 鎿嶄綔絎?& 鑾峰緱瀵?&unk.p鐨勫瓨鍙?
hr = cf->CreateInstance(0, IID_IUnknown, (void**)&unk);
if (FAILED(hr)) throw hr;
// 鎿嶄綔絎?IUnknown * 榪斿洖 unk.p
UseObject(unk);
// 鏋愭瀯鍑芥暟閲婃斁unk.p 鍜?cf.p
}
聽聽聽 闄や簡緙轟箯瀵筊elease鐨勬樉寮忚皟鐢ㄥ錛岃繖孌典唬鐮佸儚鏄函綺圭殑COM浠g爜銆傛湁浜咰ComPtr綾葷殑姝﹁錛屽墠闈㈡墍閬囧埌鐨勯夯鐑﹂棶棰橀】鏃跺彉寰楃畝鍗曚簡錛?br />void f(void) {
CComPtr<IUnknown> rgpUnk[3];
if (FAILED(GetObject(&rgpUnk[0]))) return;
if (FAILED(GetObject(&rgpUnk[1]))) return;
if (FAILED(GetObject(&rgpUnk[2]))) return;
UseObjects(rgpUnk[0], rgpUnk[1], rgpUnk[2]);
}
鐢變簬CComPtr瀵規(guī)搷浣滅閲嶈澆鐢ㄦ硶鐨勬墿灞曪紝浣垮緱浠g爜鐨勭紪璇戝拰榪愯鏃犳噲鍙嚮銆?br />聽聽聽 鍋囧畾妯℃澘綾葷煡閬撳畠鎵鎿嶇旱鐨勬寚閽堢被鍨嬶紝浣犲彲鑳戒細闂細閭d負浠涔堟櫤鑳芥寚閽堜笉鑳藉湪瀹冪殑鍔熻兘鎿嶄綔絎︽垨鏋勯犲嚱鏁頒腑鑷姩璋冪敤QueryInterface錛屼粠鑰屾洿鏈夋晥鍦板寘瑁匢Unknown鍛紵鍦╒isual C++ 5.0鍑烘潵浠ュ墠錛屾病鏈夊姙娉曞皢鏌愪釜鎺ュ彛鐨凣UID涓庡畠鐨勬湰韜殑C++綾誨瀷鍏寵仈璧鋒潵鈥斺擵isual C++ 5.0鐢ㄧ鏈夌殑declspec灝嗘煇涓狪ID涓庝竴涓帴鍙e畾涔夌粦瀹氬湪涓璧楓傚洜涓篈TL鐨勮璁?鑰冭檻鍒頒簡瀹冭涓庡ぇ閲忎笉鍚岀殑C++緙栬瘧鍣ㄤ竴璧峰伐浣滐紝瀹冮渶瑕佺敤涓庣紪璇戝櫒鏃犲叧鐨勬墜孌墊彁渚汫UID銆備笅闈㈡垜浠潵鎺㈣鍙︿竴涓被鈥斺擟ComQIPtr綾匯?br />聽聽聽 CComQIPtr涓嶤ComPtr鍏崇郴寰堝瘑鍒囷紙瀹為檯涓婏紝瀹冨彧澧炲姞浜嗕袱涓垚鍛樺嚱鏁幫級銆侰ComQIPtr蹇呴』瑕佷袱涓ā鏉垮弬鏁幫細涓涓槸琚搷綰電殑鎸囬拡綾誨瀷 錛屽彟涓涓槸瀵瑰簲浜庤繖涓寚閽堢被鍨嬬殑GUID銆備緥濡傦紝涓嬪垪浠g爜澹版槑浜嗘搷綰礗DataObject 鍜孖Persist鎺ュ彛鐨勬櫤鑳芥寚閽堬細 CComQIPtr<IDataObject, &IID_IDataObject> do;
CComQIPtr<IPersist, &IID_IPersist> p;
聽聽聽 CComQIPtr鐨勪紭鐐規(guī)槸瀹冩湁閲嶈澆鐨勬瀯閫犲嚱鏁板拰璧嬪兼搷浣滅銆傚悓綾葷増鏈紙渚嬪錛屾帴鍙楃浉鍚岀被鍨嬬殑鎺ュ彛錛変粎浠匒ddRef鍙寵竟鐨勮祴鍊?鍒濆鍖栨搷浣溿傝繖瀹為檯涓婂氨鏄疌ComPtr鐨勫姛鑳姐傚紓綾葷増鏈紙鎺ュ彈綾誨瀷涓嶄竴鑷寸殑鎺ュ彛錛夋紜皟鐢≦ueryInterface鏉ュ喅瀹氭槸鍚﹁繖涓璞$‘瀹炴敮鎸佹墍璇鋒眰鐨勬帴鍙o細
void f(IPersist *pPersist) {
CComQIPtr<IPersist, &IID_IPersist> p;
// 鍚岀被璧嬪?- AddRef''s
p = pPersist;
CComQIPtr<IDataObject, &IID_IDataObject> do;
// 寮傜被璧嬪?- QueryInterface''s
do = pPersist;
}
聽聽聽 鍦ㄧ浜岀璧嬪艱鍙ヤ腑錛屽洜涓簆Persist鏄潪IDataObject *綾誨瀷錛屼絾瀹冩槸媧劇敓浜嶪Unknown鐨勬帴鍙f寚閽堬紝CComQIPtr閫氳繃pPersist璋冪敤QueryInterface鏉ヨ瘯鍥捐幏寰楄繖涓璞$殑IDataObject鎺ュ彛鎸囬拡銆傚鏋淨ueryInterface璋冪敤鎴愬姛錛屽垯姝ゆ櫤鑳芥寚閽堝皢鍚湁浣滀負緇撴灉鐨勫師濮婭DataObject鎸囬拡銆傚鏋淨ueryInterface璋冪敤澶辮觸錛屽垯do.p灝嗚緗負null銆傚鏋淨ueryInterface榪斿洖鐨凥RESULT鍊煎緢閲嶈錛屼絾鍙堟病鏈夊姙娉曚粠璧嬪兼搷浣滆幏寰楀叾鍊兼椂錛屽垯蹇呴』鏄懼紡璋冪敤QueryInterface銆?br />聽聽聽 鏃㈢劧鏈変簡CComQIPtr錛岄偅涓轟粈涔堣繕瑕丆ComPtr鍛紵鐢卞嚑涓悊鐢憋細棣栧厛錛孉TL鏈鍒濈殑鍙戝竷鐗堟湰鍙敮鎸丆ComPtr錛屾墍浠ュ畠?yōu)兏鐩村悎娉曞湴淇濈暀涓嬫潵浜嗐傚叾浜岋紙涔熸槸鏈閲嶈鐨勭悊鐢憋級錛岀敱浜庨噸杞界殑鏋勯犲嚱鏁板拰璧嬪兼搷浣滐紝瀵笽Unknown浣跨敤CComQIPtr鏄潪娉曠殑銆傚洜涓烘墍鏈塁OM鎺ュ彛鐨勭被鍨嬪畾涔夐兘蹇呴』涓嶪Unknown鍏煎銆?br />CComPtr<IUnknown> unk;浠庡姛鑳戒笂灝嗗畠絳夊悓浜?
CComQIPtr<IUnknown, &IID_IUnknown> unk;鍓嶈呮紜傚悗鑰呮槸閿欒鐨勭敤娉曘傚鏋滀綘榪欐牱鍐欎簡錛孋++緙栬瘧鍣ㄥ皢鎻愰啋浣犳敼姝c?br />聽聽聽 灝咰ComPtr浣滀負棣栭夌殑鍙﹀涓涓悊鐢卞彲鑳芥槸涓浜涘紑鍙戜漢鍛樼浉淇¢潤鎮(zhèn)勬?zhèn)勫湴璋冪敤QueryInterface錛屾病鏈夎鍛婏紝鍓婂急浜咰++緋葷粺鐨勭被鍨嬨傛瘯绔燂紝C++鍦ㄦ病鏈夎繘琛屽己鍒剁被鍨嬭漿鎹㈢殑鎯呭喌涓嬩笉鍏佽瀵圭被鍨嬩笉涓鑷寸殑鍘熷鎸囬拡 榪涜璧嬪兼搷浣滐紝鎵浠ヤ負浠涔堣鐢ㄦ櫤鑳芥寚閽堢殑閬撶悊涔熷湪榪欙紝騫歌繍鐨勬槸寮鍙戜漢鍛樺彲浠ラ夋嫨鏈鑳芥弧瓚抽渶瑕佺殑鎸囬拡綾誨瀷銆?br />聽聽聽 璁稿寮鍙戜漢鍛樺皢鏅鴻兘鎸囬拡鐪嬫垚鏄榪囦簬鐨勫鏉傜紪紼嬩換鍔$殑綆鍖栥傛垜鏈鍒濅篃鏄繖涔堣涓虹殑銆備絾鍙鐣欐剰瀹冧滑浣跨敤COM鏅鴻兘鎸囬拡鐨勬柟娉曘傚氨浼氶愭笎璁よ瘑鍒板畠浠紩鍏ョ殑娼滃湪鍗遍櫓涓庡畠浠В鍐崇殑闂涓鏍峰銆?br />鍏充簬榪欎竴鐐癸紝鎴戠敤涓涓幇鎴愮殑浣跨敤鍘熷鎸囬拡鐨勫嚱鏁頒負渚嬶細
void f(void) {
IFoo *pFoo = 0;
HRESULT hr = GetSomeObject(&pFoo);
if (SUCCEEDED(hr)) {
UseSomeObject(pFoo);
pFoo->Release();
}
} 灝嗗畠鑷劧鑰岀劧杞崲鍒頒嬌鐢–ComPtr銆?br /> void f(void) {
CComPtr<IFoo> pFoo = 0;
HRESULT hr = GetSomeObject(&pFoo);
if (SUCCEEDED(hr)) {
UseSomeObject(pFoo);
pFoo->Release();
}
}
聽聽聽 娉ㄦ剰CComPtr 鍜?CComQIPtr杈撳嚭鎵鏈夊彈鎺ф帴鍙f垚鍛橈紝鍖呮嫭AddRef鍜孯elease銆傚彲鎯滃綋瀹㈡埛绔氳繃鎿嶄綔絎?>鐨勭粨鏋滆皟鐢≧elease鏃訛紝鏅鴻兘鎸囬拡寰堝仴蹇?錛屼細浜屾璋冪敤鏋勯犲嚱鏁頒腑鐨凴elease銆傛樉鐒惰繖鏄敊璇殑錛岀紪璇戝櫒鍜岄摼鎺ュ櫒涔熸鐒舵帴鍙椾簡榪欎釜浠g爜銆傚鏋滀綘榪愭皵濂界殑璇濓紝璋冭瘯鍣ㄤ細寰堝揩鎹曡幏鍒拌繖涓敊璇?br />聽聽聽 浣跨敤ATL鏅鴻兘鎸囬拡鐨勫彟涓涓寮曡搗娉ㄦ剰鐨勯闄╂槸綾誨瀷寮哄埗杞崲鎿嶄綔絎﹀鍘熷鎸囬拡鎻愪緵鐨勮闂傚鏋滈殣寮忓己鍒惰漿鎹㈡搷浣滅鐨勪嬌鐢ㄥ瓨鍦ㄤ簤璁傚綋 ANSI/ISO C++ 濮斿憳浼氬湪鍐沖畾閲囩敤鏌愪釜C++涓茬被鏃訛紝浠栦滑鏄庣‘紱佹闅愬紡綾誨瀷杞崲銆傝屾槸瑕佹眰蹇呴』鏄懼紡浣跨敤c_str鍑芥暟鍦ㄩ渶瑕佸父閲廲har *錛坈onst char *錛夌殑鍦版柟浼犻掓爣鍑咰++涓層侫TL鎻愪緵浜嗕竴縐嶉殣鍚紡鐨勭被鍨嬭漿鎹㈡搷浣滅欏哄埄鍦拌В鍐充簡榪欎釜闂銆傞氬父錛岃繖涓漿鎹㈡搷浣滅鍙互鏍規(guī)嵁浣犵殑鍠滃ソ鏉ヤ嬌鐢紝鍏佽浣犲皢鏅鴻兘鎸囬拡浼犻掑埌闇瑕佺敤鍘熷鎸囬拡鐨勫嚱鏁般?br /> void f(IUnknown *pUnk) {
CComPtr unk = pUnk;
// 闅愬紡璋冪敤鎿嶄綔絎Unknown *()
CoLockObjectExternal(unk, TRUE, TRUE);
}
榪欐浠g爜鑳芥紜繍琛岋紝浣嗘槸涓嬮潰鐨勪唬鐮佷篃涓嶄細浜х敓璀﹀憡淇℃伅錛岀紪璇戞甯擱氳繃錛?HRESULT CFoo::Clone(IUnknown **ppUnk) {
CComPtr unk;
CoCreateInstance(CLSID_Foo, 0, CLSCTX_ALL,
IID_IUnknown, (void **) &unk);
// 闅愬紡璋冪敤鎿嶄綔絎Unknown *()
*ppUnk = unk;
return S_OK;
}
聽聽聽 鍦ㄨ繖縐嶆儏鍐典笅錛屾櫤鑳芥寚閽堬紙unk錛夊鍘熷鍊奸拡**ppUnk鐨勮祴鍊艱Е鍙戜簡涓庡墠闈唬鐮佹鐩稿悓鐨勫己鍒剁被鍨嬭漿鎹€傚湪絎竴涓緥瀛愪腑錛屼笉闇瑕佺敤AddRef銆傚湪絎簩涓緥瀛愪腑錛屽繀欏昏鐢ˋddRef銆?br />聽聽聽 鏈夊叧浣跨敤鏅鴻兘鎸囬拡鐨勬洿璇︾粏涓鑸俊鎭紝璇峰弬瑙丼cott Meyer鐨勩奙ore Effective C++銆嬶紙Addison-Wesley, 1995騫村嚭鐗堬級銆傚浗鍐呯洰鍓嶈繕娌℃湁榪欐湰涔︾殑涓瘧鏈垨褰卞嵃鏈傛湁鍏矯OM鏅鴻兘鎸囬拡鐨勬洿澶氱壒瀹氫俊鎭紝璇峰弬瑙丏on Box鐨勪竴綃囧叧浜庢櫤鑳芥寚閽堢殑涓撻鏂囩珷http://www.develop.com/dbox/cxx/SmartPointer.htm銆?錛堝緟緇級2涓櫤鑳芥寚閽堢殑妯℃澘鍖呰綾伙紝CComPtr<> 鍜?CComQIPtr<>錛岃繖涓や釜綾婚兘鍦?<atlbase.h> 涓0鏄庛侰ComQIPtr<>
鍖呭惈浜?CComPtr<>鐨勬墍鏈夊姛鑳斤紝鍥犳鎴戜滑鍙互瀹屽叏鐢?CComQIPtr<> 鏉ヤ嬌鐢ㄦ櫤鑳芥帴鍙f寚閽堬紝鍞竴瑕佽鏄庣殑涓鐐瑰氨
鏄細CComQIPtr<> 鐢變簬浣跨敤浜嗚繍綆楃鐨勯噸杞藉姛鑳斤紝瀹冧細鑷姩甯垜浠皟鐢≦ueryInterface()鍑芥暟錛屽洜姝?
CComQIPtr<> 鍞竴鐨勭己鐐瑰氨鏄笉鑳藉畾涔?IUnknown * 鎸囬拡銆?/p>
銆銆聽 // 鏅鴻兘鎸囬拡 smart pointer錛屾寜鐓у寛鐗欏埄鍛藉悕娉曪紝涓鑸互 sp 寮澶存潵琛ㄧず鍙橀噺綾誨瀷
銆銆聽 CComPtr < IUnknown > spUnk;聽// 姝g‘
銆銆聽 // 鍋囪 IFun 鏄竴涓帴鍙g被鍨?br />銆銆聽 CComPtr < IFun > spFun;聽// 姝g‘
銆銆聽 CComQIPtr < IFun > spFun;聽// 姝g‘
銆銆聽 CComQIPtr < IFun, &IID_IFun > spFun;聽// 姝g‘
銆銆聽 CComQIPtr < IUnknown > spUnk;聽// 閿欒錛丆ComQIPtr涓嶈兘瀹氫箟IUnknown鎸囬拡
緇欐櫤鑳芥寚閽堣祴鍊肩殑鏂規(guī)硶錛氥銆聽 CComQIPtr < IFun > spFun;聽// 璋冪敤鏋勯犲嚱鏁幫紝榪樻病鏈夎祴鍊鹼紝琚寘瑁呯殑鍐呴儴
鎺ュ彛鎸囬拡涓?NULL
銆銆聽
銆銆聽 CComQIPtr < IFun > spFun( pOtherInterface );聽// 璋冪敤鏋勯犲嚱鏁幫紝鍐呴儴鎺ュ彛鎸囬拡璧嬪間負
銆銆聽 // 閫氳繃 pOtherInterface 榪欎釜鏅氭帴鍙f寚閽堣皟鐢≦ueryInterface()寰楀埌鐨処Fun鎺ュ彛鎸囬拡
銆銆聽
銆銆銆銆聽
銆銆聽 CComQIPtr < IFun > spFun ( pUnknown );聽// 璋冪敤鏋勯犲嚱鏁幫紝鐢盜Unknown鐨凲ueryInterface()寰楀埌
IFun鎺ュ彛鎸囬拡
銆銆聽
銆銆聽 CComQIPtr < IFun > spFun = pOtherInterface;聽// = 榪愮畻絎﹂噸杞斤紝鍚箟鍜屼笂闈竴鏍?br />銆銆聽 spFun = spOtherInterface;聽// 鍚屼笂
銆銆聽 spFun = pUnknown;聽// 鍚屼笂
銆銆聽
銆銆聽 pUnknown->QueryInterface( IID_IFun, &sp );聽// 涔熷彲浠ラ氳繃QueryInterface璧嬪?br />銆銆聽
銆銆聽 // 鏅鴻兘鎸囬拡璧嬪煎悗錛屽彲浠ョ敤鏉′歡璇彞鍒ゆ柇鏄惁鍚堟硶鏈夋晥
銆銆聽 if ( spFun ){}聽聽// 濡傛灉鎸囬拡鏈夋晥
銆銆聽 if ( NULL != spFun ){}聽// 濡傛灉鎸囬拡鏈夋晥
銆銆聽
銆銆聽 if ( !spFun ){}聽聽// 濡傛灉鎸囬拡鏃犳晥
銆銆聽 if ( NULL == spFun ){}聽// 濡傛灉鎸囬拡鏃犳晥
鏅鴻兘鎸囬拡璋冪敤鍑芥暟鐨勬柟娉曪細銆銆聽 spFun.CoCreateInstance(...);聽// 絳変環(huán)涓?API
鍑芥暟::CoCreateInstance(...)
銆銆聽 spFun.QueryInterface(...);聽// 絳変環(huán)涓?API 鍑芥暟::QueryInterface()
銆銆聽
銆銆聽 spFun->Add(...);聽// 璋冪敤鍐呴儴鎺ュ彛鎸囬拡鐨勬帴鍙e嚱鏁?/p>
銆銆聽 // 璋冪敤鍐呴儴鎺ュ彛鎸囬拡鐨凲ueryInterface()鍑芥暟錛屽叾瀹炴晥鏋滃拰 spFun.QueryInterface(...) 涓鏍?br />銆銆聽 spFun->QueryInterface(...);聽
銆銆聽
銆銆聽 spFun.Release();聽// 閲婃斁鍐呴儴鐨勬帴鍙f寚閽堬紝鍚屾椂鍐呴儴鎸囬拡璧嬪間負 NULL
銆銆聽 spFun->Release();聽// 閿欙紒錛侊紒涓瀹氫笉瑕佽繖涔堜嬌鐢ㄣ?br />銆銆聽 // 鍥犱負榪欎釜璋冪敤騫朵笉鎶婂唴閮ㄦ寚閽堟竻絀猴紝閭d箞鏋愭瀯鐨勬椂鍊欎細琚啀嬈¢噴鏀撅紙閲婃斁浜嗕袱嬈★級



typedef HRESULT (WINAPI * FREG)();
TCHAR szWorkPath[ MAX_PATH ];
::GetCurrentDirectory( sizeof(szWorkPath), szWorkPath ); // 淇濆瓨褰撳墠榪涚▼鐨勫伐浣滅洰褰?
::SetCurrentDirectory( 緇勪歡鐩綍 ); // 鍒囨崲鍒扮粍浠剁殑鐩綍
HMODULE hDLL = ::LoadLibrary( 緇勪歡鏂囦歡鍚?); // 鍔ㄦ佽杞界粍浠?
if(hDLL)
{
FREG lpfunc = (FREG)::GetProcAddress( hDLL, _T("DllRegisterServer") ); // 鍙栧緱娉ㄥ唽鍑芥暟鎸囬拡
// 濡傛灉鏄弽娉ㄥ唽錛屽彲浠ュ彇寰?DllUnregisterServer"鍑芥暟鎸囬拡
if ( lpfunc ) lpfunc(); // 鎵ц娉ㄥ唽銆傝繖閲屼負浜嗙畝鍗曪紝娌℃湁鍒ゆ柇榪斿洖鍊?
::FreeLibrary(hDLL);
}
::SetCurrentDirectory(szWorkPath); // 鍒囨崲鍥炲師鍏堢殑榪涚▼宸ヤ綔鐩綍
銆銆涓婇潰鐨勭ず渚嬶紝鍦ㄥ鏁版儏鍐典笅鍙互綆鍖栨帀鍒囨崲宸ヤ綔鐩綍鐨勪唬鐮侀儴鍒嗐備絾鏄紝濡傛灉榪欎釜緇勪歡鍦ㄨ杞界殑鏃跺欙紝瀹冮渶瑕佸悓鏃跺姞杞戒竴浜涘繀欏諱緷璧栫殑DLL鏃訛紝鏈夊彲鑳界敱浜庡畠鑷韓紼嬪簭鐨?BUG 瀵艱嚧鏃犳硶姝g‘瀹氫綅銆傚挸......榪樻槸璁╂垜浠嚜宸卞啓鐨勭▼搴忥紝鏉ュ譏琛ュ畠鐨勯敊璇惂......璋佽鍜變滑鏄ソ浜哄憿 錛岃皝璁╁挶浠殑姘村鉤姣斾粬楂樺憿錛岃皝璁╁挶浠湪 vckbase 涓婃槸涓滄鐪尖濆憿......| #include 鏂規(guī)硶 | IDL緙栬瘧鍚庯紝涓烘柟渚緾/C++紼嬪簭鍛樼殑浣跨敤錛屼細浜х敓xxx.h鍜寈xx_i.c鏂囦歡銆傛垜浠湡騫哥錛岀洿鎺?include鍚庡氨鍙互浣跨敤浜?/td> |
| #import 鏂規(guī)硶 | 姣旇緝閫氱敤鐨勬柟娉曪紝vc 浼氬府鎴戜滑浜х敓鍖呰綾伙紝璁╂垜浠殑璋冪敤鏇存柟渚?/td> |
| 鍔犺澆綾誨瀷搴撳寘瑁呯被 鏂規(guī)硶 | 濡傛灉緇勪歡鎻愪緵浜?IDispatch 鎺ュ彛錛岀敤榪欎釜鏂規(guī)硶璋冪敤緇勪歡鏄渶綆鍗曠殑鍟︺備笉榪囪繕娌¤IDispatch錛屽彧鑳界湅浠ュ悗鐨勬枃绔犲暒 |
| 鍔犺澆ActiveX鍖呰綾?鏂規(guī)硶 | ActiveX 榪樻病浠嬬粛鍛紝浠ュ悗鍐嶈鍟?/td> |
銆銆涓嬭澆紺轟緥紼嬪簭鍚庯紝璇烽愰」嫻忚浣跨敤鏂規(guī)硶錛?/p>
| 紺轟緥 | 鏂規(guī)硶 | 綆瑕佽鏄?/b> |
| 1 | #include | 瀹屽叏鐢ㄦ渶鍩烘湰鐨?API 鏂瑰紡璋冪敤緇勪歡錛屼嬌澶у鐔熸?zhèn)夎皟鐢ㄥ師鐞?/td> |
| 2 | #include | 澶ч儴鍒嗕嬌鐢?API 鏂瑰紡錛屼嬌鐢?CComBSTR 綆鍖栧瀛楃涓茬殑浣跨敤 |
| 3 | #include | 灞曠ず鏅鴻兘鎸囬拡 CComPtr<> 鐨勪嬌鐢ㄦ柟娉?/td> |
| 4 | #include | 灞曠ず鏅鴻兘鎸囬拡 CComPtr<> 鍜?CComQIPtr<> 娣峰悎鐨勪嬌鐢ㄦ柟娉?/td> |
| 5 | #include | 灞曠ず鏅鴻兘鎸囬拡 CComQIPtr<> 鐨勪嬌鐢ㄦ柟娉?/td> |
| 6 | #include | 灞曠ず鏅鴻兘鎸囬拡鐨勯噴鏀炬柟娉?/td> |
| 7 | #import | vc 鍖呰鐨勬櫤鑳芥寚閽?IxxxPtr銆乢bstr_t銆乢variant_t 鐨勪嬌鐢ㄦ柟娉曞拰寮傚父澶勭悊 |
| 8 | #import | import 鍚庣殑鍛藉悕絀洪棿鐨勪嬌鐢ㄦ柟娉?/td> |
銆銆紺轟緥紼嬪簭涓兘鍐欐湁娉ㄩ噴錛岃璇昏呬粩緇嗛槄璇誨茍鍚屾椂鍙傝?MSDN 鐨勫嚱鏁拌鏄庛傝繖閲岋紝鎴戠粰澶у浠嬬粛涓涓嬧滄櫤鑳芥寚閽堚濓細
銆銆瀵逛簬鎿嶄綔鍘熷鐨勬帴鍙f寚閽堟槸姣旇緝楹葷儲鐨勶紝闇瑕佹垜浠嚜宸辨帶鍒跺紩鐢ㄨ鏁般丄PI 璋冪敤銆佸紓甯稿鐞嗐備簬鏄?ATL 鎻愪緵浜?涓櫤鑳芥寚閽堢殑妯℃澘鍖呰綾伙紝CComPtr<> 鍜?CComQIPtr<>錛岃繖涓や釜綾婚兘鍦?<atlbase.h> 涓0鏄庛侰ComQIPtr<> 鍖呭惈浜?CComPtr<>鐨勬墍鏈夊姛鑳斤紝鍥犳鎴戜滑鍙互瀹屽叏鐢?CComQIPtr<> 鏉ヤ嬌鐢ㄦ櫤鑳芥帴鍙f寚閽堬紝鍞竴瑕佽鏄庣殑涓鐐瑰氨鏄細CComQIPtr<> 鐢變簬浣跨敤浜嗚繍綆楃鐨勯噸杞藉姛鑳斤紝瀹冧細鑷姩甯垜浠皟鐢≦ueryInterface()鍑芥暟錛屽洜姝?CComQIPtr<> 鍞竴鐨勭己鐐瑰氨鏄笉鑳藉畾涔?IUnknown * 鎸囬拡銆?/p>
銆銆 // 鏅鴻兘鎸囬拡 smart pointer錛屾寜鐓у寛鐗欏埄鍛藉悕娉曪紝涓鑸互 sp 寮澶存潵琛ㄧず鍙橀噺綾誨瀷 銆銆 CComPtr < IUnknown > spUnk; // 姝g‘ 銆銆 // 鍋囪 IFun 鏄竴涓帴鍙g被鍨? 銆銆 CComPtr < IFun > spFun; // 姝g‘ 銆銆 CComQIPtr < IFun > spFun; // 姝g‘ 銆銆 CComQIPtr < IFun, &IID_IFun > spFun; // 姝g‘ 銆銆 CComQIPtr < IUnknown > spUnk; // 閿欒錛丆ComQIPtr涓嶈兘瀹氫箟IUnknown鎸囬拡緇欐櫤鑳芥寚閽堣祴鍊肩殑鏂規(guī)硶錛?pre>銆銆 CComQIPtr < IFun > spFun; // 璋冪敤鏋勯犲嚱鏁幫紝榪樻病鏈夎祴鍊鹼紝琚寘瑁呯殑鍐呴儴鎺ュ彛鎸囬拡涓?NULL 銆銆 銆銆 CComQIPtr < IFun > spFun( pOtherInterface ); // 璋冪敤鏋勯犲嚱鏁幫紝鍐呴儴鎺ュ彛鎸囬拡璧嬪間負 銆銆 // 閫氳繃 pOtherInterface 榪欎釜鏅氭帴鍙f寚閽堣皟鐢≦ueryInterface()寰楀埌鐨処Fun鎺ュ彛鎸囬拡 銆銆 銆銆 CComQIPtr < IFun > spFun( spOtherInterface ); // 璋冪敤鏋勯犲嚱鏁幫紝鍐呴儴鎺ュ彛鎸囬拡璧嬪間負 銆銆 // 閫氳繃 spOtherInterface 榪欎釜鍙兘鎺ュ彛鎸囬拡璋冪敤QueryInterface()寰楀埌鐨処Fun鎺ュ彛鎸囬拡 銆銆 銆銆 CComQIPtr < IFun > spFun ( pUnknown ); // 璋冪敤鏋勯犲嚱鏁幫紝鐢盜Unknown鐨凲ueryInterface()寰楀埌IFun鎺ュ彛鎸囬拡 銆銆 銆銆 CComQIPtr < IFun > spFun = pOtherInterface; // = 榪愮畻絎﹂噸杞斤紝鍚箟鍜屼笂闈竴鏍? 銆銆 spFun = spOtherInterface; // 鍚屼笂 銆銆 spFun = pUnknown; // 鍚屼笂 銆銆 銆銆 pUnknown->QueryInterface( IID_IFun, &sp ); // 涔熷彲浠ラ氳繃QueryInterface璧嬪? 銆銆 銆銆 // 鏅鴻兘鎸囬拡璧嬪煎悗錛屽彲浠ョ敤鏉′歡璇彞鍒ゆ柇鏄惁鍚堟硶鏈夋晥 銆銆 if ( spFun ){} // 濡傛灉鎸囬拡鏈夋晥 銆銆 if ( NULL != spFun ){} // 濡傛灉鎸囬拡鏈夋晥 銆銆 銆銆 if ( !spFun ){} // 濡傛灉鎸囬拡鏃犳晥 銆銆 if ( NULL == spFun ){} // 濡傛灉鎸囬拡鏃犳晥鏅鴻兘鎸囬拡璋冪敤鍑芥暟鐨勬柟娉曪細
銆銆 spFun.CoCreateInstance(...); // 絳変環(huán)涓?API 鍑芥暟::CoCreateInstance(...) 銆銆 spFun.QueryInterface(...); // 絳変環(huán)涓?API 鍑芥暟::QueryInterface() 銆銆 銆銆 spFun->Add(...); // 璋冪敤鍐呴儴鎺ュ彛鎸囬拡鐨勬帴鍙e嚱鏁? 銆銆 // 璋冪敤鍐呴儴鎺ュ彛鎸囬拡鐨凲ueryInterface()鍑芥暟錛屽叾瀹炴晥鏋滃拰 spFun.QueryInterface(...) 涓鏍? 銆銆 spFun->QueryInterface(...); 銆銆 銆銆 spFun.Release(); // 閲婃斁鍐呴儴鐨勬帴鍙f寚閽堬紝鍚屾椂鍐呴儴鎸囬拡璧嬪間負 NULL 銆銆 spFun->Release(); // 閿欙紒錛侊紒涓瀹氫笉瑕佽繖涔堜嬌鐢ㄣ? 銆銆 // 鍥犱負榪欎釜璋冪敤騫朵笉鎶婂唴閮ㄦ寚閽堟竻絀猴紝閭d箞鏋愭瀯鐨勬椂鍊欎細琚啀嬈¢噴鏀撅紙閲婃斁浜嗕袱嬈★級鍜?.....涓嶈浜嗭紝涓嶈浜嗭紝澶у澶氱湅涔︼紝澶氱湅MSND錛屽鐪嬬ず渚嬬▼搴忓惂銆?鍐欑瘡浜?-(
浜屻?/b>寤虹珛 ATL 宸ョ▼
銆銆姝ラ2.1錛氬緩绔嬩竴涓В鍐蟲柟妗堛?br />銆銆姝ラ2.2錛氬湪 璇ヨВ鍐蟲柟妗堜腑錛屾柊寤轟竴涓?vc++ 鐨?ATL 欏圭洰銆傜ず渚嬬▼搴忓彨 Simple2錛屽茍閫夋嫨DLL鏂瑰紡錛岃鍥句竴銆佸浘浜屻?br />
鍥句竴銆佹柊寤?ATL 欏圭洰
鍥句簩銆侀夋嫨闈炲睘鎬у寲鐨凞LL緇勪歡綾誨瀷
銆銆灞炴у寲 灞炴у寲緙栫▼錛屾槸鏈潵鐨勬柟鍚戯紝浣嗘垜浠幇鍦ㄥ厛涓嶈閫夊畠銆?br />銆銆鍔ㄦ侀摼鎺ュ簱(DLL) 閫夋嫨瀹冦?br />銆銆鍙墽琛屾枃浠?EXE) 浠ュ悗鍐嶈銆?br />銆銆鏈嶅姟(EXE) 琛ㄧず寤虹珛涓涓郴緇熸湇鍔$粍浠剁▼搴忥紝緋葷粺鍚姩鍚庡氨浼氬姞杞藉茍鎵ц鐨勭▼搴忋?br />銆銆鍏佽鍚堝茍浠g悊/瀛樻牴(stub)浠g爜 閫夋嫨璇ラ」琛ㄧず鎶娾滀唬鐞?瀛樻牴鈥濅唬鐮佸悎騫跺埌緇勪歡紼嬪簭涓紝鍚﹀垯闇瑕佸崟鐙紪璇戯紝鍗曠嫭娉ㄥ唽浠g悊瀛樻牴紼嬪簭銆備唬鐞?瀛樻牴錛岃繖涓槸浠涔堟蹇碉紵榪樿寰楁垜浠湪涓婂洖涔?/font>涓粙緇嶇殑鍚楋紵褰撹皟鐢ㄨ呰皟鐢ㄨ繘紼嬪鎴栬繙紼嬬粍浠跺姛鑳界殑鏃跺欙紝鍏跺疄鏄唬鐞?瀛樻牴璐熻矗鏁版嵁浜ゆ崲鐨勩傚叧浜庝唬鐞?瀛樻牴鐨勫叿浣撳彉鎴愬拰鎿嶄綔錛屼互鍚庡啀璇村暒......
銆銆鏀寔 MFC 闄ら潪鏈夌壒孌婄殑鍘熷洜錛屾垜浠啓 ATL 紼嬪簭錛屾渶濂戒笉瑕侀夋嫨璇ラ」銆備綘鍙兘浼氳錛屽鏋滄病鏈塎FC鐨勬敮鎸侊紝閭String鎬庝箞鍔炲憖錛熷憡璇変綘涓瀵嗗惂錛屼竴鑸漢鎴戦兘涓嶅憡璇変粬錛屾垜鍚庡崐杈堝瓙灝遍潬鐫榪欎釜縐樺瘑媧葷潃浜嗭細
銆銆1銆佷綘浼歋TL鍚楋紵鍙互鐢?STL 涓殑 string 浠f浛錛?br />銆銆2銆佽嚜宸卞啓涓?MyString 綾伙紝鍢垮樋錛?br />銆銆3銆佹?zhèn)勬?zhèn)勫湴銆佺瀵嗗湴銆佷笉瑕佸憡璇夊埆浜猴紙鐗瑰埆鏄埆鍛婅瘔寰蔣錛夛紝鎶?MFC 涓殑 CString 婧愮爜鎷胯繃鏉ョ敤錛?br />銆銆4銆佷嬌鐢?CComBSTR 綾伙紝鑷沖皯涔熻兘綆鍖栨垜浠瓧絎︿覆鎿嶄綔錛?br />銆銆5銆佺洿鎺ョ敤 API 鎿嶄綔瀛楃涓詫紝鍙嶆鎴戜滑澶у瀛︿範 C 璇█鐨勬椂鍊欙紝閮芥槸浠庤繖閲屽共璧風殑銆傦紙絳変簬娌¤錛屽懙鍛碉級
銆銆鏀寔 COM+ 1.0 鏀寔浜嬪姟澶勭悊鐨?COM+ 鍔熻兘銆侰OM+ 涔熻鍦ㄧ 99 鍥炰粙緇嶅惂銆?br />
涓夈佹坊鍔?ATL 瀵硅薄綾?/b>
銆銆姝ラ3.1錛氳彍鍗?欏圭洰\娣誨姞綾?.."錛堟垨鑰呯敤榧犳爣鍙抽敭鍦?欏圭洰涓脊鍑鴻彍鍗?娣誨姞\娣誨姞綾?.."錛夊茍閫夋嫨 ATL 綆鍗曞璞°傝鍥句笁銆?br />
鍥句笁銆侀夋嫨寤虹珛ATL綆鍗曞璞?br />
銆銆闄や簡綆鍗曞璞?鍙疄鐜頒簡 IUnknown 鎺ュ彛)錛岃繕鍙互閫夋嫨鈥淎TL鎺т歡鈥?ActiveX錛屽疄鐜頒簡10澶氫釜鎺ュ彛)......鍙互閫夋嫨鐨勭粍浠跺璞$被鍨嬪緢澶氾紝浣嗘湰璐ㄤ笂錛屽氨鏄鍚戝甯垜浠粯璁ゅ姞涓婁竴浜涙帴鍙c傚湪浠ュ悗鐨勬枃绔犱腑錛岄檰緇粙緇嶅惂銆?br />
銆銆姝ラ3.2錛氬鍔犺嚜瀹氫箟綾?CFun(鎺ュ彛 IFun) ,瑙佸浘鍥涖?br />
聽
鍥懼洓銆佸~鍐欏悕縐?br />
銆銆鍏跺疄錛屾垜浠彧闇瑕佽緭鍏ョ畝縐幫紝鍏跺畠鐨勯」鐩細鑷姩濉啓銆傛病浠涔堝璇寸殑錛屽彧璇峰ぇ瀹舵敞鎰忎竴涓?ProgID 欏癸紝榛樿鐨?ProgID 鏋勯犳柟寮忎負鈥滈」鐩悕.綆縐板悕鈥濄?br />
銆銆姝ラ3.3錛氬~鍐欐帴鍙e睘鎬ч夐」錛岃鍥?浜斻?br />
鍥句簲銆佹帴鍙i夐」
銆銆綰跨▼妯″瀷 COM 涓殑綰跨▼錛屾垜璁や負鏄渶璁ㄥ帉錛屾渶澶嶆潅鐨勯儴鍒嗐侰OM 綰跨▼鍜屽叕瀵撶殑姒傚康錛岀暀寰呭悗緇粙緇嶃傜幇鍦ㄥ悧......澶у閮介?鍗曞厓"(Apartment)錛屽畠浠h〃浠涔堥偅錛熺畝鍗曞湴璇達細褰撳湪綰跨▼涓皟鐢ㄧ粍浠跺嚱鏁扮殑鏃跺欙紝榪欎簺璋冪敤浼氭帓闃熻繘琛屻傚洜姝わ紝榪欑妯″紡涓嬶紝鎴戜滑鍙互鏆傛椂涓嶇敤鑰冭檻鍚屾鐨勯棶棰樸?娉?)
銆銆鎺ュ彛銆傚弻閲?Dual)錛岃繖涓潪甯?闈炲父閲嶈錛岄潪甯擱潪甯稿父鐢紝浣嗘垜浠粖澶╀笉璁?娉?)銆?b>鍒囪錛佸垏璁幫紒鎴戜滑鐨勮繖絎竴涓?COM 紼嬪簭涓紝涓瀹氳閫夋嫨鈥滆嚜瀹氫箟鈥濓紒錛侊紒錛?/b>錛堝鏋滀綘閫夐敊浜嗭紝璇峰垹闄ゅ叏閮ㄥ唴瀹癸紝閲嶆柊鏉ヨ繃銆傦級
銆銆鑱氬悎 鎴戜滑鍐欑殑緇勪歡錛屽皢鏉ユ槸鍚﹀厑璁歌鍒漢鑱氬悎(娉?)浣跨敤銆傗滃彧鑳藉垱寤轟負鑱氬悎鈥濓紝鏈夌偣綾諱技 C++ 涓殑綰櫄綾伙紝浣犺鏄誨伐紼嬪笀錛屽彧璐熻矗璁捐浣嗕笉浜茶嚜鍐欎唬鐮佺殑璇濓紝鎵嶉夋嫨瀹冦?br />銆銆ISupportErrorInfo 鏄惁鏀寔涓板瘜淇℃伅鐨勯敊璇鐞嗘帴鍙c備互鍚庡氨璁層?br />銆銆榪炴帴鐐?/b> 鏄惁鏀寔榪炴帴鐐規(guī)帴鍙o紙浜嬩歡銆佸洖璋冿級銆備互鍚庡氨璁層?br />銆銆IObjectWithSite 鏄惁鏀寔IE鐨勮皟鐢?br />
鍥涖佹坊鍔犳帴鍙e嚱鏁?br />
鍥懼叚銆佽皟鍑哄鍔犳帴鍙f柟娉曠殑鑿滃崟
鍥句竷銆佸鍔犳帴鍙e嚱鏁?Add
銆銆璇鋒寜鐓у浘紺虹殑鏂規(guī)硶錛屽鍔燗dd()鍑芥暟錛屽鍔燙at()鍑芥暟 銆俒in]琛ㄧず鍙傛暟鏂瑰悜鏄緭鍏ワ紱[out]琛ㄧず鍙傛暟鏂瑰悜鏄緭鍑猴紱[out,retval]琛ㄧず鍙傛暟鏂瑰悜鏄緭鍑猴紝鍚屾椂鍙互浣滀負鍑芥暟榪愮畻緇撴灉鐨勮繑鍥炲箋備竴涓嚱鏁頒腑錛屽彲浠ユ湁澶氫釜[in]銆乕out]錛屼絾[retval]鍙兘鏈変竴涓紝騫朵笖瑕佸拰[out]緇勫悎鍚庡湪鏈鍚庝竴涓綅緗?娉?)
鍥懼叓銆佹帴鍙e嚱鏁板畾涔夊畬鎴愬悗鐨勫浘紺?br />
銆銆鎴戜滑閮界煡閬擄紝瑕佹兂鏀瑰彉 C++ 涓殑綾誨嚱鏁幫紝闇瑕佷慨鏀逛袱涓湴鏂癸細涓鏄ご鏂囦歡(.h)涓被鐨勫嚱鏁板0鏄庯紝浜屾槸鍑芥暟浣?.cpp)鏂囦歡鐨勫疄鐜板銆傝屾垜浠幇鍦ㄧ敤 ATL 鍐欑粍浠剁▼搴忥紝鍒欒繕瑕佷慨鏀逛竴涓湴鏂癸紝灝辨槸鎺ュ彛瀹氫箟(IDL)鏂囦歡銆傚埆鐫鎬?IDL 涓嬫灝辮璁ㄨ鍟︺?br />
浜斻佸疄鐜版帴鍙e嚱鏁?/b>
銆銆榧犳爣鍙岀偣鍥懼叓涓瑿Fun\鍩洪」鍜屾帴鍙Add(...)灝卞彲浠ュ紑濮嬭緭鍏ュ嚱鏁板疄鐜頒簡錛?/p>STDMETHODIMP CFun::Add(long n1, long n2, long *pVal)
{
*pVal = n1 + n2;
return S_OK;
}榪欎釜澶畝鍗曚簡錛屼笉鍐嶆氮璐光滃彛鏉♀濄備笅闈㈡垜浠疄鐜板瓧絎︿覆榪炴帴鐨凜at()鍑芥暟錛?pre>STDMETHODIMP CFun::Cat(BSTR s1, BSTR s2, BSTR *pVal)
{
int nLen1 = ::SysStringLen( s1 ); // s1 鐨勫瓧絎﹂暱搴?
int nLen2 = ::SysStringLen( s2 ); // s2 鐨勫瓧絎﹂暱搴?
*pVal = ::SysAllocStringLen( s1, nLen1 + nLen2 );// 鏋勯犳柊鐨?BSTR 鍚屾椂鎶?s1 鍏堜繚瀛樿繘鍘?
if( nLen2 )
{
::memcpy( *pVal + nLen1, s2, nLen2 * sizeof(WCHAR) ); // 鐒跺悗鎶?s2 鍐嶈繛鎺ヨ繘鍘?
// wcscat( *pVal, s2 );
}
return S_OK;
}瀛︾敓錛氫笂闈㈢殑鍑芥暟瀹炵幇錛屽畬鍏ㄦ槸璋冪敤鍩烘湰鐨?API 鏂瑰紡瀹屾垚鐨勩?br />鑰佸笀錛氭槸鐨勶紝璇村疄璇濓紝鐨勭‘姣旇緝鐑︾悙銆?br />瀛︾敓錛氭垜浠槸鐢╩emcpy()瀹屾垚榪炴帴絎簩涓瓧絎︿覆鍔熻兘鐨勶紝閭d箞涓轟粈涔堜笉鐢ㄥ嚱鏁?wcscat()閭o紵
鑰佸笀錛氬鏁版儏鍐典笅鍙互錛屼絾浣犻渶瑕佺煡閬擄細鐢變簬BSTR鍖呭惈鏈夊瓧絎︿覆闀垮害錛屽洜姝ゅ疄闄呯殑BSTR瀛楃涓插唴瀹逛腑鏄彲浠ュ瓨鍌↙''\0''鐨勶紝鑰屽嚱鏁?wcscat() 鏄互L''\0''浣滀負澶嶅埗緇撴潫鏍囧織錛屽洜姝ゅ彲鑳戒細涓㈠け鏁版嵁銆傛槑鐧戒簡鍚楋紵
瀛︾敓錛氭槑鐧斤紝鏄庣櫧銆傛垜鐪嬭繃銆奀OM 緇勪歡璁捐涓庡簲鐢?涓?涔嬫暟鎹被鍨嬨?/font>鍚庡氨鏄庣櫧浜嗐傞偅涔堣佸笀錛屾湁娌℃湁綆鍗曚竴浜涚殑鏂規(guī)硶閭o紵
鑰佸笀錛氭湁鍛錛屼綘鐪?.....STDMETHODIMP CFun::Cat(BSTR s1, BSTR s2, BSTR *pVal)
{
CComBSTR sResult( s1 );
sResult.AppendBSTR( s2 );
*pVal = sResult.Copy();
// *pVal = sResult.Detach();
return S_OK;
}瀛︾敓錛氬搱鍝堬紝濂斤紒浣跨敤浜?CComBSTR錛岃繖涓氨綆鍗曞浜嗐侰ComBSTR::Copy()鍜孋ComBSTR::Detach()鏈変粈涔堝尯鍒紵
鑰佸笀錛欳ComBSTR::Copy() 浼氬埗閫犱竴涓?BSTR 鐨勫壇鏈紝鍙﹀CComBSTR::CopyTo()涔熸湁綾諱技鍔熻兘銆傝孋ComBSTR::Detach()鏄嬌瀵硅薄涓庡唴閮ㄧ殑 BSTR 鎸囬拡鍓ョ錛岃繖涓嚱鏁扮敱浜庢病鏈夊鍒惰繃紼嬶紝鍥犳閫熷害紼嶅井蹇竴鐐圭偣銆備絾瑕佹敞鎰忥紝涓浣嗗墺紱誨悗錛屽氨涓嶈兘鍐嶄嬌鐢ㄨ瀵硅薄鍟︺?br />瀛︾敓錛氳佸笀錛屾?zhèn)ㄨ鐨勫お鐗涘暒锛屾垜瀵规?zhèn)ㄧ殑鏁話濡傚穽宸嶆嘲灞憋紝鐩村叆浜戦渼......
鑰佸笀錛歋TOP錛孲TOP錛佺暀浣滀笟鍟?.....
銆銆1銆佽嚜宸卞厛鎸夌収浠婂ぉ璁茬殑鍐呭鍐欏嚭榪欎釜緇勪歡錛?br />銆銆2銆佷笉綆′綘鎳備笉鎳傦紝涓瀹氳鍘昏瀵?IDL 鏂囦歡錛孋PP 鏂囦歡錛?br />銆銆3銆佺紪璇戝悗錛岀湅閮戒駭鐢熶簡浜涗粈涔堟枃浠訛紵濡傛灉鏄枃鏈殑鏂囦歡錛屽氨鎵撳紑鐪嬬湅錛?br />銆銆4銆佷笅杞芥湰鏂囩殑紺轟緥紼嬪簭(vc.net 2003鐗堟湰)緙栬瘧榪愯錛岀湅鐪嬫晥鏋溿傜劧鍚庨涔犱竴涓嬬ず渚嬬▼搴忎腑鐨勮皟鐢ㄦ柟娉曪紱
瀛︾敓錛氱煡閬撳暒錛屽揩涓嬭鍚э紝鎴戣涓婂帟鎵錛屾垜閮芥唻鐨勪笉琛屼簡......
鑰佸笀錛氫笅璇撅紒鍒繕浜嗛《鎴戠殑甯栧瓙鍛......
鍏佸皬緇?/b>
銆銆鏈洖浠嬬粛絎竴涓狝TL緇勪歡紼嬪簭鐨勫緩绔嬫楠わ紝鑰屽浣曚嬌鐢ㄨ緇勪歡錛屾暚璇峰叧娉ㄣ奀OM 緇勪歡璁捐涓庡簲鐢?涓?銆嬨?
娉?錛欰partment錛岀郴緇熼氳繃闅愯棌鐨勭獥鍙f秷鎭潵鎺掗槦緇勪歡璋冪敤錛屽洜姝ゆ垜浠彲浠ユ殏鏃朵笉鑰冭檻鍚屾闂銆傛敞鎰忥紝鏄殏鏃跺搱銆?br />娉?錛氬弻鎺ュ彛琛ㄧず鍦ㄤ竴涓帴鍙d腑錛屽悓鏃舵敮鎸佽嚜瀹氫箟鎺ュ彛鍜?IDispatch 鎺ュ彛銆備互鍚庯紝浠ュ悗錛屼互鍚庡氨璁層傚洜涓哄弻鎺ュ彛闈炲父閲嶈錛屾垜浠互鍚庝細澶╁ぉ璁層佸澶滆銆佸父甯歌------綆縐扳滀笁璁測?)
娉?錛氱粍浠剁殑閲嶇敤鏂規(guī)硶鏈?涓紝鑱氬悎鍜屽寘瀹廣?br />娉?錛氳繖浜涢兘鏄?IDL 鏂囦歡涓殑姒傚康錛屼互鍚庣敤鍒頒粈涔堬紝灝變粙緇嶄粈涔堛?img src ="http://m.shnenglu.com/yishanhante/aggbug/19606.html" width = "1" height = "1" />
]]>
浜屻?/b>寤虹珛 ATL 宸ョ▼
銆銆姝ラ2.1錛氬緩绔嬩竴涓伐浣滃尯(WorkSpace)銆?br />銆銆姝ラ2.2錛氬湪宸ヤ綔鍖轟腑錛屽緩绔嬩竴涓?ATL 宸ョ▼(Project)銆傜ず渚嬬▼搴忓彨 Simple1錛屽茍閫夋嫨DLL鏂瑰紡錛岃鍥句竴銆?br />
鍥句竴銆佸緩绔?ATL DLL 宸ョ▼
銆銆Dynamic Link Library(DLL) 琛ㄧず寤虹珛涓涓?DLL 鐨勭粍浠剁▼搴忋?br />銆銆Executable(EXE) 琛ㄧず寤虹珛涓涓?EXE 鐨勭粍浠剁▼搴忋?br />銆銆Service(EXE) 琛ㄧず寤虹珛涓涓湇鍔$▼搴忥紝緋葷粺鍚姩鍚庡氨浼氬姞杞藉茍鎵ц鐨勭▼搴忋?br />銆銆Allow merging of proxy/stub code 閫夋嫨璇ラ」琛ㄧず鎶娾滀唬鐞?瀛樻牴鈥濅唬鐮佸悎騫跺埌緇勪歡紼嬪簭涓紝鍚﹀垯闇瑕佸崟鐙紪璇戯紝鍗曠嫭娉ㄥ唽浠g悊瀛樻牴紼嬪簭銆備唬鐞?瀛樻牴錛岃繖涓槸浠涔堟蹇碉紵榪樿寰楁垜浠湪涓婂洖涔?/a>涓粙緇嶇殑鍚楋紵褰撹皟鐢ㄨ呰皟鐢ㄨ繘紼嬪鎴栬繙紼嬬粍浠跺姛鑳界殑鏃跺欙紝鍏跺疄鏄唬鐞?瀛樻牴璐熻矗鏁版嵁浜ゆ崲鐨勩傚叧浜庝唬鐞?瀛樻牴鐨勫叿浣撳彉鎴愬拰鎿嶄綔錛屼互鍚庡啀璇村暒......
銆銆Support MFC 闄ら潪鏈夌壒孌婄殑鍘熷洜錛屾垜浠啓 ATL 紼嬪簭錛屾渶濂戒笉瑕侀夋嫨璇ラ」銆備綘鍙兘浼氳錛屽鏋滄病鏈塎FC鐨勬敮鎸侊紝閭String鎬庝箞鍔炲憖錛熷憡璇変綘涓瀵嗗惂錛屼竴鑸漢鎴戦兘涓嶅憡璇変粬錛屾垜鍚庡崐杈堝瓙灝遍潬鐫榪欎釜縐樺瘑媧葷潃浜嗭細
銆銆1銆佷綘浼歋TL鍚楋紵鍙互鐢?STL 涓殑 string 浠f浛錛?br />銆銆2銆佽嚜宸卞啓涓?MyString 綾伙紝鍢垮樋錛?br />銆銆3銆佹?zhèn)勬?zhèn)勫湴銆佺瀵嗗湴銆佷笉瑕佸憡璇夊埆浜猴紙鐗瑰埆鏄埆鍛婅瘔寰蔣錛夛紝鎶?MFC 涓殑 CString 婧愮爜鎷胯繃鏉ョ敤錛?br />銆銆4銆佷嬌鐢?CComBSTR 綾伙紝鑷沖皯涔熻兘綆鍖栨垜浠瓧絎︿覆鎿嶄綔錛?br />銆銆5銆佺洿鎺ョ敤 API 鎿嶄綔瀛楃涓詫紝鍙嶆鎴戜滑澶у瀛︿範 C 璇█鐨勬椂鍊欙紝閮芥槸浠庤繖閲屽共璧風殑銆傦紙絳変簬娌¤錛屽懙鍛碉級
銆銆Support MTS 鏀寔浜嬪姟澶勭悊錛屼篃灝辨槸鏄惁鏀寔 COM+ 鍔熻兘銆侰OM+ 涔熻鍦ㄧ 99 鍥炰粙緇嶅惂銆?br />
涓夈佸鍔?ATL 瀵硅薄綾?br />
銆銆姝ラ3.1錛氳彍鍗?Insert\New ATL Object...錛堟垨鑰呯敤榧犳爣鍙抽敭鍦?ClassView 鍗$墖涓脊鍑鴻彍鍗曪級騫墮夋嫨Object 鍒嗙被錛岄変腑 Simple Object 欏圭洰銆傝鍥句簩銆?br />
鍥句簩銆侀夋嫨寤虹珛綆鍗旵OM瀵硅薄
銆銆Category Object 鏅氱粍浠躲傚叾涓彲浠ラ夋嫨鐨勭粍浠跺璞$被鍨嬪緢澶氾紝浣嗘湰璐ㄤ笂錛屽氨鏄鍚戝甯垜浠粯璁ゅ姞涓婁竴浜涙帴鍙c傛瘮濡傛垜浠?"Simple Object"錛屽垯鍚戝緇欐垜浠殑緇勪歡鍔犱笂 IUnknown 鎺ュ彛錛涙垜浠?"Internet Explorer Object"錛屽垯鍚戝闄や簡鍔犱笂 IUnknown 鎺ュ彛澶栵紝鍐嶅鍔犱竴涓粰 IE 鎵浣跨敤鐨?IObjectWithSite 鎺ュ彛銆傚綋鐒朵簡錛屾垜浠畬鍏ㄥ彲浠ユ墜宸ュ鍔犱換浣曟帴鍙c?br />銆銆Category Controls ActiveX 鎺т歡銆傚叾涓彲浠ラ夋嫨鐨?ActiveX 綾誨瀷涔熷緢澶氥傛垜浠湪鍚庣畫鐨勪笓闂ㄤ粙緇?ActiveX 緙栫▼涓啀璁ㄨ銆?br />銆銆Category Miscellaneous 杈呭姪鏉傜被緇勪歡銆?br />銆銆Categroy Data Access 鏁版嵁搴撶被緇勪歡(鎴戞渶璁ㄥ帉鏁版嵁搴撶紪紼嬩簡錛屾墍浠ユ垜涔熶笉浼?銆?br />
銆銆姝ラ3.2錛氬鍔犺嚜瀹氫箟綾?CFun(鎺ュ彛 IFun) ,瑙佸浘涓夈?br />
鍥句笁銆佽緭鍏ョ被涓殑鍚勯」鍚嶇О
銆銆 鍏跺疄錛屾垜浠彧闇瑕佽緭鍏ョ煭鍚?Short Name)錛屽叾瀹冪殑欏圭洰浼氳嚜鍔ㄥ~鍐欍傛病浠涔堝璇寸殑錛屽彧璇峰ぇ瀹舵敞鎰忎竴涓?ProgID 欏癸紝榛樿鐨?ProgID 鏋勯犳柟寮忎負鈥滃伐紼嬪悕.鐭悕鈥濄?br />
銆銆 姝ラ3.3錛氬~鍐欐帴鍙e睘鎬э紝瑙佸浘鍥涖?br />
鍥懼洓銆佹帴鍙e睘鎬?br />
銆銆Threading Model 閫夋嫨緇勪歡鏀寔鐨勭嚎紼嬫ā鍨嬨侰OM 涓殑綰跨▼錛屾垜璁や負鏄渶璁ㄥ帉錛屾渶澶嶆潅鐨勯儴鍒嗐侰OM 綰跨▼鍜屽叕瀵撶殑姒傚康錛岀暀寰呭悗緇粙緇嶃傜幇鍦ㄥ悧......澶у閮介?Apartment錛屽畠浠h〃浠涔堥偅錛熺畝鍗曞湴璇達細褰撳湪綰跨▼涓皟鐢ㄧ粍浠跺嚱鏁扮殑鏃跺欙紝榪欎簺璋冪敤浼氭帓闃熻繘琛屻傚洜姝わ紝榪欑妯″紡涓嬶紝鎴戜滑鍙互鏆傛椂涓嶇敤鑰冭檻鍚屾鐨勯棶棰樸?娉?)
銆銆 Interface 鎺ュ彛鍩烘湰綾誨瀷銆侱ual 琛ㄧず鏀寔鍙屾帴鍙?娉?)錛岃繖涓潪甯?闈炲父閲嶈錛岄潪甯擱潪甯稿父鐢紝浣嗘垜浠粖澶╀笉璁層侰ustom 琛ㄧず鑷畾涔夊熷彛銆?b>鍒囪錛佸垏璁幫紒鎴戜滑鐨勮繖絎竴涓?COM 紼嬪簭涓紝涓瀹氳閫夋嫨瀹冿紒錛侊紒錛?/b>錛堝鏋滀綘閫夐敊浜嗭紝璇峰垹闄ゅ叏閮ㄥ唴瀹癸紝閲嶆柊鏉ヨ繃銆傦級
銆銆 Aggregation 鎴戜滑鍐欑殑緇勪歡錛屽皢鏉ユ槸鍚﹀厑璁歌鍒漢鑱氬悎(娉?)浣跨敤銆侽nly 琛ㄧず蹇呴』琚仛鍚堟墠鑳戒嬌鐢紝鏈夌偣綾諱技 C++ 涓殑綰櫄綾伙紝浣犺鏄誨伐紼嬪笀錛屽彧璐熻矗璁捐浣嗕笉浜茶嚜鍐欎唬鐮佺殑璇濓紝鎵嶉夋嫨瀹冦?br />銆銆Support ISupportErrorInfo 鏄惁鏀寔涓板瘜淇℃伅鐨勯敊璇鐞嗘帴鍙c備互鍚庡氨璁層?br />銆銆Support Connection Points 鏄惁鏀寔榪炴帴鐐規(guī)帴鍙o紙浜嬩歡銆佸洖璋冿級銆備互鍚庡氨璁層?br />銆銆Free Threaded Marshaler 浠ュ悗涔熶笉璁詫紝灝辯畻鎵撴浣狅紝鎴戜篃涓嶈錛?娉?)
鍥涖佹坊鍔犳帴鍙e嚱鏁?br />
鍥句簲銆佽皟鍑哄鍔犳帴鍙f柟娉曠殑鑿滃崟
鍥懼叚銆佸鍔犳帴鍙e嚱鏁?Add
鍥句竷銆佸鍔犳帴鍙e嚱鏁?Cat
銆銆璇蜂弗鏍兼寜鐓у浘鍏殑鏂瑰紡錛屽鍔燗dd()鍑芥暟錛涚敱浜庡浘涓冧腑澧炲姞Cat()鍑芥暟鐨勫弬鏁版瘮杈冮暱錛屾垜娌℃湁閫傚綋鐨勮緭鍏ョ┖鏍鹼紝璇峰ぇ瀹惰嚜宸辮緭鍏ョ殑鏃跺欐敞鎰忎竴涓嬨俒in]琛ㄧず鍙傛暟鏂瑰悜鏄緭鍏ワ紱[out]琛ㄧず鍙傛暟鏂瑰悜鏄緭鍑猴紱[out,retval]琛ㄧず鍙傛暟鏂瑰悜鏄緭鍑猴紝鍚屾椂鍙互浣滀負鍑芥暟榪愮畻緇撴灉鐨勮繑鍥炲箋備竴涓嚱鏁頒腑錛屽彲浠ユ湁澶氫釜[in]銆乕out]錛屼絾[retval]鍙兘鏈変竴涓紝騫朵笖瑕佸拰[out]緇勫悎鍚庡湪鏈鍚庝竴涓綅緗?娉?)
鍥懼叓銆佹帴鍙e嚱鏁板畾涔夊畬鎴愬悗鐨勫浘紺?br />銆銆鎴戜滑閮界煡閬擄紝瑕佹兂鏀瑰彉 C++ 涓殑綾誨嚱鏁幫紝闇瑕佷慨鏀逛袱涓湴鏂癸細涓鏄ご鏂囦歡(.h)涓被鐨勫嚱鏁板0鏄庯紝浜屾槸鍑芥暟浣?.cpp)鏂囦歡鐨勫疄鐜板銆傝屾垜浠幇鍦ㄧ敤 ATL 鍐欑粍浠剁▼搴忥紝鍒欒繕瑕佷慨鏀逛竴涓湴鏂癸紝灝辨槸鎺ュ彛瀹氫箟(IDL)鏂囦歡銆傚埆鐫鎬?IDL 涓嬫灝辮璁ㄨ鍟︺?br />銆銆鐢變簬 vc6.0 鐨凚UG錛屽鑷村ぇ瀹跺湪澧炲姞瀹屾帴鍙e拰鎺ュ彛鍑芥暟鍚庯紝鍙兘涓嶄細鍚戜笂鍥撅紙鍥懼叓錛夋墍琛ㄧ幇鐨勬牱寮忋傝В鍐蟲柟娉曪細
銆
| 1 | 鍏抽棴宸ョ▼錛岀劧鍚庨噸鏂版墦寮 | 璇ユ柟娉曞父甯告湁鏁?/td> |
| 2 | 鍏抽棴 IDE錛岀劧鍚庨噸鏂拌繍琛?/td> | 銆 |
| 3 | 鎵撳紑 IDL 鏂囦歡錛屾鏌ユ帴鍙e嚱鏁版槸鍚︽紜紝濡備笉姝g‘璇蜂慨鏀?/td> | 銆 |
| 4 | 鎵撳紑 IDL 鏂囦歡錛岄殢渚夸慨鏀逛竴涓?鍔犱竴涓┖鏍鹼紝鍐嶅垹闄よ繖涓┖鏍?錛岀劧鍚庝繚瀛?/td> | 璇ユ柟娉曞父甯告湁鏁?/td> |
| 5 | 鎵撳紑 h/cpp 鏂囦歡錛屾鏌ュ嚱鏁版槸鍚﹀瓨鍦ㄦ垨鏄惁姝g‘錛屾湁鍒欐敼涔?/td> | 鏃犲垯鍢夊媺錛屼笉璇村畬榪欎釜鎴愯蹇冪悊鍒壄 |
| 6 | 鍒犻櫎 IDL/H/CPP 涓殑鎺ュ彛鍑芥暟錛岀劧鍚?/td> | 鍐嶆潵涓閬?/td> |
| 7 | 閲嶆柊寤虹珛宸ョ▼銆侀噸鏂板畨瑁卾c銆侀噸鏂板畨瑁厀indows銆佺牳璁$畻鏈?/td> | 鐮革紒 |
浜斻佸疄鐜版帴鍙e嚱鏁?/b>
銆銆榧犳爣鍙岀偣鍥懼叓涓瑿Fun\IFun\Add(...)灝卞彲浠ュ紑濮嬭緭鍏ュ嚱鏁板疄鐜頒簡錛?/p>STDMETHODIMP CFun::Add(long n1, long n2, long *pVal)
{
*pVal = n1 + n2;
return S_OK;
}榪欎釜澶畝鍗曚簡錛屼笉鍐嶆氮璐光滃彛鏉♀濄備笅闈㈡垜浠疄鐜板瓧絎︿覆榪炴帴鐨凜at()鍑芥暟錛?pre>STDMETHODIMP CFun::Cat(BSTR s1, BSTR s2, BSTR *pVal)
{
int nLen1 = ::SysStringLen( s1 ); // s1 鐨勫瓧絎﹂暱搴?
int nLen2 = ::SysStringLen( s2 ); // s2 鐨勫瓧絎﹂暱搴?
*pVal = ::SysAllocStringLen( s1, nLen1 + nLen2 ); // 鏋勯犳柊鐨?BSTR 鍚屾椂鎶?s1 鍏堜繚瀛樿繘鍘?
if( nLen2 )
{
::memcpy( *pVal + nLen1, s2, nLen2 * sizeof(WCHAR) ); // 鐒跺悗鎶?s2 鍐嶈繛鎺ヨ繘鍘?
// wcscat( *pVal, s2 );
}
return S_OK;
}瀛︾敓錛氫笂闈㈢殑鍑芥暟瀹炵幇錛屽畬鍏ㄦ槸璋冪敤鍩烘湰鐨?API 鏂瑰紡瀹屾垚鐨勩?br />鑰佸笀錛氭槸鐨勶紝璇村疄璇濓紝鐨勭‘姣旇緝鐑︾悙銆?br />瀛︾敓錛氭垜浠槸鐢╩emcpy()瀹屾垚榪炴帴絎簩涓瓧絎︿覆鍔熻兘鐨勶紝閭d箞涓轟粈涔堜笉鐢ㄥ嚱鏁?wcscat()閭o紵
鑰佸笀錛氬鏁版儏鍐典笅鍙互錛屼絾浣犻渶瑕佺煡閬擄細鐢變簬BSTR鍖呭惈鏈夊瓧絎︿覆闀垮害錛屽洜姝ゅ疄闄呯殑BSTR瀛楃涓插唴瀹逛腑鏄彲浠ュ瓨鍌↙''\0''鐨勶紝鑰屽嚱鏁?wcscat() 鏄互L''\0''浣滀負澶嶅埗緇撴潫鏍囧織錛屽洜姝ゅ彲鑳戒細涓㈠け鏁版嵁銆傛槑鐧戒簡鍚楋紵
瀛︾敓錛氭槑鐧斤紝鏄庣櫧銆傛垜鐪嬭繃銆?a >COM 緇勪歡璁捐涓庡簲鐢?涓?涔嬫暟鎹被鍨嬨嬪悗灝辨槑鐧戒簡銆傞偅涔堣佸笀錛屾湁娌℃湁綆鍗曚竴浜涚殑鏂規(guī)硶閭o紵
鑰佸笀錛氭湁鍛錛屼綘鐪?.....STDMETHODIMP CFun::Cat(BSTR s1, BSTR s2, BSTR *pVal)
{
CComBSTR sResult( s1 );
sResult.AppendBSTR( s2 );
*pVal = sResult.Copy();
// *pVal = sResult.Detach();
return S_OK;
}瀛︾敓錛氬搱鍝堬紝濂斤紒浣跨敤浜?CComBSTR錛岃繖涓氨綆鍗曞浜嗐侰ComBSTR::Copy()鍜孋ComBSTR::Detach()鏈変粈涔堝尯鍒紵
鑰佸笀錛欳ComBSTR::Copy() 浼氬埗閫犱竴涓?BSTR 鐨勫壇鏈紝鍙﹀CComBSTR::CopyTo()涔熸湁綾諱技鍔熻兘銆傝孋ComBSTR::Detach()鏄嬌瀵硅薄涓庡唴閮ㄧ殑 BSTR 鎸囬拡鍓ョ錛岃繖涓嚱鏁扮敱浜庢病鏈夊鍒惰繃紼嬶紝鍥犳閫熷害紼嶅井蹇竴鐐圭偣銆備絾瑕佹敞鎰忥紝涓浣嗗墺紱誨悗錛屽氨涓嶈兘鍐嶄嬌鐢ㄨ瀵硅薄鍟︺?br />瀛︾敓錛氳佸笀錛屾?zhèn)ㄨ鐨勫お鐗涘暒锛屾垜瀵规?zhèn)ㄧ殑鏁話濡傚穽宸嶆嘲灞憋紝鐩村叆浜戦渼......
鑰佸笀錛歋TOP錛孲TOP錛佺暀浣滀笟鍟?.....
銆銆 1銆佽嚜宸卞厛鎸夌収浠婂ぉ璁茬殑鍐呭鍐欏嚭榪欎釜緇勪歡錛?br />銆銆 2銆佷笉綆′綘鎳備笉鎳傦紝涓瀹氳鍘昏瀵?IDL 鏂囦歡錛孋PP 鏂囦歡錛?br />銆銆 3銆佺紪璇戝悗錛岀湅閮戒駭鐢熶簡浜涗粈涔堟枃浠訛紵濡傛灉鏄枃鏈殑鏂囦歡錛屽氨鎵撳紑鐪嬬湅錛?br />銆銆 4銆佷笅杞芥湰鏂囩殑紺轟緥紼嬪簭(vc6.0鐗堟湰)緙栬瘧榪愯錛岀湅鐪嬫晥鏋溿傜劧鍚庨涔犱竴涓嬬ず渚嬬▼搴忎腑鐨勮皟鐢ㄦ柟娉曪紱
瀛︾敓錛氱煡閬撳暒錛屽揩涓嬭鍚э紝鎴戣涓婂帟鎵錛屾垜閮芥唻鐨勪笉琛屼簡......
鑰佸笀錛氫笅璇撅紒鍒繕浜嗛《鎴戠殑甯栧瓙鍛......
鍏佸皬緇?/b>
銆銆鏈洖浠嬬粛絎竴涓狝TL緇勪歡紼嬪簭鐨勫緩绔嬫楠わ紝鑰屽浣曚嬌鐢ㄨ緇勪歡錛屾暚璇峰叧娉ㄣ奀OM 緇勪歡璁捐涓庡簲鐢?涓?銆嬨?br />銆
娉?錛欰partment錛岀郴緇熼氳繃闅愯棌鐨勭獥鍙f秷鎭潵鎺掗槦緇勪歡璋冪敤錛屽洜姝ゆ垜浠彲浠ユ殏鏃朵笉鑰冭檻鍚屾闂銆傛敞鎰忥紝鏄殏鏃跺搱銆?br />娉?錛氬弻鎺ュ彛琛ㄧず鍦ㄤ竴涓帴鍙d腑錛屽悓鏃舵敮鎸佽嚜瀹氫箟鎺ュ彛鍜?IDispatch 鎺ュ彛銆備互鍚庯紝浠ュ悗錛屼互鍚庡氨璁層傚洜涓哄弻鎺ュ彛闈炲父閲嶈錛屾垜浠互鍚庝細澶╁ぉ璁層佸澶滆銆佸父甯歌------綆縐扳滀笁璁測?)
娉?錛氱粍浠剁殑閲嶇敤鏂規(guī)硶鏈?涓紝鑱氬悎鍜屽寘瀹廣?br />娉?錛氬悕縐扮殑鍔熻兘寰堝ソ鍚紝浣嗗井杞牴鏈氨娌℃湁瀹炵幇銆?br />娉?錛氳繖浜涢兘鏄?IDL 鏂囦歡涓殑姒傚康錛屼互鍚庣敤鍒頒粈涔堬紝灝變粙緇嶄粈涔堛?br />
]]>


