windows程序设计之窗口子类化

NAS新玩法!豆瓣与迅雷结合,轻松实现自动下载电影自动追剧功能 阅读详情

这几天都在家里,赶上了暑假,没啥事情可做,就做些小玩意。虽然都没什么技术含量,但自己毕竟是新手,做得不是很好,代码都得参考下别人的。委屈今天看到一个博客上面写的是关于SDK的窗口子类化,什么是窗口子类化,其实说得简单点就是有个多功能的窗口,你对它有绝对的控制权得意。举个例子好了,你自己写了一个软件,上面有个编辑框,在这里面只能输入“我是笨蛋”,(基本上没人会喜欢你的软件)客户要是想输入其他的,都输不进去。这就有一种思想,软件是我做的,我对它有绝对的控制权。

下面简单描述下原理:就拿上面那个例子来说好了,我前面的博客大概介绍了下windows是怎么处理键盘消息的。就拿‘A’键来说,你要是不处理,windows就会自己拜托DefWindowProc 自己去处理。就算你要处理了,那好,在WM_CHAR或者WM_KEYDOWN你自己处理吧,但其实这不是享有绝对的控制权。

真正要有绝对的控制权是我需要具有输入检测的能力,即每当用户输入一个字符到编辑框中时要能检测这个字符。那要怎么办呢?可以这样,把Windows的窗口过程处理函数“偷换”成自己的函数,这样你就能把所有的消息随你高兴怎么处理了,这才是真正有有绝对控制权得意,也就是所谓的窗口子类化。由于Windows是认定窗口过程函数的格式的,所以你自己定义的函数也要和Windows本事的窗口过程函数格式一样。这样一说其实也就很简单了。

窗口子类化之前

Windows< ==>Edit 控件的窗口处理函数。

子类化之后
Windows< ==>自定义的窗口处理函数==> Edit 控件的窗口处理函数。 

注意一点子类化并不局限于控件,可以子类化任何窗口

还是先看代码吧:(代码主要实现功能:在编辑框中只能输入0或者1,可用于纯二进制输入)

#include <windows.h>

#define  ID_EDIT  1
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
LRESULT CALLBACK EditWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ;

WNDPROC OldWndProc;
static HWND  hwndEdit; 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
					PSTR szCmdLine, int iCmdShow)
{
	static TCHAR szAppName[] = TEXT ("窗口子类化") ;
	HWND         hwnd ;
	MSG          msg ;
	WNDCLASS     wndclass ;

	wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
	wndclass.lpfnWndProc   = WndProc ;
	wndclass.cbClsExtra    = 0 ;
	wndclass.cbWndExtra    = 0 ;
	wndclass.hInstance     = hInstance ;
	wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
	wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
	wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
	wndclass.lpszMenuName  = NULL ;
	wndclass.lpszClassName = szAppName ;

	if (!RegisterClass (&wndclass))
	{
		MessageBox (NULL, TEXT ("This program requires Windows NT!"), 
			szAppName, MB_ICONERROR) ;
		return 0 ;
	}

	hwnd = CreateWindow (szAppName,                  // window class name
		TEXT ("The Hello Program"), // window caption
		WS_OVERLAPPEDWINDOW,        // window style
		CW_USEDEFAULT,              // initial x position
		CW_USEDEFAULT,              // initial y position
		CW_USEDEFAULT,              // initial x size
		CW_USEDEFAULT,              // initial y size
		NULL,                       // parent window handle
		NULL,                       // window menu handle
		hInstance,                  // program instance handle
		NULL) ;                     // creation parameters

	ShowWindow (hwnd, iCmdShow) ;
	UpdateWindow (hwnd) ;

	while (GetMessage (&msg, NULL, 0, 0))
	{
		TranslateMessage (&msg) ;
		DispatchMessage (&msg) ;
	}
	return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

	switch (message)
	{
	case WM_CREATE :
		hwndEdit = CreateWindow (TEXT ("Edit"), NULL,  
			WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL |  
			WS_BORDER | ES_LEFT | ES_MULTILINE |  
			ES_AUTOHSCROLL | ES_AUTOVSCROLL,  
			20, 20, 300, 25, hwnd, (HMENU) ID_EDIT,  
			((LPCREATESTRUCT) lParam) -> hInstance, NULL) ;
		OldWndProc = (WNDPROC)SetWindowLong(hwndEdit,GWL_WNDPROC,(LONG)EditWndProc) ;
		return 0 ;
	case WM_SIZE :   
		MoveWindow (hwndEdit, 0, 0, LOWORD (lParam), HIWORD (lParam), TRUE) ;
		return 0 ;
	case WM_SETFOCUS:
		SetFocus(hwndEdit) ;
		return 0 ;
	case WM_DESTROY:
		PostQuitMessage(0) ;
		return 0 ;
	}
	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

LRESULT CALLBACK EditWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static char KeyMsg ;
	switch(message)
	{
	case WM_CHAR :
		KeyMsg = LOWORD(wParam);
		if(KeyMsg == '0' || KeyMsg == '1'  || KeyMsg == VK_RETURN)
			//只能输入1或者0,这里若是不处理Enter,
			//则还给windows自己处理,后下面的WM_KEYDOWN又要处理,会导致两次弹框。
		{
			return CallWindowProc(OldWndProc,hwnd,message,KeyMsg,lParam) ;
		}
	case WM_KEYDOWN :
		if(LOWORD(wParam) == VK_RETURN)  //如果键盘输入Enter
		{
			MessageBox(NULL,"Pressed Enter in New","Edit",MB_OK|MB_ICONINFORMATION) ;
			SetFocus(hwndEdit);
		}
		return 0 ;
	case WM_DESTROY:
		PostQuitMessage(0) ;
		return 0 ;
	}
	return CallWindowProc(OldWndProc,hwnd,message,wParam,lParam) ;
}


