DWM 相關實現代碼 [自用]

· 1. DWM 縮略圖和模糊隱藏實現半透明

#include <windows.h>
#include <dwmapi.h>
#include <string>
#pragma comment(lib, "dwmapi.lib")// 檢查 UWP 窗口是否可見
bool IsUWPWindowVisible(HWND hwnd) {DWORD cloaked = 0;DwmGetWindowAttribute(hwnd, DWMWA_CLOAKED, &cloaked, sizeof(cloaked));return (cloaked == 0);
}bool IsBadWindow(HWND hwnd) {wchar_t title[256];wchar_t className[256];GetWindowTextW(hwnd, title, 256);GetClassNameW(hwnd, className, 256);LPCWSTR badTitleList[] = { L"NVIDIA", L"Xaml" };for (LPCWSTR badTitle : badTitleList) {if (wcsstr(title, badTitle) != nullptr) {return true;}}return false;
}void UpdateInfoWindow(HWND infoHwnd, HWND mainHwnd) {if (infoHwnd) {RECT mdrc;GetWindowRect(mainHwnd, &mdrc);// 獲取屏幕工作區和任務欄的位置信息RECT rcWorkArea = { 0 };SystemParametersInfoW(SPI_GETWORKAREA, 0, &rcWorkArea, 0);HWND hTrayWnd = FindWindowW(L"Shell_TrayWnd", nullptr);// 計算任務欄是否遮擋信息窗口bool taskbarVisible = false;if (IsWindow(hTrayWnd)&& IsWindowVisible(hTrayWnd)) {RECT tbrc;GetWindowRect(hTrayWnd, &tbrc);if (tbrc.top >= rcWorkArea.bottom && mdrc.bottom + 50 > tbrc.top) {// 任務欄在底部且信息窗口底部超出工作區域底部taskbarVisible = true;}}if (taskbarVisible) {// 將信息窗口移動到窗口上方SetWindowPos(infoHwnd, nullptr, mdrc.left + 10, mdrc.top - 110,mdrc.right - mdrc.left - 25,100, SWP_NOZORDER | SWP_SHOWWINDOW);}else {// 將信息窗口移動到窗口底部SetWindowPos(infoHwnd, nullptr, mdrc.left + 10, mdrc.bottom,mdrc.right - mdrc.left - 25,100, SWP_NOZORDER | SWP_SHOWWINDOW);}}
}LRESULT CALLBACK InfoWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {switch (uMsg) {case WM_PAINT: {PAINTSTRUCT ps;HDC hdc = BeginPaint(hwnd, &ps);RECT rc;GetClientRect(hwnd, &rc);// 獲取目標窗口信息HWND targetHwnd = (HWND)GetWindowLongPtrW(hwnd, GWLP_USERDATA);if (targetHwnd) {wchar_t title[256];wchar_t className[256];GetWindowTextW(targetHwnd, title, 256);GetClassNameW(targetHwnd, className, 256);wchar_t info[512];swprintf(info, 512, L"Title: %s\nClass: %s\nHandle: 0x%llX",title, className, (UINT_PTR)targetHwnd);// 繪制信息文本SetBkMode(hdc, TRANSPARENT);SetTextColor(hdc, RGB(0, 0, 0));DrawTextW(hdc, info, -1, &rc, DT_LEFT | DT_TOP | DT_NOPREFIX);}EndPaint(hwnd, &ps);return 0;}default:break;}return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {static HTHUMBNAIL thumbnail = NULL;static HWND infoHwnd = NULL;static HWND oldBehindWnd = NULL;// 最小窗口尺寸const int MIN_WIDTH = 100;const int MIN_HEIGHT = 100;switch (uMsg) {case WM_CREATE: {// 創建子窗口用于顯示信息HINSTANCE hInstance = (HINSTANCE)GetWindowLongPtrW(hwnd, GWLP_HINSTANCE);const wchar_t INFO_CLASS_NAME[] = L"InfoWindowClass";WNDCLASS wc = {};wc.lpfnWndProc = InfoWindowProc;wc.hInstance = hInstance;wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);  // 白色背景wc.lpszClassName = INFO_CLASS_NAME;RegisterClassW(&wc);infoHwnd = CreateWindowExW(WS_EX_TRANSPARENT | WS_EX_NOACTIVATE,  // 擴展窗口樣式INFO_CLASS_NAME,                 // 窗口類名nullptr,                         // 窗口標題WS_POPUP,                        // 窗口樣式0, 0, 800, 100,                  // 窗口尺寸hwnd, nullptr, hInstance, nullptr);if (infoHwnd == nullptr) {return 0;}SetLayeredWindowAttributes(infoHwnd, RGB(0,0,0), 0, LWA_COLORKEY);// 初始化信息窗口的位置RECT rc;GetWindowRect(hwnd, &rc);SetWindowPos(infoHwnd, nullptr, rc.left + 10, rc.bottom, 0, 0,SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);}case WM_ACTIVATE: {// 查找第一個可見且尺寸不小于最小尺寸的后臺窗口HWND hwndBehind = GetWindow(hwnd, GW_HWNDNEXT);while (hwndBehind) {if (IsWindowVisible(hwndBehind)&& IsUWPWindowVisible(hwndBehind)&& !IsBadWindow(hwndBehind)) {RECT rcBehind;GetWindowRect(hwndBehind, &rcBehind);int width = rcBehind.right - rcBehind.left;int height = rcBehind.bottom - rcBehind.top;if (width >= MIN_WIDTH && height >= MIN_HEIGHT) {break;}}hwndBehind = GetWindow(hwndBehind, GW_HWNDNEXT);}if (oldBehindWnd != hwndBehind) {// 注銷當前縮略圖if (thumbnail) {DwmUnregisterThumbnail(thumbnail);thumbnail = NULL;}if (hwndBehind) {oldBehindWnd = hwndBehind;// 注冊后臺窗口的縮略圖DwmRegisterThumbnail(hwnd, hwndBehind, &thumbnail);RECT rcBehindWnd;GetWindowRect(hwndBehind, &rcBehindWnd);SetWindowPos(hwnd, nullptr,0, 0,rcBehindWnd.right - rcBehindWnd.left,rcBehindWnd.bottom - rcBehindWnd.top + 50,SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW);// 更新縮略圖屬性RECT rcClient;GetClientRect(hwnd, &rcClient);DWM_THUMBNAIL_PROPERTIES dpt;dpt.dwFlags = DWM_TNP_RECTDESTINATION | DWM_TNP_OPACITY;dpt.rcDestination = rcClient;dpt.opacity = (BYTE)(255 * 0.7);  // 設置透明度為70%DwmUpdateThumbnailProperties(thumbnail, &dpt);// 設置子窗口的用戶數據為目標窗口句柄SetWindowLongPtrW(infoHwnd, GWLP_USERDATA, (LONG_PTR)hwndBehind);InvalidateRect(infoHwnd, NULL, TRUE);  // 重新繪制子窗口}else {// 設置子窗口的用戶數據為目標窗口句柄SetWindowLongPtrW(infoHwnd, GWLP_USERDATA, (LONG_PTR)NULL);MessageBoxW(NULL,L"沒有找到合適窗口", L"提示",MB_OK | MB_ICONINFORMATION |MB_APPLMODAL | MB_TOPMOST);}}return 0;}case WM_DESTROY:if (thumbnail) {DwmUnregisterThumbnail(thumbnail);}PostQuitMessage(0);return 0;case WM_SIZE: {if (thumbnail) {RECT rcClient;GetClientRect(hwnd, &rcClient);// 窗口大小改變時重新擴展DWM框架到客戶區MARGINS margins = { 0, 0, 0, rcClient.bottom - rcClient.top };DwmExtendFrameIntoClientArea(hwnd, &margins);// 更新縮略圖屬性DWM_THUMBNAIL_PROPERTIES dpt;dpt.dwFlags = DWM_TNP_RECTDESTINATION | DWM_TNP_OPACITY;dpt.rcDestination = rcClient;dpt.opacity = (BYTE)(255 * 0.7);  // 設置透明度為70%DwmUpdateThumbnailProperties(thumbnail, &dpt);}// 更新信息窗口的位置UpdateInfoWindow(infoHwnd, hwnd);return 0;}case WM_MOVE: {// 更新信息窗口的位置UpdateInfoWindow(infoHwnd, hwnd);return 0;}case WM_PAINT: {PAINTSTRUCT ps;HDC hdc = BeginPaint(hwnd, &ps);RECT rc;GetClientRect(hwnd, &rc);// 繪制半透明背景HBRUSH hBrush = CreateSolidBrush(RGB(255, 255, 255));SetBkMode(hdc, TRANSPARENT);FillRect(hdc, &rc, hBrush);DeleteObject(hBrush);EndPaint(hwnd, &ps);return 0;}default:return DefWindowProcW(hwnd, uMsg, wParam, lParam);}return 0;
}int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow) {// 注冊窗口類const wchar_t CLASS_NAME[] = L"TransparentWindowClass";WNDCLASS wc = {};wc.lpfnWndProc = WindowProc;wc.hInstance = hInstance;wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);  // 防止背景重繪wc.lpszClassName = CLASS_NAME;RegisterClassW(&wc);// 創建窗口HWND hwnd = CreateWindowExW(WS_EX_NOREDIRECTIONBITMAP,  // 擴展窗口樣式CLASS_NAME,                 // 窗口類名L"Transparent Window",      // 窗口標題WS_OVERLAPPEDWINDOW,        // 窗口樣式CW_USEDEFAULT, CW_USEDEFAULT, 1000, 600,nullptr, nullptr, hInstance, nullptr);if (hwnd == nullptr) {return 0;}// 使用 DWM API 設置毛玻璃效果DWM_BLURBEHIND bb = { 0 };bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;bb.fEnable = TRUE;bb.hRgnBlur = NULL;DwmEnableBlurBehindWindow(hwnd, &bb);// 設置標題欄顏色為深色(示例為灰色)COLORREF grey = RGB(30, 30, 30);DwmSetWindowAttribute(hwnd, DWMWA_CAPTION_COLOR, &grey, sizeof(grey));// 顯示窗口ShowWindow(hwnd, nCmdShow);UpdateWindow(hwnd);// 消息循環MSG msg = {};while (GetMessageW(&msg, nullptr, 0, 0)) {TranslateMessage(&msg);DispatchMessageW(&msg);}return 0;
}

效果圖:

窗口縮略圖實現背景墻(自動識別窗口切換)

窗口切換和大小跟隨:?

演示截圖 2

· 2. 更多代碼......

(...)


本文發布于:2024.07.08

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/41952.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41952.shtml
英文地址,請注明出處:http://en.pswp.cn/web/41952.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【c語言】玩轉文件操作

&#x1f31f;&#x1f31f;作者主頁&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所屬專欄&#xff1a;C語言 目錄 引言 一、文件的打開和關閉 1.流 2.標準流 3.文本文件和二進制文件 4.控制文件打開與關閉的函數 二、文件的順序讀寫 三、文件的隨機讀寫 1…

深入理解OAuth 2.0:原理、流程與實踐

一、什么是OAuth 2.0 1. 什么是OAuth 2.0 OAuth 2.0 是一套關于授權的行業標準協議。 OAuth 2.0 允許用戶授權第三方應用訪問他們在另一個服務提供方上的數據&#xff0c;而無需分享他們的憑據&#xff08;如用戶名、密碼&#xff09;。 2. OAuth 2.0 應用場景 OAuth 2.0的…

非參數檢測6——優缺點

優點&#xff1a; 參量檢測的特點在于以似然比處理器為基礎&#xff0c;并建立在假定干擾或噪聲的統計特性已知的基礎上。但實際上&#xff0c;干擾環境往往十分復雜&#xff0c;包括自然和人為因素&#xff0c;且常常隨時改變。這使我們很難確定噪聲的統計特性。因此人們提出…

服務器U盤安裝Centos 7時提示Warning:/dev/root does not exist

這是沒有找到正確的鏡像路徑導致的&#xff0c;我們可以在命令行輸入ls /dev看一下有哪些盤符 像圖中紅色圈起來的就是我插入U盤的盤符&#xff0c;大家的輸幾盤可能做了多個邏輯盤&#xff0c;這種情況下就可以先將U盤拔掉再ls /dev看一下和剛才相比少了那兩個盤符&#xff0c…

在Spring Boot中實現多線程任務調度

在Spring Boot中實現多線程任務調度 大家好&#xff0c;我是微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 1. Spring Boot中的任務調度 Spring Boot通過集成Spring框架的Task Execution和Scheduling支持&#xff0c;提供…

Double 4 VR仿真情景實訓教學系統在法律專業課堂上的應用

隨著科技的飛速發展&#xff0c;VR技術逐漸滲透到各個領域&#xff0c;為教育行業帶來了革命性的變化。 VR技術以其獨特的沉浸式體驗&#xff0c;為法律課堂帶來了前所未有的學習體驗。通過Double 4 VR仿真情景實訓教學系統&#xff0c;學生可以身臨其境地進入虛擬的仿真情景中…

vue前端面試

一 .v-if和v-show的區別 v-if 和 v-show 是 Vue.js 中兩個常用的條件渲染指令&#xff0c;它們都可以根據條件決定是否渲染某個元素。但是它們之間存在一些區別。 語法&#xff1a;v-if 和 v-show 的語法相同&#xff0c;都接收一個布爾值作為參數。 <div v-if"show…

權力之望怎么下載客戶端 權力之望一鍵下載

《權力之望》是一款由NX3 Games開發、Smilegate發行的多人在線動作MMORPG游戲。這款游戲最大的特點是高度的自由度和豐富的角色定制選項。我們在游戲中不僅可以自由更換武器&#xff0c;而且游戲還提供了54種能力和60多種職業選擇&#xff0c;讓我們可以根據自己的游戲風格和喜…

繼 承

為什么要有繼承&#xff0c;繼承的作用&#xff1f; 繼承(inheritance)機制&#xff1a;是面向對象程序設計使代碼可以復用的最重要的手段&#xff0c;它允許程序員在保持原有類特性的基礎上進行擴展&#xff0c;增加新功能&#xff0c;這樣產生新的類&#xff0c;稱派生類。 …

【人工智能】—基于成都市各區(市)縣租房價格預測建模研究

引言 隨著城市化進程的加速&#xff0c;人口流動日益頻繁&#xff0c;租房市場作為城市生活的重要組成部分&#xff0c;其價格波動對居民生活質量和城市經濟發展具有顯著影響。成都市&#xff0c;作為中國西部地區的經濟、文化、交通和科技中心&#xff0c;近年來吸引了大量人…

為什么獨立站需要高質量的GPB外鏈?

獨立站需要高質量的GPB外鏈&#xff0c;主要是因為它們能顯著提升網站的可信度和可見性。高質量的外鏈相當于得到其他權威網站的認可和推薦&#xff0c;這會讓搜索引擎認為你的內容有價值&#xff0c;從而提升你的搜索排名。試想一下&#xff0c;當其他有影響力的網站愿意鏈接到…

非阻塞式 I/O 模型 【NIO】補充內容

NIO是一種同步非阻塞IO, 基于Reactor模型來實現的。其實相當于就是一個線程處理大量的客戶端的請求&#xff0c;通過一個線程輪詢大量的channel&#xff0c;每次就獲取一批有事件的channel&#xff0c;然后對每個請求啟動一個線程處理即可。這里的核心就是非阻塞&#xff0c;就…

請求接口在控制臺報cors跨域問題

我的問題是&#xff1a;BASE_URL沒有和本地IP設置一致 剛開始&#xff1a;&#xff08;這個不是我本地電腦的地址&#xff09; 所以我要把&#xff1a;這個地址改為我本地電腦的ip&#xff08;http://192.168.2.50:8087&#xff09; BASE_URL: http://localhost:8087/api/ 或…

單位電腦文檔怎么加密?哪種方法最有效?

單位電腦文檔的加密是保障信息安全的重要措施之一&#xff0c;它可以防止未經授權的訪問和數據泄露。 選擇最佳的加密方法取決于您的具體需求&#xff0c;包括文檔的敏感程度、加密的便捷性、成本、以及是否需要跨平臺兼容性。下面是幾種常見的加密方法及其優缺點&#xff0c;…

【SpringBoot3】結合 gRpc 實現遠程服務調用

一、gRPC概念介紹 gRPC&#xff08;Google Remote Procedure Call&#xff0c;Google遠程過程調用&#xff09;是一個現代開源高性能遠程過程調用(RPC)框架&#xff0c;可以在任何環境中運行。它由Google開發&#xff0c;旨在幫助開發人員更輕松地構建分布式應用&#xff0c;特…

昇思學習打卡-8-FCN圖像語義分割

目錄 FCN介紹FCN所用的技術訓練數據的可視化模型訓練模型推理FCN的優點和不足優點不足 FCN介紹 FCN主要用于圖像分割領域&#xff0c;是一種端到端的分割方法&#xff0c;是深度學習應用在圖像語義分割的開山之作。通過進行像素級的預測直接得出與原圖大小相等的label map。因…

clean code-代碼整潔之道 閱讀筆記(第十六章)

第十六章 重構SerialDate 16.1 首先&#xff0c;讓它能工作 利用SerialDateTests來完整的理解和重構SerialDate用Clover來檢查單元測試覆蓋了哪些代碼&#xff0c;效果不行重新編寫自己的單元測試經過簡單的修改&#xff0c;讓測試能夠通過 16.2 讓它做對 全過程&#xff1…

若依微服務初始化搭建教程

文章目錄 &#x1f95d;從Gitee拉取代碼&#x1f344;初始化項目配置配置項目maven配置項目JDKmaven - clean - install &#x1f352;數據源配置創建config / seata數據庫創建ry-cloud數據源導入ry-cloud數據 &#x1f370;啟動Nacos下載Nacos修改Nacos配置雙擊startup.cmd啟動…

梧桐數據庫:查詢優化器是提升數據庫性能的關鍵技術

查詢優化器是數據庫管理系統中的核心組件之一&#xff0c;它的主要作用是在執行查詢語句之前&#xff0c;選擇最優的執行計劃&#xff0c;以提高查詢性能。 查詢優化器的基本原理 查詢優化器的主要目標是找到一個執行代價最小的查詢執行計劃。它通過對查詢語句進行語法分析、…

GraphRAG:AI的全局文本理解革新

前言 在人工智能領域&#xff0c;處理和理解大量文本數據始終是一個挑戰。隨著大型語言模型&#xff08;LLMs&#xff09;的出現&#xff0c;自動化地進行復雜的語義理解和文本摘要變得可能。檢索增強生成&#xff08;RAG&#xff09;方法因其能有效結合檢索與生成技術&#x…