MFCを使用してアプリケーションを実行しています。OnChar()をインターセプトしてデータ検証を実行できるように、CEditから派生したクラスを作成しました。アプリケーションの編集コントロールを、作成した派生コントロールに置き換えるにはどうすればよいですか?
2 に答える
解決策を見つけました。こんなに苦労したのは、Class Wizard を使用して新しいクラスを作成しなかったため、非常に複雑でした。Class Wizard を使用するだけの場合、基本クラスが要素に適したクラスである限り、派生クラスが通常のクラスであるかのように、制御変数を派生クラスに追加するオプションがあります。ただし、これは必要ありません。非派生クラスで通常行うように、派生クラスの型のポインターを作成し、取得しようとしているアイテムをキャストするだけです。
CEdit から派生したクラスを使用してエディット コントロールにアクセスする例
CMyCustomEdit * editPtr = (CMyCustomEdit*)GetDlgItem(IDC_EDIT1);
以下で別のメンバーが述べているように (ありがとうございます)、GetDlgItem を使用することはお勧めできません。私は実際に、私のコードでそれをサブクラス化して、既存の編集コントロールで新しいクラスを使用できるようにしました。前述のように、エディット コントロールが必ずしも CEdit にアタッチされているとは限らないことを理解していなかったので、上記の例から、IDC_EDIT を CMyCustomEdit や CWnd などとして使用できることが明確にわかるはずです。適切なクラスで参照する限り、自然に動作します。
次にサブクラスです。基本クラスの前に常に派生クラスを呼び出すようにエディット コントロールを作成したい場合は、それをサブ クラスにする必要があります。オブジェクト指向の概念とは考えないでください。これは、メッセージ (WN_CHAR など) が最初に派生クラスを通過してから、基本クラスを呼び出すためだけです。
エディット コントロールで CMyCustomEdit をサブクラス化する例:
最初に、新しいクラスの .h ファイルをダイアログ ボックスの .cpp と .h に含める必要があります。これらは、通常、プロジェクトと同じ名前を持つものです。ここでは MyMainDialog になります。
#include "CMyCustomEdit.h"
派生ダイアログ クラスに、新しい派生クラスの型の変数を含めます。
class MyMainDialog : public CDialogEx
{
protected:
CMyCustomEdit m_cmCEdit;
}
次に、派生ダイアログ クラス (MyMainDialog) サブクラスの OnInitDialog() で、編集コントロールを作成します。安全のために、関数内の通常のコードの後、リターンの前にこれを追加します(通常どおり):
m_cmCEdit.SubclassDlgItem(IDC_EDIT1, this);
これが完了したら、ID IDC_EDIT1 を使用して編集コントロールで何かを行うと、メッセージは CEdit に行く前に CMyCustomEdit を通過します。これは通常、基本クラスからのメッセージを上書きする必要がある場合に必要です。
同様の質問をしている人の助けになることを願っています。
使用しないでくださいGetDlgItem
!!
GetDlgItem()
CWnd
-pointer のみを返します。これは、スライスされたCMyCustomEdit
ポインターがあることを意味します。もちろん、メソッドが基になるにメッセージを送信するHWND
すべてのケースで機能します。しかし、それはただの運です!問題の詳細については、こちらをご覧ください。
正しい解決策は、DDX_Controlを使用してエディット コントロールをサブクラス化することです。