MFC PNG作背景 透明边框GDI+

记录下啦。刚刚实现,怕忘了。从上往下,建立对话框工程就行。

1-把PNG图片当作位图的形式载入,在资源里面会多出一个PNG的文件夹例如载入一张了。

[code=c]
2-stdafx.h里加上两句:
#include //新加的
using namespace Gdiplus;

3-然后在该窗口的.h文件里面加上以下代码


.h 文件里的 protected:
HICON m_hIcon;  /

private:
BLENDFUNCTION m_Blend;
HDC m_hdcMemory;
Image *image;
int m_BakWidth , m_BakHeight ;
HINSTANCE hFuncInst ;
typedef BOOL (WINAPI *MYFUNC)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
MYFUNC UpdateLayeredWindow;

ULONG_PTR m_gdiplusToken;
BOOL UpdateClockDisplay(int Transparent=255);//其实重要的是这个跟下面一个函数
BOOL ImageFromIDResource(UINT nID,LPCTSTR sTR,Image * &pImg);

4-public:里面应该有以下的几个消息响应,注意不是直接添加,要在类向导-->消息中添加。
afx_msg void OnPaint();
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg HCURSOR OnQueryDragIcon();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

5-然后就去实现这些消息,还有private里的两个重要函数,这两个我也不懂,加上去,不要露了5-public里的各个消息处理
函数就可以使用了。以下是在.cpp里面的实现:


主要是在以下函数里面执行:UpdateClockDisplay(); ImageFromIDResource()两个函数
BOOL titelDlg::OnInitDialog()//所有的窗口属性都可以在这个初始化时候设置,例如标题栏是否显示
{
CDialogEx::OnInitDialog();

// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标

// TODO: 在此添加额外的初始化代码

Gdiplus::GdiplusStartupInput gdiplusStartupInput;//启动时初始化gdi+
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);

ImageFromIDResource(IDB_PNG1,L"PNG",image);//这里是已经加载到了资源的PNG图片
//image = Image::FromFile(L"D:/test.png"); //图片和路径自己换,同上?

m_BakWidth =image->GetWidth();
m_BakHeight =image->GetHeight();

UpdateClockDisplay();

return TRUE;
}

5-以上说的两个函数的实现如下我也看不懂:
BOOL titelDlg::ImageFromIDResource(UINT nID, LPCTSTR sTR,Image * &pImg)
{
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID),sTR); // type
if (!hRsrc)
return FALSE;

// load resource into memory
DWORD len = SizeofResource(hInst, hRsrc);
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
if (!lpRsrc)
return FALSE;

// Allocate global memory on which to create stream
HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, len);
BYTE* pmem = (BYTE*)GlobalLock(m_hMem);
memcpy(pmem,lpRsrc,len);
IStream* pstm;
CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);

// load from stream
pImg=Gdiplus::Image::FromStream(pstm,1);

// free/release stuff
GlobalUnlock(m_hMem);
pstm->Release();
FreeResource(lpRsrc);

return true;
}

BOOL titelDlg::UpdateClockDisplay(int Transparent)
{
HDC hdcTemp=GetDC()->m_hDC;
m_hdcMemory=CreateCompatibleDC(hdcTemp);
HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp,m_BakWidth,m_BakHeight);
SelectObject(m_hdcMemory,hBitMap);
if(Transparent<0||Transparent>100) Transparent=100;

m_Blend.SourceConstantAlpha=int(Transparent*2.55);//1~255
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)};

graph.DrawImage(image, 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);

BOOL bRet=FALSE;
bRet= 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;

return bRet;
}

6-还有以下几个消息函数,添加消息后,把代码重载进去,否则上面函数不能使用

void titelDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
titelDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}


HCURSOR titelDlg::OnQueryDragIcon()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值

return static_cast(m_hIcon);
}


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

// TODO: 在此添加您专用的创建代码
hFuncInst = LoadLibrary(L"user32.dll");
BOOL bRet=FALSE;
if(hFuncInst)
UpdateLayeredWindow=(MYFUNC)GetProcAddress(hFuncInst, "UpdateLayeredWindow");
else
{
MessageBox(L"User32.dll ERROR!");
exit(0);
}
//初始化gdiplus的环境
m_Blend.BlendOp=0; //theonlyBlendOpdefinedinWindows2000
m_Blend.BlendFlags=0; //nothingelseisspecial...
m_Blend.AlphaFormat=1; //...
m_Blend.SourceConstantAlpha=255;//AC_SRC_ALPHA
return 0;
}

这个叫做GDI+画图是吧?我弄了一天CIMAGE都不行,最后找了份代码实现的。纯属加代码上去的。
动态的实现应该加上定时器就不难吧,迟点在实现。


部分问题:

void Dialog_Warn_Dlg::OnSysCommand(UINT nID, LPARAM lParam) 信号响应里把 titelDlg 改为自己的类
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
titelDlg dlgAbout;
dlgAbout.DoModal();
}

void Dialog_Warn_Dlg::OnSysCommand(UINT nID, LPARAM lParam)信号响应中 IDM_ABOUTBOX

去 Resource.h把

#define IDM_ABOUTBOX                    0x0010
#define IDS_ABOUTBOX                    101


http://blog.csdn.net/weiwangchao_/article/details/6795360

[/code]

你可能感兴趣的:(MFC PNG作背景 透明边框GDI+)