WPARAM.LPARAM区别
对wm_command的详细解释
当用户点击菜单、按钮、下拉列表框等控件时候,会触发WM_COMMAND
LOWORD(wParam) 是控件或菜单或加速键的ID,菜单的sparator的ID为0
如果LOWORD(wParam) 是控件ID,HIWORD(wParam)是notification code, 比如BN_CLI件的操作,双击,单击之类。
WM_COMMAND产生的条件:点击菜单,点击加速键,点击子窗口按钮,点击工具栏按钮。这些时候都有command消息产生。
WM_COMMAND消息中有两个参数,wparam、lparam,定义如下:
wParam 高两个字节 通知码
wParam 低两字节 命令ID
lParam 发送命令消息的子窗体句柄。
当到了Win32后,控件的种类越来越多,当然不可以为每一个控件都定义一套消息,这样也不利于系统的扩充。所以在Win32中定义了唯一一个强大的消息 WM_NOTIFY。当然WM_NOTIFY也遵守原来的消息规则,既只带参数wParam和lParam。唯一不同处在于,此时的lParam中传送的是一个NMHDR指针。不同的控件可以按照规则对NMHDR进行扩充,因此WM_NOTIFY消息传送的信息量可以相当的大,这个可以看看MSDN中的相关说明,TreeControl中就有很多这种消息。
对于菜单和加速键来说,lParam为0,只有控件此项才非0。命令ID也就是资源脚本中定义的菜单项的命令ID或者加速键的命令ID;菜单的通知码为0;加速键的通知码为1。
对于Windows菜单中菜单项和加速键,点击后,Windows会向所属的窗体发送WM_SYSCOMMAND,而不是WM_COMMAND消息。注意,WINDOWS菜单是系统菜单,也就是在标题栏点击鼠标左键的时候弹出的菜单。我们可以捕获WM_CREATE消息,加入自己的操作:GetSysMenu获取系统菜单句柄,然后对系统菜单进行操作,并且捕获添加菜单项(根据菜单命令ID)ID对应的WM_SYSCOMMAND消息进行处理。修改系统默认的菜单行为。
关于Windows 消息的wparamh和lparam
WM_DRAWITEM,WM_DELETEITEM,WM_MEASUREITEM,WM_CHARTOITEM:
通知父窗口将绘制控件自身窗口
命令消息的lParam为0L,区分于控件消息
3、控件消息:控件通知消息也是以WM_COMMAND为消息名.由编辑框,列表框,子窗口发送给父窗口的
通知消息.
目前控件消息有3种格式:
仿窗口消息格式 -- 如:WM_HSCROLL 或者 WM_VSCROLL : 滚动控件通知父窗口沿水平或者垂直
方向滚动窗口
WM_PARENTNOTIFY: 通知控件窗口建立或销毁其他事件
一、消息的类别
1、窗口消息:即标准的WINDOWS消息,它与创建窗口,绘制窗口,移动窗口和销毁窗口等操作窗口的动
作有关,这类消息是以WM_为前缀,不过WM_COMMAND例外.
例如: WM_CREATE -- 创建窗口后立即发出的一个消息,用于指示窗口初始化
WM_CLOSE -- 通知窗口要将它关闭
WM_PAINT -- 通知窗口绘制自身
WM_LBUTTONDOWN -- 通知窗口在它的客户区中按下了鼠标左键
WM_MOVE、WM_QUIT等等.. 其他的可查看微软发布的技术参考资料 -- 窗口息的类别。
NMHDR 定义如下:
typedef struct tagNMHDR{
HWND hwndFrom ; -- 发出控件消息的控件窗口的句柄
UINT idFrom ; -- 控件的资源ID
UINT code ; -- 控件消息的消息通知码EX_XXX
仿命令消息格式 -- messge为WM_COMMAND;wParam底16位为控件ID,高16位为消息通知码;
VC跨进程传递数据
[VC]SendMessage和PostMessage发送消息(不同进程传递字符串)一、函数功能该函数将指定的消息发送到一个或多个窗口。
此函数为指定的窗口调用窗口程序,直到窗口程序处理完消息再返回。
而函数PostMessage不同,将一个消息寄送到一个线程的消息队列后立即返回。
二、函数原型SendMessage函数的原型为LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);参数:hWnd:其窗口程序将接收消息的窗口的句柄。
Msg:指定被发送的消息。
wParam:指定附加的消息指定信息。
IParam:指定附加的消息指定信息。
返回值:返回值指定消息处理的结果,依赖于所发送的消息WPARAM 和 LPARAM 两个附加参数,可以传递一些附加信息,由于它们是long 型的,所以只能传递数字,如果想要传递字符串之类的则需要使用指针,即字符串的地址。
三、同一进程里发送消息1.发送消息void CSendMessageDlg::OnBnClickedButtonSend(){ CString* msg = new CString("发送的字符串"); ::SendMessage(m_hWnd,WM_USER+1,0,(LPARAM)msg);delete msg; }2.添加消息响应函数(1)SendMessageDlg.h 添加afx_msg HRESULT OnClickBtn1(WPARAM,LPARAM);(2)SendMessageDlg.cppBEGIN_MESSAGE_MAPEND_MESSAGE_MAP()中间ON_MESSAGE(WM_USER+1,OnClickBtnSend)(3)实现函数HRESULT CSendMessageDlg::OnClickBtn1(WPARAM wParam,LPARAM lParam) { CString* rmsg = (CString*)lParam; MessageBox(*rmsg);return TRUE; }3.点击发送,响应消息四、不同进程发送消息传递字符串1.两个进程间(1)两个不同的进程不能用上面的方法,当然只发送消息是可以的。
c语言sendmessage函数用法
c语言sendmessage函数用法摘要:1.C语言SendMessage函数简介2.SendMessage函数的参数3.SendMessage函数的用法示例4.注意事项正文:C语言SendMessage函数是一种在Windows操作系统中发送消息的函数,它主要用于窗口程序设计。
SendMessage函数的原型为:```INT WINAPI SendMessage(HWND hWnd, // 窗口句柄UINT uMsg, // 消息码WPARAM wParam, // 消息参数LPARAM lParam // 消息附加参数);```SendMessage函数共有四个参数,分别是:1.hWnd:窗口句柄,表示要发送消息的窗口。
2.uMsg:消息码,表示要发送的消息类型。
例如:WM_NULL、WM_KEYDOWN、WM_LBUTTONDOWN等。
3.wParam:消息参数,根据不同消息类型,传递相应的信息。
例如,在WM_KEYDOWN消息中,wParam表示按下的键码。
4.lParam:消息附加参数,用于提供消息的相关信息。
例如,在WM_MOUSEMOVE消息中,lParam表示鼠标移动的坐标。
下面举一个SendMessage函数的用法示例:```c#include <windows.h>LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){switch (message){case WM_DESTROY:PostQuitMessage(0);return 0;case WM_KEYDOWN:switch (wParam){case VK_SPACE:MessageBox(NULL, TEXT("你按下了空格键"), TEXT("提示"), MB_OK);break;}return 0;default:return DefWindowProc(hWnd, message, wParam, lParam);}}int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){WNDCLASS wc = {0};wc.lpfnWndProc = WndProc;wc.hInstance = hInstance;wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);wc.lpszClassName = TEXT("SendMessageExample");if (!RegisterClass(&wc)){MessageBox(NULL, TEXT("注册窗口类失败"), TEXT("错误"), MB_OK);return 1;}HWND hWnd = CreateWindowEx(0,TEXT("SendMessageExample"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 300, 200,NULL,NULL,hInstance,NULL);if (!hWnd){MessageBox(NULL, TEXT("创建窗口失败"), TEXT("错误"), MB_OK);return 1;}ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);MSG msg;while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.wParam;}```以上示例创建了一个简单的窗口程序,当用户按下空格键时,会弹出一个提示框显示“你按下了空格键”。
钩子程序
WH_JOURNALPLAYBACK Hook 使应用程序可以插入消息到系统消息队列。可以使用这个 Hook 回 放通 过 使 用 WH_JOURNALRECORD Hook 记录 下 来 的 连 续 的 鼠 标 和 键 盘 事 件 。 只 要 WH_JOURNALPLAYBACK Hook 已 经 安 装 , 正 常 的 鼠 标 和 键 盘 事 件 就 是 无 效 的 。 WH_JOURNALPLAYBACK Hook 是 全 局 Hook , 它 不 能 象 线 程 特 定 Hook 一 样 使 用 。 WH_JOURNALPLAYBACK Hook 返回超时值,这个值告诉系统在处理来自回放 Hook 当前消息之前 需要等待多长时间(毫秒) 。这就使 Hook 可以控制实时事件的回放。WH_JOURNALPLAYBACK 是 system-wide local hooks,它們不會被注射到任何行程位址空間。 (估计按键精灵是用这个 hook 做的) 7、WH_JOURNALRECORD Hook WH_JOURNALRECORD Hook 用来监视和记录输入事件。典型的,可以使用这个 Hook 记录连续的 鼠标和键盘事件, 然后通过使用 WH_JOURNALPLAYBACK Hook 来回放。 WH_JOURNALRECORD Hook 是全局 Hook,它不能象线程特定 Hook 一样使用。WH_JOURNALRECORD 是 system-wide local hooks,它們不會被注射到任何行程位址空間。 8、WH_KEYBOARD Hook 在应用程序中,WH_KEYBOARD Hook 用来监视 WM_KEYDOWN and WM_KEYUP 消息,这些消息通过 GetMessage or PeekMessage function 返回。可以使用这个 Hook 来监视输入到消息队列中 的键盘消息。 9、WH_KEYBOARD_LL Hook WH_KEYBOARD_LL Hook 监视输入到线程消息队列中的键盘消息。 10、WH_MOUSE Hook WH_MOUSE Hook 监视从 GetMessage 或者 PeekMessage 函数返回的鼠标消息。使用这个 Hook 监视输入到消息队列中的鼠标消息。 11、WH_MOUSE_LL Hook WH_MOUSE_LL Hook 监视输入到线程消息队列中的鼠标消息。 12、WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks 使我们可以监视菜单,滚动条,消息框,对话框 消息并且发现用户使用 ALT+TAB or ALT+ESC 组合键切换窗口。 WH_MSGFILTER Hook 只能监视 传递到菜单,滚动条,消息框的消息,以及传递到通过安装了 Hook 子程的应用程序建立的对 话 框 的 消 息 。 WH_SYSMSGFILTER Hook 监 视 所 有 应 用 程 序 消 息 。 WH_MSGFILTER 和 WH_SYSMSGFILTER Hooks 使我们可以在模式循环期间过滤消息,这等价于在主消息循环中过 滤消息。通过调用 CallMsgFilter function 可以直接的调用 WH_MSGFILTER Hook。通过使用 这个函数,应用程序能够在模式循环期间使用相同的代码去过滤消息,如同在主消息循环里 一样。 13、WH_SHELL Hook 外壳应用程序可以使用 WH_SHELL Hook 去接收重要的通知。当外壳应用程序是激活的并且当 顶层窗口建立或者销毁时,系统调用 WH_SHELL Hook 子程。 WH_SHELL 共有5钟情況: 1. 只要有个 top-level、unowned 窗口被产生、起作用、或是被摧毁; 2. 当 Taskbar 需要重画某个按钮; 3. 当系统需要显示关于 Taskbar 的一个程序的最小化形式; 4. 当目前的键盘布局状态改变; 5. 当使用者按 Ctrl+Esc 去执行 Task Manager(或相同级别的程序) 。 按照惯例,外壳应用程序都不接收 WH_SHELL 消息。所以,在应用程序能够接收 WH_SHELL 消 息之前,应用程序必须调用 SystemParametersInfo function 注册它自己。
C#手柄控制
前段时间花38元从网上买了一对北通的USB游戏手柄,这样周末与晚上的休闲时间就可以玩玩孩儿时的SFC与街机模拟游戏了。
某日在某个网站上玩一个Flash游戏时,突然想到,如果也能使用手柄来玩Flash游戏,那该多爽。
但可惜的是,目前的Flash都是不支持对游戏手柄进行编程,这不免是Flash中的一个遗憾。
虽然Flash中不支持对游戏手柄进行编程,但我们可以换种方法,做一个辅助程序(外挂? ),将手柄中的操作事件转换为Flash中可接受的键盘与鼠标操作事件,这样不就可以使用游戏手柄来玩Flash游戏了吗?!于是,上网查了相关资料,但却发现只有C 方面的案例,而C#一个也找不,这不打紧,自己动手,丰衣足食。
(注:类似这样的功能,网络已有现成的软件,是一个日本人开发的,叫JoyToKey)对游戏手柄进行操作,大概有两种方式:采用系统API或者使用DirectInput 操作游戏手柄设备。
(也许还有其它方式,但我的知识范围有限,其它方式就不得而知了)采用系统API是一种最简单的方式,因为系统已帮我们封装好了所有细节,我们只要在程序中定时取得游戏手柄设备的状态就可以了(轮循)。
操作游戏手柄(杆)的API有以下几个:函数名称函数说明joyGetNumDevs 获取当前系统支持的游戏设备数量joyGetDevCaps 查询获取指定的游戏杆设备以确定其性能joySetCapture 向系统申请捕获某个游戏设备并定时将该设备的状态值通过消息发送到某个窗口joyReleaseCapture 释放对某个游戏设备的捕获joyGetPos 获取游戏设备的坐标位置和按钮状态joyGetPosEx 获取游戏设备的坐标位置和按钮状态joyGetThreshold 查询指定的游戏杆设备的当前移动阈值joySetThreshold 设置指定的游戏杆设备的移动阈值其中,根据调用不同的方法又可分为两种方式。
1)被动方式:调用joySetCapture方法,向系统申请对某个游戏手柄的捕捉,如果成功申请,系统将会定时将此游戏手柄的状态信息通过消息方式通知到我们的某个窗口上。
VC++6[1].0入门【第三章、MFC编程概述】
第三章 MFC 应用程序概述第3章 MFC 应用程序概述Microsoft Windows 是微软公司推出的一个应用于微机上的具有图形用户界面的多任务和多窗口的操作系统。
Windows 应用程序也称为窗口应用程序,所有的窗口应用程序都有着相同的窗口风格和菜单结构,用户界面友好,方便用户操作。
本章从剖析窗口应用程序的基本结构入手,继而介绍使用MFC 类库开发的应用程序框架结构,并介绍窗口应用程序运行的核心机制-消息映射。
学习了本章,你将对MFC 应用程序框架结构和运行机制有个整体的了解,为后面进入窗口应用程序开发打下良好的基础。
3.1 窗口应用程序概述窗口应用程序的开发一般采用可视化的面向对象的开发,可选择的窗口应用程序开发语言有Visual C++、Visual Basic 、Visual Java 、Dephi 等等。
无论采用哪一种开发语言,首先要了解窗口应用程序的基本机制。
3.1.1 窗口编程基础窗口应用程序运行于Windows 操作系统,Windows操作系统是一个多任务操作系统,因此窗口应用程序的组成,支持技术,基本运行机制等与DOS 应用程序有着本质的区别。
在学习开发窗口应用程序之前,先要对窗口应用程序有一个概念上的了解。
1. 窗口窗口是应用程序与用户进行交互的界面,应用程序通过窗口传递信息给用户,同样用户通过窗口输入数据,发布命令给应用程序。
Windows 界面包含了丰富的标准用户界面元素,包括窗口、图标、菜单、滚动条、对话框、控件和消息框等。
用户使用这些界面元素可以方便的与应用程序进行交互,一个典型的窗口外观如图3-1所示。
垂直滚动条控制菜单栏标题栏菜单栏关闭按钮最小化按钮最大化按钮客户区VC++6简明教程图3-1 Windows应用程序窗口组成在Windows编程中,各种窗口、菜单、按钮、对话框及程序模块等Windows的规范部件是按“对象”来组织的。
为了提高开发窗口应用程序的效率,微软公司为用户提供了大量能创建上述标准元素的API函数和C++类,并且以Windows API函数库和C++类库的形式提供给用户,以充分满足构成应用程序操作界面的需要。
WM_COMMAND消息
WM_MESSAGE是最普通的WINDOWS消息,对于这种类型的消息没什么好说的。那WM_COMMAND和WM_NOTIFY消息都是WINDOWS CONTROL给它的父窗体发的消息,那这两种消息有什么不同呢?WM_COMMAND消息其实是早期的(WIN3.X时代)子窗体消息,子窗体给父窗体发送消息,父窗体就捕获WM_COMMAND来处理子窗体的消息。但是这个消息只包括了有限的信息,例如wParam包括了子窗口ID和通知码,lParam则包括了子窗口句柄,就这点信息了,如果想知道一些额外的信息的话(例如,鼠标点在了子控件的位置)就要借助于其他的WM_*消息。所以对于新型的WIN32控件,微软就增加了一个新的NOTIFICATION消息,这个消息的参数是这样的:wParam包含了控件ID,而lParam则包含了一个结构体的指针,这个结构体是NMHDR结构或者以NMHDR结构为第一项的一个更大的结构体。这样就可以包含了很多的子控件想给父窗体提供的信息了,甚至可以自己去定义这种的结构体。这就是这几种消息的差别点了。
当到了Win32后,控件的种类越来越多,当然不可以为每一个控件都定义一套消息,这样也不利于系统的扩充。所以在Win32中定义了唯一一个强大的消息 WM_NOTIFY。当然WM_NOTIFY也遵守原来的消息规则,既只带参数wParam和lParam。唯一不同处在于,此时的lParam中传送的是一个NMHDR指针。不同的控件可以按照规则对NMHDR进行扩充,因此WM_NOTIFY消息传送的信息量可以相当的大,这个可以看看MSDN中的相关说明,TreeControl中就有很多这种消息。
在Windows3.1里,控件会将mouse, keybord等等的消息通知它的父窗口, 使用的消息就只有WM_COMMAND, 事件种类和控件ID被包含在wParam中, 控件的句柄包含在lParam中。由于wParam和 lParam已经满了,当控件要向父窗口发送其它特殊消息同时附带很多信息的时候就没有地方可以存放它们了。所以Windows3.1中定义了许多其它的消息种类,比如WM_VSCROLL, WM_CTLCOLOR等等,每种消息wParam,lParam中附带的信息是不同的。
关于VC++中两种自定义消息的发送与接收的方法实现进行说明
在MFC中添加用户自定义消息首先弄清楚两点:(1)谁要发送这个消息(2)谁要接受这个消息。
用一个简单的例子来说明。
对象A向B(也可以就是A到A)发送消息。
1 发送消息首先在A的头文件中定义这个消息:#define WM_USERMESSAGE WM_USER+30所有自定义消息都是以WM_USER消息为基础加上一个任意的自然数来表示的。
A是向外发送消息的对象,因此在A的某个方法(函数)里就会调用用来发消息的函数B::SendMessage()/B::PostMessage(),因为是B接受消息,因此是如上的形式。
2 接受消息对象接受一个消息,应该有三部分:在头文件中有该消息的处理函数的原型;在实现文件中有接受消息映射的宏;以及该消息的处理函数的具体实现。
2.1 头文件中加上自定义消息的处理函数原型在DECLARE_MESSAGE_MAP()语句之前,一对AFX_MSG之间加上如下形式的函数原型:afx_msg LRESULT OnProcName( WPARAM wParam, LPARAM lParam );对Win32来说,wParam, lParam是传递消息最常用的手段。
2.2 在实现文件中加上接受消息映射的宏在cpp文件里,BEGIN_MESSAGE_MAP语句之后,在一对AFX_MSG_MAP之间,增加如下形式的代码:ON_MESSAGE(WM_USERMESSAGE, OnProcName)上面是不用分号结尾的。
2.3 在实现文件中给出消息处理函数的具体实现。
发信人: Amia (小羊·橘子·和中南海有缘), 信区: VisualC标题: MFC中自由使用自定义消息发信站: 哈工大紫丁香(2003年11月26日07:45:34 星期三), 站内信件消息映射、循环机制是Windows程序运行的基本方式。
V C++MFC 中有许多现成的消息句柄,可当我们需要完成其它的任务,需要自定义消息,就遇到了一些困难。
wParam,lParam
wParam,lParam(2009-11-24 17:07:00)转载▼分类:MSN搬家标签:杂谈一般应用程序需要处理的几个菜单消息有:(1)WM_INITMENU菜单消息。
这个消息在初始化主菜单时产生,如果程序员想拥有像Office 2003那样的菜单,就可以处理这个消息并重画主菜单。
这个消息具有下列参数:wParam:主菜单句柄lParam:0其中wParam的值是主菜单的句柄,即使用户选择的是系统菜单中的项。
(2)WM_MENUSELECT菜单消息。
当用户在菜单项中拖动鼠标的时候,你的应用程序的窗口过程会收到很多WM_MENUSELECT菜单消息,这时我们可以在状态栏中显示对该菜单项的文本描述。
这个消息具有下列参数:LOWORD(wParam):菜单项的ID或弹出式菜单的句柄。
HIWORD(wParam):选择标志。
lParam:包含该菜单项的菜单句柄。
这个消息是一个菜单跟踪消息。
其中wParam的低位字的值告诉你当前选择的是那一个菜单项(该菜单项会被加亮);wParam的高位字的值是“选择标志”,它可以是下列标志的组合:MF_GRAYED、MF_DISABLED、MF_CHECKED、MF_BITMAP、MF_POPUP、 MF_HELP、MF_SYSMENU和MF_MOUSESELECT。
如果你要实现Office 2003那样的菜单,你需要在这个消息产生时作一些处理,例如重画这个菜单项。
(3)WM_INITMENUPOPUP菜单消息。
当Windows准备显示一个弹出式菜单时,它就会给应用程序的窗口过程发送这个消息。
如果需要在显示弹出式菜单之前启用或禁用某些菜单项,我们就需要处理这个消息了。
这个消息具有下列参数:wParam:弹出式菜单句柄。
LOWORD(lParam):弹出式菜单索引。
HIWORD(lParam):系统菜单为1,其他为0。
如果你要实现Office 2003那样的菜单,你也需要在这个消息产生时作一些处理,例如重画弹出式菜单,使它具有Office 2003那样的菜单外观。
Windows消息及运行命令大全
Windows消息大全
消息,就是指Windows发出的一个通知,告诉应用程序某个事情发生了。
例如,单击鼠标、改变窗口尺寸、按下键盘上的一个键都会使Windows发送一个消息给应用程序。
消息本身是作为一个记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。
例如,对于单击鼠标所产生的消息来说,这个记录中包含了单击鼠标时的坐标。
这个记录类型叫做TMsg。
它在Windows单元中是这样声明的:
type
TMsg = packed record
hwnd: HWND / /窗口句柄
message: UINT / /消息常量标识符
wParam: WPARAM// 32位消息的特定附加信息
lParam: LPARAM // 32位消息的特定附加信息
time: DWORD / /消息创建时的时间
pt: TPoint / /消息创建时的鼠标位置
end
消息中有什么?
是否觉得一个消息记录中的信息像希腊语一样?如果是这样,那么看一看下面的解释:
通知消息(Notification message)是指这样一种消息,一个窗口内的子控件发生了一些事情,需要通知父窗口。
通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框,以及Windows 95公共控件如树状视图、列表视图等。
例如,单击或双击一个控件、在控件中选择部分文本、操作控件的滚动条都会产生通知消息。
Windows运行命令大全。
wParam和lParam消息
1 WM_PAINT消息,LOWORD(lParam)是客户区的宽,HIWORD(lParam)是客户区的高。
2 滚动条WM_VSCROLL或WM_HSCROLL消息,LOWORD(wParam)指出了鼠标对滚动条的操作。
比如上、下、左、右、翻页、移动等。
3 击键消息,有WM_SYSKEYDOWN、WM_SYSKEYUP、WM_KEYUP、WM_KEYDOWN,其中wParam是虚拟键代码,lParam是包含属于击键的其他信息。
lParam消息参数分为6个域,有重复计数、环境代码、键的先前状态等。
4 字符消息WM_CHAR、WM_DEADCHAR、WM_SYSCHAR、WM_SYSDEADCHAR,lParam消息参数跟击键消息的lParam消息参数内容相同,wParam参数是ANSI或Unicode 字符代码5 客户区鼠标消息WM_LBUTTONDOWN、WM_LBUTTONUP、WM_RBUTTONDOWN、WM_RBUTTONUP、WM_MBUTTONDOWN、WM_MBUTTONUP,lParam参数的低位是鼠标的客户区x坐标,高位是客户区y坐标。
wParam参数是指示鼠标键及Shift和Ctrl键的状态。
wParam&MK_SHIFT或MK_CTRL,如果返回TRUE就意味着有按下Shift或Ctrl 键。
6 非客户区消息,wParam参数指明移动或者单击鼠标键的非客户区位置,以HT开头,lParam参数低位指出了鼠标所在屏幕坐标的x坐标,高位指出了鼠标所在屏幕坐标的y坐标。
7 鼠标轮滚动消息,WM_MOUSEWHEEL消息,lParam将获得鼠标的屏幕位置(坐标),wParam参数的低位表明鼠标键和Shift与Ctrl键的状态。
wParam高位有一个“delta”值,该值可正可负,指出了滚轮导致屏幕滚动几行,120表示向上3行。
8 计时器消息WM_TIMER,wParam参数等于计时器的ID值,lParam为09 按钮子窗口的WM_COMMAND消息,wParam参数的低位是子窗口ID,高位是通知码, lParam参数是子窗口句柄。
Delphi - 关于钩子函数HOOK (一)
基本概念钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。
当消息到达后,在目标窗口处理函数之前处理它。
钩子机制允许应用程序截获处理window消息或特定事件。
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。
每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。
这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。
运行机制1、钩子链表和钩子子程:每一个Hook都有一个与之相关联的指针列表,称之为钩子链表,由系统来维护。
这个列表的指针指向指定的,应用程序定义的,被Hook子程调用的回调函数,也就是该钩子的各个处理子程。
当与指定的Hook类型关联的消息发生时,系统就把这个消息传递到Hook子程。
一些Hook子程可以只监视消息,或者修改消息,或者停止消息的前进,避免这些消息传递到下一个Hook子程或者目的窗口。
最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。
Windows 并不要求钩子子程的卸载顺序一定得和安装顺序相反。
每当有一个钩子被卸载,Windows 便释放其占用的内存,并更新整个Hook链表。
如果程序安装了钩子,但是在尚未卸载钩子之前就结束了,那么系统会自动为它做卸载钩子的操作。
钩子子程是一个应用程序定义的回调函数(CALLBACK Function),不能定义成某个类的成员函数,只能定义为普通的C函数。
用以监视系统或某一特定类型的事件,这些事件可以是与某一特定线程关联的,也可以是系统中所有线程的事件。
钩子子程必须按照以下的语法:LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam);HookProc是应用程序定义的名字。
钩子函数简介
HOOKBy Y-Z-FQQ:9766911411-WH_KEYBOARDKeyboardProc 钩子程序是一个线程钩子或系统钩子被SetWindowsHookEx函数调用.一个一个用程序无论何时调用GetMessage或PeekMessage函数之前,并且是键盘消息(WM_KEYUP 或WM_KEYDOWN )。
格式:LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam);参数:code指定一个标示让钩子程序用于确定如何处理消息,如果标示小于0,钩子过程必须通过CallNextHookEx函数,并且必须返回CallNextHookEx 函数返回的参数。
此参数可以被设置为下参数之一:HC_ACTIONwParam 和lParam 参数包含击键消息的信息。
HC_NOREMOVEwParam 和lParam 参数包含击键消息的信息,并且击键消息没有从消息队列中移除。
(一个应用程序调用PeekMessage函数,指定PM_NOREMOVE 标志)wPram指定产生击键消息的那个按键的虚拟键标示lParam指定重复次数,扫描码,扩充标记,环境代码,早先的关键标记,和过渡状态标记。
需要查看更多关于lParam参数的消息请查看Keystroke Message Flags,这个参数可以被设置为一个或多个以下值.0~15指定重复次数。
它的值是用户按住键的击键次数的重复结果。
16~23指定扫描码,这个值依赖于OEM.24指定这个键是否为一个扩充键,比如一个函数键或一个键在数字小键盘.这个值为1当这个键是一个扩充键,否则为0.25~28保留29指定环境代码.如果ALT键按下这个值为1;否则为0.30指定早先的关键标记.如果键被按下在消息发送前,则值为1。
如果键弹起则为0.31指定过渡状态标记.如果键被安下,则值为0,如果释放则为1.2-WH_CALLWNDPROC系统调用这个函数在消息到达线程之前.样式LRESULT CALLBACK CallWndProc(int nCode,WPARAM wParam,LPARAM lParam);参数:nCode指定是否钩子函数必须处理消息.如果nCode 为HC_ACTION,钩子程序必须处理消息.如果nCode小于0,钩子程序必须使用CallNextHookEx函数,并且必须返回CallNextHookEx的返回值.wParam指定消息是否为当前线程发送.如果消息为当前线程发送,并且为非0;否则为0.lParam指向一个CWPSTRUCT 结构体包含消息的细节.返回值如果nCode 小于0,钩子程序必须返回CallNextHookEx的返回.如果nCode 大于等于0,建议使用CallNextHookEx,并且返回其返回的值;另外,其他程序使用了WH_CALLWNDPROC 钩子将不会收到钩子通知和行为可能造成错误的结果。
lparam参数
lparam参数在Windows操作系统中,lparam是一个32位的参数,用于传递额外的信息给窗口过程函数。
它通常用于处理窗口消息,并提供了一种机制来传递与消息相关的数据。
lparam参数的定义和结构lparam是一个长整型数据,在32位系统中占据4个字节。
它通常被定义为一个指针类型,可以指向任意类型的数据。
在Windows API中,lparam参数被定义为一个LONG_PTR类型。
LONG_PTR是一个根据操作系统位数而定的有符号整型,用于表示指针或句柄值。
lparam参数的作用lparam参数在窗口消息处理过程中起着重要的作用。
它通过传递额外的信息来帮助程序处理不同类型的消息。
例如,在处理鼠标消息时,lparam可以携带鼠标事件相关的信息,如鼠标坐标、按下或释放的键等。
在处理键盘消息时,lparam可以携带键盘事件相关的信息,如按下或释放的键值、扫描码等。
此外,在自定义消息中,开发人员可以根据需要使用lparam参数来传递自定义数据。
lparam参数与wparam参数的区别在窗口消息处理过程中,除了lparam参数外,还有另一个重要的参数wparam。
这两个参数都用于传递额外的信息,但它们的作用和使用方式有所不同。
wparam参数是一个32位的参数,通常用于传递消息类型、命令ID等与消息相关的信息。
lparam参数则用于传递更详细的数据,如鼠标坐标、键盘事件等。
它可以携带更多的信息,并且可以指向任意类型的数据。
lparam参数的使用示例以下是一些常见窗口消息处理过程中使用lparam参数的示例:鼠标消息处理LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){switch (msg){case WM_LBUTTONDOWN:{int xPos = LOWORD(lParam);int yPos = HIWORD(lParam);// 处理鼠标左键按下事件}break;case WM_MOUSEMOVE:{int xPos = LOWORD(lParam);int yPos = HIWORD(lParam);// 处理鼠标移动事件}break;// 其他鼠标相关消息处理default:return DefWindowProc(hwnd, msg, wParam, lParam);}return 0;}在上述代码中,通过使用LOWORD和HIWORD宏来提取lparam参数中的低位和高位字。
c语言sendmessage函数用法
C语言sendMessage函数用法C语言是一种广泛使用的编程语言,它具有高效、灵活的特点,适用于各种不同类型的程序开发。
在C语言中,sendMessage函数是一种非常重要的函数,它可以实现进程间通信,使得不同的进程之间能够进行数据交换和信息传递。
本文将针对sendMessage函数的用法进行详细的介绍,帮助读者更好地理解和运用这一功能。
一、sendMessage函数概述1. sendMessage函数是Windows系统中用于进程间通信的一种函数,它可以向指定的窗口发送消息,实现不同窗口的交互和数据传递。
2. sendMessage函数的原型如下:LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);其中,hWnd表示要接收消息的窗口句柄,Msg表示要发送的消息类型,wParam和lParam分别表示消息的附加参数。
3. sendMessage函数的返回值为LRESULT类型,用于表示消息发送的结果。
二、sendMessage函数的参数详解1. hWnd:表示接收消息的窗口句柄,可以是窗口的实际句柄、父窗口句柄或者子窗口句柄,根据具体的需求进行选择。
2. Msg:表示要发送的消息类型,可以是系统定义的消息类型,也可以是自定义的消息类型,根据具体的需求进行选择。
3. wParam:表示消息的附加参数,可以用来传递一些额外的信息或者数据。
4. lParam:表示消息的附加参数,与wParam一样,可以用来传递一些额外的信息或者数据。
5. sendMessage函数的参数类型都是无符号整数类型,根据具体的需求进行选择合适的参数类型和数值。
三、sendMessage函数的使用示例下面通过一个简单的示例来演示sendMessage函数的使用方法,以便读者更好地理解和掌握这一功能。
#include <windows.h>int main(){HWND hWnd;UINT Msg;WPARAM wParam;LPARAM lParam;// 获取窗口句柄hWnd = FindWindow(NULL, "窗口标题");if (hWnd != NULL){// 发送自定义消息Msg = WM_USER + 1;wParam = 100;lParam = 200;LRESULT result = SendMessage(hWnd, Msg, wParam, lParam);if (result != 0){printf("消息发送成功\n");}else{printf("消息发送失败\n");}}else{printf("未找到指定窗口\n");}return 0;}上面的示例代码中,我们首先通过FindWindow函数获取指定窗口的句柄,然后使用sendMessage函数向该窗口发送自定义消息,并传递一些额外的参数。
TPCANMSg结构体内容
TPCANMSg结构体内容
TPCANMSg 结构体用来表示一条消息,各个字段的含义如下:typedef struct tagMSG{
HWND hwnd; //窗口句柄
UINT message; //消息类型
WPARAM wParam; //附加消息1
LPARAM lParam; //附加消息2
DWORD time; //消息被传递时候的时间
POINT pt; //消息被传递时光标在屏幕上的位置MSG;
对各个字段的说明:
(1)最后两个字段time 和pt 一般由系统使用,我们很少用到。
(2)message 为消息类型,也就是以WM 开头的消息(WM 是Window Message 的缩写),例如WM_CREATE、WM_PAINT、WM_DESTROY、WM_COMMAND 等。
(3)wParam 和lParam 是要重点说明的,它们都表示附加消息。
例如,当收到一个字符消息的时,message 的值为
WM_CHAR,但用户到底输入的是什么字符,那么就由wParam 和lParam 来说明。
wParam、lParam 表示的信息随消息类型的不同而不同,具体细节可以到MSDN中查看。
线程间通信常用的三种方法
线程间通信常⽤的三种⽅法多线程通信的⽅法主要有以下三种:1.全局变量进程中的线程间内存共享,这是⽐较常⽤的通信⽅式和交互⽅式。
注:定义全局变量时最好使⽤volatile来定义,以防编译器对此变量进⾏优化。
2.Message消息机制常⽤的Message通信的接⼝主要有两个:PostMessage和PostThreadMessage,PostMessage为线程向主窗⼝发送消息。
⽽PostThreadMessage是任意两个线程之间的通信接⼝。
2.1.PostMessage()函数原型:B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);参数:hWnd:其窗⼝程序接收消息的窗⼝的句柄。
可取有特定含义的两个值:HWND.BROADCAST:消息被寄送到系统的所有顶层窗⼝,包括⽆效或不可见的⾮⾃⾝拥有的窗⼝、被覆盖的窗⼝和弹出式窗⼝。
消息不被寄送到⼦窗⼝。
NULL:此函数的操作和调⽤参数dwThread设置为当前线程的标识符PostThreadMessage函数⼀样。
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
IParam:指定附加的消息特定的信息。
返回值:如果函数调⽤成功,返回⾮零值:如果函数调⽤失败,返回值是零。
MS还提供了SendMessage⽅法进⾏消息间通讯,SendMessage(),他和PostMessage的区别是:SendMessage是同步的,⽽PostMessage是异步的。
SendMessage必须等发送的消息执⾏之后,才返回。
2.2.PostThreadMessage()PostThreadMessage⽅法可以将消息发送到指定线程。
函数原型:BOOL PostThreadMessage(DWORD idThread,UINT Msg,WPARAM wParam, LPARAM lParam);参数除了ThreadId之外,基本和PostMessage相同。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
m_pParent->SendMessage(WM_DLG_NOTIFY,(WPARAM)szOut);
}
/*在消息接收窗口中*/
/*映射消息处理函数*/
ON_MESSAGE(WM_DLG_NOTIFY,OnDlgNotifyMsg)
2、谁将收到消息:一个消息必须由一个窗口接收。在窗口的过程(WNDPROC)中可以对消息进行分析,对自己感兴趣的消息进行处理。例如你希望对菜单选择进行处理那么你可以定义对WM_COMMAND进行处理的代码,如果希望在窗口中进行图形输出就必须对WM_PAINT进行处理。
3、未处理的消息到那里去了:M$为窗口编写了默认的窗口过程,这个窗口过程将负责处理那些你不处理消息。正因为有了这个默认窗口过程我们才可以利用Windows的窗口进行开发而不必过多关注窗口各种消息的处理。例如窗口在被拖动时会有很多消息发送,而我们都可以不予理睬让系统自己去处理。
5、示例:下面有一段伪代码演示如何在窗口过程中处理消息
LONG yourWndProc(HWND hWnd,UINT uMessageType,WPARAM wP,LPARAM)
{
switch(uMessageType)
{//使用SWITCH语句将各种消息分开
case(WM_PAINT):
break;
}
}
接下来谈谈什么是消息机制:系统将会维护一个或多个消息队列,所有产生的消息都回被放入或是插入队列中。系统会在队列中取出每一条消息,根据消息的接收句柄而将该消息发送给拥有该窗口的程序的消息循环。每一个运行的程序都有自己的消息循环,在循环中得到属于自己的消息并根据接收窗口的句柄调用相应的窗口过程。而在没有消息时消息循环就将控制权交给系统所以Windows可以同时进行多个任务。下面的伪代码演示了消息循环的用法:
pDC->TextOut(0,0,"Display String");
pDC->TextOut(0,20,m_szOut);
}
/*处理通知消息,保存信息并更新显示*/
LONG CMy53_s1View::OnDlgNotifyMsg(WPARAM wP,LPARAM lP)
/*在视图中绘制出字符串 m_szOut*/
void CMy53_s1View::OnDraw(CDC* pDC)
{
CMy53_s1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
typedef struct tagMSG { // msg
HWND hwnd; //窗口句柄
UINT message; //消息常量标识符
WPARAM wParam; //32位消息的特定附加信息,具体表示什么处决于message
LPARAM lParam; //32位消息的特定附加信息,具体表示什么处决于message
1.自定义消息:#define WM_TRAY WM_USER 100
2.函数原形:afx_msg LRESULT OnTrayNotify(WPARAM wParam,LPARAM lParam);
3.消息映射:ON_MESSAGE(WM_TRAY,OnTrayNotify)
4.原函数:
LRESULT CMyDlg::OnTrayNotify(WPARAM wParam,LPARAM lParam)
{
return m_tray.OnTrayNotify(wParam,lParam);
}
WPARAM常常代表一些控件的ID或者高位底位组合起来分别表示鼠标的位置,如果消息的发送者需要将某种结构的指针或者是某种类型的句柄时,习惯上用LPARAM来传递,可以参考各种控件的通知消息:可以查看:EN_CHANGE (EDIT控件的一个通知消息),CBEM_INSERTITEM(可扩展组合框的可接受消息)等等来加以领会。
wParam 通常是一个与消息有关的常量值,也可能是窗口或控件的句柄。 lParam 通常是一个指向内存中数据的指针。由于wParam,lParam和指针都是32位的,需要时可以强制类型转换。具体表示什么,与message相关,他们是事先定义好的。
如果自定义消息:#define WM_MYMESSAGE WM_USER+100,需确定wParam,lParam的意义 (假设wParam=0时发送数据,wParam=1时接收数据,lParam为CMyClass* 指针,指向一个CMyClass对象,准备要发送的数据或接收数据 发送WM_MYMESSAGE时 SendMessage(hwnd,WM_MYMESSAGE,0,pMyClassObject) 接收消息的窗口,接收WM_MYMESSAGE中(CMyClass*)lParam参数即pMyClassObject传过来的数据
{
m_szOut=(char*)wP;
Invalidate();
return 0;
}
一个字符串的地址通过WPARAM来标识,再通过Windows消息发送出去;之后在消息处理函数中WPARAM接受到的参数就是该地址,然后就可以对该地址进行操作了~~~
这是Windows消息机制中经常用到的两个data type,呵呵。
doYourWindow(...);//在窗口需要重新绘制时进行输出
break;
case(WM_LBUTTONDOWN):
doYourWork(...);//在鼠标左键被按下时进行处理
break;
default:
callDefaultWndProc(...);//对于其它情况就让系统自己处理
DWORD time; //消息创建时的时间
POINT pt; //消息创建时的鼠标位置
} MSG;
hwnd 接收消息的32位窗口句柄。窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数可视对象的句柄(窗口、对话框、பைடு நூலகம்钮、编辑框等)。
message 用于区别其他消息的常量值,这些常量可以是Windows单元中预定义的常量,也可以是自定义的常量。
while(1)
{
id=getMessage(...);
if(id == quit)
break;
translateMessage(...);
}
当该程序没有消息通知时getMessage就不会返回,也就不会占用系统的CPU时间。
在Win32 SDK中消息本身是作为一个结构体记录传递给应用程序的,这个记录中包含了消息的类型以及其他信息。这个记录类型叫做MSG,它在window中是这样声明的:
具体是这么说:“在Win 3.x中,WPARAM是16位的,而LPARAM是32位的,两者有明显的区别。因为地址通常是32位的,所以LPARAM 被用来传递地址,这个习惯在Win32 API中仍然能够看到。在Win32 API中,WPARAM和LPARAM都是32位,所以没有什么本质的区 别。
Windows的消息必须参考帮助文件才能知道具体的含义。如果是你定义的消息,愿意怎么使这两个参数都行。但是习惯上,我们愿意使用LPARAM传 递地址,而WPARAM传递其他参数。”
理论上在使用自定义消息时,WPARAM LPARAM的含义可以程序员任意指定的,但是最好遵从MFC中的习惯。在调用SendMessage()函数时,第二个参数是WPARAM,第三个参数是这个消息的LPARAM,但是你在程序中某个类中写下ON_MESSAGE()宏来处理这个消息时,处理函数SomeHandler(WPARAM,LPRAM(默认是0))中解释这两个参数时必须按照SendMessage调用中的意义来进行。
MFC数据类型WPARAM 窗口函数或callback函数的一个参数
实际上所有的消息响应都有WPARAM和LPARAM的存在,只是有些消息响应WPARAM和LPARAM没有意义,所以在MFC封装后有些固定的消息响应函数看不到WPARAM和LPARAM,但依然可以通过GetCurrentMessage()取得当前的消息来查看WPARAM和LPARAM。
从消息参数中获取字符串和位置信息存放到子串口类的成员函数中。字符串m_string为什么对应wParam,点m_point对应lParam
LRESULT CChildView::OnReceive(WPARAM wParam,LPARAM lParam)
{
m_string = *((CSring *)wParam);
4、窗口句柄:说到消息就不能不说窗口句柄,系统通过窗口句柄来在整个系统中唯一标识一个窗口,发送一个消息时必须指定一个窗口句柄表明该消息由那个窗口接收。而每个窗口都会有自己的窗口过程,所以用户的输入就会被正确的处理。例如有两个窗口共用一个窗口过程代码,你在窗口一上按下鼠标时消息就会通过窗口一的句柄被发送到窗口一而不是窗口二。
消息响应机制
1、消息的组成:一个消息由一个消息名称(UINT),和两个参数(WPARAM,LPARAM)。当用户进行了输入或是窗口的状态发生改变时系统都会发送消息到某一个窗口。例如当菜单转中之后会有WM_COMMAND消息发送,WPARAM的高字中(HIWORD(wParam))是命令的ID号,对菜单来讲就是菜单ID。当然用户也可以定义自己的消息名称,也可以利用自定义消息来发送通知和传送数据。
m_point = *((CPoint *)lParam);
Invalidate();
return 0;
程序代码*在对话框中取出数据,并向其他窗口发送消息和数据,将数据指针作为一个参数发送*/