How to test if a control is a RichEdit control
Most TWinControl descendant in Delphi has an override method CreateParams to define it's subclass such as: 'EDIT', 'COMBOBOX', 'BUTTON', 'RICHEDIT' and etc.
CreateSubClass(Params, 'EDIT');
CreateSubClass(Params, 'COMBOBOX');
CreateSubClass(Params, 'BUTTON');
There are quite a number of rich edit control for Delphi including controls from third party vendors. All those controls are sub class of RichEdit.
I am wondering if there is a way to test a control is RichEdit regardless of it's original vendor by testing the SubCla开发者_运维知识库ss defined in CreateParams?
Use the Win32 API GetClassName()
or RealGetWindowClass()
function (see What makes RealGetWindowClass so much more real than GetClassName? for the difference between them), and then check the result for the various RichEdit class names that are available:
'RICHEDIT'
(1.0)'RICHEDIT20A'
or'RICHEDIT20W'
(2.x+)'RICHEDIT50W'
(4.1)'TRichEdit'
(VCL wrapper)- and so on for other 3rd party wrappers
Thanks for all the feedback. I think there is no way to get the windows class name for the TWinControl.
Here is another version of IsRichEdit modified from JamesB's version:
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;
We may modify array A if there is newer version of RichEdit class from Windows.
Another possible but risky solution is I just check if the control's VCL class name contain 'RichEdit' string as almost rich edit VCL class from Delphi or 3rd party vendors name the controls that way.
Am I missing something? Is it not simply a case of testing:
if (MyControl is TRichEdit)
or
if (MyControl is TCustomRichEdit)
You could use
function GetClassInfo(hInstance: HINST; lpClassName: PChar; var lpWndClass: TWndClass): BOOL;
I think this is what Remy was trying to do.
something like:
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;
If you are using Delphi > 2007 then you might need to test for the 'W'(unicode) versions as well e.g 'RICHEDIT20W'
Edit: added Info.WndProc test to match the control.
Oddly enough this won't work for the cxControls since the cxRichEdit isn't the control using the rich edit window (It's a containing so you would need to pass cxControl.InnerControl for this to return true).
Edit I couldn't get this to work for more than the first richedit control created.
精彩评论