win32-创建透明的图片按钮
// Test_CustomButton.cpp : Defines the entry point for the application.
// #include "framework.h"
#include "Test_CustomButton.h"
#include <commctrl.h>
#include <system_error> #pragma comment (lib,"Comctl32.lib") #define MAX_LOADSTRING 100
#define IDC_OWNERDRAWBUTTON 101
#define CRAPPY 567 // Global Variables:
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK OwnerDrawButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData); void SetLayeredWindowFromBitmapResource(
HWND hwnd, UINT bitmapResourceId, HINSTANCE hInstance = nullptr)
{
DWORD exStyle = ::GetWindowLong(hwnd, GWL_EXSTYLE); SetWindowLong(hwnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED); struct Resources {
HBITMAP hImage = nullptr;
HGDIOBJ hOldImage = nullptr;
HDC hMemDC = nullptr;
~Resources()
{
if (hMemDC)
{
if (hOldImage)
::SelectObject(hMemDC, hOldImage);
::DeleteDC(hMemDC);
}
if (hImage)
::DeleteObject(hImage);
}
} res; if (!hInstance)
hInstance = ::GetModuleHandle(nullptr); res.hImage = reinterpret_cast<HBITMAP>(::LoadImage(
hInstance, MAKEINTRESOURCE(bitmapResourceId), IMAGE_BITMAP,
0, 0, LR_CREATEDIBSECTION)); BITMAP imgInfo{ 0 };
GetObject(res.hImage, sizeof(imgInfo), &imgInfo); res.hMemDC = ::CreateCompatibleDC(nullptr);
res.hOldImage = ::SelectObject(res.hMemDC, res.hImage); // Assign the image to the child window, making it transparent.
SIZE size{ imgInfo.bmWidth, imgInfo.bmHeight };
POINT ptSrc{ 0, 0 };
BLENDFUNCTION blend{ AC_SRC_OVER, 0, 200, AC_SRC_ALPHA };
UpdateLayeredWindow(hwnd, nullptr, nullptr, &size, res.hMemDC, &ptSrc,
0, &blend, ULW_ALPHA); // Destructor of res object will cleanup resources here!
} int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine); LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_TESTCUSTOMBUTTON, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance); if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
} HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTCUSTOMBUTTON)); MSG msg; while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} return (int) msg.wParam;
} 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_TESTCUSTOMBUTTON));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_TESTCUSTOMBUTTON);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&wcex);
} BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd); if (!hWnd)
{
return FALSE;
} ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd); return TRUE;
} LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ switch (message)
{
case WM_CREATE:
{
HWND hButton = CreateWindowEx(0, L"button", NULL, WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, 150, 50, 80, 80, hWnd, (HMENU)IDC_OWNERDRAWBUTTON, hInst, NULL);
SetWindowSubclass(hButton, &OwnerDrawButtonProc, IDC_OWNERDRAWBUTTON, 0);
}
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// Used be test
HPEN hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
SelectObject(hdc, hPen);
MoveToEx(hdc, 150, 150, NULL);
LineTo(hdc, 200, 60);
LineTo(hdc, 250, 150);
LineTo(hdc, 150, 150);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
} // Message handler for about box.
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;
} LRESULT CALLBACK OwnerDrawButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
case WM_PAINT:
{
RECT rc;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
SetLayeredWindowFromBitmapResource(hWnd, IDB_BITMAP1);
EndPaint(hWnd, &ps);
return 0;
}
case WM_NCDESTROY:
RemoveWindowSubclass(hWnd, &OwnerDrawButtonProc, 1);
break;
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
注意:
在测试时,我发现需要满足以下条件:
要加载的图像必须是32 bpp的,具有预乘alpha通道的自上而下的位图(可以使用PixelFormer工具转换)。
在PixelFormer中,依次转到“文件”,“导入”并选择您的文件(在我的情况下为透明png圆圈)。接下来转到“导出”,然后选择bmp位图(它将显示Windows位图)。完成此操作后,将已经选择了A8:R8:G8:B8(32bpp),接下来必须选中最后两个框“预乘Alpha”和 “自上而下的行顺序”。
这是我的32 bpp图像供您测试。
需要添加一个清单文件,您可以自己创建一个.manifest文件。然后将其添加到编译器中。
因为从win 8开始,WS_EX_LAYERED可用于子控件。
方法:需要清单文件来指定至少Windows 8兼容性(仅Windows 8支持子层)。
您只需要将
WS_EX_LAYERED样式添加到子控件中,因为您的要求是使按钮透明。
清单文件代码:
<!-- example.exe.manifest -->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<assemblyIdentity
type="win32"
name="Contoso.ExampleApplication.ExampleBinary"
version="1.2.3.4"
processorArchitecture="x86"
/>
<description>Contoso Example Application</description>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<!--
UAC settings:
- app should run at same integrity level as calling process
- app does not need to manipulate windows belonging to
higher-integrity-level processes
-->
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"
/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
最后的效果:

