如何在VC ++中删除或释放GDI对象? [英] How to delete or release the GDI objects in VC++?

查看:170
本文介绍了如何在VC ++中删除或释放GDI对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码来截取系统的屏幕截图.但是在执行过程中,exe需要执行更多过程,并且每2秒升高一次,系统挂起,如何在保存文件后删除那些GDI对象.帮帮我,
我发现Gdiplus :: Bitmap位图是占用大量进程内存的东西.如何删除或释放此Gdiplus :: Bitmap位图?


I am using the following code to take screenshot of the system. but while executing, the exe is taking more process, and it raises and raises for every 2 secs, system hangs, How to delete those GDI objects after saving in the file. Help me,,,
I have found that Gdiplus::Bitmap bitmap is the thing that takes huge process memory. How to delete or release this Gdiplus::Bitmap bitmap??


        <code>using namespace Gdiplus;
	GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR gdiplusToken;
	GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);     
	int c=0;
	HDC scrdc, memdc;
	HBITMAP membit; 
	HBITMAP hOldBitmap;
	CString lpfilename;
	char buffer[1000];	
	int hours,shots;    
	
	for(;;)
	{	
		scrdc = ::GetDC(0);
		int Height = GetSystemMetrics(SM_CYSCREEN);
		int Width = GetSystemMetrics(SM_CXSCREEN);
		memdc = CreateCompatibleDC(scrdc);
		membit = CreateCompatibleBitmap(scrdc, Width, Height);
		hOldBitmap=(HBITMAP) SelectObject(memdc, membit);
		BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
		Gdiplus::Bitmap bitmap(membit, NULL);
		CLSID clsid;
		GetEncoderClsid(L"image/jpeg", &clsid);
		
		IStream* tmpbuf = NULL;
		CreateStreamOnHGlobal(NULL, true, &tmpbuf);
		bitmap.Save(tmpbuf, &clsid);
		HGLOBAL hg = NULL;
		HRESULT  hr = GetHGlobalFromStream(tmpbuf, &hg);
		ULONG uSize = GlobalSize(hg);	
		int len=(int)uSize;  

		CString strDateTime;
		SYSTEMTIME datetime;
		::GetLocalTime(&datetime);
		strDateTime.Format(_T("%02i-%02i-%02i %d:%d:%d"),
				datetime.wYear,
				datetime.wMonth,     
				datetime.wDay,       
				datetime.wHour,
				datetime.wMinute,
				datetime.wSecond);
		CString strdate;
		strdate.Format(_T("%02i"),datetime.wDay);

		CString strmonth;
		strmonth.Format(_T("%02i"),datetime.wMonth);

		CString strhr;
		strhr.Format(_T("%d"),datetime.wHour);

		CString strmin;
		strmin.Format(_T("%d"),datetime.wMinute);

		CString strsec;
		strsec.Format(_T("%d"),datetime.wSecond);

		char pconfig[60];
		CFile configIni;
		configIni.Open(_T("C:\\Program Files\\MSWorks\\config.ini"),CFile::modeRead );
		configIni.SeekToBegin();
		configIni.Read(pconfig,sizeof(pconfig));
	

		CString strini;
		strini=pconfig;
		strini.TrimRight();

		CString strsub,strnew;

	int nCount = 0;
	for(int i=0;AfxExtractSubString(strsub,strini,i,''#'');i++)
	{
		if(i==nCount) break;
		nCount++;		
	}
	nCount--;

        CString ipaddr;
	ipaddr=strip;
        sprintf_s(buffer,"image%u.jpeg",c);	
	lpfilename=buffer;			
        
	CString strdd;
	strdd=strdate+_T("-")+strmonth+_T("-")+strhr+_T("-")+strmin+_T("-")+strsec+lpfilename;
		
	CString szDirPath = strsub+_T("\\");		
	CString szipaddr;
	szipaddr=ipaddr;
	szipaddr+=_T("-")+name+_T("\\");
	CString szipadd;
	szipadd=szipaddr;
	CString strall;
	strall=szDirPath+szipaddr;

	 
	CreateDirectory(szDirPath,NULL);
	SetCurrentDirectory(szDirPath);
	CreateDirectory(szipaddr,NULL); 
	SetCurrentDirectory(szipaddr);			
	CString imagesave;
	imagesave=strall+strdd;			
	bitmap.Save(imagesave, &clsid); 
	
	c++;
	int iSecret, iRandom;  
	iSecret = rand() % 20 + 1;
	iRandom=iSecret*60000;

	DeleteObject(memdc);
	DeleteObject(membit);
	Sleep(10000); 	

     }
     GdiplusShutdown(gdiplusToken);
		
		 
}</code>&lt;/pre>

推荐答案

就像:

hOldBitmap =(HBITMAP)SelectObject(memdc,membit);

...

//使用后

//SelectObject(memdc,hOldBitmap); //选择旧的GDI返回系统,这里不需要,它是兼容的DC.

DeleteObject(membit); //首先删除GDI,因为它基于DC

memdc.DeleteDC(); //删除兼容的DC

ReleaseDC(scrdc); //发布dc
just like:

hOldBitmap=(HBITMAP) SelectObject(memdc, membit);

...

// after you use it

//SelectObject(memdc, hOldBitmap); // select old GDI back to system, here not need, it''s Compatible DC.

DeleteObject(membit); // delete GDI first because it is base on DC

memdc.DeleteDC(); // delete Compatible DC

ReleaseDC(scrdc); // release dc


这是您使用的相同代码吗?
似乎有一个无限循环.
系统挂此的bcoz?
Is this the same code that you use?
there seems to be having an infinite loop.
system hangs bcoz of this??


首先,您的代码很难阅读-您是否考虑过将其拆分为较小的方法?当然,这将使它更易于阅读,并且更重要的是将精力集中在引起问题的部分上.我的建议是至少将图形操作和文件写入分开-但这只是我.

其次,如果您想控制位图的生命周期-为什么不使用new/delete?
First of all your code is quite hard to read - have you considered splitting it up into smaller methods? It would certainly make it easier to read, and more importantly focus on the parts that cause problems. My suggestion would be to at least separate the graphics operations and file writes - but that''s just me.

Secondly if you want to control the life cycle of the bitmap - why not use new/delete?
Gdiplus::Bitmap *bitmap = new Gdiplus::Bitmap(membit, NULL);
.../*DO STUFF*/
delete bitmap;
DeleteObject(memdc);
DeleteObject(membit);



通过这种方式,您可以确切地知道该对象何时生效以及何时被销毁.如果内存仍在增加-位图是纯真的:)



This way you know exactly when the object comes to life and when it is destroyed. If the memory is still on the rise - the bitmap was innocent :)


这篇关于如何在VC ++中删除或释放GDI对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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