实测分析WNDCLASS结构的cbClsExtra成员与cbWndExtra成员的使用方法

参考文档: https://blog.csdn.net/u010003835/article/details/47002383

HWND CreateMyWinEx(HINSTANCE hInstance)
{
	WNDCLASSEX wndClassex;
	wndClassex.cbSize = sizeof(WNDCLASSEX);
	wndClassex.style = CS_HREDRAW | CS_VREDRAW;
	wndClassex.lpfnWndProc = ::DefWindowProc;
	wndClassex.cbClsExtra = 16;
	wndClassex.cbWndExtra = 44;  //取值范围为0-40 必须是4的倍数  但是=> win10 vs2019 32位应用程序测试这个值超过40也没问题
	wndClassex.hInstance = hInstance;
	wndClassex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndClassex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClassex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wndClassex.lpszMenuName = NULL;
	wndClassex.lpszClassName = TEXT("mywinex");
	wndClassex.hIconSm = NULL;


	if (!RegisterClassEx(static_cast<const WNDCLASSEX*>(&wndClassex))) {
		MessageBox(NULL, TEXT("Register Class Error"), TEXT("mywinex"), 0);
		return 0;
	}


	HWND hwnd = CreateWindow(
		TEXT("mywinex"),
		TEXT("Demoex"),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL
	);

	HWND hwnd2 = CreateWindow(
		TEXT("mywinex"),
		TEXT("jiangkaiex"),
		WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL
	);

	//获取额外内存大小信息
	DWORD cl = GetClassLong(hwnd, GCL_CBCLSEXTRA);
	DWORD wd = GetClassLong(hwnd, GCL_CBWNDEXTRA);

	//设置窗口类额外内存数据
	SetClassLongPtr(hwnd, 0, 11);
	SetClassLongPtr(hwnd, 4, 22);
	SetClassLongPtr(hwnd, 8, 33);

	DWORD rescl = GetClassLongPtr(hwnd, 0);
		  rescl = GetClassLongPtr(hwnd, 4);
		  rescl = GetClassLongPtr(hwnd, 8);

		  //与窗口类关联的额外内存 针对所有以该注册窗口类创建的实例窗口的额外内存的值都有效
		  rescl = GetClassLongPtr(hwnd2, 0);
		  rescl = GetClassLongPtr(hwnd2, 4);
		  rescl = GetClassLongPtr(hwnd2, 8);
	
	 //更改额外窗口类对应内存,与额外窗口实例对应内存 测试【这个测试暂时没做,这个测试验证的是窗口类额外内存与窗口实例额外内存的分配时机以及是否可以重分配】
	{
			  //原来大小分别是 16 44
		SetClassLongPtr(hwnd, GCL_CBCLSEXTRA, 20);
		SetClassLongPtr(hwnd, GCL_CBWNDEXTRA, 48);
		DWORD cl2 = GetClassLong(hwnd2, GCL_CBCLSEXTRA);//显示没改
		DWORD wd2 = GetClassLong(hwnd2, GCL_CBWNDEXTRA);//显示被修改了
		wd = GetClassLong(hwnd, GCL_CBCLSEXTRA);//显示没改
		wd = GetClassLong(hwnd, GCL_CBWNDEXTRA);//显示被修改了

		//修改后重新设置一下
		SetClassLongPtr(hwnd, 12, 111);
		rescl = GetClassLongPtr(hwnd, 12);//实际修改了  【窗口类关联的额外内存可以被SetClassLongPtr马上动态修改】
		rescl = GetClassLongPtr(hwnd2, 12);//实际修改了

		//msdn 原文:某些窗口数据会被缓存,所以使用SetWindowLongPtr所做的更改直到调用SetWindowPos函数才会生效。  
		SetWindowLongPtr(hwnd, 44, 3333333);
		SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);// 但是这里实参无论是否调用 SetWindowPos下面依然无法获取正确数据;此处问题原因应该是前面用SetClassLongPtr去修改窗口实例关联的额外内存时对已经实例化的窗口是无效的;【 msdn上并没有查到此处细节的详细说明】
		

		auto res = GetWindowLongPtr(hwnd, 44);//实际没改
		res = GetWindowLongPtr(hwnd2, 44);//实际没改

		getchar();

	 }



	//第二参数 index代表的是一个地址偏移量以字节为单位;但是必须是4的倍数;因为存储每次都是以四个字节存储的
	SetWindowLongPtr(hwnd, 0, 1);//每次从偏移地址函数写入占用4个字节
	SetWindowLongPtr(hwnd, 4, 2);
	SetWindowLongPtr(hwnd, 8, 3123);
	SetWindowLongPtr(hwnd, 12, 45546);
	SetWindowLongPtr(hwnd, 36, 1111111);//cbWndExtra=32 时error
	SetWindowLongPtr(hwnd, 40, 2222222);//cbWndExtra=44 时 超过40个字节偏移依然正确获取了
	SetWindowLongPtr(hwnd, GWLP_USERDATA, 464);

	LONG_PTR  res = GetWindowLongPtr(hwnd, 0);//每次从偏移地址函数读取4个字节的值
	res = GetWindowLongPtr(hwnd, 4);
	res = GetWindowLongPtr(hwnd, 8);
	res = GetWindowLongPtr(hwnd, 12);
	res = GetWindowLongPtr(hwnd, 36);//cbWndExtra=32 时error 无法获取数据返回0 
	res = GetWindowLongPtr(hwnd, 40);//cbWndExtra=44 时 超过40个字节偏移依然正确获取了
	res = GetWindowLongPtr(hwnd, GWLP_USERDATA);//GWLP_USERDATA是另一个位置为窗口实例预留了4字节空间与cbWndExtra无关

	//与窗口实例关联的额外内存 另一个窗口值无任何有效值
	res = GetWindowLongPtr(hwnd2, 4);
	res = GetWindowLongPtr(hwnd2, 8);
	res = GetWindowLongPtr(hwnd2, 12);
	res = GetWindowLongPtr(hwnd2, 36);
	res = GetWindowLongPtr(hwnd2, 40);
	res = GetWindowLongPtr(hwnd2, GWLP_USERDATA);

	ShowWindow(hwnd, SW_SHOW);
	UpdateWindow(hwnd);
	ShowWindow(hwnd2, SW_SHOW);
	UpdateWindow(hwnd2);
	return hwnd;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值