剪切板编程中遇到的一个问题

来源:互联网 发布:redmine windows 编辑:程序博客网 时间:2024/05/18 03:18

        之前在开发一个新功能的时候,需要将文件的路径信息通过剪切板传递给指定的目标。于是就需要将文件信息写入到剪切板中,获取方则从剪切板中读取想要获取的路径信息。剪切板是通过全局内存来共享数据的,存放数据的内存是通过GlobalAlloc来分配的。问题就出在这个用GlobalAlloc来分配的的内存上,在将文件信息写入到剪切板之后,想当然的就调用GlobalFree来释放之前申请来的内存,于是导致了后续的复制/粘贴功能的异常。经查阅,找出了对应的原因:不需要GlobalFree来内存,因为内存已经有剪切板托管了,最终由剪切板来释放。相关代码如下所示:

// 将图片文件拷贝到剪切板(将包含文件名的文件完整路径添加到剪切板中)void CCatchScreenDlg::CopyCatchFileToClipboard( CString strFilePath ){DROPFILES dropFiles;UINT uGblLen, uDropFilesLen;HGLOBAL hGblFiles, hGblEffect;char *szData, *szFileList;DWORD *pdwDropEffect;hGblEffect = GlobalAlloc( GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, sizeof(DWORD) );if ( hGblEffect == NULL ){return;}pdwDropEffect = (DWORD*)GlobalLock( hGblEffect );*pdwDropEffect = DROPEFFECT_COPY;GlobalUnlock( hGblEffect );uDropFilesLen = sizeof(DROPFILES);dropFiles.pFiles = uDropFilesLen;dropFiles.pt.x = 0;dropFiles.pt.y = 0;dropFiles.fNC = FALSE;dropFiles.fWide = TRUE;uGblLen = uDropFilesLen + strFilePath.GetLength()*2 + 8;hGblFiles = GlobalAlloc( GMEM_ZEROINIT|GMEM_MOVEABLE|GMEM_DDESHARE, uGblLen );if ( hGblFiles == NULL ){GlobalFree( hGblEffect );return;}szData = (char*)GlobalLock( hGblFiles );memcpy( szData, (LPVOID)(&dropFiles), uDropFilesLen );szFileList = szData + uDropFilesLen;LPWSTR lpWStrBmpFileName = NULL; // 注意:Bitmap::Save接口第一个参数是宽字节参数#ifdef _UNICODE    lpWStrBmpFileName = strFilePath.GetBuffer( 0 ); // 如果是_UNICODE模式,直接使用#elseWCHAR wchBmpFileName[MAX_PATH*2] = {0};MultiByteToWideChar( CP_ACP, 0, strFilePath.GetBuffer(0), -1, wchBmpFileName, strlen(strFilePath)+1 ); // 将窄字符转化为宽字符lpWStrBmpFileName = wchBmpFileName;#endif wmemcpy( (WCHAR *)szFileList, lpWStrBmpFileName, wcslen( lpWStrBmpFileName )+2 );GlobalUnlock( hGblFiles );if( ::OpenClipboard( NULL ) ){::EmptyClipboard();::SetClipboardData( CF_HDROP, hGblFiles );::SetClipboardData( m_dwScreenCatchClipFormat, hGblEffect );::CloseClipboard();}// 此处是剪切板编程,用GlobalAlloc申请来内存好像被ClipBoard托管了,无需使用GlobalFree来释放        // 了,如果调用GlobalFree来释放会出现一些异常,2012/06/02// GlobalFree( hGblEffect );// GlobalFree( hGblFiles );},