Windows CE コントロールパネルへのカスタムアプリケーション統合方法

コントロールパネルのアーキテクチャ概要

Windows CE システムにおけるコントロールパネルは、デスクトップ版 Windows と同様の仕組みを採用しており、システム設定やユーティリティへの統一されたアクセス窓口を提供します。この機能は Ctlpnl.exe および Control.exe によって管理されており、個々の項目は .cpl 拡張子を持つファイルとして実装されます。

内部的には、これらの .cpl ファイルはダイナミックリンクライブラリ(DLL)として動作します。コントロールパネルは特定のエクスポート関数を呼び出すことで、各アプリケーションとの連携を行います。主要なインターフェースとなるのが CPlApplet 関数であり、これはコントロールパネルからの各種メッセージを処理するエントリーポイントです。

メッセージ処理フロー

CPlApplet 関数は、コントロールパネルインフラストラクチャから送信されるメッセージに基づいて動作します。主な処理フローは以下の通りです。

  • CPL_INIT: モジュール読み込み時の初期化処理。メモリ確保などを行い、成功すれば 1 を返します。
  • CPL_GETCOUNT: この CPL ファイルが提供する項目の数を返却します。
  • CPL_NEWINQUIRE: 各項目の詳細情報(名前、アイコン、説明)を NEWCPLINFO 構造体を通じて設定します。
  • CPL_DBLCLK: ユーザーが項目をダブルクリックした際に発生し、実際のアプリケーションを起動します。
  • CPL_STOP / CPL_EXIT: アプリケーション終了時のクリーンアップ処理を行います。

項目情報の定義には NEWCPLINFO 構造体が使用されます。この構造体には、表示名、説明テキスト、アイコンハンドル、およびアプリケーション固有のデータなどを格納するメンバーが含まれています。

実装手順

独自のアプリケーションをコントロールパネルに登録するには、以下の手順でプロジェクトを構成します。

1. アプリケーション本体の作成

まず、コントロールパネルから起動される実行ファイルを作成します。WinCE プロジェクト wizard を使用し、標準的なアプリケーション(例:DemoApp.exe)として構築します。

2. CPL モジュールプロジェクトの作成

次に、コントロールパネル項目として機能する DLL プロジェクトを作成します。プロジェクトタイプとして WCE Dynamic-Link Library を選択し、シンボルをエクスポートする設定にします。プロジェクト名は例えば SysConfigCpl とします。

3. エントリポイントの実装

DLL プロジェクト内に CPlApplet 関数を実装します。以下に、コントロールパネル項目を追加するためのコード実装例を示します。この例では、アイコンや文字列リソースを読み込み、ダブルクリック時に特定の exe を起動する logic を含んでいます。

#include <tchar.h>
#include <windows.h>
#include "cpl.h"

// マクロ定義:配列要素数の取得
#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))

static HMODULE s_hInstance = NULL;

// DLL エントリーポイント
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved)
{
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
        s_hInstance = hInst;
        break;
    case DLL_PROCESS_DETACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

// コントロールパネル アプリレット エントリーポイント
extern "C" __declspec(dllexport) LONG CALLBACK CPlApplet(
    HWND hwndCPL,
    UINT uMsg,
    LPARAM lParam1,
    LPARAM lParam2)
{
    switch (uMsg)
    {
    case CPL_INIT:
        // 初期化処理。失敗場合は 0 を返す
        return 1;

    case CPL_GETCOUNT:
        // 提供する項目の数
        return 1;

    case CPL_NEWINQUIRE:
    {
        // 項目情報の設定
        LPCPLINFO lpInfo = (LPCPLINFO)lParam2;
        if (!lpInfo) return 1;

        lpInfo->dwSize = sizeof(CPLINFO);
        lpInfo->dwFlags = 0;
        lpInfo->dwHelpContext = 0;
        lpInfo->lData = 0;

        // アイコンリソースの読み込み
        lpInfo->hIcon = LoadIcon(s_hInstance, MAKEINTRESOURCE(IDR_MAIN_ICON));

        // 表示名と説明の読み込み
        LoadString(s_hInstance, IDS_CPL_NAME, lpInfo->szName, ARRAY_LEN(lpInfo->szName));
        LoadString(s_hInstance, IDS_CPL_DESC, lpInfo->szInfo, ARRAY_LEN(lpInfo->szInfo));
        
        return 0;
    }

    case CPL_DBLCLK:
    {
        // アプリケーション起動処理
        PROCESS_INFORMATION pi = {0};
        BOOL bResult = CreateProcess(
            _T("\\Windows\\DemoApp.exe"),
            NULL, NULL, NULL,
            FALSE, 0, NULL, NULL,
            NULL, &pi
        );

        if (bResult)
        {
            CloseHandle(pi.hThread);
            CloseHandle(pi.hProcess);
            return 0;
        }
        return 1;
    }

    case CPL_STOP:
    case CPL_EXIT:
        // リソース解放処理
        return 0;

    default:
        return 0;
    }
}

上記コードでは、リソースファイル(.rc)で定義されたアイコン(IDR_MAIN_ICON)および文字列(IDS_CPL_NAME, IDS_CPL_DESC)を参照しています。これらをプロジェクトに適切に追加する必要があります。

4. プロジェクト設定の構成

システムイメージに CPL ファイルを正しく配置するため、BIB ファイル(例:SysConfigCpl.bib)に以下の記述を追加します。

MODULES
    SysConfigCpl.cpl $( _FLATRELEASEDIR )/SysConfigCpl.cpl NK

また、プロジェクトのプロパティ設定において、カスタム変数 CPL1 として定義します。C/C++ 設定では、エクスポートマクロ定義(例:-DSysConfigCpl_EXPORTS)を追加し、DLL エントリーポイントを DllMain に設定します。インクルードパスには、プラットフォーム SDK のパス($( _PROJECTROOT )/cesysgen/oak/inc)が含まれていることを確認してください。

5. ビルドと検証

アプリケーション本体および CPL モジュールの両方をビルドします。WinCE 環境では、ビルド完了後に自動的に Makeimg 処理が実行され、システムイメージが生成されます。このイメージをデバイスにダウンロードして起動すると、コントロールパネル内に新規項目が表示され、経由してアプリケーションを起動できるようになります。

タグ: Windows CE CPL Embedded C++ System Integration WinCE OS

7月27日 19:00 投稿