尝试捕获对话框内容并使用GDI +保存到.emf文件。 [英] Trying to capture dialog contents and save to .emf file using GDI+.

查看:82
本文介绍了尝试捕获对话框内容并使用GDI +保存到.emf文件。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一些代码来捕获对话框中的图像作为位图,然后将其作为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