如何机器人大战w隐藏要素wndclassexw的窗口

1220人阅读
REACTOS(192)
NtUserRegisterClassEx函数是Win32k.sys里实现窗口类的注册,那么窗口类的注册是什么意思呢?到底注册是为了什么样的目的呢?下面就通过实现代码的分析来解决这些问题,代码如下:
#001& RTL_ATOM APIENTRY
#002& NtUserRegisterClassEx(IN CONST WNDCLASSEXW*
#003&&&&&&&&&&&&&&&&&&&&&&&
IN PUNICODE_STRING ClassName,
#004&&&&&&&&&&&&&&&&&&&&&&&
IN PUNICODE_STRING MenuName,
#005&&&&&&&&&&&&&&&&&&&&&&&
IN WNDPROC wpExtra,
#006&&&&&&&&&&&&&&&&&&&&&&&
IN DWORD Flags,
#007&&&&&&&&&&&&&&&&&&&&&&&
IN HMENU hMenu)
#010&& * FUNCTION:
#011&& *&&
Registers a new class with the window manager
#012&& * ARGUMENTS:
#013&& *&&
lpwcx&&&&&&&&& = Win32 extended
window class structure
#014&& *&&
bUnicodeClass = Whether to send ANSI or unicode strings
#015&& *&&&&&&&&&&&&&&&&&& to window procedures
#016&& *&&
wpExtra&&&&&& = Extra window
procedure, if this is not null, its used for the second window procedure for
standard controls.
#017&& * RETURNS:
#018&& *&&
Atom identifying the new class
#021&&&&& WNDCLASSEXW CapturedClassInfo = {0};
#022&&&&& UNICODE_STRING CapturedName = {0},
CapturedMenuName = {0};
#023&&&&& RTL_ATOM Ret = (RTL_ATOM)0;
如果注册标志有问题,就直接返回出错。
#025&&&&& if (Flags & ~REGISTERCLASS_ALL)
#026&&&&& {
#027&&&&&&&&&
SetLastWin32Error(ERROR_INVALID_FLAGS);
#028&&&&&&&&& return R
#029&&&&& }
增加用户进入锁,以便后面的代码进行临界区访问。
#031&&&&& UserEnterExclusive();
使用异常机制处理用户输入来的参数。
#033&&&&& _SEH2_TRY
#034&&&&& {
查注册类的结构大小是否符合内核的注册类的结构大小,如果不符合就返回出错。
#035&&&&&&&&& /* Probe the parameters and basic
parameter checks */
#036&&&&&&&&& if
(ProbeForReadUint(&lpwcx-&cbSize) != sizeof(WNDCLASSEXW))
#037&&&&&&&&& {
#038&&&&&&&&&&&&& goto InvalidP
#039&&&&&&&&& }
检查读取是否出错。
#041&&&&&&&&& ProbeForRead(lpwcx,
#042&&&&&&&&&&&&&&&&&&&&&& sizeof(WNDCLASSEXW),
#043&&&&&&&&&&&&&&&&&&&&&& sizeof(ULONG));
拷贝用户空间的注册类信息。
#044&&&&&&&&& RtlCopyMemory(&CapturedClassInfo,
#045&&&&&&&&&&&&&&&&&&&&&&& lpwcx,
#046&&&&&&&&&&&&&&&&&&&&&&& sizeof(WNDCLASSEXW));
读取注册窗口类的名称。
#048&&&&&&&&& CapturedName =
ProbeForReadUnicodeString(ClassName);
读取注册窗口类的菜单名称。
#049&&&&&&&&& CapturedMenuName =
ProbeForReadUnicodeString(MenuName);
窗口类的非法参数检查。
#051&&&&&&&&& if (CapturedName.Length & 1 ||
CapturedMenuName.Length & 1 ||
#052&&&&&&&&&&&&& CapturedClassInfo.cbClsExtra &
#053&&&&&&&&&&&&& CapturedClassInfo.cbClsExtra +
CapturedName.Length +
#054&&&&&&&&&&&&&&&&& CapturedMenuName.Length +
sizeof(WINDOWCLASS) & CapturedClassInfo.cbClsExtra ||
#055&&&&&&&&&&&&& CapturedClassInfo.cbWndExtra &
#056&&&&&&&&&&&&& CapturedClassInfo.hInstance ==
#057&&&&&&&&& {
#058&&&&&&&&&&&&& goto InvalidP
#059&&&&&&&&& }
#061&&&&&&&&& if (CapturedName.Length != 0)
#062&&&&&&&&& {
#063&&&&& &&&&&&&&ProbeForRead(CapturedName.Buffer,
#064&&&&&&&&&&&&&&&&&&&&&&&&&& CapturedName.Length,
#065&&&&&&&&&&&&&&&&&&&&&&&&&& sizeof(WCHAR));
#066&&&&&&&&& }
#067&&&&&&&&& else
#068&&&&&&&&& {
#069&&&&&&&&&&&&& if
(!IS_ATOM(CapturedName.Buffer))
#070&&&&&& &&&&&&&{
#071&&&&&&&&&&&&&&&&& goto InvalidP
#072&&&&&&&&&&&&& }
#073&&&&&&&&& }
#075&&&&&&&&& if (CapturedMenuName.Length != 0)
#076&&&&&&&&& {
#077&&&&&&&&&&&&&
ProbeForRead(CapturedMenuName.Buffer,
#078&&&&&&&&&&&&&&&&&&&&&&&&&& CapturedMenuName.Length,
#079&&&&&&&&&&&&&&&&&&&&&&&&&& sizeof(WCHAR));
#080&&&&&&&&& }
#081&&&&&&&&& else if (CapturedMenuName.Buffer !=
#082&&&&&&&&&&&&&&&&&&
!IS_INTRESOURCE(CapturedMenuName.Buffer))
#083&&&&&&&&& {
#084& InvalidParameter:
#085&&&&&&&& &&&&&SetLastWin32Error(ERROR_INVALID_PARAMETER);
#086&&&&&&&&&&&&& _SEH2_LEAVE;
#087&&&&&&&&& }
调用函数UserRegisterClass来更进一步处理注册过程。
#089&&&&&&&&& /* Register the class */
#090&&&&&&&&& Ret =
UserRegisterClass(&CapturedClassInfo,
#091&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&CapturedName,
#092&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&CapturedMenuName,
#093&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& hMenu, /*
FIXME - pass pointer */
#094&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& wpExtra,
#095&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Flags);
#097&&&&& }
#098&&&&& _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
#099&&&&& {
#100&&&&&&&&&
SetLastNtError(_SEH2_GetExceptionCode());
#101&&&&& }
#102&&&&& _SEH2_END;
退出临界区。
#104&&&&& UserLeave();
#106&&&&& return R
上面调用函数UserRegisterClass来更进一步处理,因而再接着分析这个函数的实现,它的代码如下:
#001& RTL_ATOM
#002& UserRegisterClass(IN CONST WNDCLASSEXW*
#003&&&&&&&&&&&&&&&&&&&
IN PUNICODE_STRING ClassName,
#004&&&&&&&&&&&&&&&&&&&
IN PUNICODE_STRING MenuName,
#005&&&&&&&&&&&&&&&&&&&
IN HANDLE hMenu, /* FIXME */
#006&&&&&&&&&&&&&&&&&&&
IN WNDPROC wpExtra,
#007&&&&&&&&&&&&&&&&&&&
IN DWORD dwFlags)
#009&&&&& PTHREADINFO
#010&&&&& PW32THREADINFO
#011&&&&& PW32PROCESSINFO
#012&&&&& PWINDOWCLASS C
#013&&&&& RTL_ATOM ClassA
#014&&&&& RTL_ATOM Ret = (RTL_ATOM)0;
#016&&&&& /* NOTE: Accessing the buffers in
ClassName and MenuName may raise exceptions! */
获取当前线程信息。
#018&&&&& pti = PsGetCurrentThreadWin32Thread();
#019&&&&& ti = GetW32ThreadInfo();
#020&&&&& if (ti == NULL ||
!ti-&kpi-&RegisteredSysClasses)
#021&&&&& {
#022&&&&&&&&&
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
#023&&&&&&&&& return (RTL_ATOM)0;
#024&&&&& }
#026&&&&& pi = ti-&
查找以前是否注册过相同名称的窗口类。
#028&&&&& /* try to find a previously registered
#029&&&&& ClassAtom = IntGetClassAtom(ClassName,
#030&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
lpwcx-&hInstance,
#031&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& pi,
#032&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &Class,
#033&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& NULL);
#034&&&&& if (ClassAtom != (RTL_ATOM)0)
#035&&&&& {
如果窗口类已经注册过,就返回相应的出错信息。
#036&&&&&&&&& if (lpwcx-&style &
CS_GLOBALCLASS)
#037&&&&&&&&& {
#038&&&&&&&&&&&&& // global classes shall not have
same names as system classes
#039&&&&&&&&&&&&& if (Class-&Global ||
Class-&System)
#040&&&&&&&&&&&&& {
#041&&&&&&&&&&&&&&&&& DPRINT("Class 0x%p does
already exist!/n", ClassAtom);
#042&&&&&&&&&&&&&&&&&
SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
#043&&&&&&&&&&&&&&&&& return (RTL_ATOM)0;
#044&&&&&&&&&&&&& }
#045&&&&&&&&& }
#046&&&&&&&&& else if ( !Class-&Global
&& !Class-&System)
#047&&&&&&&&& {
#048&&&&&&&&&&&&& // local class already exists
#049&&&&&&&&&&&&& DPRINT("Class 0x%p does
already exist!/n", ClassAtom);
#050&&&&&&&&&&&&& SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
#051&&&&&&&&&&&&& return (RTL_ATOM)0;
#052&&&&&&&&& }
#053&&&&& }
调用函数IntCreateClass来创建一个窗口类。
#055&&&&& Class = IntCreateClass(lpwcx,
#056&&&&&&&&&&&&&&&&&&&&&&&&&&&& ClassName,
#057&&&&&&&&&&&&&&&&&&&&&&&&&&&& MenuName,
#058&&&&& &&&&&&&&&&&&&&&&&&&&&&&wpExtra,
#059&&&&&&&&&&&&&&&&&&&&&&&&&&&& dwFlags,
#060&&&&&&&&&&&&&&&&&&&&&&&&&&&& pti-&Desktop,
#061&&&&&&&&&&&&&&&&&&&&&&&&&&&& pi);
如果创建注册类成功,就把这个窗口类保存到系统相应的列表里。
#063&&&&& if (Class != NULL)
#064&&&&& {
#065&&&&&&&&& PWINDOWCLASS *L
保存菜单句柄。
#067&&&&&&&&& /* FIXME - pass the PMENU pointer to
IntCreateClass instead! */
#068&&&&&&&&& Class-&hMenu = hM
根据注册类的使用范围来保存不同的系统列表里。
#070&&&&&&&&& /* Register the class */
#071&&&&&&&&& if (Class-&System)
#072&& &&&&&&&&&&&List = &pi-&SystemClassL
#073&&&&&&&&& else if (Class-&Global)
#074&&&&&&&&&&&&& List =
&pi-&GlobalClassL
#075&&&&&&&&& else
#076&&&&&&&&&&&&& List =
&pi-&LocalClassL
列表插入操作。
#078&&&&&&&&& Class-&Next = *L
#079&&&&&&&&& (void)InterlockedExchangePointer((PVOID*)List,
#080&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
#082&&&&&&&&& Ret = Class-&A
#083&&&&& }
#085&&&&& return R
通过上面的分析,可以了解到注册一个窗口类,就是分配一个新的窗口类内存结构,然后设置结构的字段,最后把它保存到合适的列表里。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:5308901次
积分:69150
积分:69150
排名:第24名
原创:1475篇
转载:61篇
译文:11篇
评论:2058条
难度:初级
类型:实战教学
难度:初级
类型:实战教学
难度:初级
类型:实战教学
(13)(15)(11)(16)(81)(40)(17)(32)(10)(1)(12)(1)(11)(17)(10)(9)(11)(11)(10)(11)(11)(11)(21)(10)(7)(9)(7)(8)(6)(3)(17)(12)(20)(6)(7)(21)(1)(5)(1)(1)(3)(3)(4)(6)(4)(4)(7)(11)(2)(3)(5)(4)(8)(4)(7)(1)(4)(4)(4)(7)(2)(7)(8)(2)(4)(5)(3)(7)(5)(4)(15)(1)(5)(10)(17)(25)(26)(23)(25)(24)(20)(1)(1)(3)(8)(8)(13)(9)(12)(17)(3)(13)(24)(29)(21)(10)(20)(14)(20)(16)(19)(15)(32)(29)(25)(12)(3)(3)(19)(24)(4)(1)(10)(16)(1)(4)(1)(1)(11)(4)(1)(1)(1)(11)(2)(2)(4)(1)(3)(21)(132)(36)3329人阅读
char szClassName[] = "MainWClass";
WNDCLASSEX
// 用描述主窗口的参数填充WNDCLASSEX结构
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc = WindowP
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = NULL;
wndclass.hIcon = ::LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = ::LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassN
wndclass.hIconSm = NULL;
::RegisterClassEx(&wndclass);&
// 创建主窗口
HWND hWnd = ::CreateWindowEx(&
szClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
if(hWnd == NULL)
::MessageBox(NULL, "创建窗口出错!", "error", MB_OK);
return -1;
CWnd* pParentWnd = CWnd::FromHandle(hWnd);
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:98067次
积分:1324
积分:1324
排名:千里之外
原创:29篇
转载:24篇
评论:18条
(1)(1)(1)(1)(3)(2)(1)(2)(4)(1)(1)(1)(1)(1)(1)(3)(3)(1)(2)(1)(1)(4)(1)(2)(3)(2)(6)(2)2734人阅读
经验(23)
#include &Windows.h&
#pragma comment( linker, &/subsystem:\&windows\& /entry:\&mainCRTStartup\&& ) //隐藏控制台用,注掉后控制台和窗口一起出现
LRESULT WINAPI WndProc(HWND,UINT,WPARAM,LPARAM);
int main()
HINSTANCE hInstance = GetModuleHandle(NULL);//获取实例句柄
WNDCLASSEX
//填充窗口属性
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndP
wc.cbClsExtra = wc.cbWndExtra = NULL;
wc.hInstance = hI
wc.hbrBackground = (HBRUSH)GetStockObject(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT(&MyWindow&);
wc.hIcon = wc.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
RegisterClassEx(&wc);//注册窗口类
hwnd = CreateWindowEx(NULL,
wc.lpszClassName,
wc.lpszClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
hInstance,
NULL );//创建窗口
ShowWindow(hwnd, SW_SHOW);//显示窗口
UpdateWindow(hwnd);//更新窗口
//进入消息循环
while(true)
if(!GetMessage(&msg,0,0,0))
TranslateMessage(&msg);
DispatchMessage(&msg);
//窗口过程回调函数,在这里处理窗口消息
LRESULT WINAPI WndProc( HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
switch(uMsg)
case WM_DESTROY:
PostQuitMessage(NULL);
return DefWindowProc(hWnd, uMsg, wParam, lParam);
vs2008 下面编译通过
比起自动创建的window窗口精简不少,而且是用新手熟悉的main函数。虽然是这么说,但是要理解这里面的过程,果然还是要看看windows编程相关基础才行。想我以前就是不理解什么叫回调,为什么窗口过程会“自己执行了”,感觉不按程序的套路来,呵呵。
其实什么回调不回调,不过是函数指针的知识罢了,注册的时候就把函数指针给了一个结构体,窗口程序在接受到窗口消息后调用了这个函数指针而已,没什么特别的,只是它是在windows内部完成的,看不到而已,如果自己写过DLL就会理解多一点。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:278745次
积分:3150
积分:3150
排名:第10620名
原创:61篇
转载:13篇
评论:79条
(1)(1)(2)(2)(3)(1)(1)(1)(3)(1)(1)(1)(3)(1)(4)(1)(2)(8)(5)(7)(4)(17)(5)君,已阅读到文档的结尾了呢~~
Windows_API一日一练一日一练,API
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
Windows_API一日一练
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口

我要回帖

更多关于 机战w隐藏要素中文版 的文章

 

随机推荐