Windows API中HANDLE和HWND有什么区别?

28
我正在尝试使用函数SetForegroundWindow(HWND hWnD)。我有一些句柄,但作为上述函数的参数时它无效。我的句柄是一个线程,我想将其在前台运行。
HWND和HANDLE之间有什么区别?
3个回答

44

它们只是抽象数据类型

根据MSDNHANDLEHWND的定义如下:

  • HANDLE是指向对象的句柄
  • HWND是窗口句柄。

所以,HWND是一个HANDLE,但并非所有的HANDLE都是HWND。事实上:

typedef void *PVOID;
typedef PVOID HANDLE;
typedef HANDLE HWND;

例子

除非你知道自己在做什么,否则你应该只传递HWNDSetForegroundWindow

HWND hWnd = FindWindow(NULL, "Calculator");
SetForegroundWindow(hWnd);

该代码先使用 FindWindow 获取一个标题为 "Calculator" 的窗口句柄,然后将该窗口置于前台。


8
如果未定义 STRICT,那么这些 typedef 会被使用。如果已定义 STRICT,则 HWND 不再作为 HANDLE 定义,而是作为一种独特且独立的数据类型定义。 - Remy Lebeau
4
@RemyLebeau,“typedef”这部分是从官方文件中引用的。(但是我查看了头文件,发现它确实是按照您所描述的方式定义的。谢谢。) - timothyqiu
即使它们使用相同的指针大小类型编译,HWNDHANDLE肯定没有关联。 HWND是窗口组件(user32.dll和相关组件)中数据结构的索引,而HANDLE是内核中数据结构的索引。 - Ben Voigt

15
一个“句柄(handle)”是指在系统上标识资源的令牌(如菜单、DLL模块、一块内存等),通常称为“幻数(magic cookie)”,当你第一次创建资源时通常就会返回它。然后,你将该句柄传递给API中其他负责处理该资源的函数。但是,你通常不需要知道句柄是什么。有时可能是指针,有时可能是数字,也可能是结构体或其他类型。这就是他们使用HWND等名称来隐藏它的原因,HWND仅用于标识窗口(由API函数“CreateWindow()”返回)。因此,你不需要将“句柄(handle)”转换为HWND,因为HWND已经是一个“句柄(handle)”(仅仅是标识你创建的窗口)。
在这里找到http://forums.codeguru.com/showthread.php?135438-Handle-and-HWND 你可以使用FindWindow从应用程序中获取hwnd http://msdn.microsoft.com/en-us/library/windows/desktop/ms633499(v=vs.85).aspx

如果你已经拥有你所寻找的句柄C++ Handle as HWND?,这应该可以让你获取HWND。


是的,谢谢!但我能将句柄转换为HWND吗? - Thangnv
1
@Thangnv 这就像是在问“我能把 void * 转换成 int * 吗?”这要看情况。你的句柄是什么? - timothyqiu
我的句柄是一个线程,我想在前台运行它,但它不是 SetForegroundWindow(HWND hWnD) 函数中的 HWND。 - Thangnv
我将其转换为HWND hWnD = (HWND) myHanle; 这不是错误,但我无法检查它是否运行。 - Thangnv
4
SetForegroundWindow 是一个用于操作窗口而非线程的 API。 - timothyqiu

11

HWND也是一个句柄,但是是全局句柄。 也就是说,在一个进程上下文中有效的HWND在另一个进程上下文中同样有效。

一些未记录的信息请参见https://winterdom.com/dev/ui/wnd/


3
“但全球性的”正是我正在寻找的。谢了,伙计。 - Pyjong
那个链接现在已经失效了。 - Rokit
HWND是一种句柄(handle)类型,但不是HANDLE - Ben Voigt
@BenVoigt 两种类型都是指针的typedef,因此在C++或操作系统级别上它们是相等的。 - Michael Chourdakis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接