牢骚牢骚rich edit,他给我找了不小的麻烦,等到中文能选半个字的时候我才知道原来那个东西还有中英文之分的,然而麻烦还不就只是这一点。
在2000下或更高版本的OS上,rich edit能接收WM_LBUTTONUP消息,然而98下,只接收一次,第二次就不理你了,至少MFC编译出来的代码是这样,没有在SDK上作过试验。
richedit.SetWindowText("a");
richedit.SetSel(0,-1);
richedit.GetSel(nStart,nEnd);
nEnd等于几?
1?很可能是3,然而也未必。
那你需要看是不是在之前调用过 richedit.SetDefaultFormat()了,调过之后和调过之前肯定是不一样的
为何有麻里麻烦
richedit.SetWindowText("a");
richedit.SetSel(0,-1);
richedit.GetSel(nStart,nEnd);
为什么不 string.GetLength()呢?
问题是GetLength()返回的是字节数,而在VC6下,SetSel()未必就是以字节数来设定选择范围的,拉丁字母,例如,是两个字节然而要选购中一个拉丁字母肯定要 SetSel(nStart,nStart + 1),然而中文又要必须 SetSel(nStart,nStart + 2)了,至于有没有 + 3 ,+4的,我不知道。我碰到这问题后,想得一个偷懒办法就是做一个隐藏的rich edit,例如字符串 ASDL,我要选D,怎么办,我不知道D前有些什么样的字符,那就先把AS放在隐藏rich edit之后,全选再用GetSel得到范围,nEnd就是D的nStart,然后ASD放入隐藏rich edit,如前得到nEnd,那这个范围就可以确保能够选到D了。可要注意两个RichEdit不能一个调用另一个不调用SetDefaultFormat(),否则结果未知。
,Net下编译的richEdit统统以字符作为单位,倒免去了这一大堆麻烦,然而还需要与VC 6下的做某种转换,大约是一个偏移量,我记不住了,然而即便.NEt也不能解决WM_LBUTTONUP消息问题,我的解决办法是干脆用鼠标钩子。
附:字节索引与字符索引转换函数:
int CharIndexToMultiIndex(CString strSrc,int nIndex){
int nLen = strSrc.GetLength();
if(nIndex < 0)
return -1;
if(nLen <= nIndex )
nIndex = nLen;
CString strText = strSrc.Left(nIndex);
nLen = _mbslen((unsigned char*)(LPCTSTR)strText);
return nLen;
}
int MultiIndexToCharIndex(CString strSrc,int nIndex){
unsigned char *pCh = (unsigned char*)(LPCTSTR)strSrc;
char *pChCur = (char*)pCh;
int nLen = _mbslen(pCh);
if(nLen < nIndex)
return strSrc.GetLength();
if( nIndex < 0)
return -1;
for(int i = 0; i < nIndex; i++){
pChCur = CharNext(pChCur);
}
int nRet = (int)pChCur - (int)pCh;
return nRet;
}
小技巧:判断一段文字多少个双字节字符多少个单字节字符函数:
int nBytes = strText.GetLength();
int nMultiBytes = _mbslen((unsigned char*)(LPCSTR)strText);
int nChinese = nBytes - nMultiBytes;
int nEnglish = nBytes - nChinese * 2;
常用函数:
CString GetSelText(); //获得选中的文本内容
GetSel(int st,int end); //获得选择文本的位置
LimitText(int); //限制最大输入文本的大小
LineCount(); //行数
Int LineLength(int ); //行的长度
Int LineIndex(int); //行的序号
GetLine(); //行的内容
Int n = GetFirstVisibleLine(); //移动滚动条
LineScroll(-n,0);