在 WNDCLASSEX 结构的成员 lpfnWndProc 指出了窗口函数地址。在WM_CREATE的时候创建一个编辑框。接着是

OldWndProc = (WNDPROC)SetWindowLong(hwndEdit,GWL_WNDPROC,(LONG)EditWndProc) ;
通过SetWindowLong来改变窗口的属性,第二个参赛GWL_WNDPROC 设置新的窗口处理函数地址。

1.  用参数GWL_WNDPROC调用SetWindowLong函数,如果调用成功那么返回值就是与调用功能相联系的一个32位的整数。在这里我们返回的值保存在 OldWndPro中,下面的将不感兴趣的消息返回给windows还需要这个参数。下面是SetWindowLong函数MSDN上的解释。

----------------------------------------------------------------------------

Note:  This function has been superseded by the SetWindowLongPtr function. To write code that is compatible with both 32-bit and 64-bit versions of Windows, use the SetWindowLongPtr function

if you use SetWindowLong with the GWL_WNDPROC index to replace the window procedure, the window procedure must conform to the guidelines specified in the description of the WindowProc callback function

----------------------------------------------------------------------------

接着我们看看EditWndProc函数,这个是我们自己定义的函数,但是样子要和windows自己的窗口过程函数一样,不然可就识别不出的。看看这个函数,其实也和windows自己的窗口过程函数差不多,也是消息的处理,等价的,我们处理感兴趣的消息,对于不需要处理的消息我们就交还给windows自己的函数处理,我们要截获我们需要的即可,WM_CHAR中我们只处理‘0’,‘1’或者Enter然后调用

LRESULT CallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd,  UINT Msg,  WPARAM wParam,  LPARAM lParam );
lpPrevWndFunc = 窗口原来函数的地址,剩下的四个参数就是发给自定义函数的参数。
我们可以通过第四个参数创传回去。把不感兴趣的字符消息丢了(也就输不到编辑框上),感兴趣的字符消息传回windows自己函数,就这样神不知鬼不觉的“偷换”了函数。
看下我的代码注释,
KeyMsg == VK_RETURN
如果没有这个的话就会出现弹两次框的结果,这个可不是我们想要的,为什么会出现两次呢??我调试了下,第一次是直接在消息
WM_KEYDOWN中
if(LOWORD(wParam) == VK_RETURN)一次弹框,然后程序往下走竟然到了WM_CHAR里面,Enter是字符消息,,但是我们如果没有
KeyMsg == VK_RETURN的话直接会被传回windows自己的消息过程函数。Enter在消息列队里总得处理吧?对应的消息处理存在啊
case WM_KEYDOWN 所以又弹了一次框。

