<?xml version="1.0" encoding="UTF-8"?>

<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns="http://purl.org/rss/1.0/"
>

<channel rdf:about="http://myprivateadversaria.seesaa.net/">
<title>My Private Adversaria</title>
<link>http://myprivateadversaria.seesaa.net/</link>
<description>ソフトウェアに関する個人的備忘録です。何かお役に立てれば嬉しいですが，役に立たなくでも怒らないで下さい(^_^;)</description>
<dc:language>ja</dc:language>
<admin:generatorAgent rdf:resource="http://blog.seesaa.jp/" />
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/118865951.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/118195165.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/117101829.html" />
<rdf:li rdf:resource="http://match.seesaa.jp/ot_listing.pl?aid=640816&amp;sid=myprivateadversaria&amp;tid=seesaa_hotspot&amp;k=Y150&amp;hid=35" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/111336772.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/111336042.html" />
<rdf:li rdf:resource="http://match.seesaa.jp/ot_listing.pl?aid=640816&amp;sid=myprivateadversaria&amp;tid=seesaa_hotspot&amp;k=%E7%99%BA%E7%86%B1%E6%82%A3%E8%80%85&amp;hid=35" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/111123915.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/111029152.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/110927181.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/105719865.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/97164572.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/97163694.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/97144857.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/97144026.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/97143821.html" />
<rdf:li rdf:resource="http://myprivateadversaria.seesaa.net/article/97143512.html" />
</rdf:Seq>
</items>
</channel>

