我做了个无边框窗体,最开始是直接重载onpaint在边框画图片,感觉闪的厉害,特别是在resize的时候,
后边在边框摆了一圈panel,以backgroundimage的形式,实现边框,效果好了很多但是想去响应WM_NCHITTEST函数,实现拖动边框大小的时候,发现窗体本身已经被上边的panel盖住了,无法触发这个事件想问一下,怎么把panel上的这个事件传递给父窗口?

解决方案 »

  1.   


    呵呵,不用这么麻烦,用api非常方便,网上搜下有很多
      

  2.   


    [DllImport("user32.dll")]//*********************拖动无窗体的控件
            public static extern bool ReleaseCapture();
            [DllImport("user32.dll")]
            public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
            public const int WM_SYSCOMMAND = 0x0112;
            public const int SC_MOVE = 0xF010;
            public const int HTCAPTION = 0x0002;
     
     
    //给界面添加MouseDown方法
    private void Form5_MouseDown(object sender, MouseEventArgs e)
            {
                ReleaseCapture();
                SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);//*********************调用移动无窗体控件函数
            }
      

  3.   

    Form5_MouseDown可以换成其他事件
      

  4.   


    恩。这样可以move窗口
    现在我想resize窗口
    试了一下,重载panel的wndproc 收到一些消息时,先setcapture到窗体,再直接把消息转发给主窗口,可以resize但是,鼠标指针不变,而且不按鼠标左键,边缘也会跟着放大缩小,不知道resize时应该拦截哪些消息...
      

  5.   

    你的可以拖边框实现resize窗口么
      

  6.   

    怎么拖动边框实现resize?...而且我发现或多或少有点闪的
      

  7.   


    不会的,和移动有边框的窗体一样的感觉,主要是实现的技术问题,看来你没有搜索?还是没找到?
    我把代码复制给你的,网上高手发的。这是原文,我自己使用时有改动,在C#和VB.net中都很好的效果。我用的是VS2012,希望对你有用。C# 无边框窗体移动和改变大小的实现using System.Runtime.InteropServices; 
    命名空间; SendMessage 像指定窗口过程发送消息 
    ReleaseCapture 释放鼠标捕获 //需添加using System.Runtime.InteropServices;
    [DllImport("user32.dll")]  
    public static extern bool ReleaseCapture();
    [DllImport("user32.dll")]
    public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
            
    //常量
    public const int WM_SYSCOMMAND = 0x0112;
            
    //窗体移动
    public const int SC_MOVE = 0xF010;
    public const int HTCAPTION = 0x0002; private const int WM_SYSCOMMAND = 0x0112;//点击窗口左上角那个图标时的系统信息 
    private const int SC_MOVE = 0xF010;//移动信息 
    private const int HTCAPTION = 0x0002;//表示鼠标在窗口标题栏时的系统信息 
    private const int WM_NCHITTEST = 0x84;//鼠标在窗体客户区(除了标题栏和边框以外的部分)时发送的消息 
    private const int HTCLIENT = 0x1;//表示鼠标在窗口客户区的系统消息 
    private const int SC_MAXIMIZE = 0xF030;//最大化信息 
    private const int SC_MINIMIZE = 0xF020;//最小化信息 //改变窗体大小
    public const int WMSZ_LEFT = 0xF001;
    public const int WMSZ_RIGHT = 0xF002;
    public const int WMSZ_TOP = 0xF003;
    public const int WMSZ_TOPLEFT = 0xF004;
    public const int WMSZ_TOPRIGHT = 0xF005;
    public const int WMSZ_BOTTOM = 0xF006;
    public const int WMSZ_BOTTOMLEFT = 0xF007;
    public const int WMSZ_BOTTOMRIGHT = 0xF008;
    声明完函数和定义完这些常量后,就是在事件里面具体的实现了//窗体移动在要实现的控件的MouseDown事件中添加以下代码:private void panel_title_bar_MouseDown(object sender, MouseEventArgs e){        ReleaseCapture();        SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);}//窗体大小的改变同理在控件的MouseDown事件中添加以下代码:private void panel_bottom_MouseDown(object sender, MouseEventArgs e){       ReleaseCapture();       SendMessage(this.Handle, WM_SYSCOMMAND, WMSZ_BOTTOM, 0);}其中的 WMSZ_BOTTOM 下边框,要改变哪个方向,换用前面的常量代码就行。
    再加一条,就是无边框最大化后会全屏显示,只要在窗体加载中加下面这句来限制最大化窗体大小即可:this.MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width,                                                           Screen.PrimaryScreen.WorkingArea.Height);同理限定最小的也可以在窗体加载中加入以下语句:this.MinimumSize = new Size(this.Width, this.Height);//窗体改变大小时最小限定在初始化大小
      

  8.   


    谢谢,resize实现了~~~
    不过我的还会有点闪,是不是因为我在窗口load的时候根据加载的皮肤图片去动态算panel的大小、位置的原因