上面就是一个小程序,毕竟是新手,可能有错,希望指正,不甚感激!



参考资料《windows+sdk编程系列文章》

国科大学习资料--数据挖掘(刘莹)--第三章习题及参考答案 国科大学习资料–数据挖掘(刘莹)–第三章习题及参考答案 国科大学习资料–数据挖掘(刘莹)–第三章习题及参考答案 国科大学习资料–数据挖掘(刘莹)–第三章习题及参考答案 第 3 章分类与回归 3.1简述决策树分类的主要步骤。 答:决策树生成的过程如下: (1)对数据源进行数据预处理, 得到训练集和测试集; (2)对训练集进行训练; (3)对初始决策树进行树剪枝; (4)由所得到的决策树提取分类规则; (5)使用测试数据集进行预测,评估决策树模型; 3.2给定决策树,选项有:(1)将决策树转换成规则,然后对结果 阅读详情

相关推荐

BUUCTF--[OGeek2019]babyrop

才学习了基本的ROP流程,到处找题练,不过也没做出来几道题,以这道32位的题作为例题吧。 这道题是BUUCTF上pwn练习题里的[OGeek2019]babyrop。 代码审计 老规矩先checksec一下: 没有canary保护,nx保护开启排除shellcode可能性,FULL RELEO为地址随机化。 观察主函数,先设定了一个闹铃,到时间就会强制退出程序,解除闹铃的方法在上一篇博客中提到过了, 这道题中闹铃函数依然对我们解题起不到什么干扰作用。 主函数的思路大概是:生成一个随机数,把这个随机数作为

N1rvana的博客 6004

窗口子类化

windows HWND子类化原理

psbeyond的专栏 1491

【详细】芯片设计全流程(包括每个流程需要用到的工具以及需要参与的工作人员)

一颗芯片的诞生经历了设计、制造和测试(分别对应集成电路产业链的设计业、制造业和封测业),而每一步都包含了复杂的步骤和流程。 图0-1 集成电路产业链 现在,我们重点介绍芯片设计的全流程以及每个流程需要用到的设计工具和需要参与的工作人员。 一、IC设计分类 首先对IC设计的分类做个介绍,如图1-1所示。 图1-1 IC设计分类 如图1-1所示,IC设计可以粗分为数字IC设计和射频/模拟IC设计,数字IC设计又可分为ASIC设计和FPGA/CPLD设计,此外还有一部分IC设计.

qq_36045093的博客 8万+

窗口子类化(SubClassing) SetWindowLong

