程序员必知:WndPric的使用方法

简介: 程序员必知:WndPric的使用方法

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);

}

protected override void WndProc(ref Message m)

{

const int WM_SYSCOMMAND = 0x0112;

const int SC_CLOSE = 0xF060;

const int SC_MINIMIZE = 0xF020;

if (m.Msg == WM_SYSCOMMAND ((int)m.WParam == SC_MINIMIZE || (int)m.WParam == SC_CLOSE))

{

//最小化到系统栏

this.Hide();

return;

}

base.WndProc(ref m);

}

--

不规则窗体拖动

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;

public void ShapedForm_MouseDown(object sender, MouseEventArgs e)

{

ReleaseCapture();

SendMessage(this.Handle, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);

}

---

protected override void WndProc(ref Message m)

{

//拦截窗体最小化按钮消息,调用隐藏动画并隐藏窗体

if (m.Msg == (int)hyFrameWork.win32Api.Enum.WinMsg.WM_SYSCOMMAND)

{

if (m.WParam.ToInt32() == (int)hyFrameWork.win32Api.Enum.ECNCSysCommandConstants.SCMINIMIZE)

{

formShowControl(false);

return;

}

}

base.WndProc(ref m);

}

---

/////////////////////////////////////////////////////////////////////

通知消息(Notification message)是指这样一种消息,一个窗口内的子控件发生了一些事情,需要通

知父窗口。通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框,以及Windows 95公

共控件如树状视图、列表视图等。例如,单击或双击一个控件、在控件中选择部分文本、操作控件的

滚动条都会产生通知消息。

按扭

B N C L I C K E D //用户单击了按钮

B N D I S A B L E //按钮被禁止

B N D O U B L E C L I C K E D //用户双击了按钮

B N H I L I T E //用户加亮了按钮

B N PA I N T按钮应当重画

B N U N H I L I T E加亮应当去掉

组合框

C B N C L O S E U P组合框的列表框被关闭

C B N D B L C L K用户双击了一个字符串

C B N D R O P D O W N组合框的列表框被拉出

C B N E D I T C H A N G E用户修改了编辑框中的文本

C B N E D I T U P D AT E编辑框内的文本即将更新

C B N E R R S PA C E组合框内存不足

C B N K I L L F O C U S组合框失去输入焦点

C B N S E L C H A N G E在组合框中选择了一项

C B N S E L E N D C A N C E L用户的选择应当被取消

C B N S E L E N D O K用户的选择是合法的

C B N S E T F O C U S组合框获得输入焦点

编辑框

E N C H A N G E编辑框中的文本己更新

E N E R R S PA C E编辑框内存不足

E N H S C R O L L用户点击了水平滚动条

E N K I L L F O C U S编辑框正在失去输入焦点

E N M A X T E X T插入的内容被截断

E N S E T F O C U S编辑框获得输入焦点

E N U P D AT E编辑框中的文本将要更新

E N V S C R O L L用户点击了垂直滚动条消息含义

列表框

L B N D B L C L K用户双击了一项

L B N E R R S PA C E列表框内存不够

L B N K I L L F O C U S列表框正在失去输入焦点

L B N S E L C A N C E L选择被取消

L B N S E L C H A N G E选择了另一项

L B N S E T F O C U S列表框获得输入焦点

static bool flag = false;

protected override void WndProc(ref Message m)//C# 重写 WndProc 移动窗口

{

switch (m.Msg) {

case 0x0200: //WM_MOUSEMOVE

if (flag)

{

PostMessage(this.Handle, 0x00A1,new IntPtr(2),m.LParam);//这里需要导入 user32.dll

}

break;

case 0x201://WM_LBUTTONDOWN

flag = true;

break;

case 0x202://WM_LBUTTONUP

flag = false;

break;

default:

base.WndProc(ref m);

break;

}

【DllImport("user32.dll", CharSet = CharSet.Unicode)】

public static extern IntPtr PostMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

【DllImport("user32.dll")】

public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wparam, int lparam);

