(转载)winForm鼠标点击消息,单击窗体最大化最小化消息 C# 重写WndProc 拦截 发送 系统消息 + windows消息常量值(2)

时间:2024-03-11 22:05:17

C# Winform 捕获窗体的最小化和最大化事件、关闭按钮事件

http://blog.csdn.net/wxm3630478/article/details/4579981

 

const int WM_SYSCOMMAND = 0x112;
const int SC_CLOSE = 0xF060;
const int SC_MINIMIZE = 0xF020;
const int SC_MAXIMIZE = 0xF030;
protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_SYSCOMMAND)
    {
        if (m.WParam.ToInt32() == SC_MINIMIZE)  //是否点击最小化
        {

            //这里写操作代码
            this.Visible = false;  //隐藏窗体
            return;
        }


        if (m.WParam.ToInt32() == SC_MAXIMIZE )

        {

             //.....................

        }

       

        if (m.WParam.ToInt32() == SC_CLOSE )

        {   //.....................}


    }
    base.WndProc(ref m);
}

 

//这个功能是 捕获最小化按钮事件  ,隐藏当前窗体.

 

关于winForm窗体最大化的设置

转载自http://blog.sina.com.cn/s/blog_6ab738af0100jux6.html

1. 窗体最大化时 非全屏 不会遮盖任务栏


private void btnFormMax_Click(object sender, EventArgs e) 

       if (this.WindowState == FormWindowState.Maximized) 
       
           this.WindowState = FormWindowState.Normal; 
       
     else 
       
           this.WindowState = FormWindowState.Maximized; 
       

此时this.FormBorderStyle. 默认为 Sizable

2. 窗体最大化时 会全屏 及遮盖任务栏
private void btnFormMax_Click(object sender, EventArgs e) 

      if (this.WindowState == FormWindowState.Maximized) 
      {        
         this.WindowState = FormWindowState.Normal; 
      
      else 
      
         this.FormBorderStyle. = FormBorderStyle.None; 
         this.WindowState = FormWindowState.Maximized; 
      
   }

此时this.FormBorderStyle.  None 不会显示窗体标题栏等相关

 

3. 窗体最大化时 非全屏 不会遮盖任务栏
private void btnFormMax_Click(object sender, EventArgs e) 

      if (this.WindowState == FormWindowState.Maximized) 
      {        
         this.WindowState = FormWindowState.Normal; 
      
      else 
      
         this.FormBorderStyle. = FormBorderStyle.None; 
         this.MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height); 
         this.WindowState = FormWindowState.Maximized; 
      
   }

此时this.FormBorderStyle.  None 不会显示窗体标题栏等相关

 

 

[]窗体最大化的时候,如何指定窗体的位置、大小(C#)


using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
namespace WindowsApplication1 

public partial class FormRegion : Form. 

private const long WM_GETMINMAXINFO = 0x24; 
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; 

public FormRegion() 

InitializeComponent(); 
this.MaximumSize = new Size(Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height); 

protected override void WndProc(ref System.Windows.Forms.Message m) 

base.WndProc(ref m); 
if (m.Msg == WM_GETMINMAXINFO) 

MINMAXINFO mmi = (MINMAXINFO)m.GetLParam(typeof(MINMAXINFO)); 
mmi.ptMinTrackSize.x = this.MinimumSize.Width; 
mmi.ptMinTrackSize.y = this.MinimumSize.Height; 
if (this.MaximumSize.Width != 0 || this.MaximumSize.Height != 0) 

mmi.ptMaxTrackSize.x = this.MaximumSize.Width; 
mmi.ptMaxTrackSize.y = this.MaximumSize.Height; 

mmi.ptMaxPosition.x = 1; 
mmi.ptMaxPosition.y = 1; 
System.Runtime.InteropServices.Marshal.StructureToPtr(mmi, m.LParam, true); 



}  

