Posted on 2013-05-25 20:58
尘末 阅读(503)
评论(0) 编辑 收藏 引用 所属分类:
C++
最近在弄一个全仿QQ截屏的控件,封装成DLL,因为里面要用到PNG图片,所以使用了CImage,间接的说就是使用了GDI+, 就在快做完的时候,输出了DLL,采用显示调用DLL的方式,结果发现退出的时候调用DLL的整个进程都卡死了,于是找了MS官方:
http://support.microsoft.com/kb/322909/zh-cn,想了半天,这个问题很久了,怎么我用VS2008都不行呢?实在想不出别的办法。被困扰了好久,终于找到一个比较间接解决的办法。
首先用VC6建一个MFC工程,修改为输出DLL,然后再用VS2008打开,转成VS2008的工程,结果发现没有问题了,居然正常了。
贴上DLL中的代码:
extern "C"
{
//开始截屏,保存时会弹出窗口选择路径, 截屏成功返回true, 失败返回false
_declspec(dllexport)
bool StartCapture(
void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CCatchScreenDlg dlg;;
dlg.SetSaveFilePath( "", 1 );
dlg.DoModal();
if ( dlg.GetResult() )
{
return true;
}
else {
return false;
}
}
//开始截屏,并指定保存目录和文件类型, 截屏成功返回true, 失败返回false
_declspec(dllexport)
bool CaptureSaveToFile(
const char* path,
int img_type )
{
CCatchScreenDlg dlg;
CString str;
str.Format( "%s", path );
dlg.SetSaveFilePath( str, img_type );
dlg.DoModal();
if ( dlg.GetResult() )
{
return true;
}
else {
return false;
}
}
}
DLL调用代码:
//注意,声望要与DLL中的一样。这里就不需要加 __stdcall* 了。
typedef
bool ( * _CaptureStart ) (
const char* path,
int img_type );
HINSTANCE hIns;
hIns = ::LoadLibrary ( "IScreenCapture.dll" );
if ( NULL == hIns )
{
AfxMessageBox( "hIns NULL" );
return;
}
_CaptureStart dllCall = (_CaptureStart)GetProcAddress( hIns, "CaptureSaveToFile" );
if ( NULL != dllCall )
{
if( (*dllCall)("c:\\ttt.bmp",1) )
{
MessageBox("截图成功!");
}
else {
MessageBox("截图失败!");
}
}
另,附上加载CImage从资源中加载的方法:
bool CCatchScreenDlg::LoadPngForRes( CImage* pCImg, UINT nResID )
{
if( pCImg ==NULL)
return false;
pCImg->Destroy();
// 查找资源
HRSRC hRsrc =::FindResource(AfxGetResourceHandle(), MAKEINTRESOURCE(nResID), "png");
if(hRsrc == NULL)
return false;
// 加载资源
HGLOBAL hImgData =::LoadResource(AfxGetResourceHandle(), hRsrc);
if(hImgData == NULL)
{
::FreeResource(hImgData);
return false;
}
// 锁定内存中的指定资源
LPVOID lpVoid =::LockResource(hImgData);
LPSTREAM pStream = NULL;
DWORD dwSize = ::SizeofResource(AfxGetResourceHandle(), hRsrc);
HGLOBAL hNew = ::GlobalAlloc(GHND, dwSize);
LPBYTE lpByte = (LPBYTE)::GlobalLock(hNew);
::memcpy(lpByte, lpVoid, dwSize);
// 解除内存中的指定资源
::GlobalUnlock(hNew);
// 从指定内存创建流对象
HRESULT ht =::CreateStreamOnHGlobal(hNew,TRUE,&pStream);
if( ht != S_OK )
{
GlobalFree(hNew);
}
else
{
// 加载图片
pCImg->Load(pStream);
GlobalFree(hNew);
}
// 释放资源
::FreeResource(hImgData);
return true;
}