protected override void OnMouseDown(MouseEventArgs e)

{

base.OnMouseDown(e); if (e.Button == MouseButtons.Left)//按下的是鼠标左键

{

Capture = false;//释放鼠标,使能够手动操作

SendMessage(Handle, 0x00A1, 2, 0);//拖动窗体

}

}

protected override void WndProc(ref Message m)

{

switch (m.Msg)

{

case 0x0201://鼠标左键按下的消息

m.Msg = 0x00A1;//更改消息为非客户区按下鼠标

m.LParam = IntPtr.Zero;//默认值

m.WParam = new IntPtr(2);//鼠标放在标题栏内

break;

}

base.WndProc(ref m);

}

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

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 鼠标点任意位置后可以拖动窗体

this.DefWndProc(ref m);

if (m.Result.ToInt32() == HTCLIENT)

{

m.Result = new IntPtr(HTCAPTION);

return;

}

break;

case 禁止双击最大化

Console.WriteLine(this.WindowState);

return;

break;

default:

base.WndProc(ref m);

break;

}

}

--

第一步,先在类的级别中申明两个API函数,

  ///注册热键

  【DllImport("user32.dll")】

  private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, Keys vk);

  ///卸载热键

  【DllImport("user32.dll")】

  private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

  注意引入名字空间 System.Runtime.InteropServices;

  上面两个函数参数的解释:

  RegisterHotKey 函数中,

  hWnd为本程序窗口的句柄,在C#的窗口中直接用Handle属性就可以引用窗口句柄

  id为热键的标示符,是我们自己定义的,因为一个程序中可以定义多个热键,所以要用这个字段来区别,具体用法见下

  fsModifiers为激活热键时,是否和系统键组合使用,none:0 Alt:1 Ctrl:2 Shift:4,并且还可以用或运算来组合使用

  vk就是要定义的热键,C#中按键都被包含在Keys枚举中

  UnregisterHotKey 函数中,

  hWnd和RegisterHotKey 函数中是一样的,id为要卸载的热键标示

  第二步,在窗口的初始化中注册热键,例如 RegisterHotKey(Handle, 100, 0, Keys.F9);

  将些热键识别为100,0表示不使用系统键,Keys.F9表示此热键为F9,若要同时按Shift+Ctrl+F9,则第三个参数应该为 2|4 其实对二进制运算熟悉的朋友,               可以立刻算出 2|4=6

  第三步,可以响应热键了:

  重写窗体的WndProc函数,具体代码为

  protected override void WndProc(ref Message m) {

  //这个if的条件中固定的

  if (m.Msg == 0x312) {

  //这个if就在于判断是哪个热键,100对应上面RegisterHotKey函数中的第二个参数

  //代码效果参考:http://www.zidongmutanji.com/zsjx/106313.html

if (m.WParam.ToInt32() == 100) {

  //这里就是响应的函数

  DoSomething();

  }

  }

  base.WndProc(ref m);

  }

  WndProc()函数的功能就是处理Windows消息,在其它地方还将看到这个函数的妙用!

  第四步,在程序结束的时候调用UnregisterHotKey(Handle,100)卸载此热键!

  WIN32

  第一步,在int WINAPI WinMain()函数中,

  while(GetMessage(msg,NULL,0,0)){……}

  之前,注册热键

  RegisterHotKey(hWnd,100,0,VK_F9)

  VK_F9为WinUser.h中定义的宏,其他键也是用类似的形式进行定义,不过数字键和字母键,直接用'0','A'这样的形式

  第二步,在while(GetMessage(msg,NULL,0,0)) {……}

  循环体内,添加代码

  //这是响应热键条件,从WM_HOTKEY宏的定义中,可以看出来它代表的值为 0x312 ,和C#中的if条件是一致的

  if(msg.message ==WM_HOTKEY)

  {

  //这里的条件用来判断热键的标示符

  if(msg.wParam==100)

  {

  //这里调用想要执行的函数

  DoSomething();

  }

  }

  第三步,在while()循环结束后,调用 UnregisterHotKey(hWnd,100) 卸载热键。

  MFC

  第一步,在MFC的窗体中添加其WM_HOTKEY消息的响应,

  void C热键Dlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)

  {

  //这里用来判断热键的标识符

  if(nHotKeyId == 100)

  {

  //响应函数

  DoSomething();

  }

  CDialog::OnHotKey(nHotKeyId, nKey1, nKey2);

  }

  第二步,在MFC窗体的初始化地方,添加注册热键的代码:

  RegisterHotKey(m_hWnd,100,0,VK_F9);

  注意上面的字段m_hWnd,是CWnd类中字段,完成由MFC控制,我们只需要在适合地方引用就可以了。

  第三步,在窗体销毁的地方调用 UnregisterHotKey(hWnd,100) 卸载热键就可以了。

  到这里,大家可以已经掌握了在三种环境中设置系统级热键的方法。笔者的体会是,在WIN32和C#中方法大概相同,笔者就是在C#的基础上,尝试着在WIN32中实现该功能,结果一次成功,但是在MFC中就走了一些弯路。

