2010-02-19 3 views
2

Большинство TWinControl потомок в Delphi имеет метод коррекции CreateParams для определения это подкласс, такие как: «EDIT», «COMBOBOX», «BUTTON», «RichEdit» и т.д.Как проверить, если элемент управления является элементом управления RichEdit

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

В Delphi имеется довольно много элементов управления редактирования, включая элементы управления сторонних поставщиков. Все эти элементы управления являются подклассом RichEdit.

Мне интересно, есть ли способ протестировать элемент управления RichEdit, независимо от его первоначального поставщика, путем тестирования SubClass, определенного в CreateParams?

ответ

1

Благодарим за отзыв. Я думаю, что нет способа получить имя класса Windows для TWinControl.

Вот еще одна версия IsRichEdit редактировался версии JamesB в:

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; 

Мы можем изменить массив А если есть новая версия класса RichEdit из Windows.

Еще одно возможное, но рискованное решение. Я просто проверяю, содержит ли имя класса VCL элемента управления строку «RichEdit» как почти богатое редактирование. Класс VCL от Delphi или сторонних поставщиков называют элементы управления таким образом.

0

Я что-то упустил? Разве это не просто случай тестирования:

if (MyControl is TRichEdit) 

или

if (MyControl is TCustomRichEdit) 
+0

Это расширенные элементы управления Delphi VCL. Существуют TcxRichEdit, TRxRichEdit и т. Д. ... –

+1

Это работает только для элементов управления, которые получены из T (Custom) RichEdit. Он не будет работать для элементов управления, которые производятся от TWinControl или TCustomControl. –

+0

Да, но в вашем вопросе вы сказали: «Для Delphi существует довольно много элементов управления редактирования, включая элементы управления от сторонних поставщиков. Все эти элементы управления являются подклассом RichEdit». Если они являются подклассом TRichEdit, то работает тест 'is'. –

2

Использование командной Win32 API GetClassName() или RealGetWindowClass() функцию (см What makes RealGetWindowClass so much more real than GetClassName? разницу между ними), а затем проверить результат для различных имена RichEdit класса, которые доступны:

  • 'RICHEDIT' (1.0)
  • 'RICHEDIT20A' или 'RICHEDIT20W' (2.x +)
  • 'RICHEDIT50W' (4,1)
  • 'TRichEdit' (VCL обертка)
  • и так далее для других 3-й партии оберток
+0

Я не могу найти GetWindowClass в Windows.pas. Я использую Delphi 2010. –

+0

Я думаю, что это сработало бы, если бы вы могли получить доступ к «ControlClassName», переданному CreateSubClass. –

+0

Итак, как мне получить доступ к нему? Я не могу найти GetWindowClass в unit windows.pas –

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'

Edit: добавлен тест Info.WndProc для соответствия элементу управления.

Как ни странно, это не сработает для cxControls, поскольку cxRichEdit не является элементом управления, используя богатое окно редактирования (оно содержит, поэтому вам нужно будет передать cxControl.InnerControl для этого, чтобы вернуть true).

Редактировать Я не мог заставить это работать больше, чем первый созданный элемент управления richedit.

+1

Почти. Кроме того, ваша функция вернет True для * любого * элемента управления, который вы передадите ему, если ваше приложение создало подкласс для одного из этих классов. Первым параметром GetClassInfo должен быть экземпляр приложения (HInstance, или 0 для системных классов), а не дескриптор элемента управления. Правильный тест, вероятно, будет: , если GetClassInfo (HInstance, «RICHEDIT», Info) и (Info.lpfnWndProc = THackWinControl (MyControl) .DefWndProc), затем ... –

+0

Ваш код работает. Это единственный способ проверить, является ли элемент управления богатым? Кажется, что есть несколько оконных классов RichEdit (например, RICHEDIT, RICHEDIT20A, RICHEDIT20W, ...). Вы знаете, сколько из них? Нужно ли возвращать имя класса окна экземпляра TWinControl? Затем я могу проверить, содержит ли имя класса окна «RICHEDIT». –

Смежные вопросы