<item rdf:about="http://myprivateadversaria.seesaa.net/article/118865951.html">
<link>http://myprivateadversaria.seesaa.net/article/118865951.html</link>
<title>VisualC++ のマクロ変数を追加する方法</title>
<description>VisualStudio2003/2005 の VC++ のプロパティ定義では，マクロ変数を使用することができます。マクロ変数にはプロジェクトのディレクトリなどがあらかじめ定義されていて，一覧表から選択する形式になっています。この便利なマクロ変数に独自の定義を追加したいところなのですが，ダイアログには「追加」などのボタンは見当たりません。で，登録できないのかと思うと，実はちゃんとできたりします。ただ，その手順がとても不自然(!!)な上，ヘルプの説明も見つけにくいので，備忘録と...</description>
<dc:subject>Index</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2009-05-08T00:34:16+09:00</dc:date>
<content:encoded><![CDATA[
VisualStudio2003/2005 の VC++ のプロパティ定義では，マクロ変数を使用することができます。マクロ変数にはプロジェクトのディレクトリなどがあらかじめ定義されていて，一覧表から選択する形式になっています。<br /><br /><a href="http://myprivateadversaria.up.seesaa.net/image/p1.gif" target="_blank"><img src="http://myprivateadversaria.up.seesaa.net/image/p1-thumbnail2.gif" width="150" height="64" border="0" align="" alt="p1.gif" onclick="location.href = 'http://myprivateadversaria.seesaa.net/upload/detail/image/p1-thumbnail2.gif.html'; return false;" style="cursor:pointer;" /></a><br /><br />この便利なマクロ変数に独自の定義を追加したいところなのですが，ダイアログには「追加」などのボタンは見当たりません。<br /><br />で，登録できないのかと思うと，実はちゃんとできたりします。ただ，その手順がとても不自然(!!)な上，ヘルプの説明も見つけにくいので，備忘録として書き留めておきます。<br /><br />1. 「プロパティマネージャ」ウィンドウを表示。<br /><br />VC2005は，メニュー [表示]->[その他のウィンドウ]->[プロパティマネージャ]と指定します。VC2008は[表示]メニューで直接選択できるようです。<br /><br />2. プロパティマネージャのツリーで，追加するプロジェクトを選択。<br /><br />3. ウィンドウ上部のツールボタン「新しいプロジェクトプロパティシートの追加」を選択。<br /><br />4. 「新しい項目の追加」ダイアログでファイル名を指定して，プロパティシートを新規作成。<br /><br /><a href="http://myprivateadversaria.up.seesaa.net/css/p2.gif" target="_blank"><img src="http://myprivateadversaria.up.seesaa.net/css/p2-thumbnail2.gif" width="150" height="89" border="0" align="" alt="p2.gif" onclick="location.href = 'http://myprivateadversaria.seesaa.net/upload/detail/css/p2-thumbnail2.gif.html'; return false;" style="cursor:pointer;" /></a><br /><br />5. プロパティマネージャで追加したプロパティシートをダブルクリックして開く。<br /><br />6. 「プロパティページ」ダイアログで「共通プロパティ／ユーザーマクロ」を選択する。<br /><br />7. マクロペインが開くので，マクロの追加を行う。<br /><br /><a href="http://myprivateadversaria.up.seesaa.net/css/p3.gif" target="_blank"><img src="http://myprivateadversaria.up.seesaa.net/css/p3-thumbnail2.gif" width="150" height="103" border="0" align="" alt="p3.gif" onclick="location.href = 'http://myprivateadversaria.seesaa.net/upload/detail/css/p3-thumbnail2.gif.html'; return false;" style="cursor:pointer;" /></a><br /><br />以上の操作で，設定されたマクロがプロジェクトから参照可能になっています。<br /><br /><a href="http://myprivateadversaria.up.seesaa.net/css/P4.gif" target="_blank"><img src="http://myprivateadversaria.up.seesaa.net/css/P4-thumbnail2.gif" width="124" height="150" border="0" align="" alt="P4.gif" onclick="location.href = 'http://myprivateadversaria.seesaa.net/upload/detail/css/P4-thumbnail2.gif.html'; return false;" style="cursor:pointer;" /></a><br /><br />もう少し直接的な入力UIはできないものでしょうか(^^;<a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/118195165.html">
<link>http://myprivateadversaria.seesaa.net/article/118195165.html</link>
<title>auto_ptr の微妙な仕様(「バグ」とも言う(^^;)</title>
<description>C++ の std::auto_ptr に関する，ちょっとした覚書です。# 以下の内容は VS2005 の VC++(8.0)で確認したものです。# 他のバージョンや他処理系では動作に違いがあるかも知れません。auto_ptr は C++ インスタンスの寿命(生成／開放)を管理するテンプレートで，  auto_ptr&amp;lt;SomeClass&amp;gt; aPtr(new SomeClass());のように宣言しておくと，メソッド終了時などにインスタンスを開放してくれる訳ですが，...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2009-04-27T23:44:25+09:00</dc:date>
<content:encoded><![CDATA[
C++ の std::auto_ptr に関する，ちょっとした覚書です。<br /># 以下の内容は VS2005 の VC++(8.0)で確認したものです。<br /># 他のバージョンや他処理系では動作に違いがあるかも知れません。<br /><br />auto_ptr は C++ インスタンスの寿命(生成／開放)を管理するテンプレートで，<br /><pre>  auto_ptr&lt;SomeClass&gt; aPtr(new SomeClass());</pre><br />のように宣言しておくと，メソッド終了時などにインスタンスを開放してくれる訳ですが，この宣言を<br /><pre>  auto_ptr&lt;SomeClass&gt; aPtr = new SomeClass();</pre>とやってしまうと，実行時に Access Vioration で落ちてしまいます。<br /><br />コンパイル時にはエラーや警告など，一切出ません。<br />で，理由が分からずに深く悩んだりします(^^;<br /><br />仕方ないので出力されたコードを調べてみると，ポインタの代入時に auto_ptr_ref というクラスへの変換が挿入されてしまっているのが分かります。<br /><br /><pre>  auto_ptr<SomeClass> aPtr = auot_ptr_ref<SomeClass>(new SomeClass();)</pre><br />だいたいこんなイメージです(厳密にはちょっと違いますが)。<br /><br />auto_ptr<T> には T* を引数とする代入演算子がなく，auto_ptr_ref を引数として取る代入演算子が定義されているため，このような暗黙の変換が挿入されるのだと思われます。<br /><br />これでうまく動くのならばＯＫなのですが，実際のコードはポインタの参照値がポインタとして扱われてしまっていて(SomeClass** として参照されていて)，アクセスした時点でダウン，という構造になっています。<br /><br />で，この auto_ptr_ref というクラス，ドキュメントにも記載されていない内部定義のようですが，どうにも実装が怪しい。<br /><pre><br />// TEMPLATE CLASS auto_ptr<br />template&lt;class _Ty&gt;<br />   class auto_ptr;<br /><br />template&lt;class _Ty&gt;<br />   struct auto_ptr_ref<br />       {       // proxy reference for auto_ptr copying<br />   auto_ptr_ref(void *_Right)<br />       : _Ref(_Right)<br />       {   // construct from generic pointer to auto_ptr ptr<br />       }<br /><br />   void *_Ref;     // generic pointer to auto_ptr ptr<br />   };</pre><br />auto_ptr の宣言がこれに続くのですが，これを見ただけで<ul><li>前方参照もしていない auto_ptr を宣言しているのは何故？</li><li>テンプレート引数 _Ty は使用しない？(テンプレートじゃない？)</li></ul>など，疑問点がふつふつ湧いてきます。<br /><br />このクラス(テンプレート？)自体は，auto_ptr 同士を代入演算子で転送するときのためのものと思うのですが，実装のレベルや今回のポインタ代入の問題を見ると，どうにも失敗作としか思えません。<br /><br />もう少し完成度の高い Smart Pointer が一般的に使えるようになるまでは，<br /><ol><li>初期化はコンストラクタ引数で行う</li><li>auto_ptr 同士の代入などは行わない</li></ol>という教訓の元で使いたい，と思うのでした(^^;<br /><br />追記：<br />やっぱり同じ内容で悩んでいる人はいるものですね。ご苦労さまです：<br /><a href="http://www.velocityreviews.com/forums/t458584-autoptr-assignment-crash-with-vc-language-extensions.html" target="_blank">http://www.velocityreviews.com/forums/t458584-autoptr-assignment-crash-with-vc-language-extensions.html</a><br /><br /><a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/117101829.html">
<link>http://myprivateadversaria.seesaa.net/article/117101829.html</link>
<title>Template クラスを friend にする</title>
<description>タイトルどおり(^^)まさにAdversaria(備忘録)です。class aClass {    .................    // テンプレートfriend    template&amp;lt;class T&amp;gt;    friend class aTemplate;    .................Googleで調べてもなかなか出てこなくて，ちょっと悩みましたが，普通に書いて大丈夫でした。当然ですが，Template の実装は別に記述します。templa...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2009-04-08T23:46:26+09:00</dc:date>
<content:encoded><![CDATA[
タイトルどおり(^^)<br />まさにAdversaria(備忘録)です。<br /><br /><pre><br />class aClass {<br />    .................<br />    // テンプレートfriend<br />    template&lt;class T&gt;<br />    friend class aTemplate;<br />    .................<br /></pre><br /><br />Googleで調べてもなかなか出てこなくて，ちょっと悩みましたが，<br />普通に書いて大丈夫でした。<br /><br />当然ですが，Template の実装は別に記述します。<br /><br /><pre><br />template&lt;class T&gt;<br />class aTempalte {<br />    ..................<br />    T  value;<br />    ..................<br />}<br /></pre><br /><a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://match.seesaa.jp/ot_listing.pl?aid=640816&amp;sid=myprivateadversaria&amp;tid=seesaa_hotspot&amp;k=Y150&amp;hid=35">
<link>http://match.seesaa.jp/ot_listing.pl?aid=640816&amp;sid=myprivateadversaria&amp;tid=seesaa_hotspot&amp;k=Y150&amp;hid=35</link>
<title>[PR]注目のキーワード「Y150」</title>
<description><![CDATA[
<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E6%A8%AA%E6%B5%9C&hid=35">横浜</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E9%96%8B%E5%9B%BD%E5%8D%9A&hid=35">開国博</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88&hid=35">イベント</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E9%9B%A8&hid=35">雨</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=GW&hid=35">GW</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E9%96%8B%E5%82%AC&hid=35">開催</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E3%82%AF%E3%83%A2&hid=35">クモ</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E8%A1%8C%E3%81%A3%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F&hid=35">行ってきました</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E8%A1%8C%E3%81%8F&hid=35">行く</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E5%B7%A8%E5%A4%A7&hid=35">巨大</a>
]]></description>
<dc:date>2009-04-08T23:46:26+09:00</dc:date>
<dc:creator>ads by Seesaa</dc:creator>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/111336772.html">
<link>http://myprivateadversaria.seesaa.net/article/111336772.html</link>
<title>ATLをサポートするコマンドアプリの作り方</title>
<description>VisualStudio 2005 以降のプロジェクト・ウィザードでは，ATLプロジェクトで生成するアプリケーションの形式として，DLL, サービスの他に「実行可能なアプリケーション」が選択できるようになりました。この時生成されるプロジェクトはATLで記述したCOMをサービスするものですが，これを改造して通常のコンソールアプリとするための修正内容をメモします。ウィザードで生成されるメインコードは，次のようなCAtlExeModuleTテンプレート派生クラスとメイン関数のみでで...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-12-16T23:54:18+09:00</dc:date>
<content:encoded><![CDATA[
VisualStudio 2005 以降のプロジェクト・ウィザードでは，
ATLプロジェクトで生成するアプリケーションの形式として，
DLL, サービスの他に「実行可能なアプリケーション」が選択できるようになりました。<br><br>
この時生成されるプロジェクトはATLで記述したCOMをサービスするものですが，
これを改造して通常のコンソールアプリとするための修正内容をメモします。<br><br>
ウィザードで生成されるメインコードは，
次のようなCAtlExeModuleTテンプレート派生クラスと
メイン関数のみでできています。<br><br>
<pre>
class CMyAppModule : public CAtlExeModuleT< CMyAppModule >
{
public :
	DECLARE_LIBID(LIBID_MyAppLib)
	DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MYAPP, "{E115D6B3-7016-4740-AF95-D2B76569B56F}")
}

CMyAppModule _AtlModule;

extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, 
                                LPTSTR /*lpCmdLine*/, int nShowCmd)
{
    return _AtlModule.WinMain(nShowCmd);
}</pre><br>

この _tWinMain で行っている処理を別スレッドにして，メインスレッドで
必要な処理をするように変更できれば，目的が達成できそうです。
<br><br>
方法はいろいろありますが，次のような形式で実装してみました。
<br><br>
1.
_AtlModule::WinMain から CMyAppModule::Run メソッドがコールされるので
これをオーバーロードします。<br>
<pre>
HRESULT
CMyAppModule::Run(int nShowCmd) throw() {
    this->showcmd_ = nShowCmd;
    unsigned int threadID;
    HANDLE hThread;
    startThread(hThread, threadID);
    doMyOperation();
    stopThread(hThread, threadID);
    return S_OK;
}</pre><br>

startThread / stopThread はスレッドの起動/停止メソッドで，
ここで起動するスレッドで元々の Run メソッドを実行してやります。
<br><pre>
void
CMyAppModule::startThread(HANDLE& hThread, unsigned int& threadID) {
    hThread = (HANDLE)::_beginthreadex(NULL, 0, threadFunc, (LPVOID)this, 0, &threadID);
}

void
CMyAppModule::stopThread(HANDLE hThread, DWORD threadID) {
    do {
        ::PostThreadMessage(threadID, WM_QUIT, NULL, NULL);
    } while(::WaitForSingleObject(hThread, 500) == WAIT_TIMEOUT);
}</pre><br>

stopThread では，
スレッドに WM_QUIT を投げた後，停止の待ち合わせをしています。
<br><br>
スレッド関数 threadFunc はこんな感じ：
<br><pre>
static unsigned int __stdcall threadFunc(LPVOID param) {
    ::CoInitialize(NULL);
    CMyAppModule* this_ = (CMyAppModule*)param;
    return this_->CAtlExeModuleT<CMyAppModule>::Run(this_->showcmd_);
}</pre><br>

インスタンス変数 showcmd_ は Run メソッドに渡された引数をスレッド関数に
引き渡すためのものです。
<br><br>
doMyOperation( ) は実際に行いたい処理を実装する場所です。
<br><br>
コード全体としては，おおよそ以下のような形式です。
エラー処理などは必要に応じて実装してください(^^;)。
<br><pre>
class CMyAppModule : public CAtlExeModuleT< CMyAppModule >
{
public :
    DECLARE_LIBID(LIBID_MyAppLib)
    DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MYAPP, "{E115D6B3-7016-4740-AF95-D2B76569B56F}")

    HRESULT
    CMyAppModule::Run(int nShowCmd) throw() {
        showcmd_ = nShowCmd;
        unsigned int threadID;
        HANDLE hThread;
        startThread(hThread, threadID);
	doMyOperation( );
        stopThread(hThread, threadID);
        return S_OK;
    }

private:
    int showcmd_;

    void startThread(HANDLE& hThread, unsigned int& threadID) {
        hThread = (HANDLE)::_beginthreadex(NULL, 0, threadFunc, (LPVOID)this, 0, &threadID);
    }

    void stopThread(HANDLE hThread, DWORD threadID) {
        do {
            ::PostThreadMessage(threadID, WM_QUIT, NULL, NULL);
        } while(::WaitForSingleObject(hThread, 500) == WAIT_TIMEOUT);
    }

    static unsigned int __stdcall threadFunc(LPVOID param) {
        ::CoInitialize(NULL);
        CMyAppModule* this_ = (CMyAppModule*)param;
        return this_->CAtlExeModuleT<CMyAppModule>::Run(this_->showcmd_);
    }

    void doMyOperation( ) {
        // ここに必要な処理を実装します。
	// このメソッドが終了すると，アプリケーションも停止します。
    }
};

CMyAppModule _AtlModule;


extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, 
                                LPTSTR /*lpCmdLine*/, int nShowCmd)
{
    return _AtlModule.WinMain(nShowCmd);
}</pre>
<a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/111336042.html">
<link>http://myprivateadversaria.seesaa.net/article/111336042.html</link>
<title>.Net言語(C#,VB.Net)でCOMを実装する</title>
<description>もしかしたら常識なのかも知れないけれど…(^^;あまり雑誌などでも紹介されていないと思うのですが，.Net言語でも簡単に COM を実装することができます。知らなかった…自分のために(^^)手順をメモ。なお，ここで紹介する操作は，VS2005で行ったものです。1. プロジェクト生成ウィザードでは「クラスライブラリ」を選択。2. クラスの実装は次のようにします。これは C# の場合ですが，VB.Netでもほとんど同じです。(1) System.Runtime.InteropSe...</description>
<dc:subject>.Net プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-12-16T23:40:10+09:00</dc:date>
<content:encoded><![CDATA[
もしかしたら常識なのかも知れないけれど…(^^;<br /><br />あまり雑誌などでも紹介されていないと思うのですが，.Net言語でも簡単に COM を実装することができます。知らなかった…<br /><br />自分のために(^^)手順をメモ。なお，ここで紹介する操作は，VS2005で行ったものです。<br /><br />1. プロジェクト生成ウィザードでは「クラスライブラリ」を選択。<br /><br />2. クラスの実装は次のようにします。これは C# の場合ですが，VB.Netでもほとんど同じです。<br /><br />(1) System.Runtime.InteropServices をインポート。<br />(2) インターフェースを明示的に定義。従ってインターフェースとそれを実装するクラスの２つを記述します。<br />(3) クラスには ClassInterfaceAttribute で ClassInterface.None を指定して，外部へ公開しないようにしておきます。<br /><br />例として作成したコードはこんな感じ。<br /><br /><pre>using System;<br />using System.Runtime.InteropServices;<br />using System.Windows.Forms;<br /><br />namespace ScriptLib {<br /><br />    public interface CsInterface {<br />        void Message(string msg);<br />    }<br /><br />    [ClassInterface(ClassInterfaceType.None)]<br />    public class CsClass : CsInterface {<br />        public void Message(string msg) {<br />            MessageBox.Show(msg, "C# COM");<br />        }<br />    }<br />}</pre><br />3. プロジェクトのプロパティから「アプリケーション」タブの[アセンブリ情報]を開きます。<br /><br />4.「アセンブリをCOM公開可能にする」チェックボックスをONにします。ここが重要。<br /><br /><a href="http://myprivateadversaria.up.seesaa.net/css/memo2.gif" target="_blank"><img src="http://myprivateadversaria.up.seesaa.net/css/memo2-thumbnail2.gif" width="150" height="138" border="0" align="" alt="memo2.gif" onclick="location.href = 'http://myprivateadversaria.seesaa.net/upload/detail/css/memo2-thumbnail2.gif.html'; return false;" style="cursor:pointer;" /></a><br /><br />5. プロパティ「ビルドイベント」タブの[ビルド後に実行するコマンドライン]に次のコマンドを定義します。<br /><br /><pre>regasm $(TargetFileName) /tlb:$(TargetName).tlb /codebase</pre><br />6. ビルドすれば出来上がり!!<br /><br />ATLよりずっと簡単で，以外と使えそうです。<a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://match.seesaa.jp/ot_listing.pl?aid=640816&amp;sid=myprivateadversaria&amp;tid=seesaa_hotspot&amp;k=%E7%99%BA%E7%86%B1%E6%82%A3%E8%80%85&amp;hid=35">
<link>http://match.seesaa.jp/ot_listing.pl?aid=640816&amp;sid=myprivateadversaria&amp;tid=seesaa_hotspot&amp;k=%E7%99%BA%E7%86%B1%E6%82%A3%E8%80%85&amp;hid=35</link>
<title>[PR]注目のキーワード「発熱患者」</title>
<description><![CDATA[
<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E5%8C%BB%E7%99%82%E6%A9%9F%E9%96%A2&hid=35">医療機関</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E8%A8%BA%E5%AF%9F%E6%8B%92%E5%90%A6&hid=35">診察拒否</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E5%8F%97%E8%A8%BA&hid=35">受診</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E6%96%B0%E5%9E%8B%E3%82%A4%E3%83%B3%E3%83%95%E3%83%AB%E3%82%A8%E3%83%B3%E3%82%B6&hid=35">新型インフルエンザ</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E7%99%BA%E7%86%B1%E5%A4%96%E6%9D%A5&hid=35">発熱外来</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E8%A8%BA%E5%AF%9F&hid=35">診察</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E6%82%A3%E8%80%85&hid=35">患者</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E3%82%B1%E3%83%BC%E3%82%B9&hid=35">ケース</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E6%8B%92%E5%90%A6&hid=35">拒否</a>&nbsp;|&nbsp;<a href="http://match.seesaa.jp/ot_listing.pl?aid=640816&sid=myprivateadversaria&tid=seesaa_hotspot&k=%E7%99%BA%E7%86%B1%E7%9B%B8%E8%AB%87%E3%82%BB%E3%83%B3%E3%82%BF%E3%83%BC&hid=35">発熱相談センター</a>
]]></description>
<dc:date>2008-12-16T23:40:10+09:00</dc:date>
<dc:creator>ads by Seesaa</dc:creator>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/111123915.html">
<link>http://myprivateadversaria.seesaa.net/article/111123915.html</link>
<title>Shell Extension を使って Explorer にコンテキストメニューを追加する</title>
<description>ShellExtension の定義方法の覚書き，その２(^^;今度はExplorerのコンテキストメニューを追加します。ここで扱う「コンテキストメニュー」は，ExplorerでファイルをDrag&amp;Dropしたときに表示される，「ここにコピー」などが入っているものです。次のようなCOM実装を行うと，Drag&amp;Dropされたファイル名を取得して処理を行うことができるようになります。1. Wizard を使って，IDL に実装クラスを定義する。import "oaidl.idl"...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-12-12T21:56:17+09:00</dc:date>
<content:encoded><![CDATA[
ShellExtension の定義方法の覚書き，その２(^^;<br/>
今度はExplorerのコンテキストメニューを追加します。<br/>
<br/>
ここで扱う「コンテキストメニュー」は，ExplorerでファイルをDrag&Dropしたときに表示される，「ここにコピー」などが入っているものです。<br/>
<br/>
次のようなCOM実装を行うと，Drag&Dropされたファイル名を取得して処理を行うことができるようになります。<br/>
<br/>
1. Wizard を使って，IDL に実装クラスを定義する。<br/>
<br/><pre>
import "oaidl.idl";
import "ocidl.idl";

[
    object,
    uuid(70C82BD2-E659-41A4-AAE8-27DC030F82BA),
    helpstring("IMyCtxExt インターフェイス"),
    pointer_default(unique)
]
interface IMyCtxExt : IUnknown{
};
...................................................
[
    uuid(7A7CEC4E-FD39-4983-9A3F-C791214721BC),
    version(1.0),
    helpstring("CtxExtTest 1.0 タイプ ライブラリ")
]
library HardLinkColumnLib
{
    importlib("stdole2.tlb");
    [
        uuid(D2E45164-9547-4356-8513-937EAF39421D),
        helpstring("MyCtxExt Class")
    ]
    coclass MyCtxExt
    {
        [default] interface IMyCtxExt;
    };
    ....................................................
};</pre><br/>
<br/>
2. IShellExtInit, IContextMenu を継承(実装)する COM クラスを定義する。<br/>
<br/><pre>
class ATL_NO_VTABLE CMyCtxExt :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyCtxExt, &CLSID_MyCtxExt>,
    public IShellExtInit,
    public IContextMenu
{
    std::vector<tstring> selectedFiles;    // 選択されたファイルを保存
    ................................................

    // IShellExtInit
    STDMETHODIMP Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY);

    // IContextMenu
    STDMETHODIMP GetCommandString(UINT, UINT, UINT*, LPSTR, UINT) {
        return E_NOTIMPL; }    // 今回は使用していない
    STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO);
    STDMETHODIMP QueryContextMenu(HMENU, UINT, UINT, UINT, UINT);
};</pre><br/>
<br/>
3. Initialize メソッドでは，処理対象として選択されたファイル一覧を取得。<br/>
<br/><pre>
//    Initialize
//        選択されたファイルのリストを取得する

HRESULT
CMyCtxExt::Initialize(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pDataObj, HKEY hProgID)
{
    // パラメータとして与えられたDataObjectから，Dropファイル情報を取得する
    FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
    STGMEDIUM stg = { TYMED_HGLOBAL };
    if(FAILED(pDataObj->GetData(&fmt, &stg)))
        return E_INVALIDARG;
    HDROP hdrop = (HDROP)::GlobalLock(stg.hGlobal);
    if(hdrop == NULL)
        return E_INVALIDARG;

    // 選択されたファイル一覧を取得し，インスタンスに保存する
    selectedFiles.clear();
    UINT uNumFiles = ::DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0);
    for(UINT uFile = 0; uFile < uNumFiles; ++uFile) {
        TCHAR szFile[MAX_PATH];
        if(!DragQueryFile(hdrop, uFile, szFile, MAX_PATH))
            continue;
        selectedFiles.push_back(tstring(szFile));
    }レジストリへの登録は，次のスクリプトで。

    // パラメータ情報を開放し，処理結果を返す
    // 対象ファイルが１つ以上あれば OK
    ::GlobalUnlock(stg.hGlobal);
    return selectedFiles.size() > 0 ? S_OK : E_FAIL;
}</pre><br/>
<br/>
4. QueryContextMenu では，表示するメニューの追加を行う<br/>
<br/><pre>
//    QueryContextMenu
//        コンテキストメニューを設定する

HRESULT
CLinkCtxExt::QueryContextMenu(HMENU hmenu, UINT uMenuIndex, UINT uidFirstCmd, 
                              UINT uidLastCmd, UINT uFlags)
{
    // デフォルトメニュー表示が指示されている場合は何もしない
    if(uFlags & CMF_DEFAULTONLY)
        return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);

    // コンテキストメニューに自身のメニューを追加する
    ::InsertMenu(hmenu, uMenuIndex, MF_STRING|MF_BYPOSITION, uidFirstCmd, "My Context Menu");
    return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 1);
}</pre><br/>
<br/>
5. InvokeCommand に実施に行う処理を記述する。対象となるファイルリストは，Initialize で取得しておいたもの。<br/>
<br/>
6. レジストリへの登録は，次のスクリプトで。<br/>
<br/><pre>
HKCR
{
    NoRemove CLSID
    {
        ForceRemove {D2E45164-9547-4356-8513-937EAF39421D} = s 'MyCtx Extension Class'
        {
            InprocServer32 = s '%MODULE%'
            {
                val ThreadingModel = s 'Apartment'
            }
        }
    }
    NoRemove *
    {
        NoRemove shellex
        {
            NoRemove ContextMenuHandlers
            {
                ForceRemove MyCtxExt = s '{D2E45164-9547-4356-8513-937EAF39421D}'
            }
        }
    }
    NoRemove Directory
    {
        NoRemove shellex
        {
            NoRemove ContextMenuHandlers
            {
                ForceRemove MyCtxExt = s '{D2E45164-9547-4356-8513-937EAF39421D}'
            }

        }
    }
    NoRemove Folder
    {
        NoRemove shellex
        {
            NoRemove ContextMenuHandlers
            {
                ForceRemove MyCtxExt = s '{D2E45164-9547-4356-8513-937EAF39421D}'
            }
        }
    }
}</pre><br/>

<a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/111029152.html">
<link>http://myprivateadversaria.seesaa.net/article/111029152.html</link>
<title>Shell Extension を使って Explorer に項目を追加する</title>
<description>ShellExtension の定義方法の覚書き。Explorer の「詳細」メニューで表示するカラムを追加することができます。1. Wizard を使って，IDL に実装クラスを定義する。// MyColumn.idl : MyColumn の IDL ソース//// このファイルは、タイプ ライブラリ (MyColumn.tlb) およびマーシャリング コードを// 作成するために MIDL ツールによって処理されます。import "oaidl.idl";import ...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-12-10T21:49:28+09:00</dc:date>
<content:encoded><![CDATA[
ShellExtension の定義方法の覚書き。<br/>
Explorer の「詳細」メニューで表示するカラムを追加することができます。<br/><br/>
1. Wizard を使って，IDL に実装クラスを定義する。<br/>
<pre>
// MyColumn.idl : MyColumn の IDL ソース
//

// このファイルは、タイプ ライブラリ (MyColumn.tlb) およびマーシャリング コードを
// 作成するために MIDL ツールによって処理されます。

import "oaidl.idl";
import "ocidl.idl";

[
	object,
	uuid(EEC69ED1-4D69-485B-8AF9-4A5EEEE0EFC8),
	helpstring("IMyColExt インターフェイス"),
	pointer_default(unique)
]
interface IMyColExt : IUnknown{
};
...................................................
[
	uuid(7A7CEC4E-FD39-4983-9A3F-C791214721BC),
	version(1.0),
	helpstring("ColExtTest 1.0 タイプ ライブラリ")
]
library HardLinkColumnLib
{
	importlib("stdole2.tlb");
	[
		uuid(5451F3B5-9CFB-4F66-9CEC-B4A596066670),
		helpstring("MyColExt Class")
	]
	coclass MyColExt
	{
		[default] interface IMyColExt;
	};
	....................................................
};</pre>
<br/>
2. IComPrivider を継承(実装)する COM クラスを定義する。<br/>
<pre>
class ATL_NO_VTABLE CMyColExt :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CMyColExt, &CLSID_MyColExt>,
	public IColumnProvider
{
	...................................
public:
	STDMETHODIMP Initialize(LPCSHCOLUMNINIT psci);
	STDMETHODIMP GetColumnInfo(DWORD dwIndex, SHCOLUMNINFO* psci);
	STDMETHODIMP GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, VARIANT* pvarData);
	...................................
};
</pre>
<br/>
3. IColumnProvider のメソッドを実装する。<br/><br/>
* 特に処理がなければ，Initialize は何もしなくてよい<br/>
<pre>
STDMETHODIMP
CMyColExt::Initialize(LPCSHCOLUMNINIT psci) {
    return S_OK;
}</pre>
<br/>
* GetColumnInfo では，カラム定義を設定して返す。<br/>
<pre>
STDMETHODIMP
CMyColExt::GetColumnInfo(DWORD dwIndex, SHCOLUMNINFO* psci) {
    if(dwIndex != 0) {
        return S_FALSE;
    }
    psci->scid.fmtid = CLSID_LinkColExt;
    psci->scid.pid   = 0;
    psci->vt         = VT_I4;				
    psci->fmt	     = LVCFMT_RIGHT;
    psci->csFlags    = SHCOLSTATE_TYPE_INT | SHCOLSTATE_SLOW;
    psci->cChars     = 10;

    ::wcsncpy_s(psci->wszTitle, OLESTR("MyColumn"));
    ::wcsncpy_s(psci->wszDescription, OLESTR("Length of File Name");

    return S_OK;
}</pre>
<br/>
* GetItemData で個別の値を取得して返す。<br/>
<pre>
STDMETHODIMP
CMyColExt::GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, VARIANT* pvarData) {
    if(pscid->fmtid != CLSID_LinkColExt || pscid->pid != 0) {
        return S_FALSE;
    }
    return CComVariant(::wcslen(pscd->wszFile).Detach(pvarData);
}</pre>
<br/>
4. レジストリへの登録は，次のスクリプトで。<br/>
<pre>
HKCR
{
    NoRemove CLSID
    {
        ForceRemove {5451F3B5-9CFB-4F66-9CEC-B4A596066670} = s 'MyCol Extension Class'
        {
            InprocServer32 = s '%MODULE%'
            {
                val ThreadingModel = s 'Apartment'
            }
        }
    }
    NoRemove Folder
    {
        NoRemove Shellex
        {
            NoRemove ColumnHandlers
            {
                ForceRemove {5451F3B5-9CFB-4F66-9CEC-B4A596066670} = s 'MyCol column ext'
            }
        }
    }
}
</pre><a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/110927181.html">
<link>http://myprivateadversaria.seesaa.net/article/110927181.html</link>
<title>JScriptオブジェクトをC++コードで生成する</title>
<description>JScript の任意のオブジェクトを C++(ATL)で生成する手順です。ActiveScript のセットアップ手順の説明は省略していますので，こちらの資料などを参照してください。オブジェクト生成には，ScriptHost COM インスタンスが必要です。スクリプトのセットアップ時に以下のような処理を実行しているので，ここで生成した IActiveScript へのポインタ(下記リストでは pAS)を参照できるようにしておきます。   LPOLESTR language ...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-12-09T00:13:41+09:00</dc:date>
<content:encoded><![CDATA[
JScript の任意のオブジェクトを C++(ATL)で生成する手順です。<br/>
ActiveScript のセットアップ手順の説明は省略していますので，<a href="http://msdn.microsoft.com/en-us/library/ccd0zt2w(VS.85).aspx" target="_blank">こちらの資料</a>などを参照してください。

<ol><li>オブジェクト生成には，ScriptHost COM インスタンスが必要です。スクリプトのセットアップ時に以下のような処理を実行しているので，ここで生成した IActiveScript へのポインタ(下記リストでは pAS)を参照できるようにしておきます。<br/>
<pre>   LPOLESTR language = OLESTR("JScript");
   CLSID CLSID_Script;
   ::CLSIDFromProgID(language, &CLSID_Script);

   CComPtr<IActiveScript> pAS;
   pAS.CoCreateInstance(CLSID_Script, 0, CLSCTX_INPROC_SERVER);
   ..........................</pre><br/></li>
<li>IActiveScript::GetScriptDispatch メソッドを使用してDispatchEx を取得します。ここで参照するオブジェクトが，JScript のルートオブジェクトに相当します。<br/>
<pre>   CComPtr<IDispatch> idisp;
   pAS->GetScriptDispatch(NULL, &idisp);
   CComQIPtr<IDispatchEx> jsroot(idisp);</pre></li>
<li>ルートオブジェクトを使用して，生成するオブジェクトの DispID を取得します。下記リストでは，JScript の Array オブジェクトのIDを取得しています。
<pre>   CComBSTR objectName("Array");
   DISPID objectID;
   jsroot->GetDispID(objectName, 0, &objectID));</pre><br/></li>
<li>オブジェクトのコンストラクタを呼び出して，インスタンスを生成します。生成したオブジェクトへの参照は，Variant 変数に IDispatch 型で格納されているので，これを IDispatchEx に QueryInterface して JScript に返してやれば，作業完了!!<br/>
<pre>   DISPPARAMS noargs = { NULL, NULL, 0, 0 };
   CComVariant var;
   jsroot->InvokeEx(objectID, LOCALE_USER_DEFAULT, DISPATCH_CONSTRUCT, &noargs, &var, NULL, NULL));
   return CComQIPtr<IDispatchEx>(var.pdispVal);</pre><br/></li>
</ol>
<br/>
この方法で，JScript組み込みオブジェクト，JScriptで記述したユーザ定義オブジェクトのいずれのインスタンスも生成することができます。<a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/105719865.html">
<link>http://myprivateadversaria.seesaa.net/article/105719865.html</link>
<title>Explorerの「詳細」表示に項目を追加する方法</title>
<description>以下のURLにサンプルが紹介されています：http://www.codeproject.com/KB/shell/shellextguide8.aspx詳しく調べたら，追記する予定。</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-08-30T09:05:25+09:00</dc:date>
<content:encoded><![CDATA[
以下のURLにサンプルが紹介されています：<br /><br />h<a href="http://www.codeproject.com/KB/shell/shellextguide8.aspx" target="_blank">ttp://www.codeproject.com/KB/shell/shellextguide8.aspx</a><br /><br />詳しく調べたら，追記する予定。<a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/97164572.html">
<link>http://myprivateadversaria.seesaa.net/article/97164572.html</link>
<title>NHibernate の設定(QuickStart)</title>
<description>最近になって“NHibernate ( Hibernate の .Net版)”というのがあるのを，初めて知りました。さっそく，QuickStart!!NHibernate を SourceForge からダウンロードする。この記事を書いている時点での最新バージョンは 1.2.1。VisualStudio 2005 でプロジェクトを作成する。ここではC#を選択。Hibernate アセンブリをプロジェクトに追加。ソリューションエクスプローラの「参照設定」を右クリック，メニューか...</description>
<dc:subject>.Net プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-05-18T19:31:31+09:00</dc:date>
<content:encoded><![CDATA[
最近になって“<a href="http://www.hibernate.org/343.html">NHibernate</a> ( Hibernate の .Net版)”というのがあるのを，初めて知りました。さっそく，QuickStart!!<br /><ol><br /><li>NHibernate を <a href="http://sourceforge.net/project/showfiles.php?group_id=73818&package_id=73969">SourceForge からダウンロード</a>する。この記事を書いている時点での最新バージョンは　1.2.1。</li><br /><li>VisualStudio 2005 でプロジェクトを作成する。ここではC#を選択。</li><br /><li>Hibernate アセンブリをプロジェクトに追加。ソリューションエクスプローラの「参照設定」を右クリック，メニューから「参照の追加」でアセンブリ NHibernate.dll を選択して追加する。VS2005 の場合はインストールディレクトリ下の bin/net-2.0 にあるものを使用。</li><br /><li>hibernate.cfg.xml という設定ファイルを新規作成し，コンフィギュレーションを記述。<br/><br />この例は MySQL を使用する場合。その他の例は，リファレンスマニュアルに詳しく記載している。リファレンスマニュアル(nhibernate_reference.pdf)は，インストールした場所の doc/ ディレクトリにある。<pre>&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />&lt;hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"&gt;<br />  &lt;!-- an ISessionFactory instance --&gt;<br />  &lt;session-factory&gt;<br />    &lt;property name="connection.provider"&gt;<br />      NHibernate.Connection.DriverConnectionProvider<br />    &lt;/property&gt;<br />    &lt;property name="connection.driver_class"&gt;<br />      NHibernate.Driver.MySqlDataDriver<br />    &lt;/property&gt;<br />    &lt;property name="connection.connection_string"&gt;<br />      Database=test;Data Source=localhost;User Id=TEST;Password=TEST<br />    &lt;/property&gt;<br />    &lt;property name="dialect"&gt;<br />      NHibernate.Dialect.MySQLDialect<br />    &lt;/property&gt;<br /><br />    &lt;mapping file="config/Project.hbm.xml"/&gt;<br /><br />  &lt;/session-factory&gt;<br />&lt;/hibernate-configuration&gt;</pre>これはlocalhost上のMySQLにあるtestデータベースへ，ユーザ名/パスワード=TEST/TESTで接続する例。</li><br /><li>設定ファイルの参照をプログラム記述する。ここではリファレンスマニュアルで紹介されている方法を参考に，簡単なヘルパクラスを作成してみる。<pre>using System;<br />using NHibernate;<br />using NHibernate.Cfg;<br />using log4net;<br /><br />namespace NHibernateTest {<br /><br />  public sealed class NHibernateHelper {<br />    private static readonly string configfile = "hibernate.cfg.xml";<br />    private static ISessionFactory sessionFactory;<br />    private static ISession currentSession = null;<br /><br />    static NHibernateHelper() {<br />      sessionFactory = <br />        new Configuration().Configure(configfile).BuildSessionFactory();<br />    }<br /><br />    public static ISession GetCurrentSession() {<br />      if(sessionFactory != null && currentSession == null) {<br />        currentSession = sessionFactory.OpenSession();<br />      }<br />      return currentSession;<br />    }<br /><br />    public static void CloseSession() {<br />      if(currentSession != null) {<br />        currentSession.Close();<br />        currentSession = null;<br />      }<br />    }<br />  }<br />}</pre></li><br /><li>永続化対象にするクラスは，基本的に普通の定義をすればよいが，少し制限もある。<br />  (1) デフォルトコンストラクタを持っていること<br />  (2) 各メンバはプロパティ(アクセサ)を定義し，かつそれがvirtualであること<br />簡単な定義をしてみる。<pre>namespace NHibernateTest {<br /><br />  public class Project {<br />    public virtual int Id {<br />      get { return  id; }<br />      set { id = value; }<br />    }<br />    private int id;<br /><br />    public virtual string Name {<br />      get { return  name; }<br />      set { name = value; }<br />    }<br />    private string name;<br />  }<br />}</pre></li><br /><li>永続化クラスに対応するテーブルも作る。<pre>CREATE TABLE PROJECTS (<br />  ID BIGINT PRIMARY KEY NOT NULL AUTO_INCREMENT,<br />  NAME VARCHAR(40)<br />);</pre></li><br /><li>.Netクラスとテーブルを対応付けるマップファイルを作成する。<br /><pre>&lt;?xml version="1.0" encoding="utf-8" ?&gt;<br />&lt;hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" <br />    namespace="HibTest1" assembly="HibTest1"&gt;<br />  &lt;class name="Project" table="Project"&gt;<br />    &lt;id name="Id" column="id" type="Int32"&gt;<br />      &lt;generator class="identity"/&gt;<br />    &lt;/id&gt;<br />    &lt;property name="Name"&gt;<br />      &lt;column name="NAME" length="40" /&gt;<br />    &lt;/property&gt;<br />  &lt;/class&gt;<br />&lt;/hibernate-mapping&gt;</pre></li><br /><li>アクセスはこんな感じで。<br /><pre>  ISession session = NHibernateHelper.GetCurrentSession();<br />  ITransaction tx = session.BeginTransaction();<br /><br />  Project project = new Project();<br />  project.Name = "test";<br />  session.Save(project);<br /><br />  tx.Commit();</pre>これを実行すると，レコードが１つできる(はず)。</li><br /><li>log4net の定義も必要<del>かもしれないので，</del>。アプリケーション側で定義する。必要ならNHibernateに関する定義も行う。<br/>設定の詳細は<a href="http://myprivateadversaria.seesaa.net/article/97055971.html" target="_blank">log4netの説明</a>を参考にしてください。</li><br /></ol><a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/97163694.html">
<link>http://myprivateadversaria.seesaa.net/article/97163694.html</link>
<title>Windows時間データの相互変換</title>
<description>Windowsでは，API/ライブラリによって時間を表現するデータ構造がまちまちで，とても不便です。そこで，おもに使用されている次の３種類のデータを相互変換する関数を作成しました。・time_t・FILETIME・SYSTEMTIME各データ形式によって精度・表現できる範囲が違っています。プログラムではオーバーフローなどのチェックは行っていませんので，その点は注意してください。//    time_t -&amp;gt; FILETIME 変換FILETIMEUnixTimeToFi...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-05-18T19:21:25+09:00</dc:date>
<content:encoded><![CDATA[
Windowsでは，API/ライブラリによって時間を表現するデータ構造がまちまちで，とても不便です。そこで，おもに使用されている次の３種類のデータを相互変換する関数を作成しました。<br /><br />・<strong>time_t</strong><br />・<strong>FILETIME</strong><br />・<strong>SYSTEMTIME</strong><br /><br />各データ形式によって精度・表現できる範囲が違っています。プログラムではオーバーフローなどのチェックは行っていませんので，その点は注意してください。<br /><br /><pre>//    time_t -> FILETIME 変換<br /><br />FILETIME<br />UnixTimeToFileTime(time_t t){<br />    FILETIME ft;<br />    LONGLONG ll = Int32x32To64(t, 10000000) + 116444736000000000;<br />    ft.dwLowDateTime = (DWORD)ll;<br />    ft.dwHighDateTime = (DWORD)(ll >> 32);<br />    return ft;<br />}<br /><br />//    time_t -> SYSTEMTIME 変換<br /><br />SYSTEMTIME<br />UnixTimeToSystemTime(time_t t){<br />    SYSTEMTIME st;<br />    FILETIME ft = UnixTimeToFileTime(t);<br />    ::FileTimeToSystemTime(&ft, &st);<br />    return st;<br />}<br /><br />//    FILETIME -> time_t 変換<br /><br />time_t<br />FileTimeToUnixTime(const FILETIME& ft){<br />    LONGLONG ll;<br />    ll = ((LONGLONG)ft.dwHighDateTime << 32) + ft.dwLowDateTime;<br />    return (time_t)((ll - 116444736000000000) / 10000000);<br />}<br /><br />//    SYSTEMTIME -> time_t 変換<br /><br />time_t<br />SystemTimeToUnixTime(const SYSTEMTIME& st){<br />    FILETIME ft;<br />    ::SystemTimeToFileTime(&st, &ft);<br />    return FileTimeToUnixTime(ft);<br />}</pre><a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/97144857.html">
<link>http://myprivateadversaria.seesaa.net/article/97144857.html</link>
<title>NUnit の設定(QuickStart)</title>
<description>ユニットテストフレームワークJUnitの.Net移植版 NUnit のQuickStartです。Nunit を公式サイトからダウンロードする。この記事を書いている時点では，最新バージョンは 2.4.7。対象となる .Net のバージョン(1.1 or 2.0)によってバイナリが違うので注意。VisualStudio2005 でプロジェクトを生成する。またはユニットテスト対象にするプロジェクトを開く。namespace UnitTest {  public class Prog...</description>
<dc:subject>.Net プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-05-18T16:00:33+09:00</dc:date>
<content:encoded><![CDATA[
ユニットテストフレームワークJUnitの.Net移植版 <strong>NUnit </strong>のQuickStartです。<br /><br /><ol><br /><li>Nunit を<a href="http://www.nunit.org/index.php?p=download">公式サイト</a>からダウンロードする。この記事を書いている時点では，最新バージョンは 2.4.7。対象となる .Net のバージョン(1.1 or 2.0)によってバイナリが違うので注意。<br /><li>VisualStudio2005 でプロジェクトを生成する。またはユニットテスト対象にするプロジェクトを開く。<br /><pre>namespace UnitTest {<br />  public class Program {<br />    static void Main(string[] args) {<br />      Console.WriteLine(new Program().sum(1, 10));<br />    }<br />    public int sum(int n1, int n2) {<br />      int sum = 0;<br />      for(int n = n1; n <= n2; ++n) {<br />        sum += n;<br />      }<br />      return sum;<br />    }<br />  }<br />}</pre><br /><li>プロジェクトの「参照の追加」→「参照」で Nunit インストールディレクトリのbin/下にある，次のアセンブリを指定して追加する。<br /><ul><li>nunit.core.dll<br /><li>nunit.fixtures.dll<br /><li>nunit.framework.dll</ul><br /><li>テストクラスを記述する。JUnitと違って，テストクラス・メソッドは Attribute で指定する。<table><tr><th align="left">[TestFixture]</th><td>テストクラス</td></tr><br /><tr><th align="left">[SetUp]</th><td>SetUpメソッド</td></tr><br /><tr><th align="left">[TearDown]</th><td>TearDownメソッド</td></tr><br /><tr><th align="left">[Test]</th><td>テストメソッド</td></tr><br /></table><br />テストメソッド内では Assert クラスの静的メソッドを使用する。<br /><pre>namespace UnitTest {<br /><br />  [TestFixture]<br />  public class Test {<br />    private Program prog = null;<br /><br />    [SetUp]<br />    public void setup() {<br />      prog = new Program();<br />    }<br /><br />    [Test]<br />    public void SubTest() {<br />      Assert.AreEqual(prog.sum(1, 2), 3);            <br />    }<br /><br />    [TearDown]<br />    public void tearDown() {<br />      prog = null;<br />    }<br />  }<br />}</pre><br /><li>プロジェクトをビルドする。<br /><li>UnitTestを実行する。ここでは NUnit GUI を使ってテストする。<br /><ul><br /><li>NUnit GUI を起動。<br /><li>File->Openメニューで，5.のビルド結果(exe, dll)ファイルを開く。ファイルが開くと，テストクラス／メソッドが認識され，ツリー表示される。<br /><li>テストを実施するクラス・メソッドなどをツリー上で選択し，Run を実行。<br /><li>テスト結果がグラフィカルに表示される。<br /></ul></ol><a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/97144026.html">
<link>http://myprivateadversaria.seesaa.net/article/97144026.html</link>
<title>ジュリアン通日(Julian date)を求めるC関数</title>
<description>必要に迫られて作った“ジュリアン通日(Julian date)”変換関数(Ｃ言語)です。long toJulianDate(int year, int month, int mday) {  int a = (14 - month) / 12;  int y = year + 4800 - a;  int m = month + 12 * a - 3;  return mday + y * 365 - 32045              + int((153 * m + 2...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-05-18T15:50:04+09:00</dc:date>
<content:encoded><![CDATA[
必要に迫られて作った“<strong>ジュリアン通日(Julian date)</strong>”変換関数(Ｃ言語)です。<br /><br /><pre>long toJulianDate(int year, int month, int mday) {<br />  int a = (14 - month) / 12;<br />  int y = year + 4800 - a;<br />  int m = month + 12 * a - 3;<br />  return mday + y * 365 - 32045<br />              + int((153 * m + 2) / 5)<br />              + int(y / 4) - int (y / 100) + int (y / 400);<br />}<br /><br />void toYMD(long jdate, int& year, int &month, int &mday) {<br />  int j = jdate + 32044;<br />  int g  = j / 146097;<br />  int dg = j % 146097;<br />  int c  = (dg / 36524 + 1) * 3 / 4;<br />  int dc = dg - c * 36524;<br />  int b  = dc / 1461;<br />  int db = dc % 1461;<br />  int a  = (db / 365 + 1) * 3 / 4;<br />  int da = db - a * 365;<br />  int y  = g * 400 + c * 100 + b * 4 + a;<br />  int m  = (da * 5 + 308) / 153 - 2;<br />  int d  = da - (m + 4) * 153 / 5 + 122;<br /><br />  year  = y - 4800 + (m + 2) / 12;<br />  month = (m + 2) % 12 + 1;<br />  mday  = d + 1;<br />}</pre><br />JulianDateの７の剰余から曜日も求められます。７で割った余りが０→月曜日，１→火曜日，…，６→日曜日，になります。<a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/97143821.html">
<link>http://myprivateadversaria.seesaa.net/article/97143821.html</link>
<title>JScript配列をCOM(C++)で参照する</title>
<description>ちょっとした経緯で，JScriptから呼び出されるCOMをC++で実装することになりました。そこでJScriptからCOMに対して，パラメータとして配列を渡す必要があったのですが，JScriptで扱う配列は，COMで通常扱うSafeArray配列ではないということをことを知りました。Webでいろいろ調べてみると，"length"と配列インデックス("0","1","2",...)をメソッドとして持つIDispatchインターフェースとして渡されているようです。このインターフェ...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-05-18T15:47:03+09:00</dc:date>
<content:encoded><![CDATA[
ちょっとした経緯で，JScriptから呼び出されるCOMをC++で実装することになりました。<br /><br />そこでJScriptからCOMに対して，パラメータとして配列を渡す必要があったのですが，JScriptで扱う配列は，COMで通常扱う<strong>SafeArray</strong>配列ではないということをことを知りました。Webでいろいろ調べてみると，"length"と配列インデックス("0","1","2",...)をメソッドとして持つ<strong>IDispatch</strong>インターフェースとして渡されているようです。<br /><br />このインターフェース(JScript配列)を，COM内部で取り扱う形式に変換する処理を作成してみましたので，紹介します。なお，今回扱っているのは旧版のJScriptで，.Net 言語になった新しいもの(JScript.Net)には当てはまりませんので，その点了承下さい。<br /><br />最初に<strong>IDispatch</strong>インターフェースを介して"name"で指定したプロパティ値を取得するメソッドを用意します。<br /><pre><br />CComVariant JsArray::GetIDispatchProperty(IDispatch* iDisp, <br />                                          const char* name) {<br />  HRESULT hr;<br /><br />  DISPID dispid = 0;<br />  OLECHAR FAR* szMember = CA2W(name);<br />  hr = iDisp->GetIDsOfNames(IID_NULL, &szMember, 1,<br />                            LOCALE_SYSTEM_DEFAULT, &dispid);<br />  if(FAILED(hr)) {<br />    throw exception("IDispatch::GetIDsOfNames");<br />  }<br /><br />  DISPPARAMS params = { NULL, NULL, 0, 0 };<br />  VARIANT  var;<br />  EXCEPINFO excepinfo;<br />  UINT nArgErr;<br />  hr = iDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, <br />                     DISPATCH_PROPERTYGET, &params, &var,<br />                     &excepinfo, &nArgErr);<br />  if(FAILED(hr)) {<br />    throw exception("IDispatch::Invoke");<br />  }<br /><br />  return CComVariant(var);<br />}</pre>このメソッドを使って，JScript配列の要素数を取得します。<br />要素数は，プロパティ"length"から取り出せる整数値(VT_I4)です。<br /><pre><br />int JsArray::GetJScriptArrayLength(IDispatch* iDispatch) {<br />  CComVariant length = GetIDispatchProperty(iDispatch, "length");<br />  HRESULT hr = length.ChangeType(VT_I4);<br />  if(FAILED(hr)) {<br />    throw exception("CComVariant::ChangeType(VT_I4)");<br />  }<br />  return length.intVal;<br />}</pre>要素数を参照して，配列の内容を取得するメソッドを作成します。<br /><br />配列値はVariantで格納されているので，CComVariant配列(Vector)として取得しています。<br /><pre><br />vector<CComVariant> JsArray::GetJScriptArrayValues(IDispatch* iDispatch) {<br />  int length = GetJScriptArrayLength(iDispatch);<br />  std::vector<CComVariant> result(length);<br />  for(int n = 0; n < length; ++n) {<br />    char str[10];<br />    ::sprintf(str, "%d", n);<br />    result[n] = GetIDispatchProperty(iDispatch, str);<br />  }<br />  return result;<br />}</pre>後は取得したVariant配列の各要素を，所定の型の値として参照すればＯＫです。<a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
<item rdf:about="http://myprivateadversaria.seesaa.net/article/97143512.html">
<link>http://myprivateadversaria.seesaa.net/article/97143512.html</link>
<title>C++でVARIANT配列を扱う</title>
<description>COMで使用するVARIANT配列を生成するコンパクトな実装コードです。ATL使用が前提で，１次元のみ対応しています。template static HRESULT createVariantArray(T* value, int count, VARIANT*&amp; retval) {    SAFEARRAYBOUND sab = { count, 0 };   // 0 ~ count-1    CComSafeArray sarray(sab);    for(int n...</description>
<dc:subject>C++/COM プログラミング TIPS</dc:subject>
<dc:creator>yoshi</dc:creator>
<dc:date>2008-05-18T15:42:43+09:00</dc:date>
<content:encoded><![CDATA[
COMで使用するVARIANT配列を生成するコンパクトな実装コードです。<br />ATL使用が前提で，１次元のみ対応しています。<br /><pre>template <class T><br />static HRESULT createVariantArray(T* value, int count, VARIANT*& retval) <br />{<br />    SAFEARRAYBOUND sab = { count, 0 };   // 0 ～ count-1<br />    CComSafeArray<T> sarray(sab);<br />    for(int n = 0; n < count; ++n) {<br />        sarray.Add(*value++);<br />    }<br />    return CComVariant(sarray).Detach(retval);<br />}<br /></pre><a name="more"></a>

]]><![CDATA[
]]></content:encoded>
</item>
</rdf:RDF>
