zoukankan      html  css  js  c++  java
  • 无标题窗体拖动(三种方法)

    通过响应“wm_NCHitTest”消息来移动窗体。
    Windows发送“wM_NCHitTest”消息来确定鼠标操作是否发生在窗体
    的客户区,或边框的特殊区上(非客户区)。
    如果Windows发现用户单击了窗体标题,系统将移动窗体,
    单击了窗体边框,则系统将开始改变窗体大小。
    例程如下:

    //声明一自定义事件,拦截“WM_NCHITTEST”消息
    Procedure MoveForm(var M:TWMNCHITTEST);Message WM_NCHITTEST;          
    
    Procedure TForm1.MoveForm (var M:TWMNCHITTEST);
    begin
    inHerited;                                 //继承,窗体可以继续处理以后的事件
    if (M.Result=HTCLIENT)                   //如果发生在客户区
    and ((GetKeyState(vk_CONTROL) < 0)           //检测“Ctrl”键是否按下
    then M.Result:=HTCAPTION;                   //更改“.Result”域的值
    end;

    方法二:
    通过为Application.OnMessage创建一个处理程序获得Windows消息,
    可以调整应用程序对不同消息的响应或为不能正常识别的
    消息提供服务。这里受到窗体客户区的鼠标按下的消息后,
    发送一条在标题栏内按下的消息。
    例程如下:

      procedure TForm1.FormCreate(Sender: TObject);
      begin Application.OnMessage := AppMessage;
      // 捕捉消息:将程序的收到消息事件与消息过滤过程关联起来
      end;
    
      procedure TForm1.AppMessage(var Msg: TMsg; var Handled: Boolean);
      begin
      if (Msg.message = WM_LButtonDown) and
      // 如果鼠标左键按下的话
        (DefWindowProc(Handle, WM_NCHitTest, 0, GetMessagePos) = HTClient) and
      // 判断光标是否在客户区内
        ((GetKeyState(vk_CONTROL) < 0)
        // 检测“Ctrl”键是否按下
          then begin SendMessage(Handle WM_NCLButtonDown HTCaption GetMessagePos);
        // 发送鼠标在标题栏内按下的消息
        Handled := true; 
       end;

    方法三:
    直接向窗体发送一条“wm_SysCommand”消息,需要使用未归档
    的“sc_DragMove”标志,定义如下:
    const sc_DragMove:LongInt=$F012;
    我们只能向TWinControl派生组件发送该消息,而且只能响应
    鼠标按下事件,因为系统会在此时捕获鼠标(当释放鼠标键时,
    拖动操作是没有意义的)。
    例程如下:

    const
    sc_DragMove:longint=$F012;
    implementation
    {$R *.DFM}
    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; XY: Integer);
    begin
    if ssCtrl in Shift then
    //判断“Ctrl”键是否按下
    Begin
    
    ReleaseCapture;
    
    //释放鼠标事件的对象
    (Sender as TWinControl).Perform(wm_SysCommand, sc_DragMove, 0);
    //发送消息
    end;
    end;

    这种方法适用与窗体与组件,如想移动组件,将其“OnMouseDown”事件写成与Form的“OnMouseDown”事件一样即可。
    如只想移动窗体可按以下方法编写代码:

    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X Y: Integer);
    begin
      if SsCtrl in Shift then
      Begin
        ReleaseCapture;
        SendMessage(handle, wm_SysCommand, sc_DragMove, 0);
      end;
    end;

    运行结果:
    按下“Ctrl”键拖动鼠标即可移动窗体。
    要实现无标题窗体的移动有很多种方法,
    还可以通过检测鼠标的位置(坐标)来确定Form的“left”
    与“top”值等方法,在此不再详细举例.

    procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    begin
    if ssleft in shift then
         releasecapture;
    perform(WM_SYSCOMMAND,$F012,0);
    end; 

    参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832063.html

    -------------------------------------------------------------------------------------

    拖动窗体的任意区域移动窗体
    这是一个通过捕获WM_NCHITTEST消息来实现拖动窗体的任意区域移动窗体的方法。

    在Form1的public部分声明WM_NCHITTEST消息处理过程:

    public
    procedure OnWmncHitTest(var M: TWmncHitTest); message WM_NCHITTEST;

    编写消息处理过程的代码:

    procedure TForm1.OnWmncHitTest(var M: TWMNCHitTest);
    begin
    inherited;
    if M.Result = HTClient then
    M.Result := HTCaption;
    end;

    http://blog.csdn.net/diligentcatrich/article/details/17242849

  • 相关阅读:
    SpringMvc执行流程
    Lock wait timeout exceeded; try restarting transaction解决方法
    MySQL删除复杂的重复数据的解决方案(一条数据项中包含多个值的情况)
    数据移植时递归运算查询部门及其下级所有部门的问题
    IDEA常用插件
    mybatis和mybatisPlus中解决实体类字段与数据库关键字冲突问题
    时间日期操作
    spring项目中使用MD5加密方式
    idea如何调出仪表盘
    scanf使用过程中的技巧与坑位
  • 原文地址:https://www.cnblogs.com/findumars/p/4801943.html
Copyright © 2011-2022 走看看