LoginSignup
2
1

More than 5 years have passed since last update.

Visual Studio 2017 Visual C++ による ATL デスクトップアプリの作成

Posted at

はじめに

ATL を使ってもデスクトップアプリを作成できます。本来は COM サーバを作成するための機能ですが、COM インターフェースを実装しなければ、普通のデスクトップアプリになります。

プロジェクトの作成

「新しいプロジェクト」ダイアログで「ATL プロジェクト」を選び OK ボタンをクリックします。

VCProj_ATLServer.png
Fig.1 新しいプロジェクト

Fig.2 のようなダイアログが開くので、「アプリケーションの種類」を「実行可能ファイル (.exe)」を選んで OK ボタンをクリックします。

ソリューションエクスプローラに新しいプロジェクトが追加されます。

VCProj_ATLServer2.png
Fig.2 ATL プロジェクト

画面の作成

プロジェクトを選択して、コンテキストメニュー「追加」/「新しい項目」を実行する。ATL の項目から「ATL ダイアログ」を選択して「追加」ボタンをクリックします。

ATLServer2_Dialog.png
Fig.3 新しい項目の追加

Fig.4 のようなダイアログが開くので、「短い名前」を入力します。これはダイアログのクラス名やファイル名の元になります。

ATLServer2_Dialog2.png
Fig.4 名前の設定

プロジェクトのリソースビューで、ツリーを展開して Dialog の中の "IDD_..." をダブルクリックしてダイアログのデザイン画面を開きます。

ここで、必要なコントロールをダイアログに貼り付けてデザインを行います。

ATLServer2_Dialog3.png
Fig.5 ダイアログのデザイン

Visual Studio のバグ(?) 対応

ビルドを行うと、次のようなエラーが発生することがあるが、これは Visual Studio のバグでリソースファイル名に余分な空白が含まれているためである。

RC2135 file not found: xxxxxx.tlb

リソースファイルをコードで開き、エラーメッセージの xxxxxx (ファイル名の拡張子を除いた部分) を検索して、余分な空白を手動で削除します。それから、ビルドしなおし、エラーが消えることを確認します。

実行するとダイアログの OK ボタンとキャンセルボタンをクリックするとエラーが発生します。これは、このダイアログがモーダルでないにも関わらず、モーダルダイアログとして閉じるようになっているためです。

ダイアログのヘッダーファイル (この例では Server2Dlg.h) を開いて、コードの最後の方にある OK ボタンとキャンセルボタンのハンドラを修正します。これは "EndDialog(wID)" をコメントアウトし、代わりに "DestroyWindow()"を追加します。

_tWinMain へのコード追加

デフォルトだと、ダイアログを作成して表示するコードがないので、これを追加しないと何も表示されません。次のコードは、ATLServer2.cpp のコード例です。

// ATLServer2.cpp : WinMain の実装

#include "stdafx.h"
#include "resource.h"
#include "ATLServer2_i.h"
#include "Server2Dlg.h"  // 追加

using namespace ATL;

class CATLServer2Module : public ATL::CAtlExeModuleT< CATLServer2Module >
{
public :
    DECLARE_LIBID(LIBID_ATLServer2Lib)
    DECLARE_REGISTRY_APPID_RESOURCEID(IDR_ATLSERVER2, "{b0f20685-a805-41b9-b28b-ab076b2375d6}")
};

CATLServer2Module _AtlModule;

//  Window メイン
extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/,
                                LPTSTR /*lpCmdLine*/, int nShowCmd)
{
    // ダイアログを表示するためのコード
    MSG msg;
    CServer2Dlg dlg;
    dlg.Create(NULL);
    dlg.ShowWindow(nShowCmd);

    while (GetMessage(&msg, 0, 0, 0))
        DispatchMessage(&msg);
    // ここまで
    return _AtlModule.WinMain(nShowCmd);
}

次の画像は、このサンプルプログラムの実行例です。コントロールは Static (Label 相当) だけ貼り付けてあります。

AxServer1.png
Fig.6 このサンプルの実行例

COM インターフェースの実装

COM インターフェースを実装すれば、COM サーバとして動作するはずです。

ソリューションエクスプローラでこのプロジェクトを選択し、コンテキストメニューの「追加」から「新しい項目の追加」ダイアログを開き、 「ATL シンプルオブジェクト」を選んで「追加」ボタンをクリックします。

ATLServer2_SimpleObject.png
Fig.7 新しい項目の追加

COM DLL の場合と同じ要領で、プロパティやメソッドを実装します。コード編集が終わったら、ビルドを行います。エラーがなくなったらできあがった exe ファイルと tlb ファイルを適切なフォルダへコピーして、レジストリに登録します。

レジストリ登録は regsvr32 でなく、自分自身で行います。コマンドプロンプトを管理者モードで起動し、スイッチ /RegServer を付けて実行することで登録が行われます。下に例を示します。

C:> AxServer1.exe /RegServer

(参考) /UnRegServer を付けて実行すると登録が解除されます。

実際に COM インターフェースを実装して、テストしてみたところ起動が非常に遅かったです。メソッドの呼び出しもうまくいきませんでした。もしかしたら、COM DLL の場合と異なりマーシャリングを手動で行わないといけないのかもしれません。(別プロセスのため)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1