//用于自定义格式数据/结构体的剪切板应用模板类
template <class MYDATA> class COwnerDataClipboard
{
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:
COwnerDataClipboard()
{
//以桌面窗口做剪切板窗口句柄
hClipboardHwnd = GetDesktopWindow();
//注册剪切板格式
CString szFormat;
szFormat.Format(_T("ClipBoard_OwnerData%d"), sizeof(MYDATA));
uFormat = RegisterClipboardFormat( szFormat );
if(uFormat == 0)
{
DWORD dwErr = GetLastError();
TRACE( _T("RegisterClipboardFormat failed : %ld\n"), dwErr);
ASSERT(FALSE);
}
}
//链表粘贴到剪切板
BOOL PasteToClipboard(const MYDATA &data)
{
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(MYDATA); //计算长度
hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dwSize); //分配内存
if(hMem == NULL)
{
TraceErr("GlobalAlloc");
break;
}
//锁定内存
MYDATA *pData = (MYDATA*)GlobalLock(hMem);
if(pData == NULL)
{
TraceErr("GlobalLock");
break;
}
//拷贝数据至内存
*pData = data;
//解锁内存
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;
}
BOOL CopyFromClipboard(MYDATA &data)
{
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;
}
//锁定内存
MYDATA *pData = (MYDATA *)GlobalLock(hMem);
if(pData == NULL)
{
TraceErr("GlobalLock");
break;
}
//拷贝数据至内存
data = *pData;
//解锁内存
if(!GlobalUnlock(hMem) && GetLastError() != ERROR_SUCCESS)
{
TraceErr("GlobalUnlock");
break;
}
} while (0);
//关闭剪切板
if(bClipOpened)
CloseClipboard();
return dwErr == ERROR_SUCCESS;
}
};
//应用测试
//测试结构体
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 TestOwerClipboard()
{
MYSTRUCT myData1(1, 2, 3), myData2;
COwnerDataClipboard < MYSTRUCT > myClip;
myClip.PasteToClipboard(myData1);
myClip.CopyFromClipboard(myData2);
ASSERT(memcmp(&myData1, &myData2, sizeof(MYSTRUCT)) == 0);
}