效果图 显示的不规则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();
存在问题 透明窗口不能点击,添加别的按钮不会显示 有解决的朋友希望能联系我改进