In-depth exploration of C ++ Builder message processing

zhaozj2021-02-11  189

In this article I will tell you how to handle Windows messages in C Builder and achieve the function that cannot be done in a general VCL component through this capability.

What is WINDOW message (Message)

Everyone knows that Windows is a job system with message driven. However, for the message itself, it is a deep, only knows that it doesn't know how it is, although C Builder encapsulates some Windows messages in the event system, but as a Windows programming designer, it is necessary to understand the message of Windows. system.

The so-called message is sent by the Windows job system to the program. It is a manner of communication in the system, for example, when moving a mouse, press the slice button, change the window size, and Windows will send a message to a notification program. Of course, in order to identify the content of the event, a number of messages are defined in the Windows system, such as WM_Paint, WM_CHAR, and more.

When the event occurs, Windows will determine that the event must be received by that program, and then send an event in a message to the program. Although hundreds of events have been included in the Windows system, the job system does not design different message structures for each event, but is described in a general structure, this structure is called in C Builder. TMESSAGE.

Of course, as the incident is different, the interpretation of the message is also different, and the exclusive structure is defined for various common messages in C Builder, and you can use them directly to interpret the message. These messages define in include / vcl / messages.hpp in the C Builder directory, you can decide to explain the TMESSAGE parameters or convert them into exclusive structures. Are you abstract? I will give an example. For WM_NCHITTEST messages, C Builder defines the exclusive structure of TwMnchittest, so you can get XPOS, YPOS equivalents directly. Or you can also get its value directly from the LPARAM of TMessage, and the end of your use is convenient. Carefully observe the two structures of TMessage and Tmnchittest, you will find that they are equivalent, that is, their size is consistent, so you can directly transform each other with mandatory transformation (this is a way similar to Union).

Struct tMessage

{

Cardinal MSG;

union

{

Struct

{

Word wparamlo;

Word wparamhi;

Word lparamlo;

Word lparamhi;

Word resultlo;

Word resulthi;

}

Struct

{

Long wparam;

Long lparam;

Long Result;

}

}

}

Struct twmnchittest

{

Cardinal MSG;

Long unused;

union

{

Struct

{

Windows :: TsmallPoint Pos;

Long Result;

}

Struct

{

Short xpos;

Short ypos;

}

}

}

After receiving the message, the program must handle the message. If not processed, it can be handed over to the Windows's internal processing program. If the program requires the return value, it can be transferred at this time, and Windows will be transmitted. This value is transmitted back to the caller. This completes the program of message delivery.

The mystery of WM_NCHITTEST messages is a very special message. It is used to determine a message that is currently attribute at the current mouse, so we can use this feature, when the mouse is moved to the specified location, pass back HTCAption, so that the system is currently located on the title rod, so you can move Window. how is it? Is it very magical?

From the above, we can smoothly spoof the system smoothly as long as we intercept the WM_NCHITTEST message, then return to HTCAption, and achieve the effect of simulating the title rod in any position.

C Builder's huge gather

In order to handle the message, C Builder, therefore defines three gauges (Macro).

Begin_MESSAGE_MAP

Message_handler (WM_NCHITEST, TMESSAGE, ONNCHITTEST)

END_MESSAGE_MAP (TFORM)

The above three gauge begin_message_map, message_handler and end_message are the gauge of C Builder definition, which is more important to message_handler; it requires three parameters, the first parameter represents the iD, the second representative parameter type, The last one is the message handler.

At first glance, this huge set seems to have a few differences between MFC and OWL, it's true, but its mechanism is more simple and concise, we can look at C Builder for these three gauges Original definition:

#define begin_message_map virtual void __fastcall dispatch (void * message) /

{/

Switch ((pMessage) -> msg) /

{

#define message_handler (MSG, Type, Meth) /

Case MSG: /

Meth (* ((type *) message); /

Break;

#define end_message_map (base) Default: /

Base :: dispatch (message); /

Break; /

} /

}

It is much simpler than the terrible gather of MFC or OWL, because C Builder has completed most of the work for you. In fact, if we start the above giant set, you can get the following results:

Virtual void __fastcall dispatch (void * message)

{

Switch ((pMessage) -> msg

{

Case WM_NCHITTEST:

ONNCHITTEST (* (tMessage *) message);

Break;

DEFAULT:

TFORM :: Dispatch (Message);

Break;

}

}

how about it? After the start, it is very easy to find out that this huge gather is very easy to sell, if you play MFC's message processing mechanism, then see the above gather, compared to pediatric However, it is also due to its simple, so the advantage of C Builder is highlighted.

I briefly explain the above program: Deconsive virtual fifth named Dispatch in each TForm, which is used to handle Windows messages, in most cases, the message is called C Builder Provide a handset, so you don't need to modify it.

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

New Post(0)