winform中如何处理无边框窗体的缩放和托动

在winform经常用到无边框的窗体,原因就是想使自己的程序界面完全的自定义,网上也有过不少的相关资料

今天我发了一下的午的时间整理了一下.觉得还不错,贴出来看看.

为了提高托动的缩放的效率,减少系统开销,一般软件都用支持只显示窗体四周的虚线的方法,这也是windows默认的设置

首先看下其它软件的窗体托动,先说QQ2009吧,QQ2009的主窗体在托动时如果在屏幕上来回快速托动,等停下来时你会发现,很有可能鼠标现在在窗体的位置已经不是按下的位置了.再说酷我音乐盒.鼠标在托动或缩放窗体时,如果鼠标移动到窗体的各边框上时,鼠标形状仍然会改变.而且就算系统设置设置成托动时显示窗体内容,在托动和缩放时也不会显示内容,仍然是虚线.此虚线遇到有些情况会很乱,比如在播放的动画的电影上时,因为直按用屏幕DC画的,而且放后破坏其它窗体的界面,其它的重画时,他就可能会不显示了下面介绍几种托动的方法

先说两种常用的,再补充说明

1.在mousemove,mousedown,mouseup三个事件的配合下来移动和缩放就不说了,代码多,效率低,一般初学者都能写出来.

2.就是用系统已经存在的方法,一般是重写窗口过程,和用sendmessage来骗系统.

重写回调函数的小例子

 protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_NCLBUTTONDBLCLK://WM_NCLBUTTONDBLCLK=163 <0xA3>拦截鼠标非客户区左键双击消息,决定窗体是否最大化显示
                    if (this.MaximizeBox)
                    {
                        base.WndProc(ref m);//这种方法的好处是自己不用处理鼠标形状了.
                        this.Invalidate();
                    }
                    return;
                case WM_NCHITTEST://WM_NCHITTEST=132 <0x84>
                    base.WndProc(ref m);//如果去掉这一行代码,窗体将失去MouseMove..等事件
                    Point lpint = new Point((int)m.LParam);//可以得到鼠标坐标,这样就可以决定怎么处理这个消息了,是移动窗体,还是缩放,以及向哪向的缩放

                   m.Result = (IntPtr)0x2;//托动HTCAPTION=2 <0x2>

                  //当然可以托动也可以改变大小了

                  //HTLEFT=10 <0xA> 左边框

                  //HTTOP=12 <0xC> 上边框

                  //HTTOPLEFT=13 <0xD>

                  //HTTOPRIGHT=14 <0xE>
                  //HTRIGHT=11 <0xB>

                  //HTBOTTOM=15 <0xF>

                  //HTBOTTOMLEFT=16 <0x10>

                  //HTBOTTOMRIGHT=17 <0x11>

                  //HTBORDER=18 <0x12>

                  //HTMINBUTTON=8 <0x8> 最小化按钮

                  //HTMAXBUTTON=9 <0x9> 最大化按钮

                  //HTCLOSE=20 <0x14> 关闭按钮

                    return;                
                default:
                    base.WndProc(ref m);
                    return;
            }
           
        }

发送消息的例子,也可以在上面的回函数中加入发送消息的方法,

也可以在窗体的mousedown..等事件和其它控件的事件里发送消息

记得要先释放鼠标用API函数ReleaseCapture();或控件的或窗体的Capture属性Capture = false;

API函数的声明我就不说了这里用到的API有三个,SetWindowLong可用可不用,只是用他来举另一个例子

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SetWindowLong(IntPtr hWnd, int Index, long Value);

//托动

SendMessage(this.Handle, /*WM_SYSCOMMAND */274,/*移动信息SC_MOVE=*/61456+/*HTCAPTION =2*/2, 0);

//左边框缩放

SendMessage(this.Handle, /*WM_SYSCOMMAND */274,/*移动信息SC_Size=*/61440 +/*WMSZ_LEFT=1 <0x1> 这里可以换成其它参数下面给出*/1, 0);

//左边框WMSZ_LEFT=1 <0x1>

//右边WMSZ_RIGHT=2 <0x2>

//上边WMSZ_TOP=3 <0x3>

//WMSZ_TOPLEFT=4 <0x4>

//WMSZ_TOPRIGHT=5 <0x5>

//WMSZ_BOTTOM=6 <0x6>

//WMSZ_BOTTOMLEFT=7 <0x7>

//WMSZ_BOTTOMRIGHT=8 <0x8>

这里就可以完成两种方法的托动和缩放了,但 是还是和有边框的不一样,有边框的托动时和缩放时可以是很粗的虚线,而现在的却很细很细的.

这时就可以用上面提到过的SetWindowLong了,

SetWindowLong(this.Handle, GWL_STYLE, WS_SYSMENU | WS_SIZEBOX | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);

这样不但是粗边框了,而且系统菜单都有了,但是有一点不好,有兴趣的话自己可以研究下

