遇到了两个Form的编程问题 请高手帮忙解决问题一 如何拦截系统改变大小的消息 实现内容:用鼠标进行拖动时 只可以放大不可以缩小 如果缩小就取消改变大小的操作(不是改变以后再改回来)现在的想法是在sizechanged方法中写 但是如何和重载的winProc结合还不清楚问题二如何能够控制去除重绘带来的闪屏效果实现内容:通过对窗口所有控件的Scale方法实现了 控件根据窗口大小和缩放的功能 但是由于控件本身放大会导致重绘过程,于是重绘时会发生阴影和闪屏的效果 请问怎么可以解决现在用的触发事件是SizeChanged 但是换成ResizeBegin ResizeEnd也是无效的多谢各位,可以给点思路之类的!

解决方案 »

  1.   

    画图的时候我可以设置this.SetStyle()用双缓冲等方式控制闪烁,但是楼主的闪烁这样是否可行,我没试验过
      

  2.   

    //重写WndProc()方法,通过监视系统消息,来调用过程
            protected override void WndProc(ref Message m)//监视Windows消息
            {
                const int WM_HOTKEY = 0x0005;            
                if (m.Msg == WM_HOTKEY)
                {
                    MessageBox.Show("窗体大小发生改变!");
                }
                base.WndProc(ref m); //将系统消息传递自父类的WndProc
            }
      

  3.   

    谢谢回复 不过即使屏蔽了 WM_SIZE消息窗体依然可以改变大小 不知楼上的试过没?
      

  4.   

    不能用
    this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
    这个吗
      

  5.   

    闪屏问题双缓冲或许有用,将窗口的DoubleBuffered设置为true试试。
      

  6.   

    实验了一下 没有太大的作用 不过经过几位楼上的提醒 试着用Control.Update()好像效果好了一些 Invalidate没有效果的
    还是谢谢大家了 第一个问题还是没有头绪
      

  7.   

    我和你讲个思路看看.具体我也没做过,但是觉得可行.
    当窗口缩放的时候,系统会请求获得该窗口的允许最小尺寸.
    如:
    msg=0x24 (WM_GETMINMAXINFO) hwnd=0xe0dc8 wparam=0x0 lparam=0x496d344 result=0x0
    你需要做的是,拦截到该消息,修改他的lparam为你当前窗口尺寸的值,然后放入消息循环.
    当然肯定有更简单的,只是我现在没时间看.
      

  8.   

    WM_SIZE=$0005:改变一个窗口的大小重写窗体的WndProc方法,在里面获取该消息:protected override void WndProc(ref Message m)
            {
                if (started && m.Msg == 0x0005)
                {
                    MessageBox.Show(string.Format("changed:{0}", m.Msg));
                }            base.WndProc(ref m);
            }
    但是窗体时变大,还是变小,无法预先判断
      

  9.   


    WM_SIZE   是在窗口大小被调整后的通知消息,无法控制窗口尺寸。  
      

  10.   


    窗体的变化 可以通过记录原来的Size和现在Size比较得出 不过这个方法还是无法让窗口大小不改变
      

  11.   

    在开始对所有控件scale前
     this.SuspendLayout();
    都完成了
      this.ResumeLayout(false);
      

  12.   

    顶一下 期待高手解决 刚才试着用WM_GETMINMAXINFO 做了一个参数检查
    可能一个Lparam的属性没有使用正确 还是没有成功 郁闷!
      

  13.   

    至于第一个问题,
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;namespace WindowsApplication63
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        public struct POINTAPI
            {
                public int x;
                public int y;
            }        public struct MINMAXINFO
            {
                public POINTAPI ptReserved;
                public POINTAPI ptMaxSize;
                public POINTAPI ptMaxPosition;
                public POINTAPI ptMinTrackSize;
                public POINTAPI ptMaxTrackSize;
            }        protected override void WndProc(ref Message m)
            {
                const int WM_GETMINMAXINFO = 0x24;            if (m.Msg == WM_GETMINMAXINFO)
                {
                    MINMAXINFO mmi = (MINMAXINFO)m.GetLParam(typeof(MINMAXINFO));
                    mmi.ptMinTrackSize.x = this.Size.Width;
                    mmi.ptMinTrackSize.y = this.Size.Height;
                    Marshal.StructureToPtr(mmi, m.LParam, true);
                }
                base.WndProc(ref m);
            }
        }
    }
      

  14.   

    通过限制最小允许尺寸ptMinTrackSize为当前尺寸,达到只能变大不能变小的目的,因为每次变大后最小允许尺寸都变成当前尺寸了
      

  15.   

    wartim,支持你!呵呵,也学习一下。
      

  16.   

    第一个问题顺利解决了居然用的最原始的方法 首先Form还是可以拖拽的 
    第二个 只要设置FOrm的MinimunSize属性 就可以达到效果了追求了半天高深层次 原来一个属性就搞定了不过第二个问题依然和大家继续关注控件的缩放两种方法 第一个 Control.Scale目前可行 呈现出来的位置和大小也都正确 但是很明显 有闪屏的效果
                       第二个 如果用Anchor 如果控件多的情况下 不能呈现出效果来 但是在放大时几乎没有闪屏 效果历史理想如何将效果达到两全其美 希望各位一起研究 不胜感激!
      

  17.   

    兄弟的这个代码能否贴一下?Marshal.StructureToPtr(mmi, m.LParam, true);
      

  18.   

    Scale有没有一些平滑处理的方式 也可以提供一下另外有没有兄弟用过Scale方式实现控件的缩放 效果有哪些不足等也希望指正
    现在贴下实现源码
           ///   <summary>   
            ///   控件随窗体自动缩放   
            ///   </summary>   
            ///   <param   name= "frm "> </param>   
            public void AutoScale(Form frm)
            {
                frm.Tag = frm.Width.ToString() + ", " + frm.Height.ToString();
                //frm.ResizeBegin += new EventHandler(frm_SizeChanged3);
                //frm.Resize += new EventHandler(frm_SizeChanged2);
                frm.Resize += new EventHandler(frm_SizeChanged);
            }        void frm_SizeChanged(object sender, EventArgs e)
            {
                if (this.Size.Height >= OrginSize.Height || this.Size.Width >= OrginSize.Width)
                {
                    string[] tmp = ((Form)sender).Tag.ToString().Split(',');
                    float width = (float)((Form)sender).Width / (float)Convert.ToInt16(tmp[0]);
                    float heigth = (float)((Form)sender).Height / (float)Convert.ToInt16(tmp[1]);                ((Form)sender).Tag = ((Form)sender).Width.ToString() + ", " + ((Form)sender).Height;
                    foreach (Control control in ((Form)sender).Controls)
                    {
                        control.Scale(new SizeF(width, heigth));
                        control.Update();
                        //control.Invalidate();
                    }
                }
            }
    大家也可以试一下这种方式效果如何 因为项目较大 希望用一种稳妥可行的方式 来做一个基类的Form
      

  19.   


    这个方法是.net提供的,我前面using过的,写全了就是
    System.Runtime.InteropServices.Marshal.StructureToPtr(mmi, m.LParam, true); 
      

  20.   

    一  重写 wndproc二  记得有个属性,专门用来解决闪烁问题的。    大概是先写到内存,然后整体显示,闪烁会好很多。
      

  21.   

    不知道这样是不是你要的效果 Dim X, Y As Integer
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            X = Me.Width
            Y = Me.Height    End Sub
        Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize        If Me.Width < X OrElse Me.Height < Y Then            Me.Size = New Size(X, Y)
            Else
                X = Me.Width
                Y = Me.Height
            End If
        End Sub
      

  22.   


    你说的大概是 suspendlayout 和 releaselayout 不过,这两个只在布局的时候有效。查看 design.cs 文件就可以看得到。
      

  23.   


    不是的,指的是双倍缓存。 ControlStyles.DoubleBuffer