サブクラス化に疑似関数を使用する:
CreateSpecialHandle(TWinControl *Control, const TCreateParams &Params, const AnsiString SubClass)
{
......;
set Control DefWndProc to SubClass.lpfnWndProc
set Control WindowHandle from CreateWindowEx
......;
subclass(TWinControl *Control);
}
subclass(TWinControl *Control)
{
......;
oldWProc = (void*)GetWindowLong(Control->Handle, GWL_WNDPROC);
oldDefWProc = (void*)(Control->DefWndProc);
oldWindowProc = Control->WindowProc;
MakeObjectInstance(newWProc) for SetWindowLong
MakeObjectInstance(newDefWProc) for Control->DefWndProc
Control->WindowProc = newWindowProc;
......;
}
ここで、サブクラス化されたコントロールの予期しない動作が発生します。
WM_NCHITTEST
結果0など...
たとえば、newWProc
インターセプトWM_NCHITTEST
してに設定Result
すると、マウスの応答がありますが、私の間違いと間違ったサブクラス化の結果、 1に HTCLIENT
設定せずに応答しないのですか?他に手動で処理する必要があるのは何ですか? msg.result
msg.msg WM_NCHITTEST
newWProc
のコールバックを行うoldWProc
newDefWProc
のコールバックを行うoldDefWProc
newWindowProc
通話oldWindowProc
サブクラス化されたコントロールの親コントロールもサブクラス化する必要がありますか? また、空のバッファで結果を
送信します。
明らかに、私たちはここで何か間違ったことをしています。説明が必要
です。事前に感謝します更新:WM_GETTEXT
in TDCEdit:public TCustomEdit overriding CreateWindowHandle
void __fastcal CreateWindowHandle(const TCreateParams &Params)
{
CreateSpecialHandle(this,Params,TEXT("EDIT"));
}
void CreateSpecialHandle(TWinControl *Control,const TCreateParams &Params, AnsiString SubClass)
{
...
Control->WindowHandle = CreateWindowEx(...,"EDIT",....);
....
subclass(Control);
}
subclass(TWinControl* Control)
{
......;
oldWProc = (void*)GetWindowLong(Control->Handle, GWL_WNDPROC);
oldDefWProc = (void*)(Control->DefWndProc);
oldWindowProc = Control->WindowProc;
MakeObjectInstance(newWProc) for SetWindowLong
MakeObjectInstance(newDefWProc) for Control->DefWndProc
Control->WindowProc = newWindowProc;
......;
}
ここで、TDCEdit を使用して newWProc 内で Message.Msg == WM_NCHITTEST をインターセプトすると、
Message.Result は 0 になり、すべてのメッセージ プロセス チェーンで 0 のままになります。
TCustomEdit のサブクラス化は
、プロジェクトでサブクラス化する必要がある他のコントロールの 1 つであり、すべてに対して同じサブクラス (TWinControl*) 関数を使用しようとすることに注意してください。
これは newWProc の一部で、問題に焦点を当てるためにさらにいくつかの行があります
void __fastcall TControlWrapper::newWProc(Messages::TMessage &Message)
{
if(Message.Msg == WM_NCHITTEST ) // TEST
if(Message.Result == 0)
Message.Result=1;//<- WHY I NEED TO DO THIS
if( Message.Msg == WM_DESTROY) {
HandleWMDestroy(Message);
return;
}
CallWindowProcW( (int(__stdcall*)())oldWProc,
Handle, Message.Msg, Message.WParam,
Message.LParam);
if(Message.Msg == WM_NCHITTEST )
if(Message.Result == 0)Message.Result=1;//<- OR THIS
}