delphi 拖拽图片_拖动不带标题栏的Delphi表单

delphi 拖拽图片

The most common way to move a window is to drag it by its title bar. Read on to find out how you can provide dragging capabilities for Delphi forms without a title bar, so the user can move a form by clicking anywhere on the client area.

移动窗口的最常见方法是通过其标题栏拖动它。 请继续阅读以了解如何在不带标题栏的情况下为Delph i表单提供拖动功能,以便用户可以通过单击工作区中的任意位置来移动表单。

For example, consider the case of a Windows application that doesn't have a title bar, how can we move such a window? In fact, it's possible to create windows with a nonstandard title bar and even non-rectangular forms. In this case, how could Windows know where the borders and the corners of the window are?

例如,考虑Windows应用程序没有标题栏的情况,我们如何移动这样的窗口? 实际上,可以创建带有非标准标题栏甚至非矩形表单的窗口。 在这种情况下,Windows如何知道窗口的边界和角落在哪里?

WM_NCHitTest Windows消息 ( The WM_NCHitTest Windows Message )

The Windows operating system is heavily based on handling messages. For example, when you click on a window or a control, Windows sends it a wm_LButtonDown message, with additional information about where the mouse cursor is and which control keys are currently pressed. Sounds familiar? Yes, this is nothing more than an OnMouseDown event in Delphi.

Windows操作系统很大程度上基于处理消息 。 例如,当您单击窗口或控件时,Windows向其发送wm_LButtonDown消息,以及有关鼠标光标在何处以及当前按下了哪些控制键的附加信息。 听起来很熟悉? 是的,这只不过是Delphi中的OnMouseDown事件。

Similarly, Windows sends a wm_NCHitTest message whenever a mouse event occurs, that is, when the cursor moves, or when a mouse button is pressed or released.

同样,每当发生鼠标事件 (即,光标移动或按下或释放鼠标按钮)时,Windows都会发送wm_NCHitTest消息。

输入代码 ( Code to Input )

If we can make Windows think that the user is dragging (has clicked on) the title bar rather than the client area, then the user could drag the window by clicking in the client area. The easiest way to do this is to "fool" Windows into thinking that you're actually clicking on the title bar of a form. Here's what you have to do:

如果我们可以使Windows认为用户正在拖动(已单击)标题栏而不是工作区,则用户可以通过单击工作区来拖动窗口。 最简单的方法是“欺骗” Windows,使您认为您实际上是在单击表单的标题栏。 这是您要做的:

1. Insert the following line into your form's "Private declarations" section (message handling procedure declaration):

1.将以下行插入到表单的“私人声明”部分(消息处理过程声明)中:

 procedure WMNCHitTest(var Msg: TWMNCHitTest) ; message WM_NCHitTest; 

2. Add the following code into the "implementation" section of your form's unit (where Form1 is the assumed form name):

2.将以下代码添加到表单单元的“实现”部分(其中Form1是假定的表单名称):

 procedure TForm1.WMNCHitTest(var Msg: TWMNCHitTest) ;
begin
    inherited;
if Msg.Result = htClient then Msg.Result := htCaption;
end; 

The first line of code in the message handler calls the inherited method to obtain the default handling for the wm_NCHitTest message. The If part in the procedure intercepts and changes your window's behavior. This is what actually happens: when the operating system sends a wm_NCHitTest message to the window, together with the mouse coordinates, the window returns a code that states which portion of itself has been hit. The important piece of information, for our task, is in the value of the Msg.Result field. At this point, we have an opportunity to modify the message result.

消息处理程序中的第一行代码调用继承的方法以获得wm_NCHitTest消息的默认处理。 过程中的If部分将拦截并更改窗口的行为。 这是实际发生的情况:当操作系统将wm_NCHitTest消息与鼠标坐标一起发送到窗口时,窗口将返回一个代码,指出自身的哪一部分已被击中。 对于我们的任务而言,重要的信息是Msg.Result字段的值。 在这一点上,我们有机会修改消息结果。

