用于自定义数组/结构体数组的剪切板应用模板类



//用于自定义数组/结构体数组的剪切板应用类
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;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值