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窗口属性失效的一种场景相关推荐

  1. 索引失效的10种场景,你知道几个呢?(必知五颗星)

    目录 前言 1. 准备工作 1.1 创建user表 1.2 插入数据 1.3 查看数据库版本 1.4 查看执行计划 2. 不满足最左匹配原则 2.1 哪些情况索引有效? 2.2 哪些情况索引失效? 3 ...

  2. Redis事务失效的三种场景

    文章目录 Redis 事务失效的三种场景 命令入队报错 命令执行报错 乐观锁导致失效 Redis 事务失效的三种场景 Redis事务失败,有三种类型的失败场景: 命令入队报错 在事务提交之前,客户端执 ...

  3. MySQL 索引失效的 15 种场景!

    背景 无论你是技术大佬,还是刚入行的小白,时不时都会踩到Mysql数据库不走索引的坑.常见的现象就是:明明在字段上添加了索引,但却并未生效. 前些天就遇到一个稍微特殊的场景,同一条SQL语句,在某些参 ...

  4. 聊聊Spring事务失效的12种场景,太坑人了

    前言 对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了. 在某些业务场景下,如果一个请求中,需要同时写入多张表的数据.为了保证操作的原子性(要么同时成功,要么同时失败),避免数据 ...

  5. Spring 事务失效的 8 种场景!

    在日常工作中,如果对Spring的事务管理功能使用不当,则会造成Spring事务不生效的问题.而针对Spring事务不生效的问题,也是在跳槽面试中被问的比较频繁的一个问题. 点击上方卡片关注我 今天, ...

  6. 聊一聊Spring中@Transactional注解及其失效的七种场景

    文章目录 一.事务(基于AOP) 二.@Transactional介绍 三.@Transactional失效场景 说明:当我准备写我知道的那几个场景时,我发现有人比我写的更好,关键是好得多,于是我就用 ...

  7. spring事务失效的11种场景

    1 访问权限问题: java的访问权限有4种:private.default.protected.public,它们的权限从左到右,以此变大.如果在开发中,将事务方法定义了错误的访问权限,则事务功能会 ...

  8. MySQL索引失效的几种常见场景

    前言 我们在使用MySQL查询数据的时候,总会遇见没有正确使用到索引的情况. 这里我们列举几种常见的,搜索条件使用了索引列却没有走索引的场景. (以下测试均在MySQL8.0.28中完成,且所有数据均 ...

  9. windows 技术篇 - uispy 工具获取和使用,windows窗口属性快捷查看工具

    常用窗口工具有 spy++ 和 uispy 两种,spy++ 显示的很全,各种窗口都给你展示出来,看着很多很乱,相比来讲 uispy 就比较简洁实用了,只展示主要的窗口,节目很整洁很清晰. spy++ ...

最新文章

  1. Python_序列对象内置方法详解_String
  2. 避免后台脚本重复启动机制
  3. 湖南大学第十五届程序设计竞赛
  4. 四川大学计算机科学与技术专业分数线,2015年四川大学计算机科学与技术硕士考研复试分数线是290分...
  5. MySQL存储过程+游标+触发器
  6. 【mysql技术内幕1】mysql基础架构-一条SQL查询语句是如何执行的
  7. mqtt server python_使用python实现mqtt的发布和订阅
  8. QT创建相应文件夹在指定目录下
  9. 定时任务getScheduler
  10. 健身房,我用python给她写了个小米计时器助人为乐
  11. 微信公众平台开发之微团购
  12. 计算机苏教版初一教案,文笔精华(苏教版七年级) 教案教学设计
  13. 画图工具的认识及应用计算机,认知画图软件教学设计
  14. 如何在文件夹中打开cmd命令窗
  15. 基于MySQL的京东用户行为分析
  16. rhel6.5 oracle12c,中标麒麟Linux6.5安装Oracle12C配置过程
  17. 1.5黄金白银最新行情走势分析预测,黄金实时操作建议
  18. 为Latex生成的PDF设置背景色
  19. IDEA Intellij小技巧和插件
  20. 编写程序判断变量X的值 是偶数还是奇数,偶数buf为1,奇数buf为0

热门文章

  1. HAWQ技术解析(十一) —— 数据管理
  2. 85 数模 电动汽车目标客户销售策略研究(21 华数 C)
  3. 海信85U7G和海信85U7G-PRO有什么区别 哪个好详细性能配置对比
  4. Trac中的Ticket系统
  5. 最优化理论与KKT条件
  6. 现代数学观,何处寻?
  7. 通过网络前缀求子网掩码
  8. Windows11原版镜像
  9. Prometheus 之 Alertmanager告警抑制与静默
  10. c语言 --- 指针