CTRLTEST サンプル : カスタム コントロールの実装
更新 : 2007 年 11 月
CTRLTEST サンプルでは、カスタム コントロールを実装して使用するための手法を示します。
ライブラリ コントロール クラスから機能を継承している特殊なエディット コントロールである CParsedEdit の実装、およびカスタム コントロールの 3 つの使用方法。
スピン コントロールの使い方。スピン コントロールには、値を増減するための小さな上向きの矢印ボタンと下向きの矢印ボタンがあります。
CBitmapButton を使用した、[Custom] メニューのコマンドのビットマップ ボタンの実装。
メニューやリスト ボックスのオーナー (親ウィンドウ) 描画。CMenu クラスや CListBox クラスから派生した対応するコントロール クラスには、この機能がオブジェクト指向で用意されています。
Microsoft Visual C++ リソース エディタで保持できないリソース ファイルの使用。ここでは、ダイアログ ボックスで .rc2 ファイルを使用する場合の長所と短所を示します。このダイアログ ボックスには、ヘッダー ファイルで定義されたスタイルを持つカスタム コントロールがあります。
CTRLTEST のすべての例は、メニュー コマンドで開始します。
セキュリティに関するメモ : |
---|
このサンプル コードは概念を示す目的で提供されているものです。必ずしも最も安全なコーディング手法に従っているわけではないので、アプリケーションまたは Web サイトでは使用しないでください。Microsoft は、サンプル コードが意図しない目的で使用された場合に、付随的または間接的な損害について責任を負いません。 |
サンプルとそのインストール手順を取得するには
Visual Studio で、[ヘルプ] メニューの [サンプル] をクリックします。
詳細については、「サンプル ファイルの格納場所」を参照してください。
使用できるサンプルの最新バージョンと完全な一覧については、オンラインの Visual Studio 2008 Samples のページを参照してください。
サンプルは、コンピュータのハード ディスク上にもあります。既定では、サンプルおよび Readme ファイルは、\Program Files\Visual Studio 9.0\Samples\ の下のフォルダにコピーされます。Visual Studio Express Edition の場合、すべてのサンプルはオンライン上にあります。
サンプルのビルドと実行
CTRLTEST サンプルをビルドおよび実行するには
ソリューション Ctrltest.sln を開きます。
[ビルド] メニューの [ビルド] をクリックします。
[デバッグ] メニューの [デバッグなしで開始] をクリックします。
例 : カスタム コントロールの実装と使用
カスタム コントロールは、CWnd から派生して実装できますが、ライブラリのコントロール クラスから派生して標準 Windows のコントロールの機能を利用した方がはるかに簡単です。CTRLTEST は、この方法で、特殊なエディット コントロールである CParsedEdit を実装します。このエディット コントロールは、ユーザー入力として指定された文字のセット (英字、数字、または非制御文字) だけを受け付けます。CParsedEdit は CEdit の派生クラスです。このクラスには、文字のフィルタ処理を行う OnChar メッセージ ハンドラがあります。
[Simple] メニューのコマンドの実装では、カスタム コントロールの 3 つ使用方法を示しています。これらは、アプリケーションがダイアログ ボックスのコントロールのインスタンスを CParsedEdit クラスに関連付ける方法によって異なります。[Simple] メニューの各コマンドを使用すると、CParsedEdit コントロールの 4 つのインスタンスを持つダイアログ ボックスが表示されます。このダイアログ ボックスに入力されたデータは、TRACE 出力としてデバッグ ポートに送信されます。[Simple] メニューの 3 つのコマンドは次のとおりです。
Test C++ Deribed class
CParsedEdit コントロールは、ダイアログ クラスのデータ メンバです。CParsedEdit::CreateSet を呼び出すと、このコントロールをダイアログの OnInitDialog 関数で明示的に作成できます。Dertest.cpp を参照してください。
Test WNDCLASS Registered
CParsedEdit コントロールは、ダイアログ テンプレート リソース (IDD_WNDCLASS_EDIT) に、"paredit" という WNDCLASS を持つカスタム コントロールとして配置されます。Visual C++ ダイアログ エディタでは、次のようなカスタム コントロールのプロパティを調べることができます。
Caption : 空白。CParsedEdit コントロールに表示される初期値です。
Class : paredit。WNDCLASS 名です。ダイアログが呼び出される前に CParsedEdit::RegisterControlClass によって PAREDIT2.CPP に登録されます。
Visible : True。コントロールが表示されます。
Tabstop : True。ユーザーは、タブ キーでこのコントロールを選択できます。
スタイル : 0x5081002、0x5081001、0x5081003、0x5081ffff (4 つの解析済みエディット コントロールについて)。スタイル 0x500000 は WS_CHILD と WS_VISIBLE を表します。0x1000 は WS_TABSTOP を表します。すべてのカスタム コントロールには WS_CHILD スタイルがあります。WS_VISIBLE スタイルと WS_TABSTOP スタイルは、[Visible] と [Tabstop] をオンにすると、ダイアログ エディタによって自動的に設定されます。0x80000 は WS_BORDER に対応します。カスタム コントロールのダイアログ エディタ プロパティ ページによって、WS_BORDER などのすべてのウィンドウ スタイルが提供されるため、\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\WINUSER.H の定数を調べる必要があります。0x0001、0x0002、0x0004、0x0ffff の各スタイルは、PAREDIT.H でそれぞれ PES_NUMBERS、PES_LETTERS、PER_OTHERCHARS、および PES_ALL と定義されています。
カスタム コントロール プロパティ ページの 16 進数スタイルは、そのままでは理解されません。PES_NUMBERS や PES_LETTERS などのシンボリック スタイルを使用する必要がある場合は、RES\Ctrltest.rc2 などのリソース ファイルを手動で編集できます。このファイルは、コンパイル時にリソース コンパイラによってインクルードされますが、Visual C++ は編集時に読み込みません。.rc2 ファイルのカスタム コントロール ダイアログを手動で編集する利点と欠点については、「Visual C++ リソース エディタで保守できないリソース ファイルの使用」を参照してください。
Test Dynamic Subclassed
コントロールは、標準エディット コントロールとしてダイアログ テンプレート リソース (Ctrltest.rc の IDD_SUB_EDIT) に配置されます。コントロールは、ダイアログ クラスの CParsedEdit データ メンバとして宣言されます。ダイアログの OnInitDialog 関数は、CParsedEdit::SubClassEdit を呼び出します。この関数によって、CWnd::SubclassDlgItem が呼び出され、エディット コントロールの各インスタンスを CParsedEdit クラスに関連付けます。Paredit.cpp を参照してください。
例 : スピン コントロール
CTRLTEST サンプルには、スピン コントロールの実装が含まれています。スピン コントロールには、値を増減するための小さな上向きの矢印ボタンと下向きの矢印ボタンがあります。
[Spin Control] コマンドは、4 つの CParsedEdit コントロールを持つダイアログ ボックスを呼び出します。各コントロールは、スピン コントロールに対応付けられています。ダイアログ ボックスの CParsedEdit コントロールに入力されたデータは、0 または正の数だけを受け付けるようにフィルタ処理されます。数値データを入力するには、値を CParsedEdit コントロールに入力するか、または関連付けられたスピン コントロールを使用します。
例 : ビットマップ ボタン
次の [Custom] メニュー コマンドの実装例では、CBitmapButton を使用する方法を示しています。
Bitmap Button 1 - ダイアログ コンストラクタは、CBitmapButton::LoadBitmaps を呼び出すことによって、ボタンの 3 つの状態 (アップ、ダウン、およびフォーカス) に対応したビットマップ リソースを明示的に読み込みます。
Bitmap Button 2 - ダイアログの OnInitDialog 関数は、CBitmapButton::Autoload を呼び出して、ビットマップ リソースを読み込みます。これらのリソースは、次の名前付け規則に従って名前が付けられます。コントロールのウィンドウ テキストが基本リソース名として使用されます。この名前に英字の U、D、または F が追加されて、アップ、ダウン、およびフォーカスの 3 つのビットマップ イメージに対応する各リソースの名前が作成されます。たとえば、[OK] ボタンの 3 つのビットマップ リソースの名前は、OKU、OKD、OKF などになります。
Bitmap Button 3 - このダイアログ ボックスは、上の 2 番目のダイアログ ボックスを拡張したものです。ボタンの 4 つめの状態 "無効" が追加されています。このダイアログを使用するには、最小値 1 または最大値 10 が表示されるまで、左向きまたは右向きの矢印のビットマップ ボタンをクリックします。制限値に達すると、ボタンは無効になり、4 番目のビットマップ イメージが表示されます。無効状態のビットマップ リソースは、名前付け規則に従って X が末尾に付きます。たとえば、リソース名は PREVX および NEXTX になります。
例 : オーナー描画 (メニューおよびリスト ボックス)
Windows の各種コントロールやメニューにはオーナー描画機能があり、親 (つまりオーナー) ウィンドウは、コントロールのクライアント領域に、標準のコントロールの動作以外の動作を描画できます。対応するコントロール クラスおよび CMenu クラスには、さらに便利なオブジェクト指向の方法で、この機能が用意されています。つまり、コントロール クラスまたはメニュー クラスが描画を処理します。これは "自己描画" と呼ばれます。
CTRLTEST では、[Custom] メニューの次のコマンドの実装でオーナー描画の一般的な方法を示します。
Custom Menu - このメニュー項目は、CMenu から派生する CColorMenu ポップアップ メニューを呼び出します。各サブメニュー項目には、自己描画機能を使用して 8 色のうち 1 色が表示されます。メッセージ ボックスでは、サブメニューで選択する色を確認します。
Custom List Box - このメニュー項目は、CListBox から派生する CColorListBox を表示するダイアログ ボックスを呼び出します。リスト ボックスには 8 つのエントリがあり、それぞれ、自己描画機能を使用して 8 色のうちのいずれかで描画されます。TRACE 出力によって、リスト ボックスから選択した内容を確認できます。
例 : Visual C++ リソース エディタで保持されないリソース ファイルの使用
CTRLTEST\RES\Ctrltest.rc2 リソース ファイルは、Visual C++ リソース エディタで、ユーザーが認識できる形式で保持されないリソース ファイルの例です。Ctrltest.rc2 を Visual C++ で開いてから保存すると、ユーザーが認識できる役立つ情報が失われます。リソース コンパイラが .rc2 ファイルをコンパイルし、同等の内容のバイナリ .res ファイルを作成する場合でも同様です。このため、RES\Ctrltest.rc2 は、[リソース ファイルのインクルード] コマンドで指定されたコンパイル時ディレクティブによって、Ctrltest.rc に #include として追加されます。
ユーザーが認識できる次の 3 つの情報は、Visual C++ リソース エディタでは保持されません。Ctrltest.rc2 では、このうちの 2 つについて示します。
カスタム コントロールのスタイル シンボル - たとえば、"msctls_updown32" はスピン コントロール用に定義されたスタイルです。Visual C++ は .rc2 ファイルを読み込むときにこのシンボルを解釈しますが、.rc2 ファイルに書き込むときは 16 進値として書き込みます。
標準 Windows WS_、つまり標準の Windows コントロールの派生クラスのコントロールで使用されるコントロール スタイル シンボル - たとえば、ES_AUTOHSCROLL は IDD_SPIN_EDIT ダイアログのスピン コントロール用に定義されています。Visual C++ は .rc2 ファイルを読み取るときにこのシンボルを解釈しますが、.rc2 ファイルに書き込むときは 16 進値として書き込みます。
.rc ファイルの算術演算 - IDD_SPIN_EDIT ダイアログのコントロールを識別するための "IDC_EDIT1+2" などの式は、Visual C++ によって 1 つの 16 進値として .rc2 ファイルに書き込まれます。
CTRLTEST サンプルでは、ダイアログ ボックスのカスタム コントロールのスタイルがヘッダー ファイルの定数で定義されている場合に、.rc2 ファイルを使用する利点と欠点が示されています。IDD_WNDCLASS_EDIT ダイアログと IDD_SPIN_EDIT ダイアログの両方には、スタイルをシンボルで定義したカスタム コントロールがあります。ただし、IDD_WNDCLASS は Visual C++ ダイアログ エディタで編集できる .rc ファイルで指定されていますが、IDD_SPIN_EDIT は手動でしか編集できない .rc2 ファイルで指定されています。
.rc ファイルと .rc2 ファイルの使用方法の違いについて説明します。
IDD_WNDCLASS_EDIT ダイアログでは、リソース スクリプトは Ctrltest.rc に定義されています。IDD_SPIN_EDIT ダイアログでは、リソース スクリプトは RES\Ctrltest.rc2 に定義されています。IDD_WNDCLASS_EDIT ダイアログでは、WNDCLASS カスタム コントロールは "paredit" で、スタイル定数は PAREDIT.H に定義されており、サンプル スタイル定数は PES_NUMBER です。IDD_WNDCLASS_EDIT は Visual C++ で編集できますが、#define スタイルを使用できません。IDD_SPIN_EDIT は Visual C++ で編集できませんが、#define のスタイルを使用できます。
.rc2 ファイルを使用すると、カスタム コントロールについて、ユーザーが認識できるシンボリック スタイルをヘッダー ファイルに定義して使用できますが、.rc2 ファイルを Visual C++ ダイアログ エディタで編集することはできません。ダイアログのレイアウトは、Visual C++ を使用する方が、リソース スクリプトを手動で作成するよりも簡単です。また、リソース スクリプトを作成すると、エラーが発生しやすくなります。一方、Visual C++ ダイアログ エディタを使用すると、スタイルがカスタム コントロール プロパティ ページに 16 進で表示されるため、わかりにくくなります。
キーワード
このサンプルでは、次のキーワードを使用します。
AfxGetInstanceHandle; AfxMessageBox; AfxThrowResourceException; CBitmapButton::AutoLoad; CDC::FillRect; CDC::FrameRect; CDialog::DoModal; CDialog::EndDialog; CDialog::OnInitDialog; CDialog::OnOK; CDialog::OnSetFont; CEdit::Create; CEdit::SetSel; CFrameWnd::Create; CListBox::AddString; CListBox::CompareItem; CListBox::DrawItem; CListBox::GetItemData; CListBox::MeasureItem; CMenu::AppendMenu; CMenu::CreateMenu; CMenu::Detach; CMenu::DrawItem; CMenu::EnableMenuItem; CMenu::FromHandle; CMenu::GetMenuString; CMenu::MeasureItem; CRect::Width; CStatic::Create; CString::Format; CString::LoadString; CWinApp::InitInstance; CWnd::Attach; CWnd::EnableWindow; CWnd::FromHandle; CWnd::GetDlgCtrlID; CWnd::GetDlgItem; CWnd::GetDlgItemInt; CWnd::GetMenu; CWnd::GetParent; CWnd::GetWindowRect; CWnd::GetWindowText; CWnd::IsWindowEnabled; CWnd::MessageBox; CWnd::OnChar; CWnd::OnCommand; CWnd::OnVScroll; CWnd::PostNcDestroy; CWnd::SendMessage; CWnd::SetDlgItemInt; CWnd::SetFocus; CWnd::SetFont; CWnd::SetWindowPos; CWnd::ShowWindow; CWnd::SubclassDlgItem; CallWindowProc; GetBValue; GetClassInfo; GetGValue; GetRValue; GetSystemMetrics; HIWORD; IsCharAlpha; IsCharAlphaNumeric; LOWORD; MAKEINTRESOURCE; MAKELONG; MessageBeep; ModifyMenu; RGB; RegisterClass; SetWindowLong
メモ : |
---|
このサンプルを含む一部のサンプルには、Visual C++ のウィザード、ライブラリ、およびコンパイラの変更が反映されていませんが、必要なタスクを実行する方法は示されています。 |