回 帖 发 新 帖 刷新版面

主题:RichEdit控件的疑难问题

我想用EM_STREAMIN从RichEdit控件中导出数据,可每次执行完一次EditStreamCallBack函数后(第一次执行该函数不会出异常),程序即会出现异常,而且程序中断的位置在主窗口回调函数的: 
return   DefWindowProc(hwnd,   message,   wParam,   lParam); 

这让我搞不懂异常到底是出在哪里,一个不明白的地方是: 
EditStreamCallBack(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG   *pcb); 
dwCookie是首先由程序员在EDITSTREAM结构中指定的,此后在EditStreamCallBack中
我们是不是就不需要再对其进行更改了? 

除此外我的EditStreamCallBack采用的是类的静态成员函数形式(编程需要),再说
别的吗... 实在找不出什么地方能导致这个奇怪的异常了...晕[em10]

回复列表 (共5个回复)

沙发

能否把你的问题简化后(只把出问题的代码拣出来)放在一个程序里,然后把代码放上来看看,这样更容易发现问题。

另外,查查是否是参数的类型或者值不符合,指针有没有问题。

再有,静态成员函数只能更改类的静态成员,而且没有this指针,查查这些地方是否出了问题。

板凳

class   CRichEdit   
    { 
      /*从控件获取完整数据(文字+格式信息),返回获取的数据大小   */ 
      int   GetData(BYTE   *   outBuffer,   DWORD   bufferSize); 

      /*向控件导入数据,成功返回控件获取的数据大小*/ 
      int   SetData(BYTE   *   inBuffer,   DWORD   Size); 

      static   DWORD   dataSize   ; 
      static   DWORD   validSize   ; 

      static   DWORD   EditStreamInCallback(                   
        DWORD_PTR   dwCookie, 
        LPBYTE   pbBuff, 
        LONG   cb, 
        LONG   *pcb   ); 

      static   DWORD   EditStreamOutCallback(                   
        DWORD_PTR   dwCookie, 
        LPBYTE   pbBuff, 
        LONG   cb, 
        LONG   *pcb   ); 

      EDITSTREAM   es   ; 

    };//end   class 

    DWORD   CRichEdit::dataSize   ; 
    DWORD   CRichEdit::validSize   ; 
      

  int   CRichEdit::GetData(BYTE   *   outBuffer,   DWORD   bufferSize) 
  { 
      dataSize=0; 
      validSize=bufferSize   ;//表示接收区有多少空间可用 

      es.dwCookie=(DWORD_PTR   )outBuffer   ; 
      es.dwError=0; 
      
      es.pfnCallback=(EDITSTREAMCALLBACK)EditStreamOutCallback   ; 

      SendMessage((pCWI+index)-> hwnd,EM_STREAMOUT,(WPARAM)SF_RTF,(LPARAM)&es); 

      return   (dataSize   ); 
  }//end   fun 


  /*成功返回控件获得的数据大小*/ 
  int   CRichEdit::SetData(BYTE   *   inBuffer,   DWORD   Size) 
  { 
      dataSize=0; 

      //validSize表示需要向控件写入的数据 
      validSize=Size   ; 

      es.dwCookie=(DWORD_PTR   )inBuffer   ; 
      es.dwError=0; 
      
      es.pfnCallback=(EDITSTREAMCALLBACK)EditStreamInCallback   ; 

      SendMessage((pCWI+index)-> hwnd,EM_STREAMIN   ,(WPARAM)SF_RTF,(LPARAM)&es)   ; 
  
      return   (dataSize); 
  }//end   fun 


  DWORD   CRichEdit::EditStreamInCallback(   DWORD_PTR   dwCookie,LPBYTE   pbBuff,LONG   cb,LONG   *pcb   ) 
  {         

if(     validSize   <   cb   ) 

*pcb   =   validSize; 

CopyMemory(   pbBuff,(PBYTE)(dwCookie),*pcb   ); 
                validSize=0;//没有数据需要向控件写入 
                  dataSize+=(*pcb)   ;   

else   

*pcb   =   cb; 
CopyMemory(   pbBuff,(PBYTE)(dwCookie),*pcb   ); 
validSize-=(*pcb)   ;//还有多少数据需要向控件写入 
dataSize+=(*pcb)   ;     

        
        return   0; 
  }//end   fun 


  DWORD   CRichEdit::EditStreamOutCallback(   DWORD_PTR   dwCookie,LPBYTE   pbBuff,LONG   cb,LONG   *pcb   ) 
  { 
        
      if(validSize> =cb)//表示接收区有多少空间可用 
      { 
        CopyMemory(   (PBYTE)(dwCookie),pbBuff,cb   ); 
      *pcb   =   cb; 

        validSize-=*pcb   ; 
        dataSize+=*pcb; 
      } 
      else   if(validSize> 0) 
      { 
        CopyMemory(   (PBYTE)(dwCookie),pbBuff,validSize   ); 
        *pcb   =   validSize; 
        validSize=0   ; 
        dataSize+=*pcb; 
      } 
          return   0; 
  }//end   fun 

3 楼

还是不太明白,为什么不用现成的CRichEdit或者从它派生呢?

你的这个类是做什么用的,怎么用?所以这么问是因为这种错误往往在调试中更容易发现问题,所以我想建个工程跟一下。

4 楼

我是先从win32 api学起的, 我不会MFC,而C#刚学. 自己用api 封装个类用.
当程序异常后,选择调试,可程序中断在  DefWindowProc ,凭此实在难以判断问题出在哪

5 楼

问题解决: 

回调函数声明一定要加CALLBACK

我来回复

您尚未登录,请登录后再回复。点此登录或注册