效果图:

其实实现方法非常简单,只需要两个窗口,一个负责主窗口另外一个负责透明即可:

首先依旧创建一个Win32工程:

#include "stdafx.h"
#include <windows.h>HWND hWnd;    //progman//消息函数
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{//判断消息IDswitch (uMsg){case WM_DESTROY:    // 窗口销毁消息PostQuitMessage(0);   //  发送退出消息return 0;}// 其他的消息调用缺省的消息处理程序return DefWindowProc(hwnd, uMsg, wParam, lParam);}
// 3、注册窗口类型
BOOL RegisterWindow(LPCSTR lpcWndName, HINSTANCE hInstance)
{ATOM nAtom = 0;// 构造创建窗口参数WNDCLASS wndClass = { 0 };wndClass.style = CS_HREDRAW | CS_VREDRAW;wndClass.lpfnWndProc = WindowProc;      // 指向窗口过程函数wndClass.cbClsExtra = 0;wndClass.cbWndExtra = 0;wndClass.hInstance = hInstance;wndClass.hIcon = NULL;wndClass.hCursor = NULL;wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);wndClass.lpszMenuName = NULL;wndClass.lpszClassName = lpcWndName;    // 注册的窗口名称,并非标题,以后创建窗口根据此注册的名称创建nAtom = RegisterClass(&wndClass);return TRUE;
}
//创建窗口(lpClassName 一定是已经注册过的窗口类型)
HWND CreateMyWindow(LPCTSTR lpClassName, HINSTANCE hInstance)
{HWND hWnd = NULL;// 创建窗口hWnd = CreateWindow(lpClassName, "test", WS_OVERLAPPEDWINDOW^WS_THICKFRAME, 0, 0, 1000, 800, NULL, NULL, hInstance, NULL);return hWnd;
}
//显示窗口
void DisplayMyWnd(HWND hWnd)
{//获得屏幕尺寸int scrWidth = GetSystemMetrics(SM_CXSCREEN);int scrHeight = GetSystemMetrics(SM_CYSCREEN);RECT rect;GetWindowRect(hWnd, &rect);ShowWindow(hWnd, SW_SHOW);//重新设置rect里的值rect.left = (scrWidth - rect.right) / 2;rect.top = (scrHeight - rect.bottom) / 2;//移动窗口到指定的位置SetWindowPos(hWnd, HWND_TOP, rect.left, rect.top, rect.right, rect.bottom, SWP_SHOWWINDOW);UpdateWindow(hWnd);
}void doMessage()        // 消息循环处理函数
{MSG msg = { 0 };// 获取消息while (GetMessage(&msg, NULL, 0, 0)) // 当接收到WM_QIUT消息时,GetMessage函数返回0,结束循环{DispatchMessage(&msg); // 派发消息,到WindowPro函数处理}
}// 入口函数
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{LPCTSTR lpClassName = "MyWnd";  // 注册窗口的名称RegisterWindow(lpClassName, hInstance);hWnd = CreateMyWindow(lpClassName, hInstance);DisplayMyWnd(hWnd);doMessage();return 0;
}

在主窗口消息循环里添加绘图消息绘制背景图:

case WM_PAINT:PAINTSTRUCT ps;HDC hdc;HBITMAP hbmp;// 位图绘制对象句柄,模糊图像HDC mdc;hdc = BeginPaint(hwnd, &ps);mdc = CreateCompatibleDC(hdc); // 创建兼容的缓存DC对象//加载位图hbmp = (HBITMAP)LoadImage(NULL, // 模块实例句柄"C:\\Users\\ZZH\\Desktop\\D.bmp", // 位图路径。注意双斜杠,单斜杠表示转义,此时文件会加载不成功!!!IMAGE_BITMAP, // 图片类型1000,800,LR_LOADFROMFILE // 从路径处加载图片);// 缓存DC(mdc)选择位图绘制对象(可以理解为将图片保存到mdc中)SelectObject(mdc, hbmp);BitBlt(hdc, // 目的DC0, 0,1000, // 目的DC的 x,y 坐标800,mdc, // 缓存DC0, 0, // 缓存DC的x,y坐标SRCCOPY // 粘贴方式);DeleteObject(hbmp);DeleteDC(mdc);EndPaint(hwnd, &ps);break;

在Main函数里创建一个透明窗口,并在上面添加edit控件:

在此之前添加一个全局的句柄变量用于保存透明窗口的HWND方便移动:

HWND M_hwnd;
//CREATEGetClientRect(hWnd, &rect);  //对于客户区左上角为0PO.x = rect.left;      //0PO.y = rect.top;        //0//屏幕坐标转换,转换前需要给PO结构体赋予客户区坐标,也就是给PO结构体赋予初始值Windows才能转换ClientToScreen(hWnd, &PO);M_hwnd = CreateWindowEx(WS_EX_LAYERED, lpClassName, NULL, WS_POPUP, PO.x + 10, PO.y + 10, 33, 22, hWnd, NULL, GetModuleHandle(NULL), NULL);  //坐标是左上角坐标所以我们要+偏移量得到对应的客户区坐标//透明化SetLayeredWindowAttributes(M_hwnd, RGB(0, 0, 0), 155, LWA_ALPHA);//创建控件Edit = CreateWindow(   //edit控件"edit","SS",WS_VISIBLE | WS_CHILD | WS_BORDER/*|DT_CENTER*/ | DT_VCENTER,0, 0, 33, 22,M_hwnd,NULL,NULL,NULL);//SHOWShowWindow(M_hwnd, SW_SHOW);

在主窗口的消息循环函数里修改MOVE消息:

case WM_MOVE:RECT rect; //RECTPOINT PO;  //屏幕坐标//获取窗口的客户区坐标GetClientRect(hWnd, &rect);   //对于客户区左上角为0PO.x = rect.left;      //0PO.y = rect.top;        //0//屏幕坐标转换,转换前需要给PO结构体赋予客户区坐标,也就是给PO结构体赋予初始值Windows才能转换ClientToScreen(hWnd, &PO);MoveWindow(M_hwnd, PO.x + 10, PO.y + 10, 33, 22, TRUE);break;

运行效果:

完整代码:

#include "stdafx.h"
#include <windows.h>HWND hWnd;    //progman
HWND M_hwnd;
//消息函数
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{//判断消息IDswitch (uMsg){case WM_PAINT:PAINTSTRUCT ps;HDC hdc;HBITMAP hbmp;// 位图绘制对象句柄,模糊图像HDC mdc;hdc = BeginPaint(hwnd, &ps);mdc = CreateCompatibleDC(hdc); // 创建兼容的缓存DC对象//加载位图hbmp = (HBITMAP)LoadImage(NULL, // 模块实例句柄"C:\\Users\\ZZH\\Desktop\\D.bmp", // 位图路径。注意双斜杠,单斜杠表示转义,此时文件会加载不成功!!!IMAGE_BITMAP, // 图片类型1000,800,LR_LOADFROMFILE // 从路径处加载图片);// 缓存DC(mdc)选择位图绘制对象(可以理解为将图片保存到mdc中)SelectObject(mdc, hbmp);BitBlt(hdc, // 目的DC0, 0,1000, // 目的DC的 x,y 坐标800,mdc, // 缓存DC0, 0, // 缓存DC的x,y坐标SRCCOPY // 粘贴方式);DeleteObject(hbmp);DeleteDC(mdc);EndPaint(hwnd, &ps);break;case WM_MOVE:RECT rect; //RECTPOINT PO;  //屏幕坐标//获取窗口的客户区坐标GetClientRect(hWnd, &rect);   //对于客户区左上角为0PO.x = rect.left;      //0PO.y = rect.top;        //0//屏幕坐标转换,转换前需要给PO结构体赋予客户区坐标,也就是给PO结构体赋予初始值Windows才能转换ClientToScreen(hWnd, &PO);MoveWindow(M_hwnd, PO.x + 10, PO.y + 10, 33, 22, TRUE);break;case WM_DESTROY:    // 窗口销毁消息PostQuitMessage(0);   //  发送退出消息return 0;}// 其他的消息调用缺省的消息处理程序return DefWindowProc(hwnd, uMsg, wParam, lParam);}
// 3、注册窗口类型
BOOL RegisterWindow(LPCSTR lpcWndName, HINSTANCE hInstance)
{ATOM nAtom = 0;// 构造创建窗口参数WNDCLASS wndClass = { 0 };wndClass.style = CS_HREDRAW | CS_VREDRAW;wndClass.lpfnWndProc = WindowProc;      // 指向窗口过程函数wndClass.cbClsExtra = 0;wndClass.cbWndExtra = 0;wndClass.hInstance = hInstance;wndClass.hIcon = NULL;wndClass.hCursor = NULL;wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);wndClass.lpszMenuName = NULL;wndClass.lpszClassName = lpcWndName;    // 注册的窗口名称,并非标题,以后创建窗口根据此注册的名称创建nAtom = RegisterClass(&wndClass);return TRUE;
}
//创建窗口(lpClassName 一定是已经注册过的窗口类型)
HWND CreateMyWindow(LPCTSTR lpClassName, HINSTANCE hInstance)
{HWND hWnd = NULL;// 创建窗口hWnd = CreateWindow(lpClassName, "test", WS_OVERLAPPEDWINDOW^WS_THICKFRAME, 0, 0, 1000, 800, NULL, NULL, hInstance, NULL);return hWnd;
}
//显示窗口
void DisplayMyWnd(HWND hWnd)
{//获得屏幕尺寸int scrWidth = GetSystemMetrics(SM_CXSCREEN);int scrHeight = GetSystemMetrics(SM_CYSCREEN);RECT rect;GetWindowRect(hWnd, &rect);ShowWindow(hWnd, SW_SHOW);//重新设置rect里的值rect.left = (scrWidth - rect.right) / 2;rect.top = (scrHeight - rect.bottom) / 2;//移动窗口到指定的位置SetWindowPos(hWnd, HWND_TOP, rect.left, rect.top, rect.right, rect.bottom, SWP_SHOWWINDOW);UpdateWindow(hWnd);
}void doMessage()        // 消息循环处理函数
{MSG msg = { 0 };// 获取消息while (GetMessage(&msg, NULL, 0, 0)) // 当接收到WM_QIUT消息时,GetMessage函数返回0,结束循环{DispatchMessage(&msg); // 派发消息,到WindowPro函数处理}
}// 入口函数
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{LPCTSTR lpClassName = "MyWnd";  // 注册窗口的名称RegisterWindow(lpClassName, hInstance);hWnd = CreateMyWindow(lpClassName, hInstance);HWND Edit;  //EDITRECT rect; //RECTPOINT PO;    //屏幕坐标//创建具有扩展风格的窗口//获取窗口的客户区坐标DisplayMyWnd(hWnd);//CREATEGetClientRect(hWnd, &rect);   //对于客户区左上角为0PO.x = rect.left;      //0PO.y = rect.top;        //0//屏幕坐标转换,转换前需要给PO结构体赋予客户区坐标,也就是给PO结构体赋予初始值Windows才能转换ClientToScreen(hWnd, &PO);M_hwnd = CreateWindowEx(WS_EX_LAYERED, lpClassName, NULL, WS_POPUP, PO.x + 10, PO.y + 10, 33, 22, hWnd, NULL, GetModuleHandle(NULL), NULL);  //坐标是左上角坐标所以我们要+偏移量得到对应的客户区坐标//透明化SetLayeredWindowAttributes(M_hwnd, RGB(0, 0, 0), 155, LWA_ALPHA);//创建控件Edit = CreateWindow(   //edit控件"edit","SS",WS_VISIBLE | WS_CHILD | WS_BORDER/*|DT_CENTER*/ | DT_VCENTER,0, 0, 33, 22,M_hwnd,NULL,NULL,NULL);//SHOWShowWindow(M_hwnd, SW_SHOW);doMessage();return 0;
}

Windows核心编程_组件透明相关推荐

  1. Windows核心编程_窗口透明组件不透明

    经过前几篇对界面编程的学习,已经对Windows窗口消息有了更加深刻的理解,今天就教大家写一个窗口透明而组件却不透明的小示列! 这个demo并不难,而且还非常的简单,如果你看过我的前几篇针对界面编程写 ...

  2. Windows核心编程_设置Windows开机自动登录

    设置自动登录的方法在Windows中已经给出了非常方便的方法,当Windows内核进入登入界面时会检查HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ ...

  3. Windows核心编程_获取鼠标指定位置的RGB颜色值

    Windows核心编程_获取鼠标指定位置的RGB颜色值 大家平常会见到很多屏幕取色工具,其原理都是获取鼠标位置的屏幕像素点颜色! 一般思路都是:获取鼠标位置,然后取出鼠标指向的屏幕像素点颜色! Get ...

  4. Windows核心编程_提权

    在Windows下编程有些涉及到硬件或者跨内存的API会发现失效了,原因是因为权限问题,这也是Windows出于安全的保护,但是事物都有两面性的,Windows又为我们提供了提权的API! 1.Adj ...

  5. Windows核心编程_将窗口嵌入到桌面图标下面不被遮挡 spy 分析过程

    近年很流行动态视频桌面,实则上早期的windows vista系统上有一个Windows DreamScene软件将桌面壁纸设置成视频,但是是收费的! 首先先来观察一下Windows桌面的组成单元: ...

  6. Windows核心编程_判断是否管理员权限运行

    在Windows安全性越来越强的情况下,不常于XP时代,几乎毫无安全可言,各种对内核文件操控的rin3API不需要权限就可以运行和随意修改,如常见的注册表需改! 但是Win8以后安全性得到了强力的提升 ...

  7. Windows核心编程_让窗口跟随系统样式变化

    当我们使用 VS 编写win32程序时,窗口会有点丑,这个是因为GDI库,Windows有自己的UI库代码,但是版本很多,不同内核版本使用的GUI库不一样,一般vs在编译win32程序时会给你加载一个 ...

  8. Windows核心编程_异型窗口(续)

    上一篇文章介绍的是使用SetLayeredWindowAttributes API来实现异型窗口,但是很明显效果很差劲,在剔除颜色的过程中凹凸边缘区域的像素点会剔除的非常不明显,在查找信息之后,得出的 ...

  9. Windows核心编程_关闭Windows

    下面介绍几种在Windows编程中关闭Windows的几种方式 首先介绍一个API ExitWindowsEx 这个API是WIndows下为开发人员提供的对操作系统睡眠的几种方式 API介绍: 函数 ...

最新文章

  1. 转帖:HttpStatusCode状态说明C#版
  2. pygame系列_mouse鼠标事件
  3. iNeuOS工业互联网操作系统,矿山动态产量计量系统和铁路车辆识别系统应用场景案例...
  4. 博时基金基于 RocketMQ 的互联网开放平台 Matrix 架构实践
  5. 超级玛丽游戏 C++简单实现
  6. 关于在vSphere环境中,安装WindowsServer2008_R2_x64系统,分区格式为GPT,隐藏分区为200M方法心得
  7. SQL Server游标+延迟执行简介
  8. Build desktop apps for Windows PCs
  9. 什么时候不选择mysql_MySQL请选择合适的列_MySQL
  10. java 对象嵌套_java如何把嵌套的对象装入集合?
  11. Unity通过压缩字体减小包体大小
  12. 中医经典《伤寒论》-原文
  13. ucdavis计算机科学专业,加州大学戴维斯分校有哪些专业处于世界顶尖水平?
  14. 基于STM32单片机的智能药盒带语音播报原理图程序
  15. 7分钟学会HTML网页制作
  16. 如何将本地代码保存至码云中
  17. 碎片化时间学习,这几个在线视频学习网站值得拥有!
  18. vim 基本够用的操作命令
  19. ppt护理文书流程图_病案管理试题及答案
  20. 微信公众平台模拟登陆和发送消息详解

热门文章

  1. abb变频器acs880说明书_ABB变频器ACS880-104/ACS880-204/ACS880-304产品参数及功能介绍
  2. python模型预测结果 取整_一日一技:Python里面的//并不是做了除法以后取整
  3. vue3.0 vuex 全局变量 存储更改
  4. git学习(四)比较文件差异diff
  5. c语言输入的成绩由高到低该怎么,c语言编程:输入学生信息(姓名年龄分数)并按照分数由高到低输出...
  6. vivado ip xdc 和user xdc 编译顺序
  7. Tcl Tutorial 笔记8 · proc
  8. three几何线在mapbox地图显示
  9. pythontuple数据类型_Python数据类型之Tuple元组实例详解
  10. oracle静态,oracle静态sql和动态sql