根据提供的文件信息,本文将详细解析如何在MFC框架下创建使用PNG图片作为背景的不规则窗口,并结合代码示例来深入理解整个实现过程。 ### 一、创建单例事件对象 代码中出现了一个单例事件对象的创建与打开逻辑: ```cpp HANDLE m_hSingleApp; // 定义事件句柄 m_hSingleApp = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, MUTE_SINGLE_APP); // 尝试打开已存在的事件 if (NULL == m_hSingleApp) { // 如果打开失败(即不存在) m_hSingleApp = ::CreateEvent(NULL, FALSE, FALSE, MUTE_SINGLE_APP); // 创建新的事件 } ``` 这里通过`OpenEvent`尝试打开一个已经存在的事件对象,如果该事件不存在,则使用`CreateEvent`创建一个新的事件。这样做的目的是为了确保在整个程序运行期间只有一个实例在执行,即实现了单例模式。 ### 二、初始化按钮 接下来是一段关于按钮初始化的代码: ```cpp void InitButtonST(CButtonST& bt, UINT nIconID, UINT nIconID1); void CSipDialog::InitButtonST(CButtonST& bt, UINT nIconID, UINT nIconID1) { bt.SetIcon(nIconID, nIconID1); // 设置图标资源 bt.SizeToContent(); // 自动调整按钮大小以适应图标 bt.DrawBorder(FALSE); // 隐藏边框(TRUE为显示边框) bt.DrawTransparent(); // 设置透明效果(TRUE为透明) } InitButtonST(m_btn_nomute, IDI_ICON_V1_RECORDING1, IDI_ICON_V1_RECORDING1); ``` 这一段代码展示了如何初始化一个按钮,包括设置图标、调整按钮大小以适应图标、隐藏边框以及设置透明效果等操作。这些操作使得按钮更加美观且与整体界面风格一致。 ### 三、加载并绘制背景图片 接下来是加载并绘制背景图片的过程: ```cpp CRect rect; // 用于获取窗口尺寸 CBitmap bitmap; // 图片对象 BITMAP bmp; // 保存图片信息 CDC dcCompatible; // 兼容设备上下文 bitmap.LoadBitmap(IDB_LOGIN); // 加载资源中的图片 bitmap.GetBitmap(&bmp); // 获取图片信息 dcCompatible.CreateCompatibleDC(pDC); // 创建与当前DC兼容的DC CBitmap* pOldBitmap = dcCompatible.SelectObject(&bitmap); // 选择图片到DC GetWindowRect(&rect); // 获取窗口尺寸 pDC->SetStretchBltMode(COLORONCOLOR); // 设置拉伸模式 pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY); // 绘制图片 dcCompatible.SelectObject(pOldBitmap); // 还原旧的图片 dcCompatible.DeleteDC(); // 删除兼容设备上下文 ``` 这段代码主要分为几个步骤: 1. **加载图片**:使用`LoadBitmap`加载资源中的图片。 2. **获取图片信息**:使用`GetBitmap`获取图片的具体信息。 3. **创建兼容设备上下文**:使用`CreateCompatibleDC`创建一个与当前DC兼容的设备上下文。 4. **选择图片到DC**:使用`SelectObject`将图片选入DC中。 5. **获取窗口尺寸**:使用`GetWindowRect`获取窗口的实际尺寸。 6. **绘制图片**:使用`StretchBlt`将图片拉伸并绘制到窗口上。 7. **还原DC状态**:最后还原旧的图片,并删除兼容设备上下文。 ### 四、使用GDI+处理图片 此外,还有一段使用GDI+来处理图片的代码: ```cpp #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib") using namespace Gdiplus; Bitmap* m_pImage; Gdiplus::GdiplusStartupInput gdiplusStartupInput; Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); // 启动GDI+ m_pImage = Bitmap::FromFile(L"bg/normal.png"); // 从文件加载图片 SIZE sizeWindow = {m_pImage->GetWidth(), m_pImage->GetHeight()}; // 获取窗口的大小(基于图片大小) DWORD dwExStyle = ::GetWindowLong(m_hWnd, GWL_EXSTYLE); // 获取扩展样式 if ((dwExStyle & 0x80000) != 0x80000) ::SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle | 0x80000); // 设置扩展样式(0x80000表示无边框) HDC hDC = ::GetDC(m_hWnd); // 获取窗口的设备上下文 HDC hdcMemory = CreateCompatibleDC(hDC); // 创建与窗口DC兼容的内存DC // HBITMAP hBitMap = CreateCompatibleBitmap(hDC, sizeWindow.cx, sizeWindow.cy); // 创建兼容位图 // ... ``` 这一部分代码展示了如何使用GDI+来处理图片: 1. **启动GDI+**:通过`GdiplusStartup`函数启动GDI+。 2. **从文件加载图片**:使用`Bitmap::FromFile`方法从文件加载一张图片。 3. **获取图片大小**:使用`GetWidth`和`GetHeight`方法获取图片的宽度和高度。 4. **设置窗口样式**:修改窗口的扩展样式,使其成为无边框的窗口。 5. **创建兼容设备上下文**:创建一个与窗口DC兼容的内存DC,以便后续对图片进行处理。 整个代码片段通过一系列的操作实现了使用PNG图片作为背景的不规则窗口。通过加载和绘制图片、初始化按钮以及使用GDI+处理图片,最终构建出一个美观且功能完整的窗口。这对于开发具有特殊需求的GUI应用来说非常有用。
m_hSingleApp = ::OpenEvent(EVENT_ALL_ACCESS, FALSE, MUTE_SINGLE_APP); //获取进程句柄
if(NULL == m_hSingleApp) //进程不存在
{
m_hSingleApp = ::CreateEvent(NULL, FALSE, FALSE, MUTE_SINGLE_APP); //创建新进程
void InitButtonST(CButtonST & bt, UINT nIconID,UINT nIconID1); //重画图标
void CSipDialog::InitButtonST(CButtonST & bt, UINT nIconID,UINT nIconID1)
{
bt.SetIcon(nIconID,nIconID1); //指定图标的句柄
bt.SizeToContent(); //调整按钮大小,可以放下整个位图
bt.DrawBorder(FALSE); //不显示边框(TRUE显示边框)
bt.DrawTransparent(); //不马上重画按钮(TRUE马上重画按钮)
}
InitButtonST(m_btn_nomute,IDI_ICON_V1_RECORDING1,IDI_ICON_V1_RECORDING1);
CRect rect; //定义一个矩形区域用于读取客户区域
CBitmap bitmap; //位图背景对象
BITMAP bmp; //位图句柄
CDC dcCompatible; //内存绘图设备
bitmap.LoadBitmap(IDB_LOGIN); //载入位图资源
bitmap.GetBitmap(&bmp); //获取位图
dcCompatible.CreateCompatibleDC(pDC); //创建与当前DC兼容的DC
CBitmap *pOlBitmap = dcCompatible.SelectObject(&bitmap); //保存旧的位图
GetWindowRect(&rect); //获取列表框客户区域
- 粉丝: 0
- 资源: 2
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助