TOPMOST窗口属性失效的一种场景
windows桌面程序中,经常需要设置窗口TOPMOST显示,这可以通过下面代码实现。
::SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
但是有时候,在窗口层次比较复杂的情况下,发现设置后的TOPMOST属性没有了。
如下图所示,是个具有TOPMOST属性的窗口
可以通过spy++查看到这一属性。
主界面上有个按钮,用于创建非topmost的子窗口,点击会触发子窗口的建立,如下所示:
HWND hChildWnd = ::CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME, L"TOPMOSTTEST", L"MyClildTitle", WS_VISIBLE | WS_OVERLAPPEDWINDOW, 800, 800, 200, 200, g_hWnd, NULL, hInst, nullptr);
DWORD err = ::GetLastError();
::SetWindowPos(hChildWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
我们发现子窗口创建后,然后设置子窗口非TOPMOST,我们发现对应的父窗口的TOPMOST属性也会丢失。
注意,如果创建窗口时,不指定父窗口,则父窗口依然具有TOPMOST属性,对应的代码如下:
HWND hChildWnd = ::CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME, L"TOPMOSTTEST", L"MyClildTitle", WS_VISIBLE | WS_OVERLAPPEDWINDOW, 800, 800, 200, 200, NULL, NULL, hInst, nullptr);
DWORD err = ::GetLastError();
::SetWindowPos(hChildWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);
对应的界面如下:
下面给出对应的代码,在vs2017上调试通过。
// TopmostTest.cpp : 定义应用程序的入口点。
//#include "framework.h"
#include "TopmostTest.h"#define MAX_LOADSTRING 100#define IDB_ONE 3301 HWND g_hWnd = NULL;// 全局变量:
HINSTANCE hInst; // 当前实例
WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_ int nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);// TODO: 在此处放置代码。// 初始化全局字符串LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadStringW(hInstance, IDC_TOPMOSTTEST, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);// 执行应用程序初始化:if (!InitInstance (hInstance, nCmdShow)){return FALSE;}HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TOPMOSTTEST));MSG msg;// 主消息循环:while (GetMessage(&msg, nullptr, 0, 0)){if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}return (int) msg.wParam;
}//
// 函数: MyRegisterClass()
//
// 目标: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{WNDCLASSEXW wcex;wcex.cbSize = sizeof(WNDCLASSEX);wcex.style = CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc = WndProc;wcex.cbClsExtra = 0;wcex.cbWndExtra = 0;wcex.hInstance = hInstance;wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TOPMOSTTEST));wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_TOPMOSTTEST);wcex.lpszClassName = szWindowClass;wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));return RegisterClassExW(&wcex);
}//
// 函数: InitInstance(HINSTANCE, int)
//
// 目标: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{hInst = hInstance; // 将实例句柄存储在全局变量中HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);if (!hWnd){return FALSE;}ShowWindow(hWnd, nCmdShow);g_hWnd = hWnd;::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);UpdateWindow(hWnd);return TRUE;
}//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目标: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{switch (message){case WM_COMMAND:{int wmId = LOWORD(wParam);// 分析菜单选择:switch (wmId){case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_EXIT:DestroyWindow(hWnd);break;case IDB_ONE:{///此处创建一个非topmost的子窗口HWND hChildWnd = ::CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME, L"TOPMOSTTEST", L"MyClildTitle", WS_VISIBLE | WS_OVERLAPPEDWINDOW, 800, 800, 200, 200, g_hWnd, NULL, hInst, nullptr);//HWND hChildWnd = ::CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME, L"TOPMOSTTEST", L"MyClildTitle", WS_VISIBLE | WS_OVERLAPPEDWINDOW, 800, 800, 200, 200, NULL, NULL, hInst, nullptr);DWORD err = ::GetLastError();::SetWindowPos(hChildWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOACTIVATE);break;}default:return DefWindowProc(hWnd, message, wParam, lParam);}}break;case WM_PAINT:{PAINTSTRUCT ps;HDC hdc = BeginPaint(hWnd, &ps);// TODO: 在此处添加使用 hdc 的任何绘图代码...EndPaint(hWnd, &ps);}break;case WM_DESTROY:PostQuitMessage(0);break;case WM_CREATE:{CreateWindowW(L"Button", L"创建非topmost子窗口", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,35, 10, 200, 60, hWnd, (HMENU)IDB_ONE, hInst, NULL);}break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{UNREFERENCED_PARAMETER(lParam);switch (message){case WM_INITDIALOG:return (INT_PTR)TRUE;case WM_COMMAND:if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL){EndDialog(hDlg, LOWORD(wParam));return (INT_PTR)TRUE;}break;}return (INT_PTR)FALSE;
}
TOPMOST窗口属性失效的一种场景相关推荐
- 索引失效的10种场景,你知道几个呢?(必知五颗星)
目录 前言 1. 准备工作 1.1 创建user表 1.2 插入数据 1.3 查看数据库版本 1.4 查看执行计划 2. 不满足最左匹配原则 2.1 哪些情况索引有效? 2.2 哪些情况索引失效? 3 ...
- Redis事务失效的三种场景
文章目录 Redis 事务失效的三种场景 命令入队报错 命令执行报错 乐观锁导致失效 Redis 事务失效的三种场景 Redis事务失败,有三种类型的失败场景: 命令入队报错 在事务提交之前,客户端执 ...
- MySQL 索引失效的 15 种场景!
背景 无论你是技术大佬,还是刚入行的小白,时不时都会踩到Mysql数据库不走索引的坑.常见的现象就是:明明在字段上添加了索引,但却并未生效. 前些天就遇到一个稍微特殊的场景,同一条SQL语句,在某些参 ...
- 聊聊Spring事务失效的12种场景,太坑人了
前言 对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了. 在某些业务场景下,如果一个请求中,需要同时写入多张表的数据.为了保证操作的原子性(要么同时成功,要么同时失败),避免数据 ...
- Spring 事务失效的 8 种场景!
在日常工作中,如果对Spring的事务管理功能使用不当,则会造成Spring事务不生效的问题.而针对Spring事务不生效的问题,也是在跳槽面试中被问的比较频繁的一个问题. 点击上方卡片关注我 今天, ...
- 聊一聊Spring中@Transactional注解及其失效的七种场景
文章目录 一.事务(基于AOP) 二.@Transactional介绍 三.@Transactional失效场景 说明:当我准备写我知道的那几个场景时,我发现有人比我写的更好,关键是好得多,于是我就用 ...
- spring事务失效的11种场景
1 访问权限问题: java的访问权限有4种:private.default.protected.public,它们的权限从左到右,以此变大.如果在开发中,将事务方法定义了错误的访问权限,则事务功能会 ...
- MySQL索引失效的几种常见场景
前言 我们在使用MySQL查询数据的时候,总会遇见没有正确使用到索引的情况. 这里我们列举几种常见的,搜索条件使用了索引列却没有走索引的场景. (以下测试均在MySQL8.0.28中完成,且所有数据均 ...
- windows 技术篇 - uispy 工具获取和使用,windows窗口属性快捷查看工具
常用窗口工具有 spy++ 和 uispy 两种,spy++ 显示的很全,各种窗口都给你展示出来,看着很多很乱,相比来讲 uispy 就比较简洁实用了,只展示主要的窗口,节目很整洁很清晰. spy++ ...
最新文章
- Python_序列对象内置方法详解_String
- 避免后台脚本重复启动机制
- 湖南大学第十五届程序设计竞赛
- 四川大学计算机科学与技术专业分数线,2015年四川大学计算机科学与技术硕士考研复试分数线是290分...
- MySQL存储过程+游标+触发器
- 【mysql技术内幕1】mysql基础架构-一条SQL查询语句是如何执行的
- mqtt server python_使用python实现mqtt的发布和订阅
- QT创建相应文件夹在指定目录下
- 定时任务getScheduler
- 健身房,我用python给她写了个小米计时器助人为乐
- 微信公众平台开发之微团购
- 计算机苏教版初一教案,文笔精华(苏教版七年级) 教案教学设计
- 画图工具的认识及应用计算机,认知画图软件教学设计
- 如何在文件夹中打开cmd命令窗
- 基于MySQL的京东用户行为分析
- rhel6.5 oracle12c,中标麒麟Linux6.5安装Oracle12C配置过程
- 1.5黄金白银最新行情走势分析预测,黄金实时操作建议
- 为Latex生成的PDF设置背景色
- IDEA Intellij小技巧和插件
- 编写程序判断变量X的值 是偶数还是奇数,偶数buf为1,奇数buf为0