wxWidgets实现无标题栏窗口拖动效果
本文实例为大家分享了wxWidgets实现无标题栏窗口拖动的具体代码,供大家参考,具体内容如下
最近需要做一个自定义的标题栏,而其中最重要的就是要实现窗口的拖动。默认情况下有标题栏,都可以通过拖动系统默认的标题栏,但是自定义的标题栏需要自己实现拖动。
实现无标题窗口的拖动,在MFC中可以在鼠标在窗口中拖动时,发送虚假的消息给窗口来进行实现(注:MFC可以发送鼠标在标题栏拖动的消息)。但是在wxWidgets中,暂时没有看到类似的消息。因工作需要,才学习wxWidgets不久。如果有知道相关消息的朋友,请发消息告诉。而自己实现拖动,大致可以分为三个步骤。
1、在鼠标左键按下时,记录下鼠标位置,使用CaptureMouse来进行鼠标捕获 。注意,这里如果不捕获鼠标,那么也能实现拖动窗口,但是会出现一个小问题,就是当鼠标在窗口边缘快速的拖出窗口的时候,窗口不能进行移动。因为系统对鼠标的移动事件的发送是有事件间隔的,窗口收到该消息时鼠标已经离开了窗口,所以不能正确拖动。一定要记得设置鼠标捕获。
2、当鼠标拖动的时候(在鼠标事件中判断鼠标左键按下且在拖拽),计算鼠标新的位置相对之前的位移向量,并移动窗口到相应的位置。
3、处理鼠标左键抬起事件,在鼠标抬起事件中使用ReleaseMouse来释放之前捕获的鼠标。
4、处理EVT_MOUSE_CAPTURE_LOST(func)事件,在其中释放鼠标捕获。官方文档有说明,对鼠标进行捕获必须处理该事件,并在其中释放鼠标捕获。因为弹出对话框等情况会导致鼠标是按下的,但是父窗口却失去了鼠标焦点的状况,所以必须处理该事件释放鼠标。
下面给出我自己实现的一个可以通过鼠标拖拽实现移动的无标题栏窗口的代码,可以对照上边的介绍看一下具体的实现。这个类实现的是拖动自己,当然可以利用在计算坐标之后获取父窗口来进行移动,那样就可以实现鼠标在子窗口上拖动来实现整个窗口的移动。也就是自定义的标题栏应该具有的基本功能。
头文件:MyTitleWnd.h
#pragma once #include <wx/wx.h> class MyTitleWnd:public wxFrame { public: MyTitleWnd(wxWindow *parent,wxWindowID id=wxID_ANY); virtual ~MyTitleWnd(); void OnMouseMove(wxMouseEvent& event); void OnMouseLeave(wxMouseEvent& event); void OnMouseLDown(wxMouseEvent& event); void OnMouseLUp(wxMouseEvent& event); void OnMouseCaptureLost(wxMouseCaptureLostEvent& event); private: wxPoint mLastPt; wxString mText; DECLARE_EVENT_TABLE() };
源文件:MyTitleWnd.cpp
#include "MyTitleWnd.h" BEGIN_EVENT_TABLE(MyTitleWnd, wxFrame) EVT_MOUSE_CAPTURE_LOST(MyTitleWnd::OnMouseCaptureLost) //EVT_LEFT_DOWN(MyTitleWnd::OnMouseLDown) EVT_LEFT_UP(MyTitleWnd::OnMouseLUp) EVT_MOUSE_EVENTS(MyTitleWnd::OnMouseMove) EVT_LEAVE_WINDOW(MyTitleWnd::OnMouseLeave) END_EVENT_TABLE() MyTitleWnd::MyTitleWnd(wxWindow *parent, wxWindowID id/*=wxID_ANY*/) :wxFrame(parent, id,"", wxDefaultPosition, wxDefaultSize, wxBORDER_NONE) { } MyTitleWnd::~MyTitleWnd() { } void MyTitleWnd::OnMouseMove(wxMouseEvent &event) { if(event.LeftIsDown()&&event.Dragging()) { wxPoint pt = event.GetPosition(); wxPoint wndLeftTopPt = GetPosition(); int distanceX = pt.x - mLastPt.x; int distanceY = pt.y - mLastPt.y; wxPoint desPt; desPt.x = distanceX + wndLeftTopPt.x; desPt.y = distanceY + wndLeftTopPt.y; this->Move(desPt); } if (event.LeftDown()) { this->CaptureMouse(); mLastPt = event.GetPosition(); } } void MyTitleWnd::OnMouseLeave(wxMouseEvent& event) { if (event.LeftIsDown() && event.Dragging()) { wxPoint pt = event.GetPosition(); wxPoint wndLeftTopPt = GetPosition(); int distanceX = pt.x - mLastPt.x; int distanceY = pt.y - mLastPt.y; wxPoint desPt; desPt.x = distanceX + wndLeftTopPt.x; desPt.y = distanceY + wndLeftTopPt.y; this->Move(desPt); } } void MyTitleWnd::OnMouseLDown(wxMouseEvent& event) { this->CaptureMouse(); } void MyTitleWnd::OnMouseLUp(wxMouseEvent& event) { if (HasCapture()) ReleaseMouse(); } void MyTitleWnd::OnMouseCaptureLost(wxMouseCaptureLostEvent& event) { if (HasCapture()) ReleaseMouse(); }
好了,最后贴出效果图。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
您可能感兴趣的文章
- 01-10数据结构课程设计-用栈实现表达式求值的方法详解
- 01-10使用OpenGL实现3D立体显示的程序代码
- 01-10求斐波那契(Fibonacci)数列通项的七种实现方法
- 01-10C语言 解决不用+、-、&#215;、&#247;数字运算符做加法
- 01-10使用C++实现全排列算法的方法详解
- 01-10fatal error LNK1104: 无法打开文件“libc.lib”的解决方法
- 01-10用C++实现DBSCAN聚类算法
- 01-10深入全排列算法及其实现方法
- 01-10全排列算法的非递归实现与递归实现的方法(C++)
- 01-10用C语言实现单链表的各种操作(一)
阅读排行
本栏相关
- 04-02c语言函数调用后清空内存 c语言调用
- 04-02func函数+在C语言 func函数在c语言中
- 04-02c语言的正则匹配函数 c语言正则表达
- 04-02c语言用函数写分段 用c语言表示分段
- 04-02c语言中对数函数的表达式 c语言中对
- 04-02c语言编写函数冒泡排序 c语言冒泡排
- 04-02c语言没有round函数 round c语言
- 04-02c语言分段函数怎么求 用c语言求分段
- 04-02C语言中怎么打出三角函数 c语言中怎
- 04-02c语言调用函数求fibo C语言调用函数求
随机阅读
- 08-05dedecms(织梦)副栏目数量限制代码修改
- 01-10SublimeText编译C开发环境设置
- 01-10使用C语言求解扑克牌的顺子及n个骰子
- 01-11Mac OSX 打开原生自带读写NTFS功能(图文
- 08-05DEDE织梦data目录下的sessions文件夹有什
- 01-11ajax实现页面的局部加载
- 04-02jquery与jsp,用jquery
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法实例总结
- 08-05织梦dedecms什么时候用栏目交叉功能?