[转]C# 获得窗体句柄并发送消息(利用windows API可在不同进程中获取)
编写程序模拟鼠标和键盘操作可以方便的实现你需要的功能,而不需要对方程序为你开放接口。
首先,引入如下API接口:
[DllImport("User32.dll ")]
public static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childe, string strclass, string FrmText);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
[DllImport("user32.dll", EntryPoint = "SendMessageA")]
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam);
一、
第一个与第二个是用于查找窗口句柄的,凡运行于Windows上的窗口,都具有句柄。窗口上的文本框,按钮之类的,也有其句柄(可看作子窗口句柄)。这些句柄的类型可以通过Spy++进行查询。比如C语言编写的程序中,文本框的句柄类型一般为“EDIT”,C#写的程序则不是,可以具体去查。第二个接口则是用于向窗口发送各种消息,比如向文本框发送字符串,或者向按钮发送按下与弹起的消息等。详细解释如下:
IntPtr hwnd = FindWindow(null, "无标题 - 记事本"); //不同进程也可使用此API查找其他进程下的窗体
这是用于查找操作系统中打开的窗口中标题名为无标题 - 记事本的窗口。第一个参数是此窗口的类型。这两个参数知道一
个即可,另一个可以填null。但是如果是用窗口类型查找,则可能只能得到其中的一个窗口。因此通过标题进行查找是非常方便的。
IntPtr htextbox = FindWindowEx(hwnd, IntPtr.Zero, "EDIT", null);
这个函数用于获得窗口中子窗口的句柄,子窗口指的其实就是窗口中的各种控件。第一个参数是父窗口的句柄,第二个参数指示获得的是同一类型中的第几个子窗口。填IntPtr.Zero则表示获得第一个子窗口。第三个参数表示你需要找的子窗口的类型,第四个参数一般为null。如果一个窗口中有两个文本框,那么可以用如下操作获得第二个文本框的句柄。
IntPtr htextbox = FindWindowEx(hwnd, IntPtr.Zero, "EDIT", null);
IntPtr htextbox2 = FindWindowEx(hwnd, htextbox, "EDIT", null);//填上次获得的句柄,可以得到下一个的句柄。
这里只是先将第二个参数填为IntPtr.Zero,获取第一个EDIT类型的文本框,然后第二次调用时,再将第二参数填为第一个文本框的句柄,那么执行返回的就是下一个文本框的句柄了。因此htextbox2得到的就是第二文本框的句柄。
二、
SendMessage函数的第一个参数是窗口句柄,或者窗口中控件的句柄,第二个参数是消息的类型Flag,这些值是在API的一些头文件中定义好的。你要是在C#中用,就自己去定义他们。比如
const int WM_LBUTTONUP =0x0202;
const int WM_CLOSE =0x0010;
还有其他的类型Flag,可以参考上一篇Blog查询,也可以去查MSDN。第三个参数和第四个参数都是消息的具体内容。一般我们用的是最后一个参数。第三个参数填为IntPtr.Zero。
* 前面声明时,是声明了多个SendMessage函数(overload),用所需的数据类型直接替换IntPtr。
* 对要求返回字符串的类型(out string)可以用 StringBuilder 代替,此时不需要 out/ref。
在可以自由获得各种窗口及其上控件的句柄后,我们就可以向其发送各种消息进行鼠标和键盘的模拟了。比如:
SendMessage(htextbox, WM_SETTEXT, IntPtr.Zero, "name");
这句是为文本框填写相应的字符串name。但这句是覆盖现有文本,而不是追加。
如果是追加文本,可以
const int buffer_size = 1024;
StringBuilder buffer = new StringBuilder(buffer_size);
SendMessage(htextbox, WM_GETTEXT, buffer_size, buffer);//读取现有文本
SendMessage(htextbox, WM_SETTEXT, IntPtr.Zero, buffer.ToString() + "name");
IntPtr hbutton = FindWindowEx(hwnd, IntPtr.Zero, "BUTTON", null);
SendMessage(hbutton, WM_LBUTTONDOWN, IntPtr.Zero, null);//鼠标按下按钮
SendMessage(hbutton, WM_LBUTTONUP, IntPtr.Zero, null);//鼠标弹起按钮
当然如果是鼠标的动作,那么最后一个参数就是null。
在项目中有这样的需求,在主窗体隐藏时或者主进程运行时对其它窗体的控件或者事件进行控制,而且其它窗体是处于活动状态,而主窗体或者主进程是隐藏在后面的。这个时候使用句柄和消息来处理就比较好解决这些问题了,当然了也可以使用其它方法。比如将其它窗体在主窗体中申明并且定义,使之和主窗体一样一直存在于内存中,在各个窗体中申明公共方法,在主进程需要调用时直接调用即可,但是这样耗费了大量的系统资源。现在使用消息来解决这个问题。下面提供一个小程序,在主窗体中通过句柄和消息来控制子窗体中Label上文字变化和颜色,代码如下:
Windowns的API类
using System;
using System.Runtime.InteropServices;
namespace TestHwnd
{
public class Win32API
{
[DllImport("user32.dll ", CharSet = CharSet.Unicode)]
public static extern IntPtr PostMessage(IntPtr hwnd, int wMsg, string wParam, string lParam);
}
}
主窗体程序(发送消息):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TestHwnd
{
public partial class Main : Form
{
//定义了一个子窗体的句柄
public IntPtr hwndfrmTest;
public Main()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
if(hwndfrmTest!=(IntPtr)0)
{
if(DateTime.Now.Second % 3 == 0)
{
Win32API.PostMessage(hwndfrmTest, 0x60, "", "");
}
if(DateTime.Now.Second % 5 == 0)
{
Win32API.PostMessage(hwndfrmTest, 0x61, "", "");
}
}
}
void Button2Click(object sender, EventArgs e)
{
frmTest frm=new frmTest();
frm.Show(this);
}
}
子窗体程序(接收消息)
using System;
using System.Drawing;
using System.Windows.Forms;
namespace TestHwnd
{
/// <summary>
/// Description of frmTest.
/// </summary>
public partial class frmTest : Form
{
Main main;
public frmTest()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
}
void FrmTest_Load( object sender, EventArgs e)
{
main = this.Owner as Main;
//初始化该窗体的句柄
main.hwndfrmTest = this.Handle;
}
/// 重写窗体的消息处理函数DefWndProc,从中加入自己定义消息 MYMESSAGE 的检测的处理入口
protected override void DefWndProc( ref Message m)
{
switch (m.Msg)
{
case 0x60:
{
label1.ForeColor=Color.Red;
label1.Text = DateTime.Now. ToString() + "-" + "测试成功。。。。,呵呵,变红了";
}
break;
case 0x61:
{
label1.ForeColor=Color.Blue;
label1.Text = DateTime.Now. ToString() + "-" + "测试成功。。。。,呵呵,变蓝了";
}
break;
default:
base. DefWndProc( ref m);
break;
}
}
void Button1Click( object sender, EventArgs e)
{
main.hwndfrmTest = (IntPtr) ( 0);
this. Close();
}
}
}
//******************************************
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
namespace findWindowTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Find Window
// 查找窗体
// @para1: 窗体的类名 例如对话框类是"#32770"
// @para2: 窗体的标题 例如打开记事本 标题是"无标题 - 记事本" 注意 - 号两侧的空格
// return: 窗体的句柄
[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow(string className, string windowName);
// Find Window Ex
// 查找窗体的子窗体
// @para1: 父窗体的句柄 如果为null,则函数以桌面窗口为父窗口,查找桌面窗口的所有子窗口
// @para2: 子窗体的句柄 如果为null,从@para1的直接子窗口的第一个开始查找
// @para3: 子窗体的类名 为""表示所有类
// @para4: 子窗体的标题 为""表示要查找的窗体无标题 如空白的textBox控件
// return: 子窗体的句柄
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
private static extern IntPtr FindWindowEx(
IntPtr hwndParent,
IntPtr hwndChildAfter,
string lpszClass,
string lpszWindow);
// SendMessage
// 向窗体发送消息
// @para1: 窗体句柄
// @para2: 消息类型
// @para3: 附加的消息信息
// @para4: 附加的消息信息
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(
IntPtr hWnd,
int Msg,
IntPtr wParam,
string lParam);
// 消息类型(部分)
const int WM_GETTEXT = 0x000D; // 获得窗体文本 如获得对话框标题
const int WM_SETTEXT = 0x000C; // 设置窗体文本 如设置文本框内容
const int WM_CLICK = 0x00F5; // 发送点击消息如调用该窗体(按钮)的"button1_Click();"
// 本程序针对指定的另一程序窗体因此声名了如下变量
IntPtr Wnd = new IntPtr(0);// 一卡通注册程序主窗体
IntPtr sWnd = new IntPtr(0);// GroupBox控件 此为“一卡通注册程序”主窗体的子窗体
IntPtr txt = new IntPtr(0);// 文本框
IntPtr btn1 = new IntPtr(0);// 查询按钮
IntPtr btn2 = new IntPtr(0);// 注册按钮 这三个窗体又为“GroupBox控件”的子窗体
//IntPtr popW = new IntPtr(0);// 弹出对话框
//IntPtr popB = new IntPtr(0);// 弹出对话框确定按钮
// 文件操作
private String filename = string.Empty;
private StreamReader reader = null;
// 从“打开文件”对话框打开txt文件 同时获得需要的窗口句柄
private void button2_Click(object sender, EventArgs e)
{
label2.Text = "";
openFileDialog1.DefaultExt = "txt";
openFileDialog1.Filter = "文本文件|*.txt";
openFileDialog1.RestoreDirectory = true;
openFileDialog1.FilterIndex = 1;
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
filename = openFileDialog1.FileName;
}
// 获得窗口句柄
Wnd = FindWindowEx((IntPtr)0, (IntPtr)0, null, "读者一卡通注册");// 一个注册程序的窗体
sWnd = FindWindowEx(Wnd, (IntPtr)0, null, "条件"); // 窗体上的一个GroupBox控件
txt = FindWindowEx(sWnd, (IntPtr)0, null, ""); // GroupBox内的textBox控件
btn1 = FindWindowEx(sWnd, (IntPtr)0, null, "查询"); // GroupBox内的查询按钮
btn2 = FindWindowEx(sWnd, (IntPtr)0, null, "注册"); // GroupBox内的注册按钮
}
// 重复地把文件内读取的行
// 将该行发送给注册程序窗体上的文本框中
// 并“点击”查询按钮和注册按钮
// 直到文件读取完毕
private void button3_Click(object sender, EventArgs e)
{
//计数
int count = 0;
//读取文件
if (filename == string.Empty)
{
button2.Focus();
return;
}
reader = new StreamReader(filename);
if (reader.EndOfStream)
{
return;
}
string str = string.Empty;
do
{
//读取学号 保存在变量str中
str = reader.ReadLine();
//设置学号
SendMessage(txt, WM_SETTEXT, (IntPtr)0, str);
//点击查询按钮
SendMessage(btn1, WM_CLICK, (IntPtr)0, "");
//点击注册按钮
SendMessage(btn2, WM_CLICK, (IntPtr)0, "");
count++;
}
while(!reader.EndOfStream);
reader.Close();
filename = string.Empty;
label1.Text = "注册人数:";
label2.Text = Convert.ToString(count);
}
}
}
//******************************
C#获取进程的主窗口句柄
通过调用Win32 API实现。
public class User32API
{
private static Hashtable processWnd = null;
public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam);
static User32API()
{
if (processWnd == null)
{
processWnd = new Hashtable();
}
}
[DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)]
public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);
[DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);
[DllImport("user32.dll", EntryPoint = "IsWindow")]
public static extern bool IsWindow(IntPtr hWnd);
[DllImport("kernel32.dll", EntryPoint = "SetLastError")]
public static extern void SetLastError(uint dwErrCode);
public static IntPtr GetCurrentWindowHandle()
{
IntPtr ptrWnd = IntPtr.Zero;
uint uiPid = (uint)Process.GetCurrentProcess().Id; // 当前进程 ID
object objWnd = processWnd[uiPid];
if (objWnd != null)
{
ptrWnd = (IntPtr)objWnd;
if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd)) // 从缓存中获取句柄
{
return ptrWnd;
}
else
{
ptrWnd = IntPtr.Zero;
}
}
bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);
// 枚举窗口返回 false 并且没有错误号时表明获取成功
if (!bResult && Marshal.GetLastWin32Error() == 0)
{
objWnd = processWnd[uiPid];
if (objWnd != null)
{
ptrWnd = (IntPtr)objWnd;
}
}
return ptrWnd;
}
private static bool EnumWindowsProc(IntPtr hwnd, uint lParam)
{
uint uiPid = 0;
if (GetParent(hwnd) == IntPtr.Zero)
{
GetWindowThreadProcessId(hwnd, ref uiPid);
if (uiPid == lParam) // 找到进程对应的主窗口句柄
{
processWnd[uiPid] = hwnd; // 把句柄缓存起来
SetLastError(0); // 设置无错误
return false; // 返回 false 以终止枚举窗口
}
}
return true;
}
}
调用User32API.GetCurrentWindowHandle()即可返回当前进程的主窗口句柄,如果获取失败则返回IntPtr.Zero。
补充:微软实现的获取进程主窗口句柄代码
public class MyProcess
{
private bool haveMainWindow = false;
private IntPtr mainWindowHandle = IntPtr.Zero;
private int processId = 0;
private delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam);
public IntPtr GetMainWindowHandle(int processId)
{
if (!this.haveMainWindow)
{
this.mainWindowHandle = IntPtr.Zero;
this.processId = processId;
EnumThreadWindowsCallback callback = new EnumThreadWindowsCallback(this.EnumWindowsCallback);
EnumWindows(callback, IntPtr.Zero);
GC.KeepAlive(callback);
this.haveMainWindow = true;
}
return this.mainWindowHandle;
}
private bool EnumWindowsCallback(IntPtr handle, IntPtr extraParameter)
{
int num;
GetWindowThreadProcessId(new HandleRef(this, handle), out num);
if ((num == this.processId) && this.IsMainWindow(handle))
{
this.mainWindowHandle = handle;
return false;
}
return true;
}
private bool IsMainWindow(IntPtr handle)
{
return (!(GetWindow(new HandleRef(this, handle), 4) != IntPtr.Zero) && IsWindowVisible(new HandleRef(this, handle)));
}
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetWindowThreadProcessId(HandleRef handle, out int processId);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetWindow(HandleRef hWnd, int uCmd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool IsWindowVisible(HandleRef hWnd);
}
[参考]https://www.cnblogs.com/2SBC/p/12892647.html
---------------------------------------------------------------------------------------------------------------------------------
wMsg常量值:
-
//创建一个窗口
-
const int WM_CREATE = 0x01;
-
//当一个窗口被破坏时发送
-
const int WM_DESTROY = 0x02;
-
//移动一个窗口
-
const int WM_MOVE = 0x03;
-
//改变一个窗口的大小
-
const int WM_SIZE = 0x05;
-
//一个窗口被激活或失去激活状态
-
const int WM_ACTIVATE = 0x06;
-
//一个窗口获得焦点
-
const int WM_SETFOCUS = 0x07;
-
//一个窗口失去焦点
-
const int WM_KILLFOCUS = 0x08;
-
//一个窗口改变成Enable状态
-
const int WM_ENABLE = 0x0A;
-
//设置窗口是否能重画
-
const int WM_SETREDRAW = 0x0B;
-
//应用程序发送此消息来设置一个窗口的文本
-
const int WM_SETTEXT = 0x0C;
-
//应用程序发送此消息来复制对应窗口的文本到缓冲区
-
const int WM_GETTEXT = 0x0D;
-
//得到与一个窗口有关的文本的长度(不包含空字符)
-
const int WM_GETTEXTLENGTH = 0x0E;
-
//要求一个窗口重画自己
-
const int WM_PAINT = 0x0F;
-
//当一个窗口或应用程序要关闭时发送一个信号
-
const int WM_CLOSE = 0x10;
-
//当用户选择结束对话框或程序自己调用ExitWindows函数
-
const int WM_QUERYENDSESSION = 0x11;
-
//用来结束程序运行
-
const int WM_QUIT = 0x12;
-
//当用户窗口恢复以前的大小位置时,把此消息发送给某个图标
-
const int WM_QUERYOPEN = 0x13;
-
//当窗口背景必须被擦除时(例在窗口改变大小时)
-
const int WM_ERASEBKGND = 0x14;
-
//当系统颜色改变时,发送此消息给所有顶级窗口
-
const int WM_SYSCOLORCHANGE = 0x15;
-
//当系统进程发出WM_QUERYENDSESSION消息后,此消息发送给应用程序,通知它对话是否结束
-
const int WM_ENDSESSION = 0x16;
-
//当隐藏或显示窗口是发送此消息给这个窗口
-
const int WM_SHOWWINDOW = 0x18;
-
//发此消息给应用程序哪个窗口是激活的,哪个是非激活的
-
const int WM_ACTIVATEAPP = 0x1C;
-
//当系统的字体资源库变化时发送此消息给所有顶级窗口
-
const int WM_FONTCHANGE = 0x1D;
-
//当系统的时间变化时发送此消息给所有顶级窗口
-
const int WM_TIMECHANGE = 0x1E;
-
//发送此消息来取消某种正在进行的摸态(操作)
-
const int WM_CANCELMODE = 0x1F;
-
//如果鼠标引起光标在某个窗口中移动且鼠标输入没有被捕获时,就发消息给某个窗口
-
const int WM_SETCURSOR = 0x20;
-
//当光标在某个非激活的窗口中而用户正按着鼠标的某个键发送此消息给//当前窗口
-
const int WM_MOUSEACTIVATE = 0x21;
-
//发送此消息给MDI子窗口//当用户点击此窗口的标题栏,或//当窗口被激活,移动,改变大小
-
const int WM_CHILDACTIVATE = 0x22;
-
//此消息由基于计算机的训练程序发送,通过WH_JOURNALPALYBACK的hook程序分离出用户输入消息
-
const int WM_QUEUESYNC = 0x23;
-
//此消息发送给窗口当它将要改变大小或位置
-
const int WM_GETMINMAXINFO = 0x24;
-
//发送给最小化窗口当它图标将要被重画
-
const int WM_PAINTICON = 0x26;
-
//此消息发送给某个最小化窗口,仅//当它在画图标前它的背景必须被重画
-
const int WM_ICONERASEBKGND = 0x27;
-
//发送此消息给一个对话框程序去更改焦点位置
-
const int WM_NEXTDLGCTL = 0x28;
-
//每当打印管理列队增加或减少一条作业时发出此消息
-
const int WM_SPOOLERSTATUS = 0x2A;
-
//当button,combobox,listbox,menu的可视外观改变时发送
-
const int WM_DRAWITEM = 0x2B;
-
//当button, combo box, list box, list view control, or menu item 被创建时
-
const int WM_MEASUREITEM = 0x2C;
-
//此消息有一个LBS_WANTKEYBOARDINPUT风格的发出给它的所有者来响应WM_KEYDOWN消息
-
const int WM_VKEYTOITEM = 0x2E;
-
//此消息由一个LBS_WANTKEYBOARDINPUT风格的列表框发送给他的所有者来响应WM_CHAR消息
-
const int WM_CHARTOITEM = 0x2F;
-
//当绘制文本时程序发送此消息得到控件要用的颜色
-
const int WM_SETFONT = 0x30;
-
//应用程序发送此消息得到当前控件绘制文本的字体
-
const int WM_GETFONT = 0x31;
-
//应用程序发送此消息让一个窗口与一个热键相关连
-
const int WM_SETHOTKEY = 0x32;
-
//应用程序发送此消息来判断热键与某个窗口是否有关联
-
const int WM_GETHOTKEY = 0x33;
-
//此消息发送给最小化窗口,当此窗口将要被拖放而它的类中没有定义图标,应用程序能返回一个图标或光标的句柄,当用户拖放图标时系统显示这个图标或光标
-
const int WM_QUERYDRAGICON = 0x37;
-
//发送此消息来判定combobox或listbox新增加的项的相对位置
-
const int WM_COMPAREITEM = 0x39;
-
//显示内存已经很少了
-
const int WM_COMPACTING = 0x41;
-
//发送此消息给那个窗口的大小和位置将要被改变时,来调用setwindowpos函数或其它窗口管理函数
-
const int WM_WINDOWPOSCHANGING = 0x46;
-
//发送此消息给那个窗口的大小和位置已经被改变时,来调用setwindowpos函数或其它窗口管理函数
-
const int WM_WINDOWPOSCHANGED = 0x47;
-
//当系统将要进入暂停状态时发送此消息
-
const int WM_POWER = 0x48;
-
//当一个应用程序传递数据给另一个应用程序时发送此消息
-
const int WM_COPYDATA = 0x4A;
-
//当某个用户取消程序日志激活状态,提交此消息给程序
-
const int WM_CANCELJOURNA = 0x4B;
-
//当某个控件的某个事件已经发生或这个控件需要得到一些信息时,发送此消息给它的父窗口
-
const int WM_NOTIFY = 0x4E;
-
//当用户选择某种输入语言,或输入语言的热键改变
-
const int WM_INPUTLANGCHANGEREQUEST = 0x50;
-
//当平台现场已经被改变后发送此消息给受影响的最顶级窗口
-
const int WM_INPUTLANGCHANGE = 0x51;
-
//当程序已经初始化windows帮助例程时发送此消息给应用程序
-
const int WM_TCARD = 0x52;
-
//此消息显示用户按下了F1,如果某个菜单是激活的,就发送此消息个此窗口关联的菜单,否则就发送给有焦点的窗口,如果//当前都没有焦点,就把此消息发送给//当前激活的窗口
-
const int WM_HELP = 0x53;
-
//当用户已经登入或退出后发送此消息给所有的窗口,//当用户登入或退出时系统更新用户的具体设置信息,在用户更新设置时系统马上发送此消息
-
const int WM_USERCHANGED = 0x54;
-
//公用控件,自定义控件和他们的父窗口通过此消息来判断控件是使用ANSI还是UNICODE结构
-
const int WM_NOTIFYFORMAT = 0x55;
-
//当用户某个窗口中点击了一下右键就发送此消息给这个窗口
-
//const int WM_CONTEXTMENU = ??;
-
//当调用SETWINDOWLONG函数将要改变一个或多个 窗口的风格时发送此消息给那个窗口
-
const int WM_STYLECHANGING = 0x7C;
-
//当调用SETWINDOWLONG函数一个或多个 窗口的风格后发送此消息给那个窗口
-
const int WM_STYLECHANGED = 0x7D;
-
//当显示器的分辨率改变后发送此消息给所有的窗口
-
const int WM_DISPLAYCHANGE = 0x7E;
-
//此消息发送给某个窗口来返回与某个窗口有关连的大图标或小图标的句柄
-
const int WM_GETICON = 0x7F;
-
//程序发送此消息让一个新的大图标或小图标与某个窗口关联
-
const int WM_SETICON = 0x80;
-
//当某个窗口第一次被创建时,此消息在WM_CREATE消息发送前发送
-
const int WM_NCCREATE = 0x81;
-
//此消息通知某个窗口,非客户区正在销毁
-
const int WM_NCDESTROY = 0x82;
-
//当某个窗口的客户区域必须被核算时发送此消息
-
const int WM_NCCALCSIZE = 0x83;
-
//移动鼠标,按住或释放鼠标时发生
-
const int WM_NCHITTEST = 0x84;
-
//程序发送此消息给某个窗口当它(窗口)的框架必须被绘制时
-
const int WM_NCPAINT = 0x85;
-
//此消息发送给某个窗口仅当它的非客户区需要被改变来显示是激活还是非激活状态
-
const int WM_NCACTIVATE = 0x86;
-
//发送此消息给某个与对话框程序关联的控件,widdows控制方位键和TAB键使输入进入此控件通过应
-
const int WM_GETDLGCODE = 0x87;
-
//当光标在一个窗口的非客户区内移动时发送此消息给这个窗口 非客户区为:窗体的标题栏及窗 的边框体
-
const int WM_NCMOUSEMOVE = 0xA0;
-
//当光标在一个窗口的非客户区同时按下鼠标左键时提交此消息
-
const int WM_NCLBUTTONDOWN = 0xA1;
-
//当用户释放鼠标左键同时光标某个窗口在非客户区十发送此消息
-
const int WM_NCLBUTTONUP = 0xA2;
-
//当用户双击鼠标左键同时光标某个窗口在非客户区十发送此消息
-
const int WM_NCLBUTTONDBLCLK = 0xA3;
-
//当用户按下鼠标右键同时光标又在窗口的非客户区时发送此消息
-
const int WM_NCRBUTTONDOWN = 0xA4;
-
//当用户释放鼠标右键同时光标又在窗口的非客户区时发送此消息
-
const int WM_NCRBUTTONUP = 0xA5;
-
//当用户双击鼠标右键同时光标某个窗口在非客户区十发送此消息
-
const int WM_NCRBUTTONDBLCLK = 0xA6;
-
//当用户按下鼠标中键同时光标又在窗口的非客户区时发送此消息
-
const int WM_NCMBUTTONDOWN = 0xA7;
-
//当用户释放鼠标中键同时光标又在窗口的非客户区时发送此消息
-
const int WM_NCMBUTTONUP = 0xA8;
-
//当用户双击鼠标中键同时光标又在窗口的非客户区时发送此消息
-
const int WM_NCMBUTTONDBLCLK = 0xA9;
-
//WM_KEYDOWN 按下一个键
-
const int WM_KEYDOWN = 0x0100;
-
//释放一个键
-
const int WM_KEYUP = 0x0101;
-
//按下某键,并已发出WM_KEYDOWN, WM_KEYUP消息
-
const int WM_CHAR = 0x102;
-
//当用translatemessage函数翻译WM_KEYUP消息时发送此消息给拥有焦点的窗口
-
const int WM_DEADCHAR = 0x103;
-
//当用户按住ALT键同时按下其它键时提交此消息给拥有焦点的窗口
-
const int WM_SYSKEYDOWN = 0x104;
-
//当用户释放一个键同时ALT 键还按着时提交此消息给拥有焦点的窗口
-
const int WM_SYSKEYUP = 0x105;
-
//当WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函数翻译后提交此消息给拥有焦点的窗口
-
const int WM_SYSCHAR = 0x106;
-
//当WM_SYSKEYDOWN消息被TRANSLATEMESSAGE函数翻译后发送此消息给拥有焦点的窗口
-
const int WM_SYSDEADCHAR = 0x107;
-
//在一个对话框程序被显示前发送此消息给它,通常用此消息初始化控件和执行其它任务
-
const int WM_INITDIALOG = 0x110;
-
//当用户选择一条菜单命令项或当某个控件发送一条消息给它的父窗口,一个快捷键被翻译
-
const int WM_COMMAND = 0x111;
-
//当用户选择窗口菜单的一条命令或//当用户选择最大化或最小化时那个窗口会收到此消息
-
const int WM_SYSCOMMAND = 0x112;
-
//发生了定时器事件
-
const int WM_TIMER = 0x113;
-
//当一个窗口标准水平滚动条产生一个滚动事件时发送此消息给那个窗口,也发送给拥有它的控件
-
const int WM_HSCROLL = 0x114;
-
//当一个窗口标准垂直滚动条产生一个滚动事件时发送此消息给那个窗口也,发送给拥有它的控件
-
const int WM_VSCROLL = 0x115;
-
//当一个菜单将要被激活时发送此消息,它发生在用户菜单条中的某项或按下某个菜单键,它允许程序在显示前更改菜单
-
const int WM_INITMENU = 0x116;
-
//当一个下拉菜单或子菜单将要被激活时发送此消息,它允许程序在它显示前更改菜单,而不要改变全部
-
const int WM_INITMENUPOPUP = 0x117;
-
//当用户选择一条菜单项时发送此消息给菜单的所有者(一般是窗口)
-
const int WM_MENUSELECT = 0x11F;
-
//当菜单已被激活用户按下了某个键(不同于加速键),发送此消息给菜单的所有者
-
const int WM_MENUCHAR = 0x120;
-
//当一个模态对话框或菜单进入空载状态时发送此消息给它的所有者,一个模态对话框或菜单进入空载状态就是在处理完一条或几条先前的消息后没有消息它的列队中等待
-
const int WM_ENTERIDLE = 0x121;
-
//在windows绘制消息框前发送此消息给消息框的所有者窗口,通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置消息框的文本和背景颜色
-
const int WM_CTLCOLORMSGBOX = 0x132;
-
//当一个编辑型控件将要被绘制时发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置编辑框的文本和背景颜色
-
const int WM_CTLCOLOREDIT = 0x133;
-
-
//当一个列表框控件将要被绘制前发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置列表框的文本和背景颜色
-
const int WM_CTLCOLORLISTBOX = 0x134;
-
//当一个按钮控件将要被绘制时发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置按纽的文本和背景颜色
-
const int WM_CTLCOLORBTN = 0x135;
-
//当一个对话框控件将要被绘制前发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置对话框的文本背景颜色
-
const int WM_CTLCOLORDLG = 0x136;
-
//当一个滚动条控件将要被绘制时发送此消息给它的父窗口通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置滚动条的背景颜色
-
const int WM_CTLCOLORSCROLLBAR = 0x137;
-
//当一个静态控件将要被绘制时发送此消息给它的父窗口通过响应这条消息,所有者窗口可以 通过使用给定的相关显示设备的句柄来设置静态控件的文本和背景颜色
-
const int WM_CTLCOLORSTATIC = 0x138;
-
//当鼠标轮子转动时发送此消息个当前有焦点的控件
-
const int WM_MOUSEWHEEL = 0x20A;
-
//双击鼠标中键
-
const int WM_MBUTTONDBLCLK = 0x209;
-
//释放鼠标中键
-
const int WM_MBUTTONUP = 0x208;
-
//移动鼠标时发生,同WM_MOUSEFIRST
-
const int WM_MOUSEMOVE = 0x200;
-
//按下鼠标左键
-
const int WM_LBUTTONDOWN = 0x201;
-
//释放鼠标左键
-
const int WM_LBUTTONUP = 0x202;
-
//双击鼠标左键
-
const int WM_LBUTTONDBLCLK = 0x203;
-
//按下鼠标右键
-
const int WM_RBUTTONDOWN = 0x204;
-
//释放鼠标右键
-
const int WM_RBUTTONUP = 0x205;
-
//双击鼠标右键
-
const int WM_RBUTTONDBLCLK = 0x206;
-
//按下鼠标中键
-
const int WM_MBUTTONDOWN = 0x207;
-
-
const int WM_USER = 0x0400;
-
const int MK_LBUTTON = 0x0001;
-
const int MK_RBUTTON = 0x0002;
-
const int MK_SHIFT = 0x0004;
-
const int MK_CONTROL = 0x0008;
-
const int MK_MBUTTON = 0x0010;
-
const int MK_XBUTTON1 = 0x0020;
-
const int MK_XBUTTON2 = 0x0040;
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· NetPad:一个.NET开源、跨平台的C#编辑器