Reputation: 1547
How to find out the list of messages that a certain VCL component can accept ???/
For example if i want to scroll the Memo1 by sending message to it I probably will write the following lines of code knowing that the memo can accept EM_LINESCROLL
SendMessage(Memo1->Handle,EM_LINESCROLL,-1,0);
//Memo1->Perform(EM_SCROLL,SB_LINEUP,0);
Memo1->Perform(EM_SCROLL,SB_LINEDOWN,0);
How to find to find out if certain VCL comps can accept or do not accept messages???
Upvotes: 0
Views: 351
Reputation: 597670
TMemo
is a thin wrapper around a standard Win32 API multiline EDIT
control. You have to read the MSDN documentation to see which messages an EDIT
control natively handles. TMemo does not process EM_LINESCROLL
directly, but Windows does.
Upvotes: 0
Reputation: 429
All components accept all messages, but if a component have no assigned message handler, it just does nothing
If you want to discover if VCL component have special handler to certain Windows message, you have to look into VCL sources, which are usually provided with C++Builder (except Starter Edition's of XE and XE2).
VCL Sources are located in %CBuilderDir%\Sources\VCL (looking at my CBuilder5/6)
Sources are written in delphi, but it won't be difficult to find all what we need.
First, You'll have to find defininition of your target class. You can search through whole VCL source dir for file with line looking like
TMemo = Class
(for your example with TMemo)
Open file where you found your class, (usually it will be stdctrls.pas or controls.pas - most useful components are located there), go to the line with class definition and scroll a little down until you find a group of procedures, looking like
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMRButtonDown(var Message: TWMRButtonDown); message WM_RBUTTONDOWN;
...and so on. These procedures are called in response to certain messages, which id's are provided after procedure definition.
If a class have procedure for certain message, then it provides some response to it.
Message handlers are inherited in delphi, so if you didn't find handler for your message, you can look into base classes and their message handlers. To discover full class hierarchy you can simply look into the help file, or look at class definition again TMemo = class (TCustomMemo)
and take parent class name from braces.
Then you can repeat search for message handler for all parent classes untill you reach TObject
:-)
By the way. Simpy searching through VCL source dir of my CBuilder5 for any presense of EM_LINESCROLL
I've figured than no VCL component processes it.
If you only need to provide special interaction for certain message, not trying to figure if a component already have or not have message handlers your can simply override WindowProc
method of your component. All descendants of TControl
have this method.
This Method process all messages received by component, and you can add response to additional system or user messages here.
void __fastcall TMyForm::NewWndProc(Messages::TMessage &Message)
{
if (Message.Msg == EM_LINESCROLL)
// Do something special for this message
else OldWndProc(Message);
}
Only thing that you'll need to do is to preserve value of old WindowProc, to call it in NewWndProc after you do all your stuff.
Its better to define and assign NewWndProc
and store old WindowProc
for TMemo in the form which holds your component, so you won't need to mess with making new inherited component from TMemo
. So, define TWndMethod OldWndProc
in form and put following, for example, in form OnCreate()
handler
TWndMethod OldWndProc = MyMemo->WindowProc;
MyMemo->WindowProc = NewWndProc;
Also your can prevent firing of predefined handlers, by not passing certain messages to OldWndProc. Be careful, if you prevent processing of sensible system messages (like WM_CREATE) you'll get errors.
Upvotes: 5