请问HWND窗口句柄到底是什么?thanks
这是面试官问我的,我不知道,麻烦高手解答!
说的具体一点儿哈,不要告诉我是一个地址,我想知道是谁的地址,跟SetWindowsLong有什么关系?
我只知道dll的HANDLE是进程加载dll时候dll映射到进程空间的地址,那HWND呢?
问题点数:50、回复次数:43Top
1 楼yang_200422140033()回复于 2006-05-03 22:14:42 得分 0
HWND不就是一个窗口的标识的指针....Top
2 楼yang_200422140033()回复于 2006-05-03 22:17:44 得分 0
请问一下在这里怎么发表新贴???我怎么没有看到发贴的按钮啊???另外也想问高手们一个问题,我按例子敲了一个程序,别人运行的没有一点问题,用VC写的一个WINDOWS程序,我的为什么没有显示?(没有错误,程序可以运行,进程中有!).代码如下:
#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WinYangProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
int WINAPI WinMain(
HINSTANCE hInstance, // handle to current instance
HINSTANCE hPrevInstance, // handle to previous instance
LPSTR lpCmdLine, // pointer to command line
int nCmdShow // show state of window
)
{
WNDCLASS wndcls; //设计一个窗口类
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=HBRUSH(GetStockObject(BLACK_BRUSH));
wndcls.hCursor=LoadCursor(NULL,IDC_ARROW);
wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WinYangProc;
wndcls.lpszClassName="YangBaocen";
wndcls.lpszMenuName=NULL;
wndcls.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndcls);//注册窗口类..
////////////////////////////////////////////
//创建窗口
HWND hwnd;
//BOOL result;
hwnd=CreateWindow("YYYY","Mr. Yang's first programe!",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
MSG msg;
while(GetMessage(&msg,hwnd,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WinYangProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
switch(uMsg)
{case WM_CHAR:
char szChar[20];
sprintf(szChar,"Char is d%",wParam);
MessageBox(hwnd,szChar,"YYY",0);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd,"Mouse clicked!","YYY",0);
HDC hdc;
hdc=GetDC(hwnd);
//鼠标点击时出现一串文字
TextOut(hdc,0,50,"鼠标点击时出现一串文字",
strlen("鼠标点击时出现一串文字"));
ReleaseDC(hwnd,hdc);
break;
case WM_PAINT:
HDC hDC;
PAINTSTRUCT ps;
hDC=BeginPaint(hwnd,&ps);
TextOut(hDC,0,50,"laksdjflkasjd",strlen("laksdjflkasjd"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的关闭???","YYY",MB_YESNO))
{//IDYES常量写在前面可以防止不必要的错误
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return(DefWindowProc(hwnd,uMsg,wParam,lParam));
}
return 0;
}
Top
3 楼codewarrior(会思考的草)回复于 2006-05-04 11:56:45 得分 0
窗口内核对象的指针所在句柄表的下标索引(有可能不是下标,但是Windows必定通过hwnd的值找到对应的窗口对象)。Top
4 楼hrbniu(五彩神牛)回复于 2006-05-04 14:27:47 得分 0
yang_200422140033() :
窗口左上角有个《提问》按钮,点击此处就可以了
Top
5 楼C200501111(cv)回复于 2006-05-04 22:47:58 得分 0
我有点迷惑,相信会有高手来解释Top
6 楼eminwoo(天邪鬼)回复于 2006-05-05 05:34:49 得分 0
HWND 不是窗口的指针,我认为它是一个窗口的标识Top
7 楼buggycode(风雨寒夜)回复于 2006-05-05 06:59:19 得分 0
一种回答:这个HWND实际就是一个指针,和系统中所有的指针有相同的空间,现在常用的有32bit,64bit两种,早期的windows用过16bit.
较好的回答:HWND简单的说就是窗口的句柄。“这个大家应该都知道“。面试的人可能要问的是你的程序接口设计的问题。也就是说为什么窗口是通过一个HWND来表示的。
我们这么来看,从程序的角度看,什么是窗口?实际上窗口是一堆的数据。(微软定义的,本人觉得定义的不是非常好)。这堆数据非常的复杂。不可能每个人都能懂,也没必要每个人都懂,所以设计者给了一个HWND来做为程序访问这堆数据的入口。这样就很好的保证了数据的容易访问,和数据的封装。
如果你把上面都看懂了,面试应该不会有问题了。
“我只知道dll的HANDLE是进程加载dll时候dll映射到进程空间的地址。。。”
这个是同样的道理,这个Handle只是放了一些如何查找动态库的信息的数据。
Top
8 楼wltg2001(红猪)回复于 2006-05-05 08:59:11 得分 0
一般来说,HWND不认为是指针,因为指针表示对象的地址,根据地址我们总能找到这个对象,但是HWND的值对我们来说毫无意义,通过它我们找不到对象本身。应该这样看,窗口是一个对象,这个对象的细节是不需要我们知道的。而HWND是这个对象的某种标识,系统会根据它来找到对象,我的想法是系统也许在某个地方放有一个表格,这个表格中放有各种对象的描述,而HWND应该是相应对象在表格中的索引。Top
9 楼hrbniu(五彩神牛)回复于 2006-05-05 08:59:32 得分 0
呵呵,有道理Top
10 楼soaroc(会飞的猪)回复于 2006-05-05 11:36:44 得分 0
楼上有几位都提到了关于表格和索引的问题。如果不是我孤陋寡闻,这个表格和索引应该是在在进程中才有的,对于每一个进程的创建,系统会为他分配一个进程列表,进程的句柄就是对应的索引。而楼上几位分析估计就是按这个来的。其实,HWND不过是Windows系统资源的标示而已,比如说:我们的CWnd只不过是一种窗口的类型而已,系统怎么知道可以根据这个类来创建一个可以显示的窗口呢?我们需要将一种Windows的窗口资源与这个类来关联起来。一来,系统知道通过CWnd可以创建怎样的一种窗口资源;另一方面,在程序中,这个类就代表了一种窗口,我们可以借这个类来完成对窗口资源的操作。Top
11 楼codewarrior(会思考的草)回复于 2006-05-05 14:56:12 得分 0
to soaroc(会飞的猪) :
you are right,每个进程都有一个句柄表。
CWnd不是“一种窗口的类型”,要把C++的“类”和Windows的窗口“类”区别开!没有MFC,没有CWnd,Windows照样运行,CWnd不是Windows的一部分!Windows中所有用CreateWindow创建的东西统统都可以当成CWnd类的Instance。Top
12 楼wltg2001(红猪)回复于 2006-05-05 16:27:30 得分 0
to soaroc:
这里讨论的HWND指的是窗口的句柄,它应该是和编程语言无关的东西,你所说的CWnd是C++,确切的说是MFC中的一个类,它的意义与窗口对象相差太远了。Top
13 楼soaroc(会飞的猪)回复于 2006-05-05 18:40:28 得分 0
前面的我的确说的有错误,我承认CWnd不应该是一种窗口类型,它的确是是一种类,其实在我的后面的解释已经说清楚了。
to codewarrior(会思考的草):
我没有说CWnd是Windows的一部分.我说的是,在系统中包含了窗口这种资源,除此之外,系统还包含了很多其他的资源,比如说画刷,画笔等等。窗口其实也是一种资源。而当我们实例化一个Cwnd时,就将一个对象,一个窗口对象与这种资源相关联,此后,就可以使用这个对象来错作窗口。
to wltg2001(红猪):
请问CWnd中的m_hWnd是什么,它不是窗口的句柄吗?CWnd是一个类,但当其实例化之后,就可以成为一个窗口对象。
Top
14 楼delphihero(何去何从)回复于 2006-05-05 20:25:19 得分 0
wndcls.lpszClassName="YangBaocen";
//BOOL result;
hwnd=CreateWindow("YYYY","Mr. Yang's first
~~~~~~这个因该跟 lpszClassName一致
Top
15 楼xxtyshun(lilac)回复于 2006-05-05 20:49:01 得分 0
窗口句柄是指向地址的地址.因为在保护模式下.内存中的数据随时在变化.
如何在多变的内存环境中找到想要找到的对象.只能通过这个相对不变的指针.
这个相对不变的指针就是句柄.它在内存中一个比较特殊的位置..............
ps:自己理解.技术错误在所难免 ,请勿bsTop
16 楼xing_xing_xing(哈哈)回复于 2006-05-05 20:59:34 得分 0
Windows核心编程Top
17 楼716radar(门外汉)回复于 2006-05-05 22:06:08 得分 0
3.关于句柄
在Windows编程中我们时刻接触到一个称为句柄(HANDLE)的东西。可以这样去理解句柄,Windows程序中产生的任何资源(要占用某一块或大或小的内存),如图标,光标,窗口,应用程序的实例(已加载到内存运行中的程序)。操作系统每产生一个这样的资源时,都要将它们放入相应的内存,并为这些内存指定一个唯一的标识号,这个标识号即该资源的句柄。操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源的。按资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE),等等各种类型的句柄。操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。
Top
18 楼eein(eein)回复于 2006-05-05 22:42:06 得分 0
SetWindowsLong是什么??
HANDLE即是句柄,是一个特殊的整数,Windows利用它标志应用程序创建和使用的资源,是Windows内部表资源数据存储的内存索引值,Windows可利用它访问表中的信息。Top
19 楼eein(eein)回复于 2006-05-05 22:45:19 得分 0
我比较喜欢 把HANDLE 看成 指针。
因为每个实例的句柄可以看成指针的话,可以理解句柄是指向 所分配内存资源的起始地址。Top
20 楼anikan_yu(无话可说)回复于 2006-05-06 07:23:50 得分 0
下面是HWND的定义:
DECLARE_HANDLE (HWND);
#ifdef STRICT
typedef void *HANDLE;
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endifTop
21 楼nlstone(天外流星)回复于 2006-05-06 08:10:35 得分 20
晕,几年不来,还在句柄之争,再贴一次袁老大的标准答案吧:
Usually, the main information of a handle is an integer index into an internal table. But this is not always true. GDI handles have extra information like object type and a re-use count. Some handles are actually pointers.
There are three major groups of handles:
1) kernel handles, exposed by KERNEL32.DLL. Files, thread, process, ..
2) user handles, exposed by USER32.DLL. Icons, menus, windows, cursors, ...
3) GDI handles, exposed by GDI32.DLL. DC, font, region, DDB, DIB section, pen, brush.Top
22 楼jxufeng(玉龙猪)回复于 2006-05-06 18:46:51 得分 0
我觉得微软很恶心。hwnd是一个整数,我只知道从一个hwnd构造一个cwnd需要这样
CWnd *wnd=new CWnd;
wnd->m_hwnd=hwnd;
微软的东西怎么老是要拐很多的弯啊Top
23 楼codewarrior(会思考的草)回复于 2006-05-06 19:29:48 得分 0
soaroc(会飞的猪):
“而当我们实例化一个Cwnd时,就将一个对象,一个窗口对象与这种资源相关联,此后,就可以使用这个对象来错作窗口。”
又错。CWnd被实例化的时候可以不和任何Windows窗口关联。只有调用了Create之后才会和一个真正的Windows窗口关联起来;同样的,窗口被销毁了但CWnd的实例依然可以存在。Top
24 楼soaroc(会飞的猪)回复于 2006-05-06 20:18:01 得分 0
很高兴楼上的终于同意了我的关于将CWnd和窗口(资源)相关联的说法。另外,从始至终我没有提过窗口和Cwnd会同时销毁的说法。我只是说两者可以关联起来,我们可以使用CBitmap来关联一个位图资源,当然我们可以使用deleteOject也可以切断这种关联。我们可以通过Cwnd 的m_hWnd来判断Cwnd是否已经与一个窗口相关联了。总之,上面的意思就是----两者没有同生同灭关系Top
25 楼cici2006(以不变应万变)回复于 2006-05-06 21:22:56 得分 0
类与名柄是不同的概念呀。窗口句柄是操作系统内核分配的一个可以唯一标志识你所创建的窗口的对象。
类就不同了,可以生成是没有这个窗口呀。并不一定要用CWND,你可以自己生成createWnd窗口,就可以了呀。Top
26 楼lvkeqiang(克刚2005)回复于 2006-05-06 23:19:13 得分 0
句柄就是资源标示符号,类似于数据库的关键字 每个资源都有一个,区别于其他的,应该是kernerl创建的,详细的仔细查阅MSDNTop
27 楼codewarrior(会思考的草)回复于 2006-05-07 14:45:54 得分 0
实例化一个Cwnd时,就将一个对象,一个窗口对象与这种资源相关联
~~~~~~这里错了,实例化CWnd的时候不代表和一个窗口对象关联,你错在这里。Top
28 楼loki2k(loki)回复于 2006-05-08 13:55:32 得分 0
我一直以为H开头的就是句柄了,我想HWND只是typedef了而已,不知道对不对啊Top
29 楼SoLike(思危)回复于 2006-05-08 17:40:25 得分 0
句柄不是指针。很基本的概念啊Top
30 楼buggycode(风雨寒夜)回复于 2006-05-11 09:28:27 得分 0
SoLike
句柄不是指针。很基本的概念啊
看看定义!!!
typedef void * HANDLE;
看来是个读死书的。
Top
31 楼codewarrior(会思考的草)回复于 2006-05-11 15:35:46 得分 0
句柄的定义不是一成不变的,在不同的场合定义不一样。大多数时候不是简单的定义成指针。具体定义成什么,依赖于此种情况下句柄的本质。有的时候就是指针,有的时候是一个句柄表的索引。Top
32 楼zjz800800((对不起,偶是卧底))回复于 2006-05-11 16:46:13 得分 0
真热闹,怎么还在说句柄呀,
面试官要问你:"请问HWND窗口句柄到底是什么?"
你就说:"请问门牌号到底是什么"
面试官要是答:"标示房子第"
你就说:"欧了,HWND是标示房子里的窗口第"
Top
33 楼toxyboy(不专业,我就顶,绝不误导别人!!)回复于 2006-05-11 17:09:37 得分 0
就是个在该进程空间的一个唯一标识符。。通过它可以访问该标志符标志的资源。
Top
34 楼wo_shi_yi_zhi_yu()回复于 2006-05-11 17:48:45 得分 20
句柄不是指针
好似指针
它表示一个资源
就是标志一块数据
但是数据在内存中分配是有固定的地址
如果没有虚存的技术,这个指针恒有效
也就没有必要用句柄了
但是虚存情况下,内存中的数据会移动到磁盘中
这样呢,我们需要在内存中保存这个数据的标志,
等到需要的时候,再加载进来,但是存放的地址就不和原来一样;
所以,指针是容易弄丢,而句柄不会丢的;Top
35 楼whwjn(哈哈)回复于 2006-06-02 23:29:18 得分 10
句柄vs指针
句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这
个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址 访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一 个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化 了。如果地址总是如此变化,我们该到哪里去找该对象呢?为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门 登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。句柄地址(稳定)→记载着对象在内存中的地址→对象在内存中的地址(不稳定)→实际对象。但是,必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成 是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电 影院售给我们的门票总是不同的一个座位是一样的道理。Top
36 楼fxRen(BraveHearts)回复于 2006-06-02 23:39:29 得分 0
我想,就是窗口的ID号吧,就像你我的身份证号码一样Top
37 楼xinai0521(爱之风)回复于 2006-06-02 23:40:17 得分 0
就是一个指针,指向指针的指针。。。。。。。。
我是这么理解的。。:)Top
38 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-02 23:52:49 得分 0
这种烂问题总有那么多人扎堆,一个个还都正经八百,道貌岸然,哈哈Top
39 楼zhangyu666(咖啡)回复于 2006-06-03 00:34:38 得分 0
呵呵,楼上精辟.Top
40 楼zjz800800((对不起,偶是卧底))回复于 2006-06-03 00:42:49 得分 0
一个个的都象是个伪君子,这种烂问题以后不许扎堆Top
41 楼fireseed(【VC无敌,英明神武,千秋万代,一统江湖!】—奶油狗)回复于 2006-06-03 00:45:41 得分 0
专家分有什么难赚的?
1. 挑选人气旺、好赚分的版,比如.net技术呀,VC/MFC呀,软件使用之类的,并尽在人气够旺的基础上选择难度较高的。人气一旺,贴子就多,再加上难度高,肉多狼少,所以贴子的分数自然就会上去,这就是传说中的优胜劣汰自然选择法择!记住,虽然C/C++是个初学者学习的好地方,但只有傻子才会去那抢分!另外,地球人都知道,扩充话题的分不计在专家分内,所以别跟个火星人一样,在水园乱up抢分。
2. 时间是生命。只有尽量长时间的泡在坛子里并不断刷新,你才能有足够的机率在人气巨旺的版里抢到1楼。一般楼主结贴时先把最正确的回答给上分,还有剩下的分怎么办?一般情况下只有失恋超过49次的或着智商的绝对值直逼爱因斯坦的楼主,才会用剩余可用分除以回答人数,再一一给分!绝大多数情况,一楼拿的分是最多的,但不排除一楼和二楼、三楼、四楼……n楼并列第一的情况。
3. 能回答两次的就回答两次,尤其是自己比较有把握的问题,两次可能描述的答案都一样,但措词千万不能一样,并且两次回答之间要有一定的矩离,反正想方设法让智商明显低于你的楼主认为是两个人回答的,然后得双份的分。
4. 逢贴必回,会的简单做答,不要担误在其它贴子里抢一的时间;稍微含糊的问题就瞎蒙几句,不行就“建议楼主参阅相关书籍”;不会的就复制一下别人的回答,不行就加点油加点醋;实在连题意都看不懂的,就up、顶、楼主高人、拍一下马屁,楼主要是吃拍的,一高兴没准给你个一二十分的。
5. 楼主就是上帝,所以要抱着做学问的态度回贴,他要钻牛角尖你就陪他钻,千万不能和楼主吵翻。要是有别的抢分人和你争论,先不要管到底谁对谁错,记住,你永远是对的,只有分是真理!错的也要说成是对的,不行就上两个马甲支持你。楼主正是因为不懂才会问的,你还怕他识破?一般楼主判断回答的错对就是看人数,所以有上6、7个马甲是必要的。
6. 另外自己在机子上建一个FAQ表,据考证,论坛上每天有30%以上的技术贴是以前问过或类似的,而且这个比率还在增加。所以建一个FAQ表是很有必要的,不行就用Access写个简单的数据库程序,用关键词查找。一看见眼熟的贴子,先搜数据库,一量搜到,Ctrl+C和Ctrl+V伺候。
7. 这一招是最狠的,非到万不得已千万不要使用,以免造成“狼来了”效应。如果你看到了一个300分的贴,上面也没几条回复,而且这个问题你可以做答,OK,这个分咱们要定了!在你回答完之后,不要忘了留一个网址,其实一个是远远不够的,你在下面再用不同的马甲留下不同的n个网址,目的无非就是一个:转移视线。让想回答的人在看回贴时忍不住进入你留的网址,然后一去不复返……但有几条要注意的,不能在回贴里透露半点网址的相关内容,这样可以增加他人好奇心;所留网址必须有足够的链接,并且是以新窗口打开的那种,这样可以使他人在慌乱中关掉原窗口而彻底迷失;内容和链接必须有足够的吸引力。
8. 在回答别人问题时候要措辞干净利落,说话条理性很重要,最好先让你那不懂电脑的女友或着老妈看看能不能看懂,因为怕就怕给楼主留下二次题问的机会。一但有二次提问,你就面临着楼主把本来该给你的分送给别人的危险。所以要经常刷新“你所参与的问题”。如果你的小学语文欠佳,建议先复习小学语文中提取句子主干部分知识,以打下坚实的基础。
9. 和真正的高手保持良好的关系,最好能把QQ或着MSN要到,在遇到不会的问题时,先装做是自己遇到了天大的麻烦,明天不交差将会造成被老板炒犹鱼、被老婆抛弃、被兄弟姐妹断绝关系,被父母遗弃,天打雷劈,出门被车撞等严重后果,然后取得高手的同情心,让他详实的帮你做答。之后,你就只剩下Ctrl+C和Ctrl+V了
10. 不要只在一个论坛里转,因为即是人气再高,也经不住你12刷新次/每分钟的速度,而且论坛程序缓冲也有一段时间,为也更好的利用这些时间,就去别的论坛上回新贴抢一楼吧。平时要注意收集最新的论坛动向,关注发生重大改版事件后的版块,这些版块在改版之后的两三天到一周的时间内将会有一个人气高峰期,而且发贴的人多,回贴的人少。另外不能光看人气,还要看结贴率,人气和结贴率所占的比重为7:3。这些数据当然只有在你不断时践中都能总结出来。
以上就是各项基本原则,如果你的方法得当,一个月10000专家分是小菜一碟。这当然对于你的目标来说还要相差的很远的,你只有在不断的探索中才能够找到一条真正适合自己的成星之路。
Top
42 楼SeRapHiw(灯芯草)回复于 2006-06-04 12:39:32 得分 0
楼上的论述应该加精Top
43 楼artcpp(活着真好)回复于 2006-12-20 13:39:56 得分 0
好玩,支持一下。Top