win32-创建透明的图片按钮的更多相关文章
- NSIS:简单按钮美化插件SkinButton,支持透明PNG图片。
原文 NSIS:简单按钮美化插件SkinButton,支持透明PNG图片. 征得作者贾可的同意,特发布按钮美化插件SkinButton. 插件说明: 使用GDI+库写的一个简单按钮美化插件,支持透明P ...
- Expression Blend4经验分享:制作一个简单的图片按钮样式
这次分享如何做一个简单的图片按钮经验 在我的个人Silverlight网页上,有个Iphone手机的效果,其中用到大量的图片按钮 http://raimon.6.gwidc.com/Iphone/de ...
- xcode UIButton创建、监听按钮点击、自定义按钮 、状态 、内边距
代码创建 //创建UIButton UIButton * btnType=[[UIButton alloc]init]; //设置UIControlStateNormal状态下的文字颜色 [btnTy ...
- Unity 游戏开发技巧集锦之创建透明的材质
Unity 游戏开发技巧集锦之创建透明的材质 Unity创建透明的材质 生活中不乏透明或者半透明的事物.例如,擦的十分干净的玻璃,看起来就是透明的:一些塑料卡片,看起来就是半透明的,如图3-23所示. ...
- 网页中PNG透明背景图片的完美应用
PNG 图片在网站设计中是不可或缺的部分,最大的特点应该在于 PNG 可以无损压缩,而且还可以设置透明,对于增强网站的图片色彩效果有重要的作用. 但为什么 PNG 图片却没有 GIF 和 JPG 图片 ...
- [Xcode 实际操作]四、常用控件-(2)UIButton图片按钮的使用
目录:[Swift]Xcode实际操作 本文将演示图片按钮的使用 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit class ViewCo ...
- Qt 制作透明背景图片与裁剪图片(很实用)
这两天想做一个五子棋游戏,想从零开始自己绘制各种图片素材,将经验心得整理如下. 制作透明背景图片: void MyPainter::DrawKit() { QImage image(30, 30, Q ...
- C# 使用PictureBox实现图片按钮控件
引言 我们有时候会在程序的文件夹里看见一些图标,而这些图标恰好是作为按钮的背景图片来使用的.鼠标指针在处于不同状态时,有"进入按钮"."按下左键"," ...
- 利用box-shadow实现伪边框透明到图片
前阵子突然看到了一个效果,一张图片,有一个边框,但是边框可以透明到图片.直接上图 贴代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tr ...
- [示例] Firemonkey 图片按钮(3态)
说明:Firemonkey 图片按钮(支持三种状态:MouseOver, MouseDown, MouseUp,可各别指定图片) 原码下载:[示例]TestImageButton_圖片按鈕(3态).z ...
随机推荐
- [转帖]ssh_exporter
https://github.com/treydock/ssh_exporter SSH exporter The SSH exporter attempts to make an SSH conne ...
- [转帖]一次ORA-3136的处理
https://oracleblog.org/working-case/deal-with-ora3136/ 最近收到一个告警,用户说数据库无法连接,但是从监控上看,oracle的后台进程已经侦听进程 ...
- [转帖]linux系统主机双网卡实现路由转发问题与解决
1. 环境 拓扑: 网卡配置: host1: 192.168.1.1/24 host2: 左eth0: 192.168.1.2/24 右eth1: 192.168.2.2/24 host3: 192. ...
- [转帖]TiKV Config Learn the TiKV configuration file
The TiKV configuration file supports more options than command-line parameters. You can find the def ...
- [转帖]Elasticsearch-sql 用SQL查询Elasticsearch
https://www.cnblogs.com/kangoroo/p/7273493.html https://www.cnblogs.com/kangoroo/p/7273493.html Elas ...
- [转帖][问题已处理]-kubernetes中2次不同的oom处理
https://dandelioncloud.cn/article/details/1598699030236577793 起因: 同事反馈 服务挂了,kuboard上查看是服务挂掉了,livenes ...
- DashBoard in k8s 简单使用
DashBoard in k8s 简单使用 第一部分 拉取分发镜像 没办法的事情,公司网络实在是太垃圾了, dockerhub 又不让多次docker pull 找一台网络表好的机器 执行如下命令: ...
- 京东哥伦布即时设计平台ChatGPT落地实践
一.平台介绍 即时设计平台是一个即时搭建c端楼层的开发平台,支持通过导入relay设计稿url完成Ui2Code,在此基础上完成前端可视化搭建,同时支持通过ChatGPT完成一句话需求,搭建后的楼层自 ...
- 【构造,树】【Loj】Loj6669 Nauuo and Binary Tree
2023.7.3 Problem Link 交互库有一棵 \(n\) 个点的二叉树,你每次可以询问两个点之间的距离,猜出这棵二叉树.\(n\le 3000\),询问次数上限 \(30000\). 首先 ...
- GitHub要求2FA?不慌,有它们帮你
近日,GitHub宣布,到 2023 年底,所有用户都必须要启用双因素身份验证 (2FA),不能只用密码啦. 正如GitHub的首席安全官Mike Hanley所指出的那样,保护开发者账号是确保软件供 ...