顶层窗口
Q: What is a top-level window?
A: A top-level window is a window that is not child, i.e. it has not WS_CHILD style set.
Notes
unlike the child windows, a top-level window can be displayed anywhere in the screen;
many definitions state that a top-level window is "a window that has no parent";
that is correct but can lead in a confusion: many people think that every window which is created passing a valid hWndParent in CreateWindow(Ex) "has a parent" then, according to the definition it is not top-level;
in fact hWndParent may be either a handle to parent or owner window;
if hWndParent is a valid window handle and WS_CHILD style is not set, then we have a top-level owned window;
a top-level window can or can not be owned but is never a child; further we can say that it can have an owner but never has a parent.
top-level windows can be either overlapped windows (having WS_OVERLAPPED style and generally used as application main window) or popup windows (having WS_POPUP style, usually temporary windows like message boxes and dialogs);
the coordinates used in CreateWindow(Ex), MoveWindow, SetWindowPos, and so on are always scren coordinates (relative to top-left corner of the screen).
也就是说:顶层窗口是非子窗口,即未设置WS_CHILD样式。
与子窗口不同,顶级窗口可以显示在屏幕上的任何位置;
许多定义都指出顶层窗口是“没有父窗口”。
这是正确的,但可能导致混乱:许多人认为,通过CreateWindow(Ex)中的有效hWndParent创建的每个窗口“都有父级”,根据定义,它不是顶层的;
实际上,hWndParent可以是父窗口或所有者窗口的句柄;
如果hWndParent是有效的窗口句柄,并且未设置WS_CHILD样式,则我们有一个顶层拥有的窗口;
顶层窗口可以拥有或不能拥有,但绝不能是子窗口;更进一步,我们可以说它可以有一个所有者,但永远不能有一个父母。
顶层窗口可以是重叠窗口(具有WS_OVERLAPPED样式,通常用作应用程序主窗口)或弹出窗口(具有WS_POPUP样式,通常是诸如消息框和对话框之类的临时窗口);
CreateWindow(Ex),MoveWindow,SetWindowPos等中使用的坐标始终是scren坐标(相对于屏幕的左上角)。
WINAPI
函数原型:
BOOL WINAPI EnumWindows(
_In_ WNDENUMPROC lpEnumFunc,
_In_ LPARAM lParam
);
lpEnumFunc: 应用程序定义的回调函数的指针
lParam: 传递给回调函数的应用程序定义的值
MSDN中对EnumWindows的解释:
Enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function. EnumWindows continues until the last top-level window is enumerated or the callback function returns FALSE.
即:
枚举屏幕上的所有的顶层窗口,轮流地将这些窗口的句柄传递给一个应用程序定义的回调函数lpEnumFunc。EnumWindows会一直进行下去,直到枚举完所有的顶层窗口,或者回调函数返回了FALSE.
2.
EnumWindowsProc()函数的定义:
BOOL CALLBACK EnumWindowsProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
);
hwnd: 在枚举每个顶层窗口而调用该函数的过程中传递给该函数的顶层窗口的句柄
lParam: 即EnumWindows()函数的第二个参数。
Return Value:
返回TRUE,则EnumWindows()函数在系统中继续调用EnumWindowsProc()函数;返回FALSE,则停止枚举。
MSDN解释:
An application-defined callback function used with the EnumWindows or EnumDesktopWindows function. It receives top-level window handles. The WNDENUMPROC type defines a pointer to this callback function. EnumWindowsProc is a placeholder for the application-defined function name
即:
应用程序定义的函数,用于EnumWindows()或EnumDesktopWindos()函数。接收顶层窗口句柄。WNDENUMPROC类型定义了指向这种回调函数的指针。EnumWindowsProc是一个应用程序定义的函数名称的占位符。
3 GetWindowTextW
如果窗口有标题栏,复制标题栏标题到指定的缓冲区。如果标题栏窗口是控件,则复制控件的文本内容。但是 GetWindowText 函数不能返回其它应用程序的控件文本内容。
SetWindowText 函数可以改变窗口或控件的文本。
函数原型:
int WINAPI GetWindowTextW ( HWND hWnd,LPTSTR lpString,int nMaxCount );
参数
hWnd
类型:HWND
包含文本内容窗口或控件的窗口句柄。
lpString
类型:LPTSTR
接收文本的缓冲区。如果文本内容字符串长度大于或等于缓冲区大小,则使用NULL空字符截断文本内容。
nMaxCount
类型:int
包括结束的NULL空字符在内,复制到缓冲区的最大字符数。如果文本长度超过这个个数,会被截断。
返回值
类型:int
如果成功,返回复制到缓冲区的字符个数,字符个数不包括结尾的NULL空字符。如果窗口没有标题栏或文本、标题栏是空或窗口或控件句柄不可用,返回0。
此函数不能返回其它应用程序的文本个数。
备注
如果目标窗口被本进程拥有,GetWindowText 会向窗口发送 WM_GETTEXT 消息来获取文本。如果目标窗口被其它进程拥有并且有标题,GetWindowText 返回窗口标题文本;如果窗口没有标题,返回空字符串。GetWindowText 被这样设计,它可以允许应用程序忽略窗口是否被本进程拥有而完成调用。
4 GetClassLong 获取INCON
HICON hIcon =(HICON)GetClassLong(hWnd, GCL_HICON);
QPixmap pix = QtWin::fromHICON(hIcon);//转 QPixmap
5 获取PID 和父进程PPID
DWORD hWndPID;
//获取进程ID
::GetWindowThreadProcessId(hWnd,&hWndPID);
//获取父进程号
DWORD hPPID = GetParentProcessID(hWndPID);
6 获取 Class name
//获取class name
TCHAR szBuf_class[MAX_PATH];
GetClassName(
hWnd, // 窗口句柄
szBuf_class, // 接收窗口类名的缓冲区指针
MAX_PATH // 缓冲区字节大小
);
6 获取进程句柄
TCHAR szPath[MAX_PATH];
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, hWndPID);
7 获取进程可执行文件路径
if(!::GetModuleFileNameEx(pHandle,NULL,szPath,MAX_PATH))
{
printf("GetModuleFileName failed (%d)\n", GetLastError());
}