系统: windows XP先说明下要解决的问题:RichEdit控件(实现了一系列接口后能够导出RTF格式文本的),比如说系统的写字板。
你先用windows自带的画图程序打开任一幅JPEG图像,然后COPY。再打开系统自带的写字板,PASTE,你发现图像已粘到了写字板中。不过别高兴太早,你点保存后关闭文档,再打开--发现里面并没有图像。核实文档大小---图像确未被导出保存。
虽然上述现像仅是在特定条件下才会出现,但本着追求完美的愿望,我将其一个解决方法公布(应该还有更好办法)
我分析了剪贴板中数据类型,发现不管是由画图程序,还是其它程序送来的图像数据,都以CF_DIB类型为主。那即然都以此为主,为什么偏偏RichEdit就不导出画图程序送到剪贴板的数据呢? 我对图像格式及OLE这些东西并不了解。但猜测是不是有画蛇添足的东西,于是我将RichEdit控件窗口子类化,捕获CTRL+V,然后导出CF_DIB数据,再清空剪贴板,最后用先前导出的数据重设剪贴板。(剪贴板中原先有好几种数据类型呢) 哈哈,问题居然由此解决了!!
贴上相关代码:(本人是用API的)
//提供对windows剪贴板操作的支持 该函数应使用new方法来创建(别忘了delete)class CClipboard{public :CClipboard();
~CClipboard();
//失败返回0
UINT GetNextStyle(void);//头一次调用该函数O_buffer赋NULL,获取数据长度先
BOOL GetData(UINT I_style,PBYTE O_buffer,size_t & O_size);BOOL SetData(UINT I_style,PBYTE I_buffer,size_t  I_size);//清空剪贴板
BOOL Empty(void);private :
UINT formatsStyle[16];
};//end class
CClipboard::CClipboard()
{
 int n=0;
 UINT iFormat=0; for(int i=0;i<16;++i)
 {formatsStyle[i]=0;} if( OpenClipboard (NULL) )
 {
   while ( iFormat = EnumClipboardFormats (iFormat) ) 
   { 
       formatsStyle[n] = iFormat;    if( (++n)>15 )
   break ; 
   }
  
 }//end if}//end fun
CClipboard::~CClipboard()
{ CloseClipboard () ;}//end funUINT CClipboard::GetNextStyle(void)
{
 static int i=0; if(i==16)
 {i=0; return 0 ;} return ( formatsStyle[i++] );}//end fun
BOOL CClipboard::GetData(UINT I_style,PBYTE O_buffer,size_t & O_size)
{
 GLOBALHANDLE hGlobal ;
 LPVOID pGlobal ;
 
 if( NULL == (hGlobal = (GLOBALHANDLE)GetClipboardData (I_style)) )
 {
  MessageBox(NULL,TEXT("GetClipboardData失败!"),TEXT("CClipboard::GetData"),MB_ICONSTOP);
  return FALSE ;
 } O_size=GlobalSize (hGlobal); if(O_buffer==NULL)
 {return TRUE;} pGlobal = GlobalLock (hGlobal) ;
 CopyMemory(O_buffer,(PBYTE)pGlobal,O_size); GlobalUnlock (hGlobal) ; return TRUE ;}//end fun
BOOL CClipboard::Empty(void)
{
  return EmptyClipboard( ) ;}//end fun
BOOL CClipboard::SetData(UINT I_style,PBYTE I_buffer,size_t  I_size)
{
 GLOBALHANDLE hGlobal ;
 LPVOID pGlobal ; if( NULL==(hGlobal = GlobalAlloc (GHND | GMEM_SHARE, I_size)) )
 {
  MessageBox(NULL,TEXT("分配内存失败!"),TEXT("CClipboard::SetData"),MB_ICONSTOP);
  return FALSE ;
 } pGlobal = GlobalLock (hGlobal) ; CopyMemory((PBYTE)pGlobal,I_buffer,I_size); GlobalUnlock (hGlobal) ; if ( NULL==SetClipboardData (I_style, hGlobal) )
 {
  MessageBox(NULL,TEXT("SetClipboardData失败!"),TEXT("CClipboard::SetData"),MB_ICONSTOP);
  return FALSE ;
 } return TRUE ;
}//end fun
////////////////////////////////////////////
//窗口子类化RichEdit 
LRESULT CALLBACK EditProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)     
{
 
  CClipboard * pClb = NULL ;
  UINT style=0;
  size_t size ;
  PBYTE pb=NULL;  if(message==WM_KEYDOWN)
  {
    //如果按下了CTRL+V
    //目的是要修正剪贴薄中图像
  if ( (wParam==86) && ((GetKeyState(VK_CONTROL) && 0x1000) == 1) ) 
  {
pClb=new CClipboard();
       
        while(style=pClb->GetNextStyle())
        {
  if(style==CF_DIBV5)//处理CF_DIB应该一样
  {
           pClb->GetData(style,NULL,size);
   pb=(PBYTE)malloc(size+2);

   if (! pClb->GetData(style,pb,size))
   {break;}    pClb->Empty();    pClb->SetData(style,pb,size);
   }
}         delete pClb ;
  
     }// if ( (wParam==86)...
  }//end  if(message==WM_KEYUP)     return CallWindowProc (edit.OldProc, hwnd, message, wParam, lParam) ;  
   
}//end fun欢迎大家批抨指正!本人QQ 184263203