COMコンポーネント設計と応用5-ATLで最初のコンポーネントを書く


ソースコード1、前言1、vc 5を使用している場合はダウンロードします.0および以前のバージョンはvc 6にアップグレードしてください.0またはvc.net 2003;2、vc 6を使っている場合.0(ATL 3.0)今回の内容をお読みください.3、vcを使っている場合はNet(ATL 7.0)次の内容をお読みください.4、この最初のコンポーネントは、すべてのCOMコンポーネントに必要なIUnknownインタフェースに加えて、Add()が2つの数値の加算を完了し、Cat()が2つの文字列の接続を完了する2つの関数を持つ独自の定義インタフェースIFunを実現します.5、次は……よく聞いて!始まりました:-)
二、ATL工程ステップ2.1を創立する:ワークスペースを創立する.手順2.2:ワークスペースにおいて、ATLプロジェクトを作成する.例示的なプログラムはSimple 1と呼ばれ、図1を参照してDLL方式を選択する.図1、ATL DLLエンジニアリングDynamic Link Library(DLL)の確立は、DLLを確立するコンポーネントプログラムを示す.Executable(EXE)は、EXEのコンポーネントプログラムを作成することを表します.サービス(EXE)は、システムが起動するとロードされ実行されるサービスプログラムを作成することを意味します.Allow merging of proxy/stub codeは、「エージェント/ルート」コードをコンポーネントプログラムにマージすることを選択します.そうしないと、個別にコンパイルし、エージェントルートプログラムを個別に登録する必要があります.エージェント/ストレージ、これはどんな概念ですか?前回の本で紹介したのを覚えていますか.呼び出し元がプロセス外またはリモートコンポーネント機能を呼び出すと、実はエージェント/レジストリがデータ交換を担当します.エージェント/レジストリの具体的な変更と操作については、後で話しますが...Support MFCは特別な理由がない限り、ATLプログラムを書きます.この項目を選択しないほうがいいです.もしMFCのサポートがなければ、CStringはどうしますか?あなたに秘密を教えて、普通の人は私はすべて彼に教えないで、私の后半の一生はこの秘密に頼って生きています:1、あなたはSTLができますか?STLのstringで代用できます.2、自分でMyString類を書いて、へへへ;3、こっそり、秘密に、他の人に言わないで(特にマイクロソフトに言わないで)、MFCのCStringソースコードを持ってきてください.4、CComBSTRクラスを使用して、少なくとも私たちの文字列の操作を簡略化することができます.5、APIで文字列を直接操作します.どうせ私たちがC言語を勉強するときは、ここから始めました.(言うまでもなく、ほほほ)Support MTSはトランザクションをサポートし、つまりCOM+機能をサポートしているかどうか.COM+は第99回で紹介されるかもしれません.三、ATLオブジェクトクラスを増やす手順3.1:メニューInsert/New ATL Object...(または、マウスの右ボタンでClassViewカードからメニューをポップアップします)を選択し、Objectカテゴリを選択し、Simple Objectアイテムを選択します.図2を参照.図2、単純COMオブジェクトCategory Object一般コンポーネントの作成を選択する.選択できるコンポーネントオブジェクトのタイプはたくさんありますが、本質的には、ウィザードにデフォルトのインタフェースを追加してもらうことです.たとえば、「Simple Object」を選択すると、ウィザードはコンポーネントにIUnknownインタフェースを追加します.「Internet Explorer Object」を選択すると、ウィザードはIUnknownインタフェースに加えて、IEに使用するIObjectWithSiteインタフェースを追加します.もちろん、任意のインタフェースを手動で追加することができます.Category Control ActiveXコントロール.中でも選べるActiveXタイプも多いです.ActiveXプログラミングについては後述する.Category Miscellaneousアシストハイブリッドコンポーネント.Categroy Data Accessデータベースクラスコンポーネント(データベースプログラミングが大嫌いなので、私もできません).ステップ3.2:カスタムクラスCFun(インタフェースIFun)を追加し、図3を参照する.図3、入力クラスの各名称は、実際には短い名前(Short Name)を入力するだけで、他の項目は自動的に記入されます.あまり言うことはありませんが、ProgID項目に注意してください.デフォルトのProgID構造は「工事名.短名」です.手順3.3:インタフェースの属性を記入し、図4を参照する.図4、インタフェース属性Threading Model選択コンポーネントがサポートするスレッドモデル.COMの中のスレッドは、一番嫌いで複雑な部分だと思います.COMスレッドとマンションのコンセプトは、後述する.今ですか・・・みんなはすべてApartmentを選んで、それは何を代表しますか?簡単に言えば、スレッドでコンポーネント関数を呼び出すと、これらの呼び出しはキューに並んで行われます.従って,このモードでは,同期の問題を一時的に考慮する必要はない.(注1)Interfaceインタフェースの基本タイプ.Dualはデュアルインタフェース(注2)をサポートすることを示しています.これは非常に重要で、非常によく使われていますが、今日は言いません.Customはカスタム言い訳を表します.覚えておいて!覚えておいて!私達のこの第1のCOMプログラムの中で、きっとそれを選びます!!!△もしあなたが間違っていたら、すべての内容を削除して、やり直してください.Aggregation私たちが書いたコンポーネントは、将来他の人に集約されることを許可するかどうか(注3).Onlyは集約されなければ使用できないことを示しています.C++の純虚類に似ています.エンジニアが設計を担当していますが、自分でコードを書かない場合は、それを選択します.Support ISupportErrorInfoが豊富な情報のエラー処理インタフェースをサポートしているかどうか.後で話します.Support Connection Pointsが接続ポイントインタフェース(イベント、コールバック)をサポートしているかどうか.後で話します.Free Threaded Marshalerは後でも言わないで、たとえあなたを殺しても、私は言いません!(注4)四、インタフェース関数図五を追加し、インタフェースを追加する方法のメニュー図六を呼び出し、インタフェース関数Add図七を増加し、インタフェース関数Catを増加するには、図六の方法に厳格に従って、Add()関数を増加してください.図7にCat()関数を追加するパラメータが長いので、適切なスペースを入力していませんので、自分で入力するときに注意してください.[in]はパラメータ方向が入力であることを示す.[out]はパラメータ方向が出力であることを示す.[out,retval]はパラメータ方向が出力であることを示し,関数演算結果の戻り値としてもよい.1つの関数には[in]、[out]が複数ありますが、[retval]は1つしかありません.[out]と組み合わせて最後の位置にします.(注5)図8、インタフェース関数の定義が完了した図は、C++のクラス関数を変更するには、ヘッダファイル(.h)のクラスの関数宣言と、関数体(.cpp)ファイルの実装の2つの場所を変更する必要があることを知っています.今、ATLでコンポーネントプログラムを書きます.インタフェース定義(IDL)ファイルも変更します.焦らないでIDLは今度検討します.vc 6.0のBUGは、インタフェースとインタフェース関数を追加した後、上図(図8)に示すスタイルにならない可能性があります.解決方法:
1
プロジェクトを閉じて再開
この方法はしばしば有効である
2
IDEを閉じて再実行
 
