在Windows Template Library (WTL)中,经常需要处理图形界面的绘制问题。本文将介绍一个使用GDI+在WTL中绘制图像的类,这个类支持多种图像格式,包括位图、GIF、JPEG、PNG和TIFF。它允许从磁盘文件读取图像,将图像保存到磁盘文件,以及从数据库读取和写入图像。
这个类与WTL8.0兼容,并且示例是在Visual Studio 2008中创建的。
CWtlPicture类旨在与常见的Windows对话框中的Picture控件接口,该控件的类型设置为Owner Draw。使用GDI+ Bitmap对象从磁盘或数据库加载图像数据,然后GDI+图形对象在Picture控件表面上绘制。使用CFileDialog打开磁盘图像,并使用Bitmap::Save保存图像,补充编码器选择逻辑,能够转换图像类型。此外,还有一个图像缩放功能以及一个辅助类,实现了ISequentialStream接口,用于读取和写入OLE DB blob数据库列。
GDI+是微软的图像库。库及其头文件被添加到CWtlPicture源文件中,库在类构造函数中启动,在析构函数中停止。
代码可以从磁盘文件或OLE DB兼容数据库中打开位图、GIF、JPEG、PNG和TIFF图像。加载后,可以将图像保存到磁盘或数据库中的任何一种支持的5种格式。但是,图像处理规则适用。位图和JPEG不支持透明度,因此它们不能作为GIF、PNG或TIFF透明图像保存,当图像作为位图或JPEG保存时,透明度会丢失。此外,GDI+甚至不支持支持它的图像类型的透明度。例如,一个不支持透明度的GIF图像不能通过GDI+函数使其透明。
如果不需要数据库支持,只想处理磁盘文件,可以在WtlPicture.h中注释掉#define __DATABASE_SUPPORT__行,数据库特定的代码部分将被忽略。
需要使用资源编辑器将一个Picture控件添加到对话框中。为了简单起见,将控件命名为IDC_PICTURE,并将类型设置为Owner Draw,然后将控件调整到希望的尺寸。使用稍后讨论的缩放属性,可以控制图像在显示时的大小。
接下来,向MainDlg添加一个成员变量。例如:
CWtlPicture m_odPicture;
并在InitDialog中附加Picture控件的窗口句柄,如下所示:
m_odPicture = GetDlgItem(IDC_PICTURE);
之后,设置所需的命令处理程序,如文件打开和文件保存,在对话框的消息映射中,并添加一个消息处理程序用于绘制通知:
MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem)
最后,添加菜单命令事件处理程序和绘制事件处理程序。绘制代码非常简单,如下所示:
LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if(IDC_PICTURE == wParam)
{
// Paint the background
LPDRAWITEMSTRUCT lpDis = (LPDRAWITEMSTRUCT)lParam;
::GetClientRect(lpDis->hwndItem, &lpDis->rcItem);
::FillRect(lpDis->hDC, &lpDis->rcItem, (HBRUSH)(COLOR_BTNFACE + 1));
// Draw the image
if(!m_odPicture.IsNull()) m_odPicture.Render();
}
else
bHandled = FALSE;
return 0;
}
要将数据库支持添加到项目中,需要为数据创建一个OLE DB消费者类。Visual Studio Professional或更高版本中有一个向导(大部分)自动化了这个任务。对于VS的Express版本,可以下载Windows Driver Kit 7.1来获取ATL特性。创建消费者类后,需要做一些更改以支持图像/varbinary操作。在之前的OLE DB文章中详细说明了这个过程。
消费者类准备好后,添加一个成员变量用于表格(例如:
CProductionProductPhoto m_dbTable;
)和数据库操作的命令处理程序。示例项目包括移动下一个和上一个以及数据库读写的处理程序。