遇到了两个Form的编程问题 请高手帮忙解决问题一 如何拦截系统改变大小的消息 实现内容:用鼠标进行拖动时 只可以放大不可以缩小 如果缩小就取消改变大小的操作(不是改变以后再改回来)现在的想法是在sizechanged方法中写 但是如何和重载的winProc结合还不清楚问题二如何能够控制去除重绘带来的闪屏效果实现内容:通过对窗口所有控件的Scale方法实现了 控件根据窗口大小和缩放的功能 但是由于控件本身放大会导致重绘过程,于是重绘时会发生阴影和闪屏的效果 请问怎么可以解决现在用的触发事件是SizeChanged 但是换成ResizeBegin ResizeEnd也是无效的多谢各位,可以给点思路之类的!
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
}
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
这个吗
还是谢谢大家了 第一个问题还是没有头绪
当窗口缩放的时候,系统会请求获得该窗口的允许最小尺寸.
如:
msg=0x24 (WM_GETMINMAXINFO) hwnd=0xe0dc8 wparam=0x0 lparam=0x496d344 result=0x0
你需要做的是,拦截到该消息,修改他的lparam为你当前窗口尺寸的值,然后放入消息循环.
当然肯定有更简单的,只是我现在没时间看.
{
if (started && m.Msg == 0x0005)
{
MessageBox.Show(string.Format("changed:{0}", m.Msg));
} base.WndProc(ref m);
}
但是窗体时变大,还是变小,无法预先判断
WM_SIZE 是在窗口大小被调整后的通知消息,无法控制窗口尺寸。
窗体的变化 可以通过记录原来的Size和现在Size比较得出 不过这个方法还是无法让窗口大小不改变
this.SuspendLayout();
都完成了
this.ResumeLayout(false);
可能一个Lparam的属性没有使用正确 还是没有成功 郁闷!
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);
}
}
}
第二个 只要设置FOrm的MinimunSize属性 就可以达到效果了追求了半天高深层次 原来一个属性就搞定了不过第二个问题依然和大家继续关注控件的缩放两种方法 第一个 Control.Scale目前可行 呈现出来的位置和大小也都正确 但是很明显 有闪屏的效果
第二个 如果用Anchor 如果控件多的情况下 不能呈现出效果来 但是在放大时几乎没有闪屏 效果历史理想如何将效果达到两全其美 希望各位一起研究 不胜感激!
现在贴下实现源码
/// <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
这个方法是.net提供的,我前面using过的,写全了就是
System.Runtime.InteropServices.Marshal.StructureToPtr(mmi, m.LParam, true);
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
你说的大概是 suspendlayout 和 releaselayout 不过,这两个只在布局的时候有效。查看 design.cs 文件就可以看得到。
不是的,指的是双倍缓存。 ControlStyles.DoubleBuffer