当前位置: 首页 > article >正文

MFC实现以不规则PNG图片作为窗口背景

效果图 显示的不规则PNG图片在这里插入图片描述

头文件

#pragma once
#include <gdiplus.h>
#pragma comment (lib,"Gdiplus.lib")

// CShowBack 对话框

class CShowBack : public CDialogEx
{
	DECLARE_DYNAMIC(CShowBack)
public:
	CShowBack(CWnd* pParent = nullptr);   // 标准构造函数
	virtual ~CShowBack();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_DIALOG2 };
#endif

protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

	DECLARE_MESSAGE_MAP()

	Gdiplus::GdiplusStartupInput m_gdiplusStartupInput;
	ULONG_PTR m_gdiplusToken;
	Gdiplus::Image* m_image;
public:
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
	afx_msg void OnPaint();


	void OnDestroy();
	void OnLButtonDown(UINT nFlags, CPoint point);

	Gdiplus::Image* m_pImageBack; // 背景图像指针,Image是一个图像类。
	HDC m_hdcMemory;
	int m_BakWidth; // 背景图像宽
	int m_BakHeight; // 背景图像高
	BLENDFUNCTION m_Blend;

};

cpp文件

#include "stdafx.h"
#include "CShowBack.h"
#include "afxdialogex.h"
#include "resource.h"

// CShowBack 对话框
IMPLEMENT_DYNAMIC(CShowBack, CDialogEx)
CShowBack::CShowBack(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MY_DIALOG, pParent)
{

}

CShowBack::~CShowBack()
{

}

void CShowBack::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CShowBack, CDialogEx)
	ON_WM_CREATE()
	ON_WM_DRAWITEM()
	ON_WM_PAINT()
END_MESSAGE_MAP()


// CShowBack 消息处理程序
using namespace Gdiplus; // 名称空间

int CShowBack::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialogEx::OnCreate(lpCreateStruct) == -1)
		return -1;

	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR           gdiplusToken;
	// Initialize GDI+.
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

	m_Blend.BlendOp = 0; //theonlyBlendOpdefinedinWindows2000
	m_Blend.BlendFlags = 0; //nothingelseisspecial...
	m_Blend.AlphaFormat = 1; //...
	m_Blend.SourceConstantAlpha = 255;//AC_SRC_ALPHA // 透明度


	m_pImageBack = Gdiplus::Image::FromFile(L"backimage.png"); // 直接读取文件,注意是双“\\”斜杠
	// ImageFromIDResource(IDR_PNG2, "PNG", m_pImageBack); // 读取资源中的PNG图片, 为自订义类形“PNG”
	// 这里Image没有提供字节调用资源中图像的函数,
	// ImageFromIDResource()是通过资源名称"PNG"和资源ID号将图像的Image指针传递给指针应用。来完成的。
	// 这个函数是摘自网上
	// ImageFileMe("F:\\abc.png", m_pImageBack); // 读取二进制文件
	m_BakWidth = m_pImageBack->GetWidth(); // 返回图片宽度
	m_BakHeight = m_pImageBack->GetHeight(); // 返回图片高度

	// 以下是实现窗口在最上面。
	//::SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, m_BakWidth, m_BakHeight, SWP_NOSIZE | SWP_NOMOVE);

	return 0;
}

void CShowBack::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CDialogEx::OnDrawItem(nIDCtl, lpDrawItemStruct);
}

//从资源中加载
BOOL ImageFormResource(UINT nID, LPCTSTR str, Image*& pImage)
{
	HINSTANCE hIns = AfxGetResourceHandle();
	HRSRC hRsrc = ::FindResource(hIns, MAKEINTRESOURCE(nID), str);
	if (!hRsrc)
		return FALSE;

	DWORD dwLen = SizeofResource(hIns, hRsrc);
	BYTE* lpRsrc = (BYTE*)LoadResource(hIns, hRsrc);
	if (!lpRsrc)
		return FALSE;

	HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, dwLen);
	BYTE* pMem = (BYTE*)GlobalLock(m_hMem);
	memcpy(pMem, lpRsrc, dwLen);
	GlobalUnlock(m_hMem);
	IStream* pStream;
	CreateStreamOnHGlobal(m_hMem, FALSE, &pStream);

	pImage = Image::FromStream(pStream);//如果pImage加载成功,需要释放,不然会有内存泄漏
	pStream->Release();
	FreeResource(lpRsrc);
	GlobalFree(m_hMem);
	return TRUE;
}