3
IDLファイルを開き、インタフェース関数が正しいかどうかを確認します.正しくない場合は変更してください.
 
4
IDLファイルを開き、勝手に変更(スペースを追加し、このスペースを削除)して保存します.
この方法はしばしば有効である
5
h/cppファイルを開き、関数が存在するか正しいかどうかを確認します.
この成語を言わないと気がすまない
6
IDL/H/CPPのインタフェース関数を削除し、
もう一度
7
工事の再構築、vcの再インストール、windowsの再インストール、コンピュータの破壊
壊せ!
五、インタフェース関数を実現するマウス二点図八中CFun/IFun/Add(...)入力関数の実装を開始できます.
STDMETHODIMP CFun::Add(long n1, long n2, long *pVal)
{
*pVal = n1 + n2;

return S_OK;
}
これは簡単すぎて、「口条」を無駄にしません.文字列接続のCat()関数を実装します.
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方式を呼び出して完了します.
先生:はい、正直に言うと、確かに煩わしいですね.
学生:私たちはmemcpy()で2番目の文字列を接続する機能を完成しました.では、なぜ関数wcscat()を使わないのですか.
先生:多くの場合可能ですが、BSTRには文字列の長さが含まれているため、実際のBSTR文字列の内容にはL'/0'を格納することができ、関数wcscat()はL'/0'をコピー終了フラグとして使用するため、データが失われる可能性があります.分かりましたか.
学生:わかりました.『COMコンポーネント設計と応用(三)のデータ型』を見てから分かりました.では、先生、簡単な方法はありますか.
先生:ありますよ.ほら.
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を使っているので、これはずっと簡単です.CComBSTR::Copy()とCComBSTR::Detach()の違いは何ですか?
先生:CComBSTR::Copy()はBSTRのコピーを作ります.また、CComBSTR::CopyTo()にも似たような機能があります.一方、CComBSTR::Detach()は、オブジェクトを内部のBSTRポインタから剥離させるものであり、この関数はコピープロセスがないため、速度が少し速い.ただし、剥離すると、そのオブジェクトは使用できなくなるので注意してください.
学生:先生、あなたの話はすごいですね.私はあなたを尊敬しています.泰山のように、空にまっすぐ入っています.
先生:STOP、STOP!宿題を残して・・・
1、自分でまず今日話した内容に従ってこのコンポーネントを書きます.
2、分かるかどうかにかかわらず、IDLファイル、CPPファイルを必ず観察しなければならない.
3、コンパイルして、どんなファイルが生まれたか見てみましょう.テキストのファイルなら開いてみます.
4、本明細書のサンプルプログラム(vc 6.0バージョン)をダウンロードしてコンパイルして実行し、効果を見る.次に、サンプルプログラムの呼び出し方法を予習します.
学生:わかりました.もうすぐ授業が終わるでしょう.トイレに行きますから、もう我慢できません.
先生:授業が終わります.私の招待状を顶くことを忘れないでください......
六、まとめ
今回は、最初のATLコンポーネントプログラムの作成手順について説明します.このコンポーネントをどのように使用するかは、「COMコンポーネント設計とアプリケーション(7)」に注目してください.
注意1:Apartmentでは、非表示のウィンドウ・メッセージを使用してコンポーネント・コールをキュー化するため、同期の問題を一時的に考慮しないことができます.注意、一時ですね.
注意2:デュアルインタフェースは、1つのインタフェースに表示され、カスタムインタフェースとIDispatchインタフェースをサポートします.後で、後で、後で話します.二重インタフェースはとても重要なので、私たちはこれから毎日話して、夜遅く話して、よく話します------「三講」と略称します:)
注意3:コンポーネントの再利用方法は2つあり、集約と収容があります.
注4:名前の機能はとても良いですが、マイクロソフトは全然実現していません.
注5:これらはすべてIDLファイルの概念で、後で何を使うか、何を紹介します.
検索ワードを入力して検索フォームを発行