设计思路:
1.使用定时器(Timer)来监控鼠标位置和窗体位置,并实现窗体的停靠和隐藏
2.当鼠标拖动窗体时,窗体才有可能根据自身位置决定是否停靠
3.如果窗体四周没有接触到屏幕边缘则不会停靠
4.如果窗体最小化或最大化了则不存在停靠和隐藏
5.如果鼠标拖动窗体时,如果窗体很接近屏幕边缘则自动将其停靠在该边缘,例如窗体离屏幕顶部小于4个像素则自动将其停靠在顶部
6.窗体可以在桌面的左侧、右侧和顶部停靠和隐藏
7.如果既满足顶部停靠的条件又满足侧面停靠的条件,则规定其向侧面隐藏
8.当鼠标位于窗体内部时,窗体不会隐藏
9.当鼠标位于窗体外部,窗体根据自身的位置决定是否隐藏
10.所谓的隐藏实际上并不是真正的隐藏,而是将整个窗体移出屏幕,仅在屏幕边缘留出一小部分
11.所谓的显示隐藏窗体实际上并不是真正的显示,而是将窗体再次移入屏幕

/// <summary>
/// 时间事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void timer1_Tick(object sender, EventArgs e)
{
try
{
timer1.Interval = 200;
AutoSideHideOrShow();
}
catch (Exception ex)
{
LogHelper.WriteLog(GetType(), ex.Message);
}
}

/// <summary>
/// 隐藏功能
/// </summary>
void AutoSideHideOrShow()
{
try
{
int sideThickness = 4;//边缘的厚度,窗体停靠在边缘隐藏后留出来的可见部分的厚度
//如果窗体最小化或最大化了则什么也不做
if (this.WindowState == FormWindowState.Minimized || this.WindowState == FormWindowState.Maximized)
{
return;
}
//如果鼠标在窗体内
if (Cursor.Position.X >= this.Left && Cursor.Position.X < this.Right && Cursor.Position.Y >= this.Top && Cursor.Position.Y < this.Bottom)
{
//如果窗体离屏幕边缘很近,则自动停靠在该边缘
if (this.Top <= sideThickness)
{
this.Top = 0;
}
if (this.Left <= sideThickness)
{
this.Left = 0;
}
if (this.Left >= Screen.PrimaryScreen.WorkingArea.Width - this.Width - sideThickness)
{
this.Left = Screen.PrimaryScreen.WorkingArea.Width - this.Width;
}
}
//当鼠标离开窗体以后
else
{
//隐藏到屏幕左边缘
if (this.Left == 0)
{
this.Left = sideThickness - this.Width;
LogHelper.WriteLog(GetType(), "AutoSideHideOrShow隐藏到屏幕左边缘");
}
//隐藏到屏幕右边缘
else if (this.Left == Screen.PrimaryScreen.WorkingArea.Width - this.Width)
{
this.Left = Screen.PrimaryScreen.WorkingArea.Width - sideThickness;
LogHelper.WriteLog(GetType(), "AutoSideHideOrShow隐藏到屏幕右边缘");
}
//隐藏到屏幕上边缘
else if (this.Top == 0 && this.Left > 0 && this.Left < Screen.PrimaryScreen.WorkingArea.Width - this.Width)
{
this.Top = sideThickness - this.Height;
LogHelper.WriteLog(GetType(), "AutoSideHideOrShow隐藏到屏幕上边缘");
}
}

}
catch (Exception ex)
{
LogHelper.WriteLog(GetType(), "AutoSideHideOrShow" + ex.Message);
}
}
#region 点击右上角X按钮关闭事件
protected override void WndProc(ref Message msg)
{
try
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_CLOSE = 0xF060;
// 点击winform右上关闭按钮
if (msg.Msg == WM_SYSCOMMAND && ((int)msg.WParam == SC_CLOSE))
{
webBrowser1.ExecuteJavascript("jslog()");//调用前端js方法

this.Close();

LogHelper.WriteLog(GetType(), "WndProc关闭窗体");
return;
}
base.WndProc(ref msg);
}
catch (Exception ex)
{
LogHelper.WriteLog(GetType(), "WndProc" + ex.Message);
}
}
#endregion

  

代码:

