求一个在richeditctrl中向前快速查找的方法,我现在实现了一种低效率的向前查找的办法,用起来太慢,想知道windows是如何向前查找的,或者有没有方法调用向前查找对话框但是不出来这个对话框。

解决方案 »

  1.   


    如何得到richeditctrl的文本缓冲区?
      

  2.   


    去查一下 FINDMSGSTRING,网上应该有示例代码。
      

  3.   

    //从一个CRichEditCtrl的控件中开始查找,向前查找,只调试成功向前,向后有现成的方法。FindText
    //实际效率,未知
    //为了提高效率,还设置了一个全局的文本缓冲区g____richedittext,每次当查找且文本被修改后做一次同步,然后从内存中查找。extern char *g____richedittext;
    extern unsigned long g____richedittextlength;
    extern CRichEditCtrl *g____pEdit;//在buffer中查找,如果direct是TRUE,则由前往后查找,否则从后往前查找
    //找到从buffer开始的偏移,找不到返回0xFFFFFFFF
    unsigned long
    FindWord( unsigned char *buffer, unsigned long buflength, unsigned char *str, unsigned long strlength, BOOL direct )
    {
    unsigned long len, i;

    if( buflength < strlength )
    {
    return 0xffffffff;
    }

    len = buflength - strlength;
    if( !len )
    {
    if( !memcmp( buffer, str, buflength ) )
    {
    return 0;
    }
    else
    {
    return 0xffffffff;
    }
    }

    if( direct )
    {
    //从前往后找
    for( i = 0; i < len; i++ )
    {
    if( *buffer == *str )
    {
    //比较第一个字节一致
    if( !memcpy( buffer, str, strlength ) )
    {
    //全一致
    return i;
    }
    }
    buffer++;
    }
    return 0xffffffff;
    }
    else
    {
    //从前往后找
    buffer += len;
    for( i = ( len - 1 ); i != 0xffffffff; i-- )
    {
    if( *buffer == *str )
    {
    //比较第一个字节一致
    if( !memcmp( buffer, str, strlength ) )
    {
    //全一致
    return i;
    }
    }
    buffer--;
    }
    return 0xffffffff;
    }
    }//查找缓冲区,如果找到的话,就返回TRUE,找不到返回FALSE。
    BOOL
    SearchBuf( char *buffer, unsigned long buflength, char * searchstring, BOOL direct, OUT unsigned long *start )
    {
    size_t searchlength = strlen( searchstring );

    unsigned long result = FindWord( ( unsigned char * )buffer, buflength, ( unsigned char * )searchstring, searchlength, direct );

    if( 0xffffffff != result )
    {
    *start = result;
    return TRUE;
    }

    return FALSE;
    }
    //TRUE找到
    //FALSE没找到
    BOOL SearchEdit( CRichEditCtrl *pEdit, char *searchstring, BOOL direct, IN OUT unsigned long *start, IN OUT unsigned long *finish )
    {
    char *buffer = NULL;
    size_t i;
    char *p, *q;
    BOOL result;
    unsigned long oldstart;

    if( !*searchstring )
    {
    return FALSE;
    }
    g____richedittextlength = pEdit->GetTextLength();
    if( !g____richedittextlength )
    {
    return FALSE;
    }

    try
    {
    if( !g____richedittext )
    {
    //空间没有申请
    REMOVE_0D0A:
    pEdit->SetModify( FALSE );
    g____richedittext = new char[ g____richedittextlength + 0x10 ];
    buffer = new char[ g____richedittextlength + 0x10 ];
    memset( buffer, 0, g____richedittextlength + 0x10 );
    memset( g____richedittext, 0, g____richedittextlength + 0x10 );
    pEdit->GetWindowText( buffer, g____richedittextlength + 0x10 );
    //去掉0a,0d和0a应该算一个字符,最好的办法是将0d0a或单个的0d0a换成一个空格
    p = buffer;
    q = g____richedittext;
    for( i = 0; i < g____richedittextlength; i++ )
    {
    //if( 0x0d != *p && 0x0a != *p )
    if( 0x0a != *p )
    {
    *q = *p;
    q++;
    }
    p++;
    }
    }
    else
    {
    //空间已经申请
    if( pEdit->GetModify() )
    {
    delete []g____richedittext;
    g____richedittext = NULL;
    goto REMOVE_0D0A;
    }
    else
    {
    //无操作
    }
    }

    oldstart = *start;
    result = SearchBuf( g____richedittext + *start, *finish - *start, searchstring, direct, start );
    if( TRUE == result )
    {
    *start += ( 1 + oldstart );
    *finish = *start + strlen( searchstring );
    }
    }
    catch( ... )
    {
    throw;
    } if( buffer )
    {
    delete []buffer;
    buffer = NULL;
    }
    return result;
    }
    //调用演示
    //g____pEdit是一个CRichEditCtrl型指针
    void CXXXXX::OnSearchPrev( void )
    {
    long s, e;
    unsigned long start, finish;
    BOOL result; g____pEdit->GetSel( s, e ); start = 0;
    finish = e - 1; result = SearchEdit( g____pEdit, "===", FALSE, &start, &finish ); if( result )
    {
    g____pEdit->SetSel( start, finish );
    }
    else
    {
    start = e;
    finish = g____pEdit->GetTextLength();
    result = SearchEdit( g____pEdit, "===", FALSE, &start, &finish );
    if( result )
    {
    g____pEdit->SetSel( start, finish );
    }
    }
    }
      

  4.   

    将待搜索的文字与搜索字符串全都转换成ucs2格式的,并且小写转大写,那样就正确了。我做一下调试。
      

  5.   

    //在buffer中查找,如果direct是TRUE,则由前往后查找,否则从后往前查找
    //找到从buffer开始的偏移,找不到返回0xFFFFFFFF
    unsigned long
    FindWord( unsigned char *buffer, unsigned long buflength, unsigned char *str, unsigned long strlength, BOOL direct )
    {
    unsigned long len, i;

    if( buflength < strlength )
    {
    return 0xffffffff;
    }

    len = buflength - strlength; if( !len )
    {
    if( !memcmp( buffer, str, strlength ) )
    {
    return 0;
    }
    else
    {
    return 0xffffffff;
    }
    }

    if( direct )
    {
    //从前往后找
    for( i = 0; i < ( len / 2 ); i++ )
    {
    if( *( buffer + 1 ) == *( str + 1 ) )
    {
    //比较第一个字节一致
    if( !memcpy( buffer, str, strlength ) )
    {
    //全一致
    return i * 2;
    }
    }
    buffer += 2;
    }
    return 0xffffffff;
    }
    else
    {
    //从前往后找
    buffer += len;
    for( i = ( len / 2 ); i != 0xffffffff; i-- )
    {
    if( *( buffer + 1 ) == *( str + 1 ) )
    {
    //比较第一个字节一致
    if( !memcmp( buffer, str, strlength ) )
    {
    //全一致
    return i * 2;
    }
    }
    buffer -= 2;
    }
    return 0xffffffff;
    }
    }//查找缓冲区,如果找到的话,就返回TRUE,找不到返回FALSE。
    BOOL
    SearchBuf( char *buffer, unsigned long buflength, char * searchstring, unsigned long searchlength, BOOL direct, OUT unsigned long *start )
    {
    unsigned long result = FindWord( ( unsigned char * )buffer, buflength, ( unsigned char * )searchstring, searchlength, direct );

    if( 0xffffffff != result )
    {
    *start = result;
    return TRUE;
    }

    return FALSE;
    }//TRUE找到
    //FALSE没找到
    BOOL SearchEdit( CRichEditCtrl *pEdit, char *searchstring, BOOL direct, IN OUT unsigned long *start, IN OUT unsigned long *finish )
    {
    char *buffer = NULL;
    char *ucs2buffer = NULL;
    char *searchbuffer = NULL;
    size_t i;
    char *p, *q;
    BOOL result;
    unsigned long oldstart, searchlength;

    if( !*searchstring )
    {
    return FALSE;
    }
    g____richedittextlength = pEdit->GetTextLength();
    if( !g____richedittextlength )
    {
    return FALSE;
    }

    try
    {
    if( !g____richedittext )
    {
    //空间没有申请
    REMOVE_0D0A:
    pEdit->SetModify( FALSE ); buffer = new char[ g____richedittextlength + 0x10 ];
    ucs2buffer = new char[ 2 * g____richedittextlength + 0x10 ];
    g____richedittext = new char[ 2 * g____richedittextlength + 0x10 ]; memset( buffer, 0, g____richedittextlength + 0x10 );
    memset( ucs2buffer, 0, 2 * g____richedittextlength + 0x10 );
    memset( g____richedittext, 0, 2 * g____richedittextlength + 0x10 ); pEdit->GetWindowText( buffer, g____richedittextlength + 0x10 );
    //去掉0a,0d和0a应该算一个字符,最好的办法是将0d0a或单个的0d0a换成一个空格
    p = buffer;
    q = ucs2buffer;
    for( i = 0; i < g____richedittextlength; i++ )
    {
    //if( 0x0d != *p && 0x0a != *p )
    if( 0x0a != *p )
    {
    *q = *p;
    q++;
    }
    p++;
    } //小写转大写
    g____richedittextlength = ( unsigned long )( q - ucs2buffer );
    p = ucs2buffer;
    for( i = 0; i < g____richedittextlength; i++ )
    {
    if( *p >= 'a' && *p <= 'z' )
    {
    *p -= 0x20;
    }
    p++;
    } g____richedittextlength = s2u( ucs2buffer, ( unsigned char * )g____richedittext, g____richedittextlength ); }
    else
    {
    //空间已经申请
    if( pEdit->GetModify() )
    {
    delete []g____richedittext;
    g____richedittext = NULL;
    goto REMOVE_0D0A;
    }
    else
    {
    //无操作
    }
    }
    //处理searchstr
    oldstart = strlen( searchstring );
    Ucase( searchstring ); //临时加入
    searchbuffer = new char[ oldstart * 2 + 0x10 ];
    searchlength = oldstart * 2;
    memset( searchbuffer, 0, searchlength + 0x10 );
    searchlength = s2u( searchstring, ( unsigned char * )searchbuffer, oldstart ); oldstart = ( *start * 2 );
    result = SearchBuf( g____richedittext + ( oldstart ), ( *finish - *start ) * 2, searchbuffer, searchlength, direct, start );
    if( TRUE == result )
    {
    *start += ( oldstart );
    *finish = *start + searchlength;
    *start /= 2;
    *finish /= 2;
    }
    }
    catch( ... )
    {
    if( buffer )
    {
    delete []buffer;
    buffer = NULL;
    }

    if( ucs2buffer )
    {
    delete []ucs2buffer;
    ucs2buffer = NULL;
    }

    if( searchbuffer )
    {
    delete []searchbuffer;
    searchbuffer = NULL;
    }
    throw;
    } if( buffer )
    {
    delete []buffer;
    buffer = NULL;
    } if( ucs2buffer )
    {
    delete []ucs2buffer;
    ucs2buffer = NULL;
    } if( searchbuffer )
    {
    delete []searchbuffer;
    searchbuffer = NULL;
    }
    return result;
    }我试成了。