主题:RichEdit控件的疑难问题
win32fan
[专家分:60] 发布于 2008-02-16 16:18:00
我想用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个回复)
沙发
华山论剑 [专家分:5310] 发布于 2008-02-18 09:30:00
能否把你的问题简化后(只把出问题的代码拣出来)放在一个程序里,然后把代码放上来看看,这样更容易发现问题。
另外,查查是否是参数的类型或者值不符合,指针有没有问题。
再有,静态成员函数只能更改类的静态成员,而且没有this指针,查查这些地方是否出了问题。
板凳
win32fan [专家分:60] 发布于 2008-02-18 11:10:00
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 楼
华山论剑 [专家分:5310] 发布于 2008-02-18 12:41:00
还是不太明白,为什么不用现成的CRichEdit或者从它派生呢?
你的这个类是做什么用的,怎么用?所以这么问是因为这种错误往往在调试中更容易发现问题,所以我想建个工程跟一下。
4 楼
win32fan [专家分:60] 发布于 2008-02-18 15:53:00
我是先从win32 api学起的, 我不会MFC,而C#刚学. 自己用api 封装个类用.
当程序异常后,选择调试,可程序中断在 DefWindowProc ,凭此实在难以判断问题出在哪
5 楼
win32fan [专家分:60] 发布于 2008-02-20 13:43:00
问题解决:
回调函数声明一定要加CALLBACK
我来回复