一、什么是子类化(Subclass) 视窗系统是基于消息驱动的。因此每一个窗口都有一个函数来处理这些消息,系统管理的窗口结构中有一域记录着这个函数的地址(使用GetWindowLong函数传入索引标识GWL_WNDPROC可获取此值)。所有系统发送到这个窗口的消息都会交由此函数来处理。所以改变窗口结构中这个指针值到自定义的某个函数(使用SetWindowLong函数带GWL_WN

靠别人不如靠自已。 5575

陀螺仪及四元数解算

陀螺仪 四元数

zb313982521的博客 2003

【WorkBuddy】WorkBuddy 智能体快速上手:从零到一的实践指南

文章摘要: 传统自动化脚本难以应对灵活多变的自然语言需求,导致逻辑复杂、维护成本高。智能体(Agent)通过理解语义意图、动态决策和松耦合组件解决了这些问题。WorkBuddy采用声明式配置,通过可视化界面定义意图、实体和对话策略,无需编码即可快速构建智能体。其核心组件包括意图分类、实体提取、对话策略、故事样本和回退机制,适用于客服支持、知识问答等高频场景。通过环境准备(Python/Node.js/Redis)和简单配置,用户可以快速搭建可运行的智能体,显著提升自动化效率。

ruiqideng的博客 1599

【Windows】实现窗口子类化(基于远程线程注入)

子类化是通过更改窗口过程来重新定义窗口的行为。要更改窗口过程,窗口过程应驻留在创建窗口的进程中。我计划通过注入子类化模块在不了解创建窗口的进程的情况下替换窗口行为。众所周知,注入是一个简单的 DLL,当 DllMain 被调用时DLL_PROCESS_ATTACH,我正在进行 Hack。这段代码很简单,首先我们要知道要注入到目标进程(injectee)中的 DLL(SubClassModule)的名字。因此,它必须写入目标进程的地址空间中。本文发布于:2024.07.10,修改于:2024.07.10。

溡漪幽博客 1469

MATLAB2021b详细安装教程

1.下载 2.安装 下载安装包后打开iso文件,若是无法打开请用解压软件打开。 ①打开MATLAB_R2021b_win64,双击软件开始安装 ② 一直点击下一步,直到步骤③ ③选择我已有我的许可证的文件密钥,并输入62551-02011-26857-57509-64399-54230-13279-37181-62117-65158-40352-64197-45508-24369-45954-39446-39538-16936-10698-58393-44718-32560-10501-40

惜洛-Jankin的博客 9万+

窗口的子类化(收藏)

窗口子类化的作用 窗口子类化技术最大的特点就是能够截取 Windows 的消息。一旦用户自定义的窗口函数截取了传向原窗口函数的消息,就可以对被截取的消息进行如下处理: 将其传给原来的窗口函数。这是对大多数消息应该采取的措施,因为子类通常只对原来的窗口特性作少量的改动 截取该消息,阻止其向原窗口函数发送。 修改该消息,修改完毕以后再向原窗口函数发送。 Windows SDK 提供了一

wandoutoushu的专栏 683

【Unity动画系统】详解Root Motion动画在Unity中的应用(一)

什么时候勾选Bake into pose,当不希望动画带动游戏对象旋转时。在旋转的动画中一般是不用勾选的,因为就需要用它来带动我们的角色对象旋转。但在比如前进、后退、待机等动画来说,我们就可以勾选这里,以避免因动画文件本身的瑕疵而给我们带来的旋转。loop match:代表了这个动画在角度上的吻合度。如果这个动画在播放中转角过大,那么就会显示红色,告诉我们如果勾选bake into pose,则会带来不好的效果。

weixin_60154963的博客 6802

FLUENT 软件中design modeler网格划分后,导出失败:系统显示“在网格文件导出过程中出现异常。请将数据发送给您的技术支持供应商。”...如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1467

深入理解MFC子类化

子类化,通俗来讲就是用自己的窗口处理函数来处理特定消息,并将自己其他消息还给标准(默认)窗口处理函数。在SDK中,通过SetWindowLong来指定一个自定义窗口处理函数:SetWindowLong(hwnd, GWL_WNDPROC, (LONG)UserWndProc);。可是到了MFC中,大部分基础的东西都被封装起来了,那么,这是该怎么实现子类化呢?       先来看一个例子:

caowei880123的专栏 1274

CODESYS数据处理合集(高低字节/ 字/浮点数/位)

VAR_INPUT//字节0//字节1END_VARVAREND_VAR。

RXXW_Dor的博客 352

介绍Windows的窗口、消息、子类化和超类化

这篇文章本来只是想介绍一下子类化和超类化这两个比较“生僻”的名词。为了叙述的完整性而讨论了Windows的窗口和消息,也简要讨论了进程和线程。子类化(Subclassing)和超类化(Superclassing)是伴随Windows窗口机制而产生的两个复用代码的方法。不要把“子类化、超类化”与面向对象语言中的派生类、基类混淆起来。“子类化、超类化”中的“类”是指Windows的窗口类。

狗 899

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

详细介绍Windows中的子类化

​​定义​​子类化是指​​继承现有窗口类(如按钮、编辑框)并重写其消息处理逻辑​​的过程。通过替换默认的窗口过程函数WNDPROC),开发者可以截获控件的消息流,插入自定义处理逻辑,同时保留原始功能。​​消息传递流程​​​​默认流程​​:系统控件(如按钮)的窗口消息由系统预定义的窗口过程处理。​​子类化后​​:消息先传递到自定义的窗口过程,开发者可在此修改消息或调用原始窗口过程(继续默认处理。​​关键函数​(替换窗口过程)、CallWindowProc(调用原始处理函数)。

felicity_one的博客 933

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Windows 窗口子类化和超类化

子类化(Subclass)是指替换窗口过程(WNDPROC) 超类(Superclass)是替换窗口过程(WNDPROC),并且替换ClassName。 Subclass不太像继承,而像一种外挂(HOOK)行为。 Superclass更像继承,因为生成了新的窗口类,并且继承了行为。 WinX中Subclass和Superclass用同一个类实现,都是 WinX::Subcl

小龙王2010 1471

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

窗口子类化和超类化

目录 窗口子类化 窗口超类化 窗口子类化 窗口子类化的目的是在不修改现有代码的前提下,扩展现有窗口、控件的功能。它的思路很简单,就是将窗口过程地址修改为一个新函数地址,新的窗口过程函数处理自己感兴趣的消息,将不感兴趣的消息丢给原窗口过程处理。 窗口子类化步骤: (1)正常创建系统控件/窗口,得到控件/窗口的句柄。 (2)调用GetWindowLong()得到原来的系统的窗口函数OldWndProc。 ...

sinat_38363122的博客 844

窗口的子类化与超类化

窗口的子类化与超类化——子类化是窗口实例级别的,超类化是在窗口类(WNDCLASS)级别的 1. 子类化  理论:子类化是这样一种技术,它允许一个应用程序截获发往另一个窗口的消息。一个应用程序通过截获属于另一个窗口的消息,从而实现增加、监视或者修改那个窗口的缺省行为。子类化是用来改变或者扩展一个已存在的窗口的行为、而不用重新开发的有效途径。想要获得那些预定义控件窗口类(按钮控件、编

TU2的专栏 1207

Windows核心编程_窗口子类化

窗口子类化:窗口子类化,即重定向消息,也就是修改某个窗口消息执行函数,重定向下面代码可以让你更好的理解窗口子类化:先介绍三个函数:1.GetWindowLong函数原型:LongGetWindowLong(HWNDhWnd,intnlndex);参数介绍:HWNDhWnd:目标窗口句柄intnlndex:要获取的窗口类型信息:宏定义常量描述GWL_EXSTYLE-20获取扩展窗口样式GW...

17岁boy的博客 2453

眼见为实(2):介绍Windows的窗口、消息、子类化和超类化

眼见为实(2):介绍Windows的窗口、消息、子类化和超类化 这篇文章本来只是想介绍一下子类化和超类化这两个比较“生僻”的名词。为了叙述的完整性而讨论了Windows的窗口和消息,也简要讨论了进程和线程。子类化(Subclassing)和超类化(Superclassing)是伴随Windows窗口机制而产生的两个复用代码的方法。不要把“子类化、超类化”与面向对象语言中的派生类、基类混淆起来。“...

技术代码资料库 406

易语言大漠多线程程模板窗口子类化

为了降低对窗口组件的频繁读写,减少多线程堵塞,大漠多线程模板采用窗口子类化对窗口超级列表框发送消息,先了解一下窗口子类化: 子类化 子类化的目的是在不修改现有代码的前提下,扩展现有窗口的功能。它的思路很简单,就是将窗口过程地址修改为一个新函数地址,新的窗口过程函数处理自己感兴趣的消息,将其它消息传递给原窗口过程。通过子类化,我们不需要现有窗口的源代码,就可以定制窗口功能。 子类化可以分为实例子类化和全局子类化。实例子类化就是修改窗口实例的窗口过程地址,全局子类化就是修改窗口类的窗口过程地址。实例子类化只

511遇见 5711
上一篇: windows程序设计之编辑框简介
下一篇: windows下安装,配置gcc编译器
firefoxbug
博客等级 码龄16年 259粉丝 165原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值