用于自定义数组/结构体数组的剪切板应用模板类
来源:互联网 发布:淘宝v5会员消费多少钱 编辑:程序博客网 时间:2024/06/07 01:40
//用于自定义数组/结构体数组的剪切板应用类template <class MYDATA> class COwnerArrayDataClipboard { //用于剪切板数据结构体 typedef struct tagMYSTRUCTARRAY_t { int iCount; //记录数据个数 MYDATA data[1]; //数据 }MYSTRUCTARRAY, *LPMYSTRUCTARRAY; HWND hClipboardHwnd; //剪切板窗口句柄 UINT uFormat; //剪切板粘贴格式//Trace Error #define TraceErr(e) \ do{ \ dwErr=GetLastError();\ TRACE( _T(#e) _T(" Error Code:%ld\n"), dwErr);\ ASSERT(FALSE);\ }while(0);public: COwnerArrayDataClipboard() { //以桌面窗口做剪切板窗口句柄 hClipboardHwnd = GetDesktopWindow(); //注册剪切板格式 CString szFormat; szFormat.Format(_T("ClipBoard_%d"), sizeof(MYDATA)); uFormat = RegisterClipboardFormat( szFormat ); if(uFormat == 0) { DWORD dwErr = GetLastError(); TRACE( _T("RegisterClipboardFormat failed : %ld\n"), dwErr); ASSERT(FALSE); } } //链表粘贴到剪切板 //iCont 指示 DataArray个数 //DataArray源数据 BOOL PasteToClipboard(const int iBuffCount, const MYDATA DataArray[]) { DWORD dwErr = ERROR_SUCCESS; HGLOBAL hMem = NULL; BOOL bClipOpened = FALSE; do { //打开剪切板 bClipOpened = OpenClipboard(hClipboardHwnd); if(!bClipOpened) { TraceErr("OpenClipboard"); break; } //清空剪切板 if(!EmptyClipboard()) { TraceErr("EmptyClipboard"); break; } //分配所需内存 DWORD dwSize = sizeof(MYSTRUCTARRAY) + (iBuffCount-1) * sizeof(MYDATA); //计算长度 hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dwSize); //分配内存 if(hMem == NULL) { TraceErr("GlobalAlloc"); break; } //锁定内存 LPMYSTRUCTARRAY pArray = (LPMYSTRUCTARRAY)GlobalLock(hMem); if(pArray == NULL) { TraceErr("GlobalLock"); break; } //拷贝数据至内存 { pArray->iCount = iBuffCount; //拷贝结构体个数 for(int i=0; i<iBuffCount; i++) { pArray->data[i] = DataArray[i]; //拷贝结构体数据 } } //解锁内存 if(!GlobalUnlock(hMem) && GetLastError() != ERROR_SUCCESS) { TraceErr("GlobalUnlock"); break; } if(SetClipboardData(uFormat, hMem) == NULL) { TraceErr("SetClipboardData"); break; } } while (0); //出错释放内存 if(dwErr && hMem) { GlobalFree(hMem); hMem = NULL; } //关闭剪切板 if(bClipOpened) CloseClipboard(); return dwErr == ERROR_SUCCESS; } //从剪切板读取数据 //用于存放返回 DataArray数据缓冲区 //iBuffCount 输入时指示缓冲区大小 //函数返回值: //当DataArray==NULL 或 iBuffCount==0时 返回 剪切板中可用的数据个数 //当否则返回实际读取的个数 int CopyFromClipboard(MYDATA DataArray[], const int iBuffCount) { int iCount = 0; DWORD dwErr = ERROR_SUCCESS; BOOL bClipOpened = FALSE; do { //打开剪切板 bClipOpened = OpenClipboard(hClipboardHwnd); if(!bClipOpened) { TraceErr("OpenClipboard"); break; } if(!IsClipboardFormatAvailable(uFormat))//检查格式有效 { TraceErr("IsClipboardFormatAvailable"); break; } HGLOBAL hMem = GetClipboardData(uFormat);//读取数据句柄 if(hMem == NULL) { TraceErr("GetClipboardData"); break; } //锁定内存 LPMYSTRUCTARRAY pArray = (LPMYSTRUCTARRAY)GlobalLock(hMem); if(pArray == NULL) { TraceErr("GlobalLock"); break; } //拷贝数据至内存 if(DataArray == NULL || iBuffCount <= 0) { iCount = pArray->iCount; } else { iCount = min(iBuffCount, pArray->iCount); for(int i=0; i<iCount; i++) { DataArray[i] = pArray->data[i]; } } //解锁内存 if(!GlobalUnlock(hMem) && GetLastError() != ERROR_SUCCESS) { TraceErr("GlobalUnlock"); break; } } while (0); //关闭剪切板 if(bClipOpened) CloseClipboard(); return iCount; }};
//测试//测试结构体typedef struct tagMYSTRUCT_t{ int a, b, c; tagMYSTRUCT_t() { a = b = c = 0; } tagMYSTRUCT_t(int a1, int b1, int c1) { a = a1; b = b1; c = c1; } tagMYSTRUCT_t( tagMYSTRUCT_t & other) { memcpy(this, &other, sizeof(*this)); } }MYSTRUCT, *LPMYSTRUCT;void TestOwnerArrayDataClipboard(){ //准备源数据 const int iSrcCount = 5; MYSTRUCT myStruct1[iSrcCount]; for(int i=0; i<iSrcCount; i++) { myStruct1[0].a = i+1; } COwnerArrayDataClipboard < MYSTRUCT > clipboard; //粘贴到剪切板 clipboard.PasteToClipboard(iSrcCount, myStruct1); //获取长度 int iDstCount = clipboard.CopyFromClipboard(NULL, 0); ASSERT(iDstCount == iSrcCount); //读取全部数据 MYSTRUCT *myStruct2 = new MYSTRUCT[iDstCount]; clipboard.CopyFromClipboard(myStruct2, iDstCount); for(int j=0; j<iDstCount; j++) { if(memcmp(&myStruct1[j], &myStruct2[j], sizeof(MYSTRUCT)) != 0) { ASSERT(FALSE); } } //清理 delete []myStruct2;}