使用伪函数进行子类化:
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
为HTCLIENT
我们有鼠标响应时,但是,由于我的错误和错误的子类化,如果没有设置msg.result
为 1 就 没有响应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 是我们需要
在项目中子类化的其他控件之一,我们尝试对所有控件使用相同的子类(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
}