而我用另一种方法觉得还可以,在窗体的MouseDown里这样写

    private void Form1_MouseDown(object sender, MouseEventArgs e)
        {

            this.Capture = false;
            Form ff = new Form();
            ff.StartPosition = FormStartPosition.Manual;
            ff.Size = this.Size;
            ff.Location = this.Location;
            //ff.Show();不让窗体显示

            SendMessage(ff.Handle, 274, 61440+1, 0);//发送移动信息,也可以发送其它比如缩放消息

            this.Size= ff.Size;
            this.Location = ff.Location;

            ff.Dispose();

        }

时间: 2024-08-30 21:22:36

winform中如何处理无边框窗体的缩放和托动的相关文章

c#中无边框窗体改变大小?

问题描述 我是参考这里http://www.microsoft.com/china/community/Column/60.mspx我做的也是一个无边框的窗体现在已经实现了向右拉伸功能.方法(获得当前的鼠标横坐标(mousemove)FORM.WITCH=鼠标横坐标-location.X)如何实现向左拉伸?我思考的方法(FORM.WITCH=this.Right-当前鼠标横坐标,但是表现出来时窗体左边框没动右边框在增加缩小)不知道我是不是写错了.或者要实现无边框窗体的伸缩大小有没有另外的好方法?

C#中实现拖动无边框窗体Form

拖动无边框窗体Form至桌面任何位置 首先建一个Windows应用程序 将Form1的 FormBorderStyle属性设置为Noe   创建控件panel1放在标题栏位置   代码         Point mouseOff;//鼠标移动位置变量         bool leftFlag;//标签是否为左键         private void panel1_MouseDown(object sender, MouseEventArgs e)        {            

WPF无边框窗体,点击任务栏无法最小化

问题描述 WPF设置成无边框窗体后,点击任务栏无法最小化.在Winform中可以用以下方式解决这个问题.[DllImport("user32.dll",EntryPoint="GetWindowLong",CharSet=CharSet.Auto)]publicstaticexternintGetWindowLong(HandleRefhWnd,intnIndex);[DllImport("user32.dll",EntryPoint="

无边框窗体,窗体鼠标事件被禁止,求解决办法。

问题描述 protectedoverridevoidWndProc(refMessagem){constintWM_NCHITTEST=0x84;constintHTCLIENT=0x01;constintHTCAPTION=0x02;constintWM_SYSCOMMAND=0x112;constintSC_MAXMIZE=0xF030;constintWM_NCLBUTTONDBLCLK=0xA3;switch(m.Msg){case0x4e:case0xd:case0xe:case0x1

【Qt编程】基于Qt的词典开发系列&amp;lt;四&amp;gt;--无边框窗口的缩放与拖动

        在现在,绝大多数软件都向着简洁,时尚发展.就拿有道的单词本和我做的单词本来说,绝大多数用户肯定喜欢我所做的单词本(就单单界面,关于颜色搭配和布局问题,大家就不要在意了).有道的单词本: 我所做的单词本:         很明显,两者的主要区别就是周围的边框问题.你可以对比QQ以前的版本和这几年的版本,就会发现都倾向于下面这种窗口模式.下面我们就说说如何用Qt实现无边框窗口的缩放与拖动.         对于无边框窗口的拖动其实很简单,其基本思想是,在鼠标移动前后记录鼠标的坐标,然

winform 无边框 窗体基本功能 拖动和系统右键菜单冲突

问题描述 usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Runtime.InteropServices;usingRightMenuItem;namespaceClientFrom{pu

vb无边框窗体-[VB 6.0]无边框窗体用[JS]实现左键+拖动=改变窗体大小

问题描述 [VB 6.0]无边框窗体用[JS]实现左键+拖动=改变窗体大小 设想:Form1(绝对的无边框,不是有边框去掉标题栏)中只有webbrowser一个控件,webbrowser与Form1大小一致. 求助:Form1会被webbrowser控件完全覆盖,Form1的鼠标事件不会因鼠标操作而触发,而webbrowser控件本身没有鼠标事件[有没有不讨论,就当没有]这种情况下如何实现左键+拖动=改变窗口大小,可否在webbrowser-document中建一与Form1同样大小的DIV,用

vb.net如何在win7下不开启阴影效果,如何实现无边框窗体阴影

问题描述 vb.net如何在win7下不开启阴影效果,如何实现无边框阴影,求高手给代码,谢谢各位了 解决方案 解决方案二:WPF整

winform中去操作WPF窗体

问题描述 在winform里面调用win32API去获得一个WPF窗体的句柄没有问题,但是获得的类是这样的:HwndWrapper[XXXXXXX.exe;;50d5648e-c295-4e95-b58b-91b721bf8ccc]WPF窗体变成了这样的东西...SPY++看也看不明白怎么操作这个窗体.我想获得的是WPF窗体的文本信息,然后能够操作WPF窗体,比如点击上面的确定.取消等按钮.类似这样的:现在只能实现用SendMessage()方式去关闭窗体和用ShowWindow()最大化最小化