2

Delphi 中的大多数 TWinControl 后代都有一个覆盖方法 CreateParams 来定义它的子类,例如:'EDIT'、'COMBOBOX'、'BUTTON'、'RICHEDIT' 等。

CreateSubClass(Params, 'EDIT');
CreateSubClass(Params, 'COMBOBOX');
CreateSubClass(Params, 'BUTTON');

Delphi 有很多丰富的编辑控件,包括来自第三方供应商的控件。所有这些控件都是 RichEdit 的子类。

我想知道是否有一种方法可以通过测试 CreateParams 中定义的子类来测试控件是否为 RichEdit,而不管它的原始供应商是什么?

4

4 回答 4

2

使用 Win32 APIGetClassName()RealGetWindowClass()函数(请参阅什么使 RealGetWindowClass 比 GetClassName 更真实?了解它们之间的区别),然后检查可用的各种 RichEdit 类名称的结果:

  • 'RICHEDIT'(1.0)
  • 'RICHEDIT20A''RICHEDIT20W'(2.x+)
  • 'RICHEDIT50W'(4.1)
  • 'TRichEdit'(VCL 包装器)
  • 等等其他第 3 方包装器
于 2010-02-19T08:56:33.327 回答
1

感谢所有的反馈。我认为没有办法获得 TWinControl 的 Windows 类名。

这是从 JamesB 的版本修改而来的另一个版本的 IsRichEdit:

type TWinControlAccess = class(TWinControl);

function IsRichEdit(C: TWinControl): boolean;

const A: array[0..8] of string = (
           'RICHEDIT',
           'RICHEDIT20A', 'RICHEDIT20W',
           'RICHEDIT30A', 'RICHEDIT30W',
           'RICHEDIT41A', 'RICHEDIT41W',
           'RICHEDIT50A', 'RICHEDIT50W'
          );

var Info: TWNDClass;
    p: pointer;
    s: string;
begin
  p := TWinControlAccess(C).DefWndProc;

  Result := False;

  for s in A do begin
    if GetClassInfo(HInstance, PChar(s), Info) and (Info.lpfnWndProc = p) then begin
      Result := True;
      Break;
    end;
  end;
end;

如果 Windows 有更新版本的 RichEdit 类,我们可以修改数组 A。

另一个可能但有风险的解决方案是我只是检查控件的 VCL 类名称是否包含“RichEdit”字符串,因为来自 Delphi 的几乎丰富的编辑 VCL 类或第 3 方供应商以这种方式命名控件。

于 2010-02-20T01:38:00.607 回答
0

你可以使用

 function GetClassInfo(hInstance: HINST; lpClassName: PChar;  var lpWndClass: TWndClass): BOOL;

我想这就是雷米想要做的。

就像是:

Function IsRichEdit(MyControl : TWinControl):Boolean;
var 
    Info : TWNDClass;
begin
    Result := False;
    if GetClassInfo(HInstance,PCHAR('RICHEDIT'),Info) and (Info.lpfnWndProc = MyControl.DefWndProc) then 
        Result := True
    else if GetClassInfo(HInstance,PCHAR('RICHEDIT20A'),Info) and (Info.lpfnWndProc = MyControl.DefWndProc)  then 
        Result := True
    else if GetClassInfo(HInstance,PCHAR('RICHEDIT30A'),Info) and (Info.lpfnWndProc = MyControl.DefWndProc)  then 
        Result := True
    else if GetClassInfo(HInstance,PCHAR('RICHEDIT41A'),Info) and (Info.lpfnWndProc = MyControl.DefWndProc)  then 
        Result := True
    else if GetClassInfo(HInstance,PCHAR('RICHEDIT50A'),Info) and (Info.lpfnWndProc = MyControl.DefWndProc)  then 
        Result := True
end;

如果您使用的是 Delphi > 2007,那么您可能还需要测试“W”(unicode)版本,例如“RICHEDIT20W”

编辑:添加 Info.WndProc 测试以匹配控件。

奇怪的是,这对 cxControls 不起作用,因为 cxRichEdit 不是使用富编辑窗口的控件(它是一个包含,因此您需要传递 cxControl.InnerControl 以使其返回 true)。

编辑除了创建的第一个richedit 控件之外,我无法让它工作。

于 2010-02-19T10:20:20.217 回答
0

我错过了什么吗?不就是一个简单的测试案例吗:

if (MyControl is TRichEdit)

或者

if (MyControl is TCustomRichEdit)
于 2010-02-19T08:48:46.400 回答