コントロールパネルのアーキテクチャ概要
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
また、プロジェクトのプロパティ設定において、カスタム変数 CPL を 1 として定義します。C/C++ 設定では、エクスポートマクロ定義(例:-DSysConfigCpl_EXPORTS)を追加し、DLL エントリーポイントを DllMain に設定します。インクルードパスには、プラットフォーム SDK のパス($( _PROJECTROOT )/cesysgen/oak/inc)が含まれていることを確認してください。
5. ビルドと検証
アプリケーション本体および CPL モジュールの両方をビルドします。WinCE 環境では、ビルド完了後に自動的に Makeimg 処理が実行され、システムイメージが生成されます。このイメージをデバイスにダウンロードして起動すると、コントロールパネル内に新規項目が表示され、経由してアプリケーションを起動できるようになります。