如何让TImage、TLabel控件接收WM_RBUTTONDOWN消息
问题原因
- 你当前实现仅适配有独立窗口句柄的
TWinControl子类控件,TLabel、TImage属于无窗口句柄的TGraphicControl类型,它们的绘制、事件响应都由父控件转发,不会独立接收WM_RBUTTONDOWN消息,FindControl(Msg.hwnd)无法获取到这类控件的实例。
修改方案
修改逻辑为收到右键消息时,通过鼠标坐标定位当前点击位置的所有控件(包含无句柄图形控件),修改后的代码如下:
procedure TformMain.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean); begin case Msg.message of Winapi.Messages.WM_RBUTTONDOWN: begin var keys: TKeyboardState; GetKeyboardState(keys); // 先判断快捷键是否按下,减少不必要的计算 if (keys[VK_SHIFT] and $80 <> 0) and (keys[VK_CONTROL] and $80 <> 0) then begin var ClickPos: TPoint := Msg.pt; // 把屏幕坐标转为当前活动窗体的客户区坐标 var TargetForm := Screen.ActiveForm; if not Assigned(TargetForm) then Exit; ClickPos := TargetForm.ScreenToClient(ClickPos); // 查找坐标下的控件,支持TGraphicControl类型 var TargetControl := TargetForm.ControlAtPos(ClickPos, True, True, True); if Assigned(TargetControl) then begin Handled := True; Vcl.Clipbrd.Clipboard.AsText := TargetControl.Name; end; end; end; end; end;
参数说明
ControlAtPos的三个布尔参数含义:
- 第一个参数:是否允许递归查找子控件
- 第二个参数:是否包含不可见控件
- 第三个参数:是否包含无句柄的
TGraphicControl类型控件,设置为True即可支持TLabel、TImage等控件
内容的提问来源于stack exchange,提问作者user1580348
相关产品推荐
相关产品推荐