protected override void WndProc(ref Message m)

{

switch (m.Msg)

{

case 0x0005://change size: WM_SIZE

{

FormWindowState newState = FormWindowState.Normal;

switch (m.WParam.ToInt32())

{

case 0://SIZE_RESTORED

newState = FormWindowState.Normal;

break;

case 1://SIZE_MINIMIZED

newState = FormWindowState.Minimized;

break;

case 2://SIZE_MAXIMIZED

newState = FormWindowState.Maximized;

break;

default:

break;

}

if (newState != this<span style="color: rgba

相关文章
|
2天前
|
物联网 程序员 API
程序员必知:WndPric的使用方法
程序员必知:WndPric的使用方法
|
3天前
|
程序员 PHP
老程序员分享:PHPstripos()、strripos()和strrpos()使用方法和区别
老程序员分享:PHPstripos()、strripos()和strrpos()使用方法和区别
10 0
|
8月前
|
自然语言处理 编译器 Linux
超详细!通晓Go语言编译运行 你需要这篇攻略 | 进阶指南
超详细!通晓Go语言编译运行 你需要这篇攻略 | 进阶指南
573 0
超详细!通晓Go语言编译运行 你需要这篇攻略 | 进阶指南
|
8月前
|
Java 程序员 Android开发
C++ 程序员,安卓开发注意事项
C++ 程序员,安卓开发注意事项
|
11月前
|
缓存 算法 安全
程序员写代码为什么要阅读源码?
阅读一篇技术文章,畅聊一个技术话题。本期文章推荐的是《Node 中的 AsyncLocalStorage 的前世今生和未来》,一起来聊聊开发者阅读源码的这件事。阅读源码的过程实质上是对软件构建技术和架构深度的一种持续学习和理解。阅读源码可以揭示代码的内在逻辑,可以对技术深度的理解,也能提高对技术的理解程度。然而,仅仅阅读源码并不能代替实践操作,因为通过实践,可以更加全面的理解代码的深度和进展。
116 1
|
11月前
|
存储 Python
Python 基础语法和规范,初学者少踩坑
Python 基础语法和规范,初学者少踩坑
|
Unix 编译器 程序员
如何写出高质量的代码 -- 给所有编程学习者的一个建议
如何写出高质量的代码 -- 给所有编程学习者的一个建议
147 0
如何写出高质量的代码 -- 给所有编程学习者的一个建议
|
JSON JavaScript 安全
那些你熟悉而又陌生的函数
五层境界 我不知道我不知道 我知道我不知道 我知道我知道 我不知道我知道 第三层境界以上的兄台,可以直接离开了。 至于第五层境界,无需知道还是不知道。 废话不多说,进入正题,一起探索那些你熟悉和又陌生的函数。
128 0
那些你熟悉而又陌生的函数
|
索引 Python
Python 函数式编程,没什么废话,直接看用法和代码
lambda 这个关键词在很多语言中都存在。简单地说,它可以实现函数创建的功能。
125 0