void CShowBack::OnDestroy()
{
	CDialog::OnDestroy();

	// TODO: 在此处添加消息处理程序代码
	delete m_pImageBack;
	m_pImageBack = NULL;
}

void CShowBack::OnPaint()
{
	HDC hdcTemp = GetDC()->m_hDC;
	m_hdcMemory = CreateCompatibleDC(hdcTemp);
	HBITMAP hBitMap = CreateCompatibleBitmap(hdcTemp, m_BakWidth, m_BakHeight);
	SelectObject(m_hdcMemory, hBitMap);

	// m_Blend.SourceConstantAlpha=100; // 窗口透明度最大为255,最小为0
	HDC hdcScreen = ::GetDC(m_hWnd);
	RECT rct;
	GetWindowRect(&rct);
	POINT ptWinPos = { rct.left, rct.top };

	Graphics graph(m_hdcMemory);
	Point points[] = { Point(0, 0),
	Point(m_BakWidth, 0),
	Point(0, m_BakHeight) };
	static bool bFly = false;
	graph.DrawImage(m_pImageBack, points, 3);

	SIZE sizeWindow = { m_BakWidth,m_BakHeight };
	POINT ptSrc = { 0,0 };
	DWORD dwExStyle = GetWindowLong(m_hWnd, GWL_EXSTYLE);
	if ((dwExStyle & 0x80000) != 0x80000)
		SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle ^ 0x80000);
	::UpdateLayeredWindow(m_hWnd, hdcScreen, &ptWinPos, &sizeWindow, m_hdcMemory, &ptSrc, 0, &m_Blend, 2);

	graph.ReleaseHDC(m_hdcMemory);
	::ReleaseDC(m_hWnd, hdcScreen);
	hdcScreen = NULL;
	::ReleaseDC(m_hWnd, hdcTemp);
	hdcTemp = NULL;
	DeleteObject(hBitMap);
	DeleteDC(m_hdcMemory);
	m_hdcMemory = NULL;
}

测试调用

	CShowBack ShowBack;
	ShowBack.DoModal();

存在问题 透明窗口不能点击,添加别的按钮不会显示 有解决的朋友希望能联系我改进


http://www.kler.cn/a/370877.html

相关文章:

  • windows远程桌面连接限定ip
  • 解决报错:未定义标识符 “M_PI“
  • 基于Linux系统指令使用详细解析
  • 网络技术发展的演变与未来展望
  • keepalived双机热备(LVS+keepalived)实验笔记
  • Cosmos:英伟达发布世界基础模型,为机器人及自动驾驶开发加速!
  • IMX6ULL之使用汇编操作GPIO
  • mac 上使用 cmake 构建包含 OpenMP 的项目
  • 网络请求自定义header导致跨域问题
  • 「二叉树进阶题解:构建、遍历与结构转化全解析」
  • 【网络安全】红队人员的GPO和OU指南
  • 端口号和ip地址一样吗?区别是什么
  • [Linux] linux 软硬链接与动静态库
  • 芯片上音频相关的验证
  • 2024前端JS面试题总汇
  • 基于yolov8的布匹缺陷检测系统,支持图像、视频和摄像实时检测【pytorch框架、python源码】
  • Cisco Packet Tracer 8.0 路由器的基本配置和Telnet设置
  • 《Linux系统编程篇》fork函数——基础篇
  • 基于SSM+小程序的童装商城管理系统(商城3)
  • 用Pyhon写一款简单的益智类小游戏——2048
  • 【338】基于springboot的IT职业生涯规划系统
  • Elasticsearch Serverless 高性价比智能日志分析关键技术解读
  • 数据库基础介绍
  • 构建最新的LLaMA-Factory镜像
  • HTML的常用标签
  • 使用virtualenv导入ssl模块找不到指定的模块