This is what we do: if the user has clicked in the form's client area we make Windows to think the user clicked on the title bar. In Object Pascal "words": if the message return value is HTCLIENT, we simply change it to HTCAPTION.

这就是我们要做的:如果用户单击了表单的工作区,则使Windows认为用户单击了标题栏。 在对象Pascal “单词”中:如果消息返回值为HTCLIENT,我们只需将其更改为HTCAPTION。

没有更多的鼠标事件 ( No More Mouse Events )

By changing the default behavior of our forms we remove the ability of Windows to notify you when the mouse is over the client area. One side effect of this trick is that your form will no longer generate events for mouse messages.

通过更改表单的默认行为,我们取消了Windows在鼠标悬停在客户区域上方时通知您的功能。 此技巧的一个副作用是您的表单将不再为鼠标消息生成事件

无字幕无边界窗口 ( Captionless-Borderless Window )

If you want a captionless borderless window similar to a floating toolbar, set the Form's Caption to an empty string, disable all of the BorderIcons, and set the BorderStyle to bsNone.

如果要使用类似于浮动工具栏的无标题无边界窗口,请将窗体的标题设置为空字符串,禁用所有BorderIcons,并将BorderStyle设置为bsNone。

A form can be changed in various ways by applying custom code in the CreateParams method.

通过在CreateParams方法中应用自定义代码,可以通过多种方式更改表单。

更多WM_NCHitTest技巧 ( More WM_NCHitTest Tricks )

If you look more carefully at the wm_NCHitTest message you'll see that return value of the function indicates the position of the cursor hot spot. This enables us to play some more with the message to create strange results.

如果您仔细看一下wm_NCHitTest消息,您会发现该函数的返回值指示光标热点的位置。 这使我们能够在消息中发挥更多的作用,以创造出奇特的结果。

The following code fragment will prevent users to close your forms by clicking on the Close button.

以下代码片段将阻止用户通过单击“关闭”按钮来关闭您的表单。

 if Msg.Result = htClose then Msg.Result := htNowhere; 

If the user is trying to move the form by clicking on the caption bar and dragging, the code replaces the result of the message with a result which indicates the user clicked on the client area. This prevents the user from moving the window with the mouse (opposite to what we were doing in the begging of the article).

如果用户试图通过单击标题栏并拖动来移动表单,则该代码会将消息的结果替换为指示用户单击了客户区域的结果。 这样可以防止用户用鼠标移动窗口(与我们在文章乞求中所做的相反)。

 if Msg.Result = htCaption then Msg.Result := htClient; 

在表单上包含组件 ( Having Components On a Form )

In most cases, we'll have some components on a form. Let's say, for example, that one Panel object is on a form. If Align property of a panel is set to alClient, the Panel fills the entire client area so that it is impossible to select the parent form by clicking on it. The code above will not work — why? It's because the mouse is always moving over the Panel component, not the form.

在大多数情况下,我们在表单上会有一些组件。 例如,假设一个Panel对象在表单上。 如果将面板的“对齐”属性设置为alClient,则“面板”将填充整个客户区域,因此无法通过单击来选择父窗体。 上面的代码不起作用-为什么? 这是因为鼠标总是在面板组件而不是窗体上移动。

To move our form by dragging a panel on the form we have to add few lines of code in the OnMouseDown event procedure for the Panel component:

要通过在窗体上拖动面板来移动窗体,我们必须在OnMouseDown事件过程中为Panel组件添加几行代码:

 procedure TForm1.Panel1MouseDown

   (Sender: TObject; Button: TMouseButton;
(发件人:TObject;按钮:TMouseButton;
   Shift: TShiftState; X, Y: Integer) ;
Shift:TShiftState; X,Y:整数);
begin
    ReleaseCapture;
    SendMessage(Form1.Handle, WM_SYSCOMMAND, 61458, 0) ;
 end; 

Note: This code will not work with non-window controls such as TLabel components.

注意 :此代码不适用于非窗口控件,例如TLabel组件

翻译自: https://www.thoughtco.com/drag-a-delphi-form-1058461

delphi 拖拽图片

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值