窗口移动--基类(BaseForm)
#region 窗口移动
private bool _isLeftButtonDown = false;
public const int HTCAPTION = 0x0002;
protected override void WndProc(ref System.Windows.Forms.Message m)
{
base.WndProc(ref m);
switch (m.Msg)
{
case WinApi.WM_LBUTTONDOWN:
case WinApi.WM_LBUTTONUP:
int lParam = m.LParam.ToInt32();
int x = lParam & 0xFFFF;
int y = (lParam >> 16);
switch (m.Msg)
{
case WinApi.WM_LBUTTONDOWN:
if (x < Width - 20 || y > 20)
{
this._isLeftButtonDown = true;
WinApi.ReleaseCapture();
WinApi.SendMessage(this.Handle, WinApi.WM_SYSCOMMAND, WinApi.SC_MOVE + HTCAPTION, 0);
}
break;
case WinApi.WM_LBUTTONUP:
if (this._isLeftButtonDown)
{
this._isLeftButtonDown = false;
if (x < Width - 20 || y > 20)
{
WinApi.ReleaseCapture();
SaveLocation();
}
}
break;
}
break;
}
}
/// <summary>
/// 保存窗口位置.
/// </summary>
private void SaveLocation()
{
if (this._isLeftButtonDown)
{
SavedLocation = this.Location;
}
}
/// <summary>
/// 引发 <see cref="E:System.Windows.Forms.Control.LocationChanged"/> 事件。
/// </summary>
/// <param name="e">包含事件数据的 <see cref="T:System.EventArgs"/>。</param>
protected override void OnLocationChanged(EventArgs e)
{
const int DX = 25;
const int DY = 25;
Point location = this.Location;
Rectangle rect = Screen.PrimaryScreen.WorkingArea;
if (location.X + this.Width < DX)
{
location.X = DX - this.Width;
}
else if (location.X + DX > rect.Width)
{
location.X = rect.Width - DX;
}
if (location.Y + this.Height < DY)
{
location.Y = DY - this.Height;
}
else if (location.Y + DY > rect.Height)
{
location.Y = rect.Height - DY;
}
if (location != this.Location)
{
this.Location = location;
}
SaveLocation();
}
private const string SAVED_LOCATION_REGSTER_KEY = @"Software\AlarmClient\SavedLocation";
/// <summary>
/// 保存路径
/// </summary>
private Point SavedLocation
{
get
{
int x, y;
try
{
RegistryKey key = Registry.CurrentUser.OpenSubKey(SAVED_LOCATION_REGSTER_KEY);
if (key != null)
{
x = (int)key.GetValue("X", 0);
y = (int)key.GetValue("Y", 0);
return new Point(x, y);
}
}
catch (Exception ex)
{
TestLog.DoLog(ex);
}
Rectangle rect = Screen.PrimaryScreen.WorkingArea;
x = rect.Width - this.Width;
y = rect.Height - this.Height;
return new Point(x, y);
}
set
{
try
{
RegistryKey key = Registry.CurrentUser.CreateSubKey(SAVED_LOCATION_REGSTER_KEY);
key.SetValue("X", value.X);
key.SetValue("Y", value.Y);
}
catch (Exception ex)
{
TestLog.DoLog(ex);
}
}
}
/// <summary>
/// 引发 <see cref="E:System.Windows.Forms.Form.Load"/> 事件。
/// </summary>
/// <param name="e">包含事件数据的 <see cref="T:System.EventArgs"/>。</param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//if (this._activeWindow != IntPtr.Zero)
//{
// WinApi.SetActiveWindow(this._activeWindow);
//}
//this.Controls.EachChildFirst((Control c) =>
//{
// LabelX label = c as LabelX;
// if (label == null) return false;
// label.MouseDown += new MouseEventHandler(label_MouseDown);
// label.MouseMove += new MouseEventHandler(label_MouseMove);
// return true;
//});
// 让窗口上的每一个 LabelX 都把鼠标按下和移动的消息发送给本窗口
MouseEventHandler down = new MouseEventHandler(label_MouseDown);
MouseEventHandler move = new MouseEventHandler(label_MouseMove);
// 遍历窗口中的 LabelX
this.Controls.EachChildFirst((Control c) =>
{
LabelX label = c as LabelX;
if (label == null) return false;
label.MouseDown += down;
label.MouseMove += move;
return true;
});
// 加载初始位置
this.Location = this.SavedLocation;
// 设置窗口为一个圆角的矩形
//this.Region = CreateRegion();
}
/// <summary>
/// 给窗口添加圆角区域
/// </summary>
/// <returns></returns>
private Region CreateRegion()
{
const int RX = 15;
const int RY = 15;
//Region region = this.Region;
System.Drawing.Drawing2D.GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
path.FillMode = System.Drawing.Drawing2D.FillMode.Winding;
path.AddRectangle(new Rectangle(1, RY, this.Width - 2, this.Height - (RY + RY)));
path.AddRectangle(new Rectangle(RX, 1, this.Width - (RX + RX + 2), this.Height - 2));
path.AddEllipse(1, 0, RX + RX, RY + RY);
path.AddEllipse(1, this.Height - (RY + RY + 2), RX + RX, RY + RY);
path.AddEllipse(this.Width - (RX + RX + 2), 0, RX + RX, RY + RY);
path.AddEllipse(this.Width - (RX + RX + 2), this.Height - (RY + RY + 2), RX + RX, RY + RY);
return new Region(path);
}
/// <summary>
/// 鼠标在 LabelX 上移动时,将消息发送给窗口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void label_MouseMove(object sender, MouseEventArgs e)
{
WinApi.PostMessage(this.Handle, WinApi.WM_MOUSEMOVE, 1, e.X | (e.Y << 16));
}
/// <summary>
/// 鼠标在 LabelX 上按下时,将消息发送给窗口
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void label_MouseDown(object sender, MouseEventArgs e)
{
WinApi.PostMessage(this.Handle, WinApi.WM_LBUTTONDOWN, 1, e.X | (e.Y << 16));
}
#endregion
窗口移动--基类(BaseForm)的更多相关文章
- CS中窗体的基类(BaseForm)注意点
窗体基类最好新建一个窗体(BaseForm) 1.这样能够保证在VS中保证他的派生窗口也能够可视化. 2.如果基类直接是一个cs类文件,对于处理派生窗口就很复杂,比如按钮权限之类的操作; 如果直接继承 ...
- QWidget QMainWindow QDialog 三个基类的区别
Qt类是一个提供所需的像全局变量一样的大量不同的标识符的命名空间.通常情况下,你可以忽略这个类.QObject和一些其它类继承了它,所以在这个Qt命名空间中定义的所有标识符通常情况下都可以无限制的使用 ...
- WPF自定义窗口基类
WPF自定义窗口基类时,窗口基类只定义.cs文件,xaml文件不定义.继承自定义窗口的类xaml文件的根节点就不再是<Window>,而是自定义窗口类名(若自定义窗口与继承者不在同一个命名 ...
- WPF自学入门(九)WPF自定义窗口基类
今天简单记录一个知识点:WPF自定义窗口基类,常用winform的人知道,winform的窗体继承是很好用的,写一个基础窗体,直接在后台代码改写继承窗体名.但如果是WPF要继承窗体,我个人感觉没有理解 ...
- WPF 之 创建继承自Window 基类的自定义窗口基类
开发项目时,按照美工的设计其外边框(包括最大化,最小化,关闭等按钮)自然不同于 Window 自身的,但窗口的外边框及窗口移动.最小化等标题栏操作基本都是一样的.所以通过查看资料,可按如下方法创建继承 ...
- wpf之mvvm基类
当我们用MVVM设计模式的时候要实现INotifyPropertyChanged,每次都要实现这个接口比较麻烦,所以基类的作用就体现出来了.代码如下: 1 2 3 4 5 6 7 8 9 10 1 ...
- Thinkphp源码分析系列(七)–控制器基类
在mvc模式中,c代表的就是控制器,是是应用程序中处理用户交互的部分.通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据.控制器是沟通视图和模型的桥梁,他接受用户请求,并调用模型层去处理用户 ...
- WPF开发时光之痕日记本(二)—— MVVM基类
当我们用MVVM的时候要实现INotifyPropertyChanged,每次都要实现这个接口比较麻烦,所以基类的作用就体现出来了.代码如下: public class ViewModelBase : ...
- Duilib学习笔记《06》— 窗体基类WindowImpBase
在前面的例子中我们发现,窗口都是继承CWindowWnd.INotifyUI,然后重载相关函数去实现.显然,我们发现窗口的创建流程实际上都是差不多的,主要只是在OnCreate加载的配置文件不同等等… ...
随机推荐
- android linux
app 权限 - shell 权限2000 system root .adb 指令 a.查看链接终端设备 adb devices b.进入设备终端 adb shell ;多台设备 adb -s 设备号 ...
- oracle的用户
1:创建用户 create user zhaoyb identified by zhaoyb default tablespace HUAPUSALEDB create user 用户名 identi ...
- 夺命雷公狗---node.js---6net模块玩telnet通信(下)
我们来升级玩玩,废话不多说,代码如下所示: /** * Created by leigood on 2016/8/12. */ var net = require('net'); var ChatSr ...
- RobotFramework 安装配置(一)
服务器接口的测试框架的选择,最后选中了 RobotFramework ,原因一:能有效的管理测试用例,,支持批量执行,能实现关键字驱动或者数据驱动.原因二:支持测试人员可以使用Python和java创 ...
- 利用Qt Assistant 定制帮助文档
为了将Qt Assistant定制为自己应用程序的帮助文档浏览器.需要完成以下几步: 一.导入HTML格式的帮助文档 (1)首先,针对自己的应用程序创建HTML格式的帮助文档,请参见<Doxyg ...
- android 学习随笔十一(网络:HttpClient框架)
1.使用HttpClient框架发送get.post请求 google收集apache提供的一个发送Http请求框架 public class Tools { public static String ...
- CentOS修改主机名和网络信息
1.修改主机名称 [root@centos ~]# vim /etc/sysconfig/network打开文件,修改以下内容并保存 NETWORKING=yes #使用网络 HOSTNAME=cen ...
- Access数据库导入到SQL Server 2005 Express中
安装好SQL Server 2005 Express后,再安装SQL Server Management Studio Express CTP就可以很方便的使用控制台进行数据库的管理.但SQL Ser ...
- datatables条件判断列显示还是隐藏
定义一个状态变量status根据条件取值true或者false,然后在datatables参数设置中相应的columns属性的data后面加上"visible":status,该列 ...
- 精通 JS正则表达式
一.正则表达式可以: 测试字符串的某个模式.例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式.这称为数据有效性验证 替换文本.可以在文档中使用一个正则表达式 ...