尝试捕获对话框内容并使用GDI +保存到.emf文件。 [英] Trying to capture dialog contents and save to .emf file using GDI+.
问题描述
我正在尝试编写一些代码来捕获对话框中的图像作为位图,然后将其作为emf文件保存到磁盘。但是。虽然.emf文件的大小以kB为单位,但.emf文件中的图像为空白。我正在使用GDI +。没有返回值显示错误。我可以使用HBITMAP将图像保存在.bmp文件中。然后我将HBITMAP转换为位图并尝试保存为emf文件,但文件图像为空白。我不认为我的转换有问题,好像我将位图转换回HBITMAP然后保存到不同的.bmp它工作正常。我想也许我在我的Metafile构造函数中使用了错误的DC但是看不到该怎么做。请有人帮我这个。
在stdafx.h我有:
I am trying to write some code to capture the image in a dialog as a bitmap then save it to disk as an emf file. But although the .emf file has a size in kB, the image in the .emf file is blank. I am using GDI+. None of the return values show an error. I can use the HBITMAP to save the image in a .bmp file. I then convert the HBITMAP to a Bitmap and try to save as an emf file, but the file image is blank. I don't think there is a problem with my conversion as if I convert the bitmap back to an HBITMAP and then save to a different .bmp it works fine. I think maybe I am using the wrong DC in my Metafile constructor but can't see what to do. Please could somebody help me with this.
In stdafx.h I have:
#include <Gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
我的方法是:
My method is:
void GDICapture::CaptureDialogImage(CDialog* dialog)// TODO: make things const
{
ULONG_PTR m_gdiplusToken;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
//Gdiplus::GdiplusShutdown(m_gdiplusToken);//do this later
// get the DCs to copy and capture to
HWND hDialog = dialog->GetSafeHwnd();
HDC hDialogDC = GetDC(hDialog);
HDC hCaptureDC = CreateCompatibleDC(hDialogDC);
// get the dialog dimensions
CRect rect;
dialog->GetClientRect(&rect);
int nDialogWidth = rect.Width();
int nDialogHeight = rect.Height();
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDialogDC, nDialogWidth, nDialogHeight);
// link hCaptureBitmap to hCaptureDC
HGDIOBJ hGDIObj = SelectObject(hCaptureDC, hCaptureBitmap);
if(hGDIObj == HGDI_ERROR)
{
int j = 1;//test
}
if(hGDIObj == NULL)
{
int j = 2;//test
}
BOOL b = BitBlt(hCaptureDC, 0, 0, nDialogWidth, nDialogHeight, hDialogDC, 0, 0, SRCCOPY | CAPTUREBLT);//non-zero == success
//deselect hCaptureBitmap from hCaptureDC before using hCapturebitmap in FromBITMAP()
SelectObject(hCaptureDC, hGDIObj);
CImage image;
image.Attach(hCaptureBitmap);
image.Save(_T("C:\\test\\bitmap.bmp"));
hCaptureBitmap = image.Detach();
//convert HBITMAP to Bitmap
Bitmap* bm = new Bitmap(nDialogWidth, nDialogHeight);
HPALETTE hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
bm->FromHBITMAP(hCaptureBitmap, hPal);
//get a bitmap handle back again
HBITMAP hbmNew;
bm->GetHBITMAP(Color::Blue, &hbmNew);
CImage image1;
image1.Attach(hCaptureBitmap);
image1.Save(_T("C:\\test\\bitmap1.bmp"));
hCaptureBitmap = image1.Detach();
/////////////////////////////////////
// Save Captured Bitmap
CStringW sWFileName = _T("C:\\test\\bitmap.emf");
Metafile* metaFile = new Metafile(sWFileName, hCaptureDC);
//tell the graphics object it has to draw on the metafile
Graphics graphics(metaFile);
graphics.DrawImage(bm, 0, 0, bm->GetWidth(), bm->GetHeight());
//////////////////////////////////////////////////////////////////////////
ReleaseDC(hDialog, hDialogDC);
DeleteDC(hCaptureDC);
DeleteObject(hCaptureBitmap);// I don't need to do this
}
推荐答案
Don'忘记调用DeleteEnhMetaFile,否则文件将被应用程序锁定
Don't forget to call DeleteEnhMetaFile, otherwise the file will be locked by the application
这段代码终于奏效了,虽然我不知道为什么我必须直接提取位图bm1的宽度和高度我已经创建了位图,好像我试图在BitBlt中的位图中访问这些变量,但由于某种原因它失败了。
很多,非常感谢Jochen坚持与我合作:)
This code finally worked, although I don't know why I had to extract the bitmap bm1 width and height straight after I had created the bitmap as if I tried to access these variable in the bitmap within BitBlt it failed for some reason.
Many, many thanks to Jochen for perservering with me :)
void GDICapture::CaptureDialogImage(CDialog* dialog)// TODO: make things const
{
ULONG_PTR m_gdiplusToken;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
//Gdiplus::GdiplusShutdown(m_gdiplusToken);//do this later
// get the DCs to copy and capture to
HWND hDialog = dialog->GetSafeHwnd();
HDC hDialogDC = GetDC(hDialog);
HDC hCaptureDC = CreateCompatibleDC(hDialogDC);
// get the dialog dimensions
CRect rect;
dialog->GetClientRect(&rect);
int nDialogWidth = rect.Width();
int nDialogHeight = rect.Height();
HBITMAP hCaptureBitmap = CreateCompatibleBitmap(hDialogDC, nDialogWidth, nDialogHeight);
// link hCaptureBitmap to hCaptureDC
HGDIOBJ hGDIObj = SelectObject(hCaptureDC, hCaptureBitmap);
BOOL b = BitBlt(hCaptureDC, 0, 0, nDialogWidth, nDialogHeight, hDialogDC, 0, 0, SRCCOPY | CAPTUREBLT);//non-zero == success
//deselect hCaptureBitmap from hCaptureDC before using hCapturebitmap in FromBITMAP()
SelectObject(hCaptureDC, hGDIObj);
CImage image;
image.Attach(hCaptureBitmap);
image.Save(_T("C:\\test\\bitmap.bmp"));
hCaptureBitmap = image.Detach();
//convert HBITMAP to Bitmap
Bitmap* bm = new Bitmap(nDialogWidth, nDialogHeight);
HPALETTE hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
bm->FromHBITMAP(hCaptureBitmap, hPal);
//save the bmp in an emf file
Bitmap* bm1 = new Bitmap(nDialogWidth, nDialogHeight);
int nWidth = bm1->GetWidth();
int nHeight = bm1->GetHeight();
GetObject(hCaptureBitmap, sizeof(BITMAP), bm1);
HDC hdcMem = ::CreateCompatibleDC(GetDC(NULL));
SelectObject(hdcMem, hCaptureBitmap);
HDC emfdc = CreateEnhMetaFile(hdcMem, _T("C:\\test\\testEmf.emf"), NULL, "bkjfygsd");
BitBlt(emfdc, 0, 0, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY);
::CloseEnhMetaFile(emfdc);
ReleaseDC(hDialog, hDialogDC);
DeleteDC(hCaptureDC);
DeleteObject(hCaptureBitmap);// I don't need to do this
}
这篇关于尝试捕获对话框内容并使用GDI +保存到.emf文件。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!