какие сообщения VCL принимает? / - PullRequest
0 голосов
/ 18 октября 2011

Как узнать список сообщений, которые может принимать определенный компонент VCL ??? /

Например, если я хочу прокрутить Memo1, отправив ему сообщение Я, вероятно, напишу следующие строки кода, зная, что памятка может принять EM_LINESCROLL

SendMessage(Memo1->Handle,EM_LINESCROLL,-1,0);
//Memo1->Perform(EM_SCROLL,SB_LINEUP,0);
Memo1->Perform(EM_SCROLL,SB_LINEDOWN,0);

Как найти, чтобы узнать, могут ли определенные компиляторы VCL принимать или не принимать сообщения ???

Ответы [ 2 ]

5 голосов
/ 18 октября 2011

Все компоненты принимают все сообщения, но если компонент не имеет назначенного обработчика сообщений, он просто ничего не делает

Если вы хотите узнать, есть ли у компонента VCL специальный обработчик для определенного сообщения Windows, вам нужно изучить источники VCL, которые обычно предоставляются в C ++ Builder (кроме версий XE и XE2 для начинающих).

VCL-источники расположены в% CBuilderDir% \ Sources \ VCL (глядя на мой CBuilder5 / 6)

Источники написаны на Delphi, но не составит труда найти все, что нам нужно.

Во-первых, вам нужно найти определение вашего целевого класса. Вы можете искать по всему каталогу исходного кода VCL файл со строкой, похожей на

TMemo = Class (для вашего примера с TMemo)

Откройте файл, в котором вы нашли свой класс (обычно это будет stdctrls.pas или controls.pas - там находятся самые полезные компоненты), перейдите к строке с определением класса и прокрутите немного вниз, пока не найдете группу процедуры, похожие на

procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN; procedure WMRButtonDown(var Message: TWMRButtonDown); message WM_RBUTTONDOWN;

... и так далее. Эти процедуры вызываются в ответ на определенные сообщения, идентификаторы которых предоставляются после определения процедуры.

Если у класса есть процедура для определенного сообщения, то он дает на него некоторый ответ.

Обработчики сообщений наследуются в delphi, поэтому, если вы не нашли обработчик для вашего сообщения, вы можете посмотреть на базовые классы и их обработчики сообщений. Чтобы обнаружить полную иерархию классов, вы можете просто заглянуть в файл справки или снова посмотреть определение класса TMemo = class (TCustomMemo) и взять имя родительского класса из фигурных скобок.

Затем вы можете повторить поиск обработчика сообщений для всех родительских классов, пока не достигнете TObject: -)

Кстати. Простой поиск в директории источника VCL моего CBuilder5 любого присутствия EM_LINESCROLL Я понял, что ни один компонент VCL не обрабатывает его.

Если вам нужно только обеспечить специальное взаимодействие для определенного сообщения, не пытаясь выяснить, есть ли у компонента уже есть обработчики сообщений или нет, вы можете просто переопределить метод WindowProc вашего компонента. У всех потомков TControl есть этот метод.

Этот метод обрабатывает все сообщения, полученные компонентом, и вы можете добавить ответ к дополнительным системным или пользовательским сообщениям здесь.

void __fastcall TMyForm::NewWndProc(Messages::TMessage &Message)   
{    
if (Message.Msg == EM_LINESCROLL)  
 // Do something special for this message    
else  OldWndProc(Message);    
}

Единственное, что вам нужно сделать, это сохранить значение старого WindowProc, чтобы вызвать его в NewWndProc после того, как вы все сделаете.

Лучше определить и назначить NewWndProc и сохранить старое WindowProc для TMemo в форме, содержащей ваш компонент, так что вам не придется возиться с созданием нового унаследованного компонента из TMemo. Итак, определите TWndMethod OldWndProc в форме и поместите следующее, например, в форму OnCreate() handler

TWndMethod OldWndProc = MyMemo->WindowProc;
MyMemo->WindowProc = NewWndProc;

Также вы можете предотвратить запуск предопределенных обработчиков, не передавая определенные сообщения в OldWndProc. Будьте осторожны, если вы запретите обработку разумных системных сообщений (например, WM_CREATE), вы получите ошибки.

0 голосов
/ 19 октября 2011

TMemo - это тонкая оболочка вокруг стандартного многострочного элемента управления Win32 API EDIT. Вы должны прочитать документацию MSDN, чтобы увидеть, какие сообщения обрабатывает элемент управления EDIT. TMemo не обрабатывает EM_LINESCROLL напрямую, а Windows -

...