How to apply messages in C ++ Builder

zhaozj2021-02-16  79

The standard BCB program uses Application-> Run () into the message loop. In the Application's ProcessMessage method, use the PeekMessage method to extract messages from the message queue and remove this message from the message queue. The ProcessMessage method then checks if there is an Application-> OnMessage method. Presence, transfer to this method to process the message. The processed message distribution will then give each object in the program. At this point, the WndProc method receives the message and processes. If there is a DISPATCH method that cannot be handled overloaded. If you still can't handle it, you will be handed over to the DISPATCH method of the parent class. Finally, the Dispatch method actually transfer the message to the defaultHandler method. (Hey, in fact, you can overload the DefaultHandler method to process the message, but it is too late, I think no one is willing to handle the message).

1. TAPPLICATION ONMessage Event In the application developed by C Builder, any form is received to trigger an OnMessage event, so you can capture any Windows sent to this program by the ONMessage event of the corresponding Tapplication object. news.

The processed function prototype of onMessage is as follows: typedef void __fastcall (__closure * tMESSAGEVENT) (Tagmsg & MSG, Bool & Handled); this processing function has two parameters, where the parameter MSG represents the intercepted message, and the parameter handled is used Indicates if this message has been processed. In the program, you can use the parameter handled to true to avoid subsequent processes to process this message, and it is confusing the Handled to FALSE to allow the subsequent process to continue to process this message. It should be noted that OnMessage events only accept messages sent to the message queue, and the messages sent directly to the window function passing through the API function sendMessage () will not be intercepted. In addition, when the program is running, the frequency that the onMessage event is triggered may be very high, so the processing function code execution time of this event will directly affect the running efficiency of the entire program.

2. The VCL of the Message Map C Builder provides a process mechanism for most Windows messages, which is sufficient for the general application. However, VCL is not unpacking. In some cases, the program needs to handle the Windows messages that have not been processed, or when the program needs to block some specific messages, the programmer needs to capture the Windows message. To this end, C Builder provides a message mapping mechanism that can associate a specific Windows message with the corresponding processing function via a message mapping program that automatically calls the corresponding processing function when the window captures this message. With message mapping, there are several steps: (1) message mapping table, handle the processing of certain messages to custom message processing functions. Such a message mapping list should be in a definition of a component class, starting with an end_message_map macro with a begin_message_map macro without a parameter. The unique parameter of the END_MESSAGE_MAP macro should be the name of the parent class of the component. Normally, this so-called parent class refers to TFORM. Insert one or multiple message_handler macros in the macro begin_Message_map and End_Message_MAP. The message_handler macro links a message handle and a message handler. Message_handler has three parameters: Windows message name, message structure name, and corresponding message processing function name. Among them, the message structural body name can be either universal message structure TMESSAGE, or a specific message structure, such as TWMMOUSE. Pay attention to the following two points when using the message mapping: a. There is only one message mapping table in a window class definition. b. The message mapping must be in the back of all message processing functions it referenced. (2) The message processing function name and parameters that are declared in the window class must be consistent with the corresponding Message_Handler macro. The declaration of a typical message processing function is as follows: VOID __FASTCALL message processing function name (Message Structure Name & Message); for example: void __fastcall wmnchittest (TMESSAGE & Message); (3) Implementing the preparation of message processing function message processing functions and ordinary functions Nothing is too much difference, the only difference is that the final form of this function is to add a statement TForm :: Dispatch (& Message) to complete the default processing of the VCL for the message. If there is no such thing, the message will be completely intercepted; in some cases, the VCL may not work because there is no message.

3. The overloaded WndProc () function In some cases, the program needs to capture or block certain specific messages, and the message maps described above can be used. Of course, this method is not unique, or it can be implemented by the overload window function WndProc (). Because the system will call the window function WndProc () before the call function Dispatch () is sent, it is possible to obtain a chance to filter messages before dispatching messages by overloaded functions. The window function prototype message processing as follows: virtual void __fastcall WndProc (TMessage & Message); e.g. :( details see examples of NowCan) void __fastcall TForm1 :: WndProc (TMessage & Message) {PCOPYDATASTRUCT pMyCDS; if (Message.Msg == g_mymsg) {showMessage ("Received Registration Message, WPARAM =" INTOSTR (Message.wParam) "LParam =" INTOSTR (Message.LParam)); Message.Result = 0; // Message Processing Results, of course There is no meaning in this example. } else if (message.msg == g_mymsg1) {Application-> MessageBoxa ((char *) message.lparam, "Received Sage", MB_OK);} else if (Message.msg == WM_COPYDATA) { PMYCDS = (pcopyDataStruct) message.lparam; Application-> MessageBoxa (Char *) PMYCDS-> LPDATA, "Received String", MB_OK);} TFORM :: WndProc (Message); // Other Messages Continue to pass} At first, this is similar to the overloaded dispatch method. But actually there is still different. The difference is in the order, the message is handed over to WndProc, and finally call the Dispatch method. Thus, the overloaded WndProc method can get a message and process the message earlier than the reloaded DISPATCH method.

4. Application-> hookmainWindow method If you plan to use Application-> OnMessage to capture all messages sent to your application, you are about to be disappointed. It can't capture messages sent to the window using SendMessage because this does not pass message queues. You may say that I can directly overload the WndProc method of the TAPPLICATION. Oh, no. Because the WndProc method of Tapplication is static by Borland, it cannot be overloaded. Obviously, this reason is probably Borland worried that the side effects brought. What should this be good? View the Pascal source code for Tapplication WndProc You can see: procedure tapplication.wndproc (var message: tMessage); ... // save space, here is unrelated to begentryMessage.Result: = 0; for i: = 0 To FwindowHooks.count - 1 Doif TwindowHook (FWindowHooks [i] ^) (Message) THEN EXIT; ... // Save space, here is unrelated to the topic to go to the WNDPROC method first call the HookmainWindow hook custom message processing Method, then call the default process processing message. This allows you to add your own message processing method in WndProc using hookmainwindow. Use this method to respond to message sent by SendMessage. Finally, remind it to use the hookmainwindow hook to call the UnHookMainWindow uninstall the hook program. For an example: void __fastcall tform1 :: formcreate (TOBJECT * Sender) {Application-> hookmainwindow (apphookfunc);} // --------------------------------------- -------------------------------------------------- --bool __fastcall TForm1 :: AppHookFunc (TMessage & Message) {bool Handled; switch (Message.Msg) {case WM_CLOSE: mrYes == MessageDlg ( "Really Close ??", mtWarning, TMsgDlgButtons () << mbYes unhookmainWindow (AppHookFunc);} // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------------------------------------- void __fastcall tform1 :: button1click (Tobject * sender) {sendMessage (Application-> Handle, WM_Close, 0, 0);} // ----------------------------------------------------------------------------------------------------------------------------------------- -----------------------------------------

5. It is also possible to send messages between windows or components like a Windows system. C Builder provides several ways: using functions tcontrol :: perform () or API function sendMessage (), and postMessage () send messages to a specific form, or use functions TwinControl :: Broadcast () and API Function BroadcastsystemMessage () broadcast message. The performance of the Perform () function is to pass the specified message to the TControl's WndProc process, which is suitable for all objects derived by the TControl class. The Perform () prototype is as follows: int __fastcall perform (unsigned MSG, int wparam, int Lparam); The message is returned.

Use function perform () between different forms and controls of the same application is very convenient. But this function is a member function of the TControl class. That is, when using it, the program must know the example of the control of this message. In many cases, the program does not know the form of the form of the form, just know the handle of this form, such as the sending message between the form of different applications belongs to this situation. At this time, the function perform () is obviously unable to use, and the replacement should be the function sendMessage () and postmessage ().

The functions of the function sendMessage () and postMessage () are basically the same, and they can be used to send messages to a specific window handle. The main difference is that the function sendMessage () is sent directly to the window function, and the message is returned after the message is processed; and the function postmessage () is just sent the message to the message queue, and then returns immediately. The prototyping statements of these two functions are as follows: LResult SendMessage (HWND HWND, UINRT MSG, WPARAM, WPARAM, LPARAM, LPARAM); BOOL PostMessage (HWND HWND, UINT MSG, WPARAM, WPARAM, LPARAM, LPARAM); can be seen, These two function parameters are similar to the function perform (), but only an HWND parameter is used to represent the handle of the target window.

转载请注明原文地址:https://www.9cbs.com/read-17024.html

New Post(0)