去除边框
1.把窗口边框改成无边框:
但只这样做会导致无法拖动窗口。
2.在类向导中添加这个消息:OnHcHitTest
3.修改这个消息处理函数的返回值为:HTCAPTION
添加背景图片
1.准备一张 bmp 格式的图片(其他格式我没有实验,可能会有问题),在项目中添加资源,选择 BitMap ,导入:
2.在 OnPaint() 函数中添加如下代码:
// 上面还有一部分代码,是 vs 自动生成的
else
{
//CDialogEx::OnPaint(); // 这是原本的,注释掉
/*
从这里开始是我们自己的代码 ---------------
*/
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect); // 获取对话框长宽
CDC dcBmp; // 定义并创建一个内存设备环境
dcBmp.CreateCompatibleDC(&dc); // 创建兼容性DC
CBitmap bmpBackground;
bmpBackground.LoadBitmap(IDB_BITMAP1); // 载入资源中图片
BITMAP m_bitmap; // 图片变量
bmpBackground.GetBitmap(&m_bitmap); // 将图片载入位图中
//将位图选入临时内存设备环境
CBitmap* pbmpOld = dcBmp.SelectObject(&bmpBackground);
//调用函数显示图片StretchBlt显示形状可变
dc.SetStretchBltMode(COLORONCOLOR); // 防止 bmp 图片压缩后失真
dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcBmp, 0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight, SRCCOPY);
}
注意:背景图片在窗口拉伸时会失真,但配合无边框使用时不需要在意,因为本身无边框窗体不支持拉伸窗口。
添加背景颜色
这个没有添加背景图片好用,但还是记录一下吧。
1.类向导里添加消息处理函数 : WM_CTLCOLOR
2.在 xxxDlg.h 的 protected 里添加成员变量:CBrush m_brush;
3.在 WM_CTLCOLOR 的处理函数 OnCtlColor() 中 ,修改返回值为 m_brush
HBRUSH Ctestmfc2Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: 在此更改 DC 的任何特性
// TODO: 如果默认的不是所需画笔,则返回另一个画笔
return /*hbr*/m_brush;
}
4.在 OnInitDialog() 中添加代码,绘制背景颜色:
m_brush.CreateSolidBrush(RGB(255, 255, 102));
给按钮添加背景图片
比起 bmp 图片,显然按钮必须要用 png 的透明图片更加好看,但是 MFC 对 png 的支持并不太友好,我找了很久,终于在这篇文章的启发下完成了这个功能:https://www.codeproject.com/Articles/26887/A-user-draw-button-that-supports-PNG-files-with-tr
https://github.com/JustLoveI/GdipButton 这里的代码更新,但是我没有调通,所以我用的时上面连接里的代码。
以防链接失效,这里记录下具体实现过程,不愿看英文的人也可以直接看我下面写的。
1.首先需要几个文件
CGdiPlusBitmap.h
#pragma once
class CGdiPlusBitmap
{
public:
Gdiplus::Bitmap* m_pBitmap;
public:
CGdiPlusBitmap() {
m_pBitmap = NULL; }
CGdiPlusBitmap(LPCWSTR pFile) {
m_pBitmap = NULL; Load(pFile); }
virtual ~CGdiPlusBitmap() {
Empty(); }
void Empty() {
delete m_pBitmap; m_pBitmap = NULL; }
bool Load(LPCWSTR pFile)
{
Empty();
m_pBitmap = Gdiplus::Bitmap::FromFile(pFile);
return m_pBitmap->GetLastStatus() == Gdiplus::Ok;
}
operator Gdiplus::Bitmap*() const {
return m_pBitmap; }
};
class CGdiPlusBitmapResource : public CGdiPlusBitmap
{
protected:
HGLOBAL m_hBuffer;
public:
CGdiPlusBitmapResource() {
m_hBuffer = NULL; }
CGdiPlusBitmapResource(LPCTSTR pName, LPCTSTR pType = RT_RCDATA, HMODULE hInst = NULL)
{
m_hBuffer = NULL; Load(pName, pType, hInst); }
CGdiPlusBitmapResource(UINT id, LPCTSTR pType = RT_RCDATA, HMODULE hInst = NULL)
{
m_hBuffer = NULL; Load(id, pType, hInst); }
CGdiPlusBitmapResource(UINT id, UINT type, HMODULE hInst = NULL)
{
m_hBuffer = NULL; Load(id, type, hInst); }
virtual ~CGdiPlusBitmapResource() {
Empty(); }
void Empty();
bool Load(LPCTSTR pName, LPCTSTR pType = RT_RCDATA, HMODULE hInst = NULL);
bool Load(UINT id, LPCTSTR pType = RT_RCDATA, HMODULE hInst = NULL)
{
return Load(MAKEINTRESOURCE(id), pType, hInst); }
bool Load(UINT id, UINT type, HMODULE hInst = NULL)
{
return Load(MAKEINTRESOURCE(id), MAKEINTRESOURCE(type), hInst); }
};
inline
void CGdiPlusBitmapResource::Empty()
{
CGdiPlusBitmap::Empty();
if (m_hBuffer)
{
::GlobalUnlock(m_hBuffer);
::GlobalFree(m_hBuffer);
m_hBuffer = NULL;
}
}
inline
bool CGdiPlusBitmapResource::Load(LPCTSTR pName, LPCTSTR pType, HMODULE hInst)
{
Empty();
HRSRC hResource = ::FindResource(hInst, pName, pType);
if (!hResource)
return false;
DWORD imageSize = ::SizeofResource(hInst, hResource);
if (!imageSize)
return false;
const void* pResourceData = ::LockResource(::LoadResource(hInst, hResource));
if (!pResourceData)
return false;
m_hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, imageSize);
if (m_hBuffer)
{
void* pBuffer = ::GlobalLock(m_hBuffer);
if (pBuffer)
{
CopyMemory(pBuffer, pResourceData, imageSize);
IStream* pStream = NULL;
if (::CreateStreamOnHGlobal(m_hBuffer, FALSE, &pStream) == S_OK)
{
m_pBitmap = Gdiplus::Bitmap::FromStream(pStream);
pStream->Release();
if (m_pBitmap)
{
if (m_pBitmap->GetLastStatus() == Gdiplus::Ok)
return true;
delete m_pBitmap;
m_pBitmap = NULL;
}
}
::GlobalUnlock(m_hBuffer);
}
::GlobalFree(m_hBuffer);
m_hBuffer = NULL;
}
return false;
}
GdipButton.h
//
// GdipButton.h : Version 1.0 - see article at CodeProject.com
//
// Author: Darren Sessions
//
//
// Description:
// GdipButton is a CButton derived control that uses GDI+
// to support alternate image formats
//
// History
// Version 1.0 - 2008 June 10
// - Initial public release
//
// License:
// This software is released under the Code Project Open License (CPOL),
// which may be found here: http://www.codeproject.com/info/eula.aspx
// You are free to use this software in any way you like, except that you
// may not sell this source code.
//
// This software is provided "as is" with no expressed or implied warranty.
// I accept no liability for any damage or loss of business that this
// software may cause.
//
///
#pragma once
// GdipButton.h : header file
//
class CGdiPlusBitmapResource;
/
// CGdipButton window
class CGdipButton : public CButton
{
public:
CGdipButton();
virtual ~CGdipButton();
// image types
enum {
STD_TYPE = 0,
ALT_TYPE,
DIS_TYPE
};
// sets the image type
void SetImage(int type);
BOOL LoadAltImage(UINT id, LPCTSTR pType);
BOOL LoadStdImage(UINT id, LPCTSTR pType);
// if false, disables the press