How to test if a control is a RichEdit control

拜拜、爱过 提交于 2019-12-11 01:55:17

问题


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 SubClass defined in CreateParams?


回答1:


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



回答2:


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.




回答3:


Am I missing something? Is it not simply a case of testing:

if (MyControl is TRichEdit)

or

if (MyControl is TCustomRichEdit)



回答4:


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.



来源:https://stackoverflow.com/questions/2294962/how-to-test-if-a-control-is-a-richedit-control

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!