C#:winform窗体 实现类似QQ的窗体在桌面边缘停靠和隐藏的更多相关文章

  1. 转 实现类似QQ的窗体停靠

    [DllImport("User32.dll")] public static extern bool PtInRect(ref Rectangle Rects, Point lp ...

  2. C#利用API制作类似QQ一样的右下角弹出窗体

    C#利用API制作类似QQ一样的右下角弹出窗体 (2009-03-21 15:02:49) 转载▼ 标签: 杂谈 分类: .NET using System;using System.Collecti ...

  3. 用C#代码实现类似QQ窗体的“上、左、右”停靠功能

    大家都知道QQ有一个自动停靠功能,即“上.左.右”,当你把窗体拖到屏幕边缘,然后移开鼠标它会自动缩放,然后只显示一小小点出来,我们仔细观察会发现其实它只露3像素左右的边缘,当你鼠标移上去它又会伸出来, ...

  4. WinForm实现类似QQ停靠,显示隐藏过程添加特效效果

    原文:WinForm实现类似QQ停靠,显示隐藏过程添加特效效果 这可能是个老题长谈的问题了,只是在项目中会用到这个效果,所以今天做个记录.大家见了别喷我.在项目中的需求是这样的. 打开程序,在屏幕的右 ...

  5. .net winForm 实现类似qq 弹出新闻

    .net winForm 实现类似qq 弹出新闻   一.背景: echong 之前一直用 公司大牛c语言写的一个弹出托管,前几天写东西的时候发现com调用不是那么好使.而手头上写的这个东西又是.ne ...

  6. C# WinForm 慎用 override CreateParams 来重载窗体的一些特性

    窗体和控件的属性CreateParams(这真的是一个属性)很神奇,因为通过它你能够很方便的控制窗体或控件诸如边框.最大化最小化关闭按钮的隐藏.窗体的模式化弹窗模式等的一些特性.虽然,CreatePa ...

  7. winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体

    winform打开子窗体后,在子窗体中刷新父窗体,或者关闭子窗体刷新父窗体,搜集了几个方法,列举如下: 一 . 所有权法 父窗体,名称为“fuForm”,在父窗体中有个公共刷新方法,也就是窗体数据初始 ...

  8. C# WinForm 单例模式(例:同一个窗体只创建一次实例)

    //C# WinForm 单例模式(例:同一个窗体只创建一次实例) //打开窗体的事件: Form3 f = Form3.InstanceObject() ; //实例化窗体 f.Focus(); / ...

  9. c# winform 在一个窗体中使用另一个窗体中TextBox控件的值——解决办法

    [前提]一个winform应用程序项目中,窗体B,需要使用 窗体A 中一个TextBox控件的值,进行计算等操作. [解决方案] 1.在窗体A中定义:public static double a;// ...

随机推荐

  1. 毕设必看——Python ttkbootstrap 制作账户注册信息界面

    先来哔哔两句:(https://jq.qq.com/?_wv=1027&k=QgGWqAVF) ttkbootstrap 是一个基于 tkinter 的界面美化库,使用这个工具可以开发出类似前 ...

  2. UML之顺序图(时序图)

    1 顺序图 1.1 顺序图的概念 顺序图(sequence diagram): 用来描述为了完成确定事务,对象之间按照时间消息交互的顺序关系. 1.2 顺序图样式和元素 (1) 对象及命名 (2) 生 ...

  3. 广西省行政村边界shp数据/广西省乡镇边界/广西省土地利用分类数据/广西省气象数据/降雨量分布数据/太阳辐射数据

    ​  数据下载链接:数据下载链接 广西壮族自治区,地处中国南部,北回归线横贯中部,属亚热带季风气候区.南北以贺州--东兰一线为界,此界以北属中亚热带季风气候区,以南属南亚热带季风气候区. 数据范围:全 ...

  4. appium实现简单的功能测试

    实现思路 思路: 1.获取capabilities信息 2.启动app(包含安装过程) 3.检查是否安装成功 4.卸载app 5.检查是否卸载成功 6.执行×3 from time import sl ...

  5. 【docker专栏6】详解docker容器状态转换管理命令

    docker容器有三种状态运行.停止.暂停,镜像可以创建.运行容器,镜像和容器也可以转换成tar压缩包进行存储.本文为大家介绍容器的状态转换命令及镜像创建运行容器.tar包导入导出相关的命令及使用场景 ...

  6. MySQL主从复制及读写分离

    MySQL主从复制 MySQL数据库自身提供的主从复制功能可以方便的实现数据的多处自动备份,实现数据库的拓展.多个数据备份不仅可以加强数据的安全性,通过实现读写分离还能进一步提升数据库的负载性能. M ...

  7. Java 技术栈中间件优雅停机方案设计与实现全景图

    欢迎关注公众号:bin的技术小屋,阅读公众号原文 本系列 Netty 源码解析文章基于 4.1.56.Final 版本 本文概要 在上篇文章 我为 Netty 贡献源码 | 且看 Netty 如何应对 ...

  8. 使用开源Cesium+Vue实现倾斜摄影三维展示

    准备工作 VUE开发工具:Visual studio Code 倾斜摄影转换工具:CesiumLab-下载地址:http://www.cesiumlab.com/ 三维显示:Cesium,api参考网 ...

  9. CF1702B Polycarp Writes a Srting from Memory 题解

    给定一个字符串,每天可以记忆三个字符,求书写出整个字符串的天数. 每次确定要记忆的三个字母,并向后寻找,若有非三个字母其中一个,则重新开启一天记忆三个字母. #include<cstdio> ...

  10. 西文字符与中文GBK编码的区别

    一般来讲二者读取的时候西文字符的数值是正,而中文字符的数值是负的,此时读取的是中文字符的前一半,需要再读取一个char类型的数据,在大多数运行环境下这个规则都是用. ps:转自算法竞赛的笔记,要注意在 ...