Preliminary study on message processing in VCL

zhaozj2021-02-08  285

TOBJECT is a base class, so let's take a look at the Tobject's Dispatch method. Dispatch looks for the corresponding message processing method according to the incoming Message. If you can't find it, continue to find a response method in the message processing method table of the parent class, until you find it, if you find it, Call DEFAULTHANDLE to process the message. Message can be any type, Dispatch assumes that the head two of the Message is the ID of the message, which is based on the ID to find message processing methods. Although any type of Message can be accepted, the subclass of TOBJECT still wants to be incoming Message parameters is the type of TMESSAGE or other certified record type. The following statements and comments taken from the system.pas: {TObject.Dispatch accepts any data type as its Message parameter The first 2 bytes of the data are taken as the message id to search for in the object's message methods TDispatchMessage is an example of.. . such a structure with a word field for the message id} TDispatchMessage = record MsgID: Word; end; class hierarchy as follows: TObject-> TPersistent-> TComponent-> TControlTControl is so parent visual components, TControl provides a the new method, WndProc: procedure TControl.WndProc (var Message: TMessage); var Form: TCustomForm; KeyState: TKeyboardState; WheelMsg: TCMMouseWheel; begin // If you are in the design phase if (csDesigning in ComponentState) then begin Form: = GetParentForm (Self); // Get the form IF (Form <> nil) and form.designer.isdesignMSG (Self, Message) Then Exit // of the form with the component is processed by the form END;

// The form can process the keyboard message for the components they own. IF (Message.msg> = WM_KEYFIRST) AND (Message.msg <= WM_KEYLAST) THEN BEGIN form: = getParentform (Self); if (Form <> nil) and form.wantchildkey (self, message) Then Exit; end;

// About the message of the mouse else if (Message.msg> = WM_Mousefirst) and (message.msg <= wm_mouselast) THEN BEGIN / / If the component is not acceptable and handled double-click the message, you will double-click the message mapping to click the message. if not (csDoubleClicks in ControlStyle) then case Message.Msg of WM_LBUTTONDBLCLK, WM_RBUTTONDBLCLK, WM_MBUTTONDBLCLK: Dec (Message.Msg, WM_LBUTTONDBLCLK - WM_LBUTTONDOWN); end; case Message.Msg of WM_MOUSEMOVE: Application.HintMouseMessage (Self, Message); // If it is a message, the Hint window WM_LBUTTONDOWN, WM_LBUTTONDBLCLK: // If the left button is pressed, or double-click, if it is automatically dragged mode, start dragging and put the left button to add the status to the component. status. begin if FDragMode = dmAutomatic then begin BeginAutoDrag; Exit; end; Include (FControlState, csLButtonDown); end; WM_LBUTTONUP: Exclude (FControlState, csLButtonDown); // if it is left open, then the button pressed state removed.

Else with mouse do if WheelPresent and (regwheelmessage <> 0) And // If the mouse has a roller and the scroll is sliding (Message.MSG = RegwheelMessage) Then Begin getKeyboardState (KeyState); // Status of the 256 virtual key copied into the cache fill to record with WheelMsg do // begin Msg: = Message.Msg; ShiftState: = KeyboardStateToShiftState (KeyState); WheelDelta: = Message.WParam; Pos: = TSmallPoint (Message.LParam); end; mouseWheelHandler (TMessage (WHEELMSG)); // Distributes the message exit; end; end; end; end else if message.msg = cm_visiblechanged the with message do senddocknotification (MSG, WPARAM, LPARAM); // Handling Custom Message Dispatch (Message); / / Distribute unprocessed message END; but only TwinControl can get focus: procedure warontrol.WndProc (var message: tMessage); var form: tcustom; begin case: // Setting the focus of the control begin form: = GetParentform; IF (Form <> nil) and not form.setfocusedControl (Self) THEN EXIT; END WM_KILLFOCUS: if csfocusing in controlState dam; // Send this message when the mouse is active, if the mouse is not captured, the message is sent to the window below, otherwise the message will be sent to the window to capture the mouse. . Wm_nchittest: Begin Inherited WndProc (Message); // Call the method of processing the parent class // If the form is blocked and there is no control at the specified point, the return result is in the Client area.

if (Message.Result = HTTRANSPARENT) and (ControlAtPos (ScreenToClient (SmallPointToPoint (TWMNCHitTest (Message) .Pos)), False) <> nil) then Message.Result: = HTCLIENT; Exit; end; WM_MOUSEFIRST..WM_MOUSELAST: if IsControlMouseMsg if (TWMMouse (message)) then // mouse messages sent directly to form subassembly components begin {Check HandleAllocated because IsControlMouseMsg might have freed the window if user code executed something like Parent:. = nil} if (Message.Result = 0) And HandleAllocated Ten DefWindowProc (Handle, Message.msg, Message.wParam, Message.lParam); // Call the default message processing method to default to the message. Exit; end; WM_KEYFIRST..WM_KEYLAST: if Dragging then Exit; WM_CANCELMODE: if (GetCapture = Handle) and (CaptureControl <> nil) and (CaptureControl.Parent = Self) then CaptureControl.Perform (WM_CANCELMODE, 0, 0); end Inherited WndProc (Message); End; Tapplication plays an important role in the program: Application.run;

procedure TApplication.Run; begin FRunning: = True; try AddExitProc (DoneApplication); if FMainForm <> nil then begin case CmdShow of SW_SHOWMINNOACTIVE: FMainForm.FWindowState: = wsMinimized; SW_SHOWMAXIMIZED: MainForm.WindowState: = wsMaximized; end; if FShowMainForm then IF FMAINFORM.FWINDOWSTATE = WSMINIMIZED THEN minize else fMainform.Visible: = true;

// A message is looped until Terminated is True. REPEAT TRY HANDLEMESSAGE; EXCEPT HANDEEXCEME (Self); End; Until Terminated; end; end;

procedure TApplication.HandleMessage; var Msg: TMsg; begin if not ProcessMessage (Msg) then Idle (Msg); end; function TApplication.ProcessMessage (var Msg: TMsg): Boolean; var Handled: Boolean; begin Result: = False; if PeekMessage (MSG, 0, 0, 0, PM_Remove) THEN / / Remove the message from the ready-made message loop and put it in the specified message structure. Begin Result: = true; if msg.Message <> WM_QUIT THEN / / If not exit message, the corresponding processing Begin Handled: = false; if Assigned (FonMessage) THEN FONMESSAGE (MSG, Handled); if not ishintmsg (MSG) And not handled and not ismdimsg (msg) and not iskeymsg (msg) and not isdlgmsg (MSG) THEN BEGIN TRANSLATEMINATE: = True; end; end;

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

New Post(0)