MessageBox.Show("当前窗体标题栏高度"+(this.Height - this.ClientRectangle.Height).ToString());//获得当前窗体标题栏高度 
ClientRectangle//
获取表示控件的工作区的矩形 
MessageBox.Show(SystemInformation.PrimaryMonitorSize.ToString()); //
获取主显示器屏幕的尺寸(像素
//
获取主显示器当前当前视频模式的尺寸(以象素为单位
MessageBox.Show("
菜单栏高度"+SystemInformation.MenuHeight.ToString()); //获取标准菜单栏的高度 
MessageBox.Show("
标题栏高度"+SystemInformation.CaptionHeight.ToString()); //获取标准标题栏的高度 
MenuHeight//
获取一个菜单行的高度(以象素为单位
CaptionHeight//
获取窗口的标准标题栏区域的高度(以象素为单位)

 

 

转载自http://www.cnblogs.com/lanmiao/articles/2238239.html

接收拦截+发送消息

 对于处理所有消息.net 提供了wndproc进行重写

WndProc(ref Message m)
protected override void WndProc(ref Message m)
{

    const int WM_SYSCOMMAND = 0x0112;
  

    const int SC_CLOSE = 0xF060;
   

   if (m.Msg == WM_SYSCOMMAND && (int) m.WParam == SC_CLOSE)
    {
        // 屏蔽传入的消息事件
        this.WindowState = FormWindowState.Minimized;
        return;
     }
    base.WndProc(ref m);
}
 


//.net 提供了ProcessCmdKey 重新实现Form的键盘消息
protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)      

 

 {
            int WM_KEYDOWN = 256;
            int WM_SYSKEYDOWN = 260;

 

            if (msg.Msg == WM_KEYDOWN | msg.Msg == WM_SYSKEYDOWN)
            {
                switch (keyData)
                {
                    case Keys.Escape:
                        this.Close();//Esc退出                  

                      break;
                }

            }
            return false;
  }

C#中如何编写使用SendMessage
     在.net中,程序驱动采用了事件驱动而不是原来的消息驱动,
虽然.net框架提供的事件已经十分丰富,但是在以前的系统中定义了
丰富的消息对系统的编程提供了方便的实现方法,因此在.net中使用消
息有时候可以提高编程的效率的。
 1 定义消息

在c#中消息需要定义成windows系统中的原始的16进制数字,比如

const int WM_Lbutton = 0x201;  //定义了鼠标的左键点击消息

public const int USER = 0x0400; // 是windows系统定义的用户消息


2 消息发送


消息发送是通过windows提供的API函数SendMessage来实现的它的原型定义为
 

 [DllImport("User32.dll",EntryPoint="SendMessage")]

 private static extern int SendMessage(

 int hWnd, // handle to destination window

 int Msg,    // message

  int wParam,   // first message parameter

 int lParam     // second message parameter

);

 3 消息的接受

 在.net中,任何一个窗口都有消息的接收处理函数,就是wndproc函数

 你可以在form中重写该函数来处理消息

 protected override void WndProc ( ref System.WinForms.Message m )

{

switch(m.msg)

{

case WM_Lbutton :

 string message = string.Format("收到消息!参数为:{0},{1}",m.wParam,m.lParam);

 MessageBox.Show(message);

 break;

default:

 base.DefWndProc(ref m);//调用基类函数处理非自定义消息。

 break;

}

}

其实,C#中的事件也是通过封装系统消息来实现的,如果你在WndProc函数中不处理该消息

那么,它会被交给系统来处理该消息,系统便会通过代理来实现鼠标单击的处理函数,因此你可以通过

WndProc函数来拦截消息,比如你想拦截某个按钮的单击消息

 

4 C#中其他的消息处理方法

  在C#中有的时候需要对控件的消息进行预处理,比如你用owc的spreedsheet控件来处理

Excel文件,你不想让用户可以随便选中数据进行编辑,你就可以屏蔽掉鼠标事件,这个时

候就必须拦截系统预先定义好的事件(这在MFC中称为子类化),你可以通过C#提供的一个

接口

IMessageFilter来实现消息的过滤

public class Form1: System..Forms.Form,IMessageFilter

{

 const int WM_MOUSEMOVE = 0x200;

 public bool PreFilterMessage(ref Message m)  //实现接口

 { 

        Keys keyCode = (Keys)(int)m.WParam & Keys.KeyCode; 

   if( m.Msg==WM_MOUSEMOVE)        //或m.Msg == WM_LBUTTONDOWN

   {

    MessageBox.Show("Ignoring Escape...");  

    return true; 

   } 

    return false; 

 }

}

 

 

(转)有用的WndProc(ref Message m)方法

 

在Windows操作中,所有的操作都是基于消息的。 
我们编写的程序,也是这个道理。同样,我们也可能查看事件发生时,到底触发了什么样的消息。 
在CS中,可以重写WndProc函数,来捕捉所有发生有窗口消息。这样,我们就可以"篡改"传入的消息,而人为的让窗口改变行为。 
大家用MSN的时候会发现,当直接关闭窗口时,窗口不会关闭而会最小化到托盘。我估计它使用的也是这样的道理。 
下面就看一下关于这种方法的使用。 

protected override void WndProc(ref Message m) 

    const int WM_SYSCOMMAND = 0x0112; 
    const int SC_CLOSE = 0xF060; 
    if (m.Msg == WM_SYSCOMMAND && (int) m.WParam == SC_CLOSE) 
    { 
        // 屏蔽传入的消息事件 
        this.WindowState = FormWindowState.Minimized; 
        return; 
    } 
    base.WndProc(ref m); 

 

 

 

base.WndProc(ref m)的原理和使用

WndProc 窗体主要的消息处理函数

WndProc的实现大概是这样的: 
protected void WndProc(ref Message m) 
{ 
switch(m) 
{ 
case WM_QUIT: /*处理退出消息....;*/ break; 
case WM_PAINT:/*处理paint消息...*/ break; 
... ... 
default: 
defWndProc(ref m); //其他消息调用默认的消息处理函数 
} 
}

 

 

c#怎么通过重写 WndProc函数来同时实现无标题栏的窗体移动和禁止双击窗体最大化

2009-06-12 15:27feifeihai123 | 分类:C#/.NET | 浏览3051次
因为我已经实现了无标题栏窗体的移动,当双击窗体时,会使窗体最大化,我想禁止找个消息,怎么写呢
protected override void WndProc(ref Message m)
{
const int WM_NCHITTEST = 0x84;
const int HTCLIENT = 0x01;
const int HTCAPTION = 0x02;
const int WM_SYSCOMMAND = 0x112;
const int SC_MAXMIZE = 0xF030;

switch (m.Msg)
{
case WM_NCHITTEST://鼠标点任意位置后可以拖动窗体
this.DefWndProc(ref m);
if (m.Result.ToInt32() == HTCLIENT)
{
m.Result = new IntPtr(HTCAPTION);
return;
}
break;
case WM_SYSCOMMAND://禁止最大化
if (m.WParam.ToInt32() ==SC_MAXMIZE)
{
/./代码
return;
}
break;
default:
base.WndProc(ref m);
break;
}
}
当去掉第二个case后,可以拖动窗体,但是双击窗体会最大化;加上第二个case想禁止最大化,但是加了后什么功能也不能实现,怎么回事
 
 
举报| 2009-06-12 16:46提问者采纳
 
protected override void WndProc(ref Message m)
{
const int WM_NCHITTEST = 0x84;
const int HTCLIENT = 0x01;
const int HTCAPTION = 0x02;
const int WM_SYSCOMMAND = 0x112;
const int SC_MAXMIZE = 0xF030;
const int WM_NCLBUTTONDBLCLK = 0xA3;
switch (m.Msg)
{
case 0x4e:
case 0xd:
case 0xe:
case 0x14:
base.WndProc(ref m);
break;
case WM_NCHITTEST://鼠标点任意位置后可以拖动窗体

this.DefWndProc(ref m);
if (m.Result.ToInt32() == HTCLIENT)
{
m.Result = new IntPtr(HTCAPTION);
return;
}
break;
case WM_NCLBUTTONDBLCLK://禁止双击最大化
Console.WriteLine(this.WindowState);

return;

break;

default:

base.WndProc(ref m);
break;
}
}
提问者评价
非常谢谢,我光想这拦截最大化了,忘了拦截双击了,太谢谢了。
 
 

我们在做winform的时候,很多时候因为需求问题,要把窗体做的好看点,所以就给窗体加上了很多图片,或者其他资源

从而导致了用户在用鼠标拖动窗体的时候,窗体很卡,CPU占用很高的问题,这些都是因为窗体在拖动的时候频繁的绘制

造成的,那么要避免这些问题,其中的一个解决方法就是减少窗体绘制,或者说只绘制一次,即在用户鼠标放开(MouseUp事件)的时候绘制,代码如下:

 

 

复制代码
 1 public partial class Form1 : Form
 2     {
 3         [DllImport("user32.dll")]
 4         public static extern bool ReleaseCapture();
 5         [DllImport("user32.dll")]
 6         public static extern bool SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
 7 
 8         private const int WM_SYSCOMMAND = 0x0112;//点击窗口左上角那个图标时的系统信息
 9         private const int WM_MOVING = 0x216;//鼠标移动消息
10         private const int SC_MOVE = 0xF010;//移动信息
11         private const int HTCAPTION = 0x0002;//表示鼠标在窗口标题栏时的系统信息
12         private const int WM_NCHITTEST = 0x84;//鼠标在窗体客户区(除了标题栏和边框以外的部分)时发送的消息
13         private const int HTCLIENT = 0x1;//表示鼠标在窗口客户区的系统消息
14         private const int SC_MAXIMIZE = 0xF030;//最大化信息
15         private const int SC_MINIMIZE = 0xF020;//最小化信息
16 
17         protected override void WndProc(ref Message m)
18         {
19             switch (m.Msg)
20             {
21                 case WM_MOVING: //如果鼠标移                  
22                     base.WndProc(ref m);//调用基类的窗口过程——WndProc方法处理这个消息
23                     if (m.Result == (IntPtr)HTCLIENT)//如果返回的是HTCLIENT
24                     {
25                         m.Result = (IntPtr)HTCAPTION;//把它改为HTCAPTION
26                         return;//直接返回退出方法
27                     }
28                     break;
29             }
30             base.WndProc(ref m);//如果不是鼠标移动或单击消息就调用基类的窗口过程进行处理
31         }
32 
33         protected override void OnMouseMove(MouseEventArgs e)
34         {
35             if (e.Button == MouseButtons.Left)
36             {
37                 ReleaseCapture();
38                 SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);
39             }
40             base.OnMouseMove(e);
41         }
42     }
复制代码