We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在一些特定的应用场景中,需要把一个窗口置顶,置顶的窗口可以在其他窗口激活的情况下依然保持在最上面。
先说几个概念: 窗口:Windows是以窗口作为主要交互界面的系统,我们把那个能拖来拖去,一般带有最大化最小化关闭按钮的大方框叫做窗口,但是其实窗口的定义可以更广泛一点,一个按钮是窗口,一个文本框也是窗口。
父窗口:如果一个按钮(Button)被放在一个Panel(面板)上, 那按钮的父窗口就是Pane, 同样Panel的父窗口是Form,Form就是我们平时说的窗口了。
顶级窗口:Form的父窗口是什么? 有人说是桌面(Desktop),也有人说没有父窗口,但是通过实验得知,它没有父窗口,没有父窗口的窗口我们叫做顶级窗口,我们平时说的窗口,都是指的顶级窗口。
句柄:Handle,句柄是一种特殊的指针,指向的是内存里的对象, 通俗得讲它就是一个窗口(事实上远不止窗口)的把手,你有了这个句柄就能开窗关窗,改变窗口的状态。
只要我们获得顶级窗口的句柄,改变它的状态,把"不置顶"改为"置顶",就达成目的了。
只需要不停地找窗口的父窗口, 直到某个窗口的父窗口的句柄为0(不存在),那就找到了该窗口的顶级窗口。
有函数GetParent(),能取得窗口的父窗口。
GetParent()
取得顶级窗口的句柄后, 有函数SetWindowPos, 指定参数HWND, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE 就能置顶一个窗口。
SetWindowPos
所以其实核心代码只有下面几句话:
// 获取顶级窗口句柄 HWND GetHwnd(HWND hwd) { while (GetParent(hwd)) hwd = GetParent(hwd); return hwd; } // 置顶窗口 SetWindowPos(GetHwnd(hwnd),HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE);
置顶只需要一次,所以我在创建窗口的时候调用一下该置顶函数即可。
#include <windows.h> #include <string.h> HWND GetHwnd(HWND hwd) { while (GetParent(hwd)) hwd = GetParent(hwd); return hwd; } LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("TopDemo") ; HWND hwnd ; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, // window class name TEXT ("Top Demo"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position 400, // initial x size 100, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL) ; // creation parameters ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_CREATE: SetWindowPos(GetHwnd(hwnd),HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE); return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, TEXT ("The top window"), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
图中可以看到,Notepad++处于激活状态,但Top Demo窗口依然在顶层。
Top Demo
The text was updated successfully, but these errors were encountered:
No branches or pull requests
在一些特定的应用场景中,需要把一个窗口置顶,置顶的窗口可以在其他窗口激活的情况下依然保持在最上面。
先说几个概念:
窗口:Windows是以窗口作为主要交互界面的系统,我们把那个能拖来拖去,一般带有最大化最小化关闭按钮的大方框叫做窗口,但是其实窗口的定义可以更广泛一点,一个按钮是窗口,一个文本框也是窗口。
父窗口:如果一个按钮(Button)被放在一个Panel(面板)上, 那按钮的父窗口就是Pane, 同样Panel的父窗口是Form,Form就是我们平时说的窗口了。
顶级窗口:Form的父窗口是什么? 有人说是桌面(Desktop),也有人说没有父窗口,但是通过实验得知,它没有父窗口,没有父窗口的窗口我们叫做顶级窗口,我们平时说的窗口,都是指的顶级窗口。
句柄:Handle,句柄是一种特殊的指针,指向的是内存里的对象, 通俗得讲它就是一个窗口(事实上远不止窗口)的把手,你有了这个句柄就能开窗关窗,改变窗口的状态。
只要我们获得顶级窗口的句柄,改变它的状态,把"不置顶"改为"置顶",就达成目的了。
实现逻辑
只需要不停地找窗口的父窗口, 直到某个窗口的父窗口的句柄为0(不存在),那就找到了该窗口的顶级窗口。
有函数
GetParent()
,能取得窗口的父窗口。取得顶级窗口的句柄后, 有函数
SetWindowPos
, 指定参数HWND, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_DRAWFRAME | SWP_NOSIZE 就能置顶一个窗口。所以其实核心代码只有下面几句话:
置顶只需要一次,所以我在创建窗口的时候调用一下该置顶函数即可。
实现源码
实现效果
图中可以看到,Notepad++处于激活状态,但
Top Demo
窗口依然在顶层。参考
The text was updated successfully, but these errors were encountered: