假设我在 WinSta0 中创建了两个桌面 D1 和 D2,并且 D2 有一个窗口 B。
我的问题是:
属于 D1 的线程能否通过 GetWindowText(hwnd for B, ....) 获取窗口 B 的标题文本?
层次结构是 Session => Window Station => Desktop => Thread => window。当您使用服务时,会话很重要,它们在隔离会话 0 中运行。每个会话至少有 WinSta0 作为交互式窗口站。会话 0 有额外的服务。
一个窗口站有多个桌面,至少是您通常与之交互的默认桌面和 Winlogon 桌面,一个用于登录和屏幕保护程序的安全桌面。加上您创建的其他内容,例如您的 D2 桌面。
一个桌面有一个单独的桌面堆,其中存储了窗口对象。每个 HWND 在该堆中都是唯一的。您将需要 GetThreadDesktop() 跳回层次结构并从已知线程返回到它创建窗口的桌面。EnumDesktopWindows() 获取该桌面拥有的顶级窗口。
获取线程 ID 通常是一个障碍,您至少需要了解有关该进程的一些信息。您可以从中枚举该进程拥有的线程,例如 CreateToolhelp32Snapshot()。
这让你获得了桌面句柄。但是 GetWindowText 只能使用 D1 句柄,您需要调用 SetThreadDesktop() 才能切换到 D2。
EnumWindowStations()
EnumDesktops()
- 需要一个窗口站EnumDesktopWindows()
- 需要一个桌面(和)
EnumWindows()
EnumChildWindows()
- 需要一个父窗口使用上面的函数,做一个测试,看看它们是否是唯一的。我会说他们应该是。
PS:更多在这里。
HWND 在台式机中是独一无二的。
tagWND结构(别名 HWND)的第一个成员是_THRDESKHEAD结构
typedef struct tagWND
{
/*0x000*/ struct _THRDESKHEAD head;
/*0x014*/ ..............
(来自 win32k!tagWND 符号)
typedef struct _THRDESKHEAD
{
THROBJHEAD;
PDESKTOP rpdesk; //DESKTOP OBJECT
PVOID pSelf;
} THRDESKHEAD, *PTHRDESKHEAD;
(来自 ReactOS 源)
因此,每个 HWND 都分配给桌面边界。