最近在做一个工具软件(Cool Query),但是显示的代码不能和查询分析器一样显示不同的颜色,知道的志同请赐教

解决方案 »

  1.   

    我最近也在写一个练手的程序,我发现现在第三方的所有的支持代码高亮的程序全部都不完美(除了Delphi,VC,C++ Builder)这样的商业程序以外,其余的都有很多错误,包括UE
      

  2.   

    其它第三方控件就可以的啊/
    mwEdit控件
      

  3.   

    Tmemo可发对特定的字(/字串)改字体色彩,必须知道位置
      

  4.   

    richEdit可以做到,但是在保存时会有格式在里面。
      

  5.   

    用RichEdit来做,保存时不要直接用RichEdit的保存,可以用其它方法,不保存格式。
      

  6.   

    在 RichEdit 中实现代码着色下面的代码将以指定颜色对一些指定单词着色,就象delphi中的代码编辑器那样。procedure CodeColors(Form : TForm;Style : String; RichE : TRichedit;
                             InVisible : Boolean);
    const
      // 符号...
      CodeC1: array[0..20] of String = ('#','$','(',')','*',',',
              '.','/',':',';','[',']','{','}','<','>',
              '-','=','+','''','@');
      // 保留字...
      CodeC2: array[0..44] of String = ('and','as','begin',
              'case','char','class','const','downto',
              'else','end','except','finally','for',
              'forward','function','if','implementation','interface',
              'is','nil','or','private','procedure','public','raise',
              'repeat','string','to','try','type','unit','uses','var',
              'while','external','stdcall','do','until','array','of',
              'in','shr','shl','cos','div');
    var
      FoundAt : LongInt;
      StartPos, ToEnd, i : integer;
      OldCap,T : String;
      FontC, BackC, C1, C2 ,C3 ,strC, strC1 : TColor;
    begin
      OldCap := Form.Caption;
      with RichE do
      begin
        Font.Name := 'Courier New';
        Font.Size := 10;
        if WordWrap then WordWrap := false;
        SelectAll;
        SelAttributes.color := clBlack;
        SelAttributes.Style := [];
        SelStart := 0;
        if InVisible then
        begin
          Visible := False;
          Form.Caption := 'Executing Code Coloring...';
        end;
      end;  BackC := clWhite; FontC := clBlack;
      C1 := clBlack; C2 := clBlack; C3 := clBlack;
      strC := clBlue; strC1 := clSilver;  if Style = 'Twilight' then
      begin
        BackC := clBlack; FontC := clWhite;
        C1 := clLime; C2 := clSilver; C3 := clAqua;
        strC := clYellow; strC1 := clRed;
      end
      else
      if Style = 'Default' then
      begin
        BackC := clWhite; FontC := clBlack;
        C1 := clTeal; C2 := clMaroon; C3 := clBlue;
        strC := clMaroon; strC1 := clSilver;
      end
      else
      if Style = 'Ocean' then
      begin
        BackC := $00FFFF80; FontC := clBlack;
        C1 := clMaroon; C2 := clBlack; C3 := clBlue;
        strC := clTeal; strC1 := clBlack;
      end
      else
      if Style = 'Classic' then
      begin
        BackC := clNavy; FontC := clYellow;
        C1 := clLime; C2 := clSilver; C3 := clWhite;
        strC := clAqua; strC1 := clSilver;
      end
      else
      begin
        with RichE do
        begin
          T := '{'+Style+' = Invalid Style [Default,Classic,Twilight,Ocean] ONLY! }';
          Lines.Insert(0,T);
          StartPos := 0;
          ToEnd := Length(Text) - StartPos;
          FoundAt := FindText(T, StartPos, ToEnd, [stWholeWord]);
          SelStart := FoundAt;
          SelLength := Length(T);
          SelAttributes.Color := clRed;
          SelAttributes.Style := [fsBold];
          StartPos := 0;
          ToEnd := Length(Text) - StartPos;
          FoundAt := FindText('ONLY!', StartPos, ToEnd, [stWholeWord]);
          SelStart := FoundAt;
          SelLength := 4;
          SelAttributes.Color := clRed;
          SelAttributes.Style := [fsBold,fsUnderLine];
        end;
      end;  RichE.SelectAll;
      RichE.color := BackC;
      RichE.SelAttributes.color := FontC;  for i := 0 to 100 do
      begin
        with RichE do
        begin
          StartPos := 0;
          ToEnd := Length(Text) - StartPos;
          FoundAt := FindText(IntToStr(i), StartPos, ToEnd, [stWholeWord]);
          while (FoundAt <> -1) do
          begin
            SelStart := FoundAt;
            SelLength := Length(IntToStr(i));
            SelAttributes.Color := C1;
            SelAttributes.Style := [];
            StartPos := FoundAt + Length(IntToStr(i));
            FoundAt := FindText(IntToStr(i), StartPos, ToEnd, [stWholeWord]);
          end;
        end;
      end;
      for i := 0 to 20 do
      begin
        with RichE do
        begin
          StartPos := 0;
          ToEnd := Length(Text) - StartPos;
          FoundAt := FindText(CodeC1[i], StartPos, ToEnd, []);
          while (FoundAt <> -1) do
          begin
            SelStart := FoundAt;
            SelLength := Length(CodeC1[i]);
            SelAttributes.Color := C2;
            StartPos := FoundAt + Length(CodeC1[i]);
            FoundAt := FindText(CodeC1[i], StartPos, ToEnd, []);
          end;
        end;
      end;
      for i := 0 to 44 do
      begin
        with RichE do
        begin
          StartPos := 0;
          ToEnd := Length(Text) - StartPos;
          FoundAt := FindText(CodeC2[i], StartPos, ToEnd, [stWholeWord]);
          while (FoundAt <> -1) do
          begin
            SelStart := FoundAt;
            SelLength := Length(CodeC2[i]);
            SelAttributes.Color := C3;
            SelAttributes.Style := [fsBold];
            StartPos := FoundAt + Length(CodeC2[i]);
            FoundAt := FindText(CodeC2[i], StartPos, ToEnd, [stWholeWord]);
          end;
        end;
      end;
      Startpos := 0;
      with RichE do
      begin
        FoundAt := FindText('''', StartPos, Length(Text), []);
        while FoundAt <> -1 do
        begin
          SelStart := FoundAt;
          Startpos := FoundAt+1;
          FoundAt := FindText('''', StartPos, Length(Text), []);
          if FoundAt <> -1 then
          begin
            SelLength := (FoundAt - selstart)+1;
            SelAttributes.Style := [];
            SelAttributes.Color := strC;
            StartPos := FoundAt+1;
            FoundAt := FindText('''', StartPos, Length(Text), []);
          end;
        end;
      end;  Startpos := 0;
      with RichE do
      begin
        FoundAt := FindText('{', StartPos, Length(Text), []);
        while FoundAt <> -1 do
        begin
          SelStart := FoundAt;
          Startpos := FoundAt+1;
          FoundAt := FindText('}', StartPos, Length(Text), []);
          if FoundAt <> -1 then
          begin
            SelLength := (FoundAt - selstart)+1;
            SelAttributes.Style := [];
            SelAttributes.Color := strC1;
            StartPos := FoundAt+1;
            FoundAt := FindText('{', StartPos, Length(Text), []);
          end;
        end;
      end;     if InVisible then
      begin
        RichE.Visible := True;
        Form.Caption := OldCap;
      end;
      RichE.SelStart := 0;
    end; 
    --------------------------------------------------------------------------------
     
      

  7.   

    第三十五课: RichEdit 控件:语法高亮显示
    在读这篇教程之前先提醒你,这是一个复杂的主题:不适合初学者。这是最后一篇RichEdit 控件教程。例子.Theory
    语法高亮显示对那些编写文本编辑器的人来说是一个热点主题。最好的解决方法(我自己认为的)是编写一个定制的Edit控件,这也是很多商业软件所使用的方法。然而,对于那些没什么时间来编写这么一个控件的人来说,次策就是改写现有的控件使之符合我们的需要。让我们看一看,到底 RichEdit 控件提供了什么功能来帮助我们实现语法高亮。现在我应该声明,下面的方法不是一个“正确”方法:我只是给你们指出那些缺陷。 RichEdit 控件提供了EM_SETCHARFORMAT 消息,是你可以用来改变正文颜色。乍一看,这个消息好象是一个完美的解决方法(我之所以知道是因为我也是其中的一个受骗者)。然而靠近看看,将会发现有几个不合意的地方:EM_SETCHARFORMAT 仅仅对选定的正文或者控件中所有的正文有影响。如果你想改变正文颜色(高亮显示某一个特定的词),你必须先选定它。 
    EM_SETCHARFORMAT 执行速度很慢。 
    RichEdit 控件中的插入点位置处理也有一点问题。 
    通过上面的讨论,你可以看到使用 EM_SETCHARFORMAT 是一个错误的选择,我会给你演示 "相当正确" 的选择。我现在使用的方法是“即时语法高亮”,我只高亮显示可见部分的正文。因此高亮显示的速度跟文件的大小根本是无关的。无论是多大的文件,在某一时刻只有一小部分是可见的。怎么样实现?答案很简单: 子类化RichEdit控件并在你自己的窗口处理函数中处理 WM_PAINT 消息。 
    当收到 WM_PAINT 消息时,它调用RichEdit控件原来的窗口过程,让它正常地更新屏幕。 
    之后,我们将要高亮显示的词用不同的颜色来覆盖掉。 
    当然了,路也不是这么容易走的:仍然有两个次要的问题需要矫正,不过上面的方法工作起来很好。显示速度令人很满意。现在让我们集中在细节上。子类化处理是很简单的,不需要很多注意力。真正复杂的部分是:我们必须找到一个快速的方法来搜索那些需要高亮的词。更复杂的那些在某个注释块里的 不 需要高亮显示的词。 我使用的方法可能不是最好的,但是它工作的很好。我敢肯定你可以找到更快的方法。不管怎么说,先看看我下面的方法:我创建一个有256元素的双字(DWORD)数组,全部初始化为0。每一个元素对应一个可能的 ASCII 字符,数组名叫 ASMSyntaxArray。例如,第21个元素代表ASCII 20h (空格字符)。我将他们作为快速查询表使用:譬如,假定我有一个词 "include",我从词中分离出第一个字符 (i) ,并以响应索引查找数组。如果该元素为0,我就立刻知道需要高亮的词是没有以 "i" 开头的。如果该元素非0,它就包含一个指针,指向一个 WORDINFO 结构的链表。里面包含了需要高亮词的信息。 
    我读取需要高亮显示的词,并为每个词创建一个 WORDINFO 结构。 
    WORDINFO struct 
    WordLen dd ?  ; 词的长度,用来快速比较
    pszWord dd ?         ; 词的指针
    pColor dd ?  ; 用来高亮显示的颜色所在的DWORD的指针
    NextLink dd ?  ; 下一个 WORDINFO 结构
    WORDINFO ends 正如你所看到的,我使用词的长度来作为第二个快速比较方法。如果词中的第一个字符匹配后,我们下一个比较的是词的才长度。ASMSyntaxArray 中的每一个元素包含了一个指针,指向一个相关的WORDINFO 数组.例如,代表字符 "i" 的元素将会包含一个指向以"i"开头的词的链表。 pColor 成员指向一个DWORD,包含用来做高亮显示该词的颜色值。pszWord 指向要高亮显示的词。是小写形式的。链表的内存是从堆(heap)中分配的,速度快,容易清除,也就是说根本不用清楚。 
    高亮词列表保存在文件 "wordfile.txt"中,我通过 GetPrivateProfileString API 函数来访问。我提供了多达10种不同的语法颜色,从 C1 到 C10。颜色数组名叫 ASMColorArray。每一个 WORDINFO 结构的 pColor 成员都指向 ASMColorArray 中的某一个元素。因此闲时很容易改变语法颜色:你只需要改变 ASMColorArray 中的元素的值,这样所有使用那种颜色高亮的词就立刻使用新颜色显示。
      

  8.   

    例子
    .386
    .model flat,stdcall
    option casemap:none
    include \masm32\include\windows.inc
    include \masm32\include\user32.inc
    include \masm32\include\comdlg32.inc
    include \masm32\include\gdi32.inc
    include \masm32\include\kernel32.inc
    includelib \masm32\lib\gdi32.lib
    includelib \masm32\lib\comdlg32.lib
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.libWinMain proto :DWORD,:DWORD,:DWORD,:DWORDWORDINFO struct
    WordLen dd ? ; 词的长度:用来进行快速比较
    pszWord dd ? ; 词的指针
    pColor dd ? ; 指向某个DWORD,里面包含用来高亮显示词的颜色值。
    NextLink dd ? ; 指向下一个 WORDINFO 结构
    WORDINFO ends.const
    IDR_MAINMENU                   equ 101
    IDM_OPEN                      equ  40001
    IDM_SAVE                       equ 40002
    IDM_CLOSE                      equ 40003
    IDM_SAVEAS                     equ 40004
    IDM_EXIT                       equ 40005
    IDM_COPY                      equ  40006
    IDM_CUT                       equ  40007
    IDM_PASTE                      equ 40008
    IDM_DELETE                     equ 40009
    IDM_SELECTALL                  equ 40010
    IDM_OPTION  equ 40011
    IDM_UNDO equ 40012
    IDM_REDO equ 40013
    IDD_OPTIONDLG                  equ 101
    IDC_BACKCOLORBOX               equ 1000
    IDC_TEXTCOLORBOX               equ 1001
    IDR_MAINACCEL                 equ  105
    IDD_FINDDLG                    equ 102
    IDD_GOTODLG                    equ 103
    IDD_REPLACEDLG                 equ 104
    IDC_FINDEDIT                  equ  1000
    IDC_MATCHCASE                  equ 1001
    IDC_REPLACEEDIT                 equ 1001
    IDC_WHOLEWORD                  equ 1002
    IDC_DOWN                       equ 1003
    IDC_UP                       equ   1004
    IDC_LINENO                   equ   1005
    IDM_FIND                       equ 40014
    IDM_FINDNEXT                  equ  40015
    IDM_REPLACE                     equ 40016
    IDM_GOTOLINE                   equ 40017
    IDM_FINDPREV                  equ  40018
    RichEditID  equ 300
      

  9.   

    .data
    ClassName db "IczEditClass",0
    AppName  db "IczEdit version 3.0",0
    RichEditDLL db "riched20.dll",0
    RichEditClass db "RichEdit20A",0
    NoRichEdit db "Cannot find riched20.dll",0
    ASMFilterString  db "ASM Source code (*.asm)",0,"*.asm",0
    db "All Files (*.*)",0,"*.*",0,0
    OpenFileFail db "Cannot open the file",0
    WannaSave db "The data in the control is modified. Want to save it?",0
    FileOpened dd FALSE
    BackgroundColor dd 0FFFFFFh ; 缺省为白色
    TextColor dd 0 ; 缺省为黑色
    WordFileName db "\wordfile.txt",0
    ASMSection db "ASSEMBLY",0
    C1Key db "C1",0
    C2Key db "C2",0
    C3Key db "C3",0
    C4Key db "C4",0
    C5Key db "C5",0
    C6Key db "C6",0
    C7Key db "C7",0
    C8Key db "C8",0
    C9Key db "C9",0
    C10Key db "C10",0
    ZeroString db 0
    ASMColorArray dd 0FF0000h,0805F50h,0FFh,666F00h,44F0h,5F8754h,4 dup(0FF0000h)
    CommentColor dd 808000h.data?
    hInstance dd ?
    hRichEdit dd ?
    hwndRichEdit dd ?
    FileName db 256 dup(?)
    AlternateFileName db 256 dup(?)
    CustomColors dd 16 dup(?)
    FindBuffer db 256 dup(?)
    ReplaceBuffer db 256 dup(?)
    uFlags dd ?
    findtext FINDTEXTEX <>
    ASMSyntaxArray dd 256 dup(?)
    hSearch dd ? ; 搜索/替换对话框的句柄
    hAccel dd ?
    hMainHeap dd ? ; 堆的句柄
    OldWndProc dd ?
    RichEditVersion dd ?.code
    start:
    mov byte ptr [FindBuffer],0
    mov byte ptr [ReplaceBuffer],0
    invoke GetModuleHandle, NULL
    mov    hInstance,eax
    invoke LoadLibrary,addr RichEditDLL
    .if eax!=0
    mov hRichEdit,eax
    invoke GetProcessHeap
    mov hMainHeap,eax
    call FillHiliteInfo
    invoke WinMain, hInstance,0,0, SW_SHOWDEFAULT
    invoke FreeLibrary,hRichEdit
    .else
    invoke MessageBox,0,addr NoRichEdit,addr AppName,MB_OK or MB_ICONERROR
    .endif
    invoke ExitProcess,eax

    WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:DWORD
    mov   wc.cbSize,SIZEOF WNDCLASSEX
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc, OFFSET WndProc
    mov   wc.cbClsExtra,NULL
    mov   wc.cbWndExtra,NULL
    push  hInst
    pop   wc.hInstance
    mov   wc.hbrBackground,COLOR_WINDOW+1
    mov   wc.lpszMenuName,IDR_MAINMENU
    mov   wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov   wc.hIcon,eax
    mov   wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov   wc.hCursor,eax
    invoke RegisterClassEx, addr wc
    INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
               WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
               CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
               hInst,NULL
    mov   hwnd,eax
    invoke ShowWindow, hwnd,SW_SHOWNORMAL
    invoke UpdateWindow, hwnd
    invoke LoadAccelerators,hInstance,IDR_MAINACCEL
    mov hAccel,eax
    .while TRUE
    invoke GetMessage, ADDR msg,0,0,0
    .break .if (!eax)
    invoke IsDialogMessage,hSearch,addr msg
    .if eax==FALSE
    invoke TranslateAccelerator,hwnd,hAccel,addr msg
    .if eax==0
    invoke TranslateMessage, ADDR msg
    invoke DispatchMessage, ADDR msg
    .endif
    .endif
    .endw
    mov   eax,msg.wParam
    ret
    WinMain endp
      

  10.   

    晕~~我还以为是Delphi的什么教程
      

  11.   

    StreamInProc proc hFile:DWORD,pBuffer:DWORD, NumBytes:DWORD, pBytesRead:DWORD
    invoke ReadFile,hFile,pBuffer,NumBytes,pBytesRead,0
    xor eax,1
    ret
    StreamInProc endpStreamOutProc proc hFile:DWORD,pBuffer:DWORD, NumBytes:DWORD, pBytesWritten:DWORD
    invoke WriteFile,hFile,pBuffer,NumBytes,pBytesWritten,0
    xor eax,1
    ret
    StreamOutProc endpCheckModifyState proc hWnd:DWORD
    invoke SendMessage,hwndRichEdit,EM_GETMODIFY,0,0
    .if eax!=0
    invoke MessageBox,hWnd,addr WannaSave,addr AppName,MB_YESNOCANCEL
    .if eax==IDYES
    invoke SendMessage,hWnd,WM_COMMAND,IDM_SAVE,0
    .elseif eax==IDCANCEL
    mov eax,FALSE
    ret
    .endif
    .endif
    mov eax,TRUE
    ret
    CheckModifyState endpSetColor proc
    LOCAL cfm:CHARFORMAT
    invoke SendMessage,hwndRichEdit,EM_SETBKGNDCOLOR,0,BackgroundColor
    invoke RtlZeroMemory,addr cfm,sizeof cfm
    mov cfm.cbSize,sizeof cfm
    mov cfm.dwMask,CFM_COLOR
    push TextColor
    pop cfm.crTextColor
    invoke SendMessage,hwndRichEdit,EM_SETCHARFORMAT,SCF_ALL,addr cfm
    ret
    SetColor endp
      

  12.   

    StreamInProc proc hFile:DWORD,pBuffer:DWORD, NumBytes:DWORD, pBytesRead:DWORD
    invoke ReadFile,hFile,pBuffer,NumBytes,pBytesRead,0
    xor eax,1
    ret
    StreamInProc endpStreamOutProc proc hFile:DWORD,pBuffer:DWORD, NumBytes:DWORD, pBytesWritten:DWORD
    invoke WriteFile,hFile,pBuffer,NumBytes,pBytesWritten,0
    xor eax,1
    ret
    StreamOutProc endpCheckModifyState proc hWnd:DWORD
    invoke SendMessage,hwndRichEdit,EM_GETMODIFY,0,0
    .if eax!=0
    invoke MessageBox,hWnd,addr WannaSave,addr AppName,MB_YESNOCANCEL
    .if eax==IDYES
    invoke SendMessage,hWnd,WM_COMMAND,IDM_SAVE,0
    .elseif eax==IDCANCEL
    mov eax,FALSE
    ret
    .endif
    .endif
    mov eax,TRUE
    ret
    CheckModifyState endpSetColor proc
    LOCAL cfm:CHARFORMAT
    invoke SendMessage,hwndRichEdit,EM_SETBKGNDCOLOR,0,BackgroundColor
    invoke RtlZeroMemory,addr cfm,sizeof cfm
    mov cfm.cbSize,sizeof cfm
    mov cfm.dwMask,CFM_COLOR
    push TextColor
    pop cfm.crTextColor
    invoke SendMessage,hwndRichEdit,EM_SETCHARFORMAT,SCF_ALL,addr cfm
    ret
    SetColor endpOptionProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
    LOCAL clr:CHOOSECOLOR
    .if uMsg==WM_INITDIALOG
    .elseif uMsg==WM_COMMAND
    mov eax,wParam
    shr eax,16
    .if ax==BN_CLICKED
    mov eax,wParam
    .if ax==IDCANCEL
    invoke SendMessage,hWnd,WM_CLOSE,0,0
    .elseif ax==IDC_BACKCOLORBOX
    invoke RtlZeroMemory,addr clr,sizeof clr
    mov clr.lStructSize,sizeof clr
    push hWnd
    pop clr.hwndOwner
    push hInstance
    pop clr.hInstance
    push BackgroundColor
    pop clr.rgbResult
    mov clr.lpCustColors,offset CustomColors
    mov clr.Flags,CC_ANYCOLOR or CC_RGBINIT
    invoke ChooseColor,addr clr
    .if eax!=0
    push clr.rgbResult
    pop BackgroundColor
    invoke GetDlgItem,hWnd,IDC_BACKCOLORBOX
    invoke InvalidateRect,eax,0,TRUE
    .endif
    .elseif ax==IDC_TEXTCOLORBOX
    invoke RtlZeroMemory,addr clr,sizeof clr
    mov clr.lStructSize,sizeof clr
    push hWnd
    pop clr.hwndOwner
    push hInstance
    pop clr.hInstance
    push TextColor
    pop clr.rgbResult
    mov clr.lpCustColors,offset CustomColors
    mov clr.Flags,CC_ANYCOLOR or CC_RGBINIT
    invoke ChooseColor,addr clr
    .if eax!=0
    push clr.rgbResult
    pop TextColor
    invoke GetDlgItem,hWnd,IDC_TEXTCOLORBOX
    invoke InvalidateRect,eax,0,TRUE
    .endif
    .elseif ax==IDOK
    invoke SendMessage,hwndRichEdit,EM_GETMODIFY,0,0
    push eax
    invoke SetColor
    pop eax
    invoke SendMessage,hwndRichEdit,EM_SETMODIFY,eax,0
    invoke EndDialog,hWnd,0
    .endif
    .endif
    .elseif uMsg==WM_CTLCOLORSTATIC
    invoke GetDlgItem,hWnd,IDC_BACKCOLORBOX
    .if eax==lParam
    invoke CreateSolidBrush,BackgroundColor
    ret
    .else
    invoke GetDlgItem,hWnd,IDC_TEXTCOLORBOX
    .if eax==lParam
    invoke CreateSolidBrush,TextColor
    ret
    .endif
    .endif
    mov eax,FALSE
    ret
    .elseif uMsg==WM_CLOSE
    invoke EndDialog,hWnd,0
    .else
    mov eax,FALSE
    ret
    .endif
    mov eax,TRUE
    ret
    OptionProc endp
      

  13.   

    SearchProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
    .if uMsg==WM_INITDIALOG
    push hWnd
    pop hSearch
    invoke CheckRadioButton,hWnd,IDC_DOWN,IDC_UP,IDC_DOWN
    invoke SendDlgItemMessage,hWnd,IDC_FINDEDIT,WM_SETTEXT,0,addr FindBuffer
    .elseif uMsg==WM_COMMAND
    mov eax,wParam
    shr eax,16
    .if ax==BN_CLICKED
    mov eax,wParam
    .if ax==IDOK
    mov uFlags,0
    invoke SendMessage,hwndRichEdit,EM_EXGETSEL,0,addr findtext.chrg
    invoke GetDlgItemText,hWnd,IDC_FINDEDIT,addr FindBuffer,sizeof FindBuffer
    .if eax!=0
    invoke IsDlgButtonChecked,hWnd,IDC_DOWN
    .if eax==BST_CHECKED
    or uFlags,FR_DOWN
    mov eax,findtext.chrg.cpMin
    .if eax!=findtext.chrg.cpMax
    push findtext.chrg.cpMax
    pop findtext.chrg.cpMin
    .endif
    mov findtext.chrg.cpMax,-1
    .else
    mov findtext.chrg.cpMax,0
    .endif
    invoke IsDlgButtonChecked,hWnd,IDC_MATCHCASE
    .if eax==BST_CHECKED
    or uFlags,FR_MATCHCASE
    .endif
    invoke IsDlgButtonChecked,hWnd,IDC_WHOLEWORD
    .if eax==BST_CHECKED
    or uFlags,FR_WHOLEWORD
    .endif
    mov findtext.lpstrText,offset FindBuffer
    invoke SendMessage,hwndRichEdit,EM_FINDTEXTEX,uFlags,addr findtext
    .if eax!=-1
    invoke SendMessage,hwndRichEdit,EM_EXSETSEL,0,addr findtext.chrgText
    .endif
    .endif
    .elseif ax==IDCANCEL
    invoke SendMessage,hWnd,WM_CLOSE,0,0
    .else
    mov eax,FALSE
    ret
    .endif
    .endif
    .elseif uMsg==WM_CLOSE
    mov hSearch,0
    invoke EndDialog,hWnd,0
    .else
    mov eax,FALSE
    ret
    .endif
    mov eax,TRUE
    ret
    SearchProc endpReplaceProc proc hWnd:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
    LOCAL settext:SETTEXTEX
    .if uMsg==WM_INITDIALOG
    push hWnd
    pop hSearch
    invoke SetDlgItemText,hWnd,IDC_FINDEDIT,addr FindBuffer
    invoke SetDlgItemText,hWnd,IDC_REPLACEEDIT,addr ReplaceBuffer
    .elseif uMsg==WM_COMMAND
    mov eax,wParam
    shr eax,16
    .if ax==BN_CLICKED
    mov eax,wParam
    .if ax==IDCANCEL
    invoke SendMessage,hWnd,WM_CLOSE,0,0
    .elseif ax==IDOK
    invoke GetDlgItemText,hWnd,IDC_FINDEDIT,addr FindBuffer,sizeof FindBuffer
    invoke GetDlgItemText,hWnd,IDC_REPLACEEDIT,addr ReplaceBuffer,sizeof ReplaceBuffer
    mov findtext.chrg.cpMin,0
    mov findtext.chrg.cpMax,-1
    mov findtext.lpstrText,offset FindBuffer
    mov settext.flags,ST_SELECTION
    mov settext.codepage,CP_ACP
    .while TRUE
    invoke SendMessage,hwndRichEdit,EM_FINDTEXTEX,FR_DOWN,addr findtext
    .if eax==-1
    .break
    .else
    invoke SendMessage,hwndRichEdit,EM_EXSETSEL,0,addr findtext.chrgText
    invoke SendMessage,hwndRichEdit,EM_SETTEXTEX,addr settext,addr ReplaceBuffer
    .endif
    .endw
    .endif
    .endif
    .elseif uMsg==WM_CLOSE
    mov hSearch,0
    invoke EndDialog,hWnd,0
    .else
    mov eax,FALSE
    ret
    .endif
    mov eax,TRUE
    ret
    ReplaceProc endp
      

  14.   

    下面还有很长,我就不拷贝粘贴了,全是汇编的,谁要请给我发邮件。[email protected]最好哪位高收将其翻译成 Delphi 的。
      

  15.   

    还有很长的分析,以下是其中一段:跟着,我们需要先高亮显示注释,并将它们排除在目标之外。我使用的方法是搜索 ";" 并用注释颜色来高亮显示那些正文,直到遇到回车符。我在这里不分析这个过程了:它相当的长和复杂。现在可以说,当所有的注释高亮显示后,我们就在缓冲区中用 0 来替换掉它们,以便注释中的词在以后不会再被重复高亮处理。 mov ecx,BufferSize
    lea esi,buffer
    .while ecx>0
    mov al,byte ptr [esi]
    .if al==" " || al==0Dh || al=="/" || al=="," || al=="|" || al=="+" || al=="-" || al=="*" || al=="&" || al=="<" || al==">" || al=="=" || al=="(" || al==")" || al=="{" || al=="}" || al=="[" || al=="]" || al=="^" || al==":" || al==9
    mov byte ptr [esi],0
    .endif
    dec ecx
    inc esi
    .endw
    将注释内容排除掉后,我们通过使用 0 替换掉分隔符,将缓冲区中的词表分开为一个个单个的词。用这个方法,我们在处理缓冲区中的词时就再不需要考虑分隔符了:只有一个分隔符,就是 NULL 。 lea esi,buffer
    mov ecx,BufferSize
    .while ecx>0
    mov al,byte ptr [esi]
    .if al!=0
    搜索缓冲区找到第一个非NULL字符,也就是某个词的第一个字符。 push ecx
    invoke lstrlen,esi
    push eax
    mov edx,eax
    取得词的长度并保存到 EDX  movzx eax,byte ptr [esi]
    .if al>="A" && al<="Z"
    sub al,"A"
    add al,"a"
    .endif
    将字符转换为小写的 (如果是大写字符的话)  shl eax,2
    add eax,edi ; edi 为 WORDINFO 指针数组的指针
    .if dword ptr [eax]!=0
    之后,我们跳到 ASMSyntaxArray 中的相应的DWORD,并检查该DWORD的值是否为 0 ,是的话我们就跳到下一个词。 mov eax,dword ptr [eax]
    assume eax:ptr WORDINFO
    .while eax!=0
    .if edx==[eax].WordLen
    如果DWORD的值不为 0 ,它就指向一个 WORDINFO 结构的链表。我们跟着遍历该链表,将局部缓冲区中词的长度跟 WORDINFO 结构中词的长度进行比较。这是在我们比较词之前进行的快速测试,可以节约一些时钟周期。 pushad
    invoke lstrcmpi,[eax].pszWord,esi
    .if eax==0
    如果两个词的长度相等,我们就继续使用 lstrcmpi 比较两个词。 popad
    mov ecx,esi
    lea edx,buffer
    sub ecx,edx
    add ecx,FirstChar
    我们用缓冲区中的匹配词的第一个字符的地址来构造字符索引。首先取得它跟缓冲区开始地址的相对偏移量,然后加上第一个可见字符的字符索引。 pushad
    .if RichEditVersion==3
    invoke SendMessage,hWnd,EM_POSFROMCHAR,addr rect,ecx
    .else
    invoke SendMessage,hWnd,EM_POSFROMCHAR,ecx,0
    mov ecx,eax
    and ecx,0FFFFh
    mov rect.left,ecx
    shr eax,16
    mov rect.top,eax
    .endif
    popad
    知道需要高亮显示的词的第一个字符的字符索引后,我们跟着通过发送 EM_POSFROMCHAR 消息取得它的位置。然而这个消息在RichEdit 2.0 和 3.0 中的解释是不同的。对RichEdit 2.0 来说,wParam 包含字符索引,lParam 没有使用。它在 EAX 返回 坐标。对 RichEdit 3.0 来说,wParam 是一个指向 POINT 结构的指针,该调用将会将结果坐标填入这里,而 lParam 则包含字符索引。 正如你看到的,如果传递错误的参数给 EM_POSFROMCHAR ,它可以对你的系统造成重大破坏。这个就是为什么我必须区分 RichEdit 控件的版本的缘故。 mov edx,[eax].pColor
    invoke SetTextColor,hdc,dword ptr [edx]
    invoke DrawText,hdc,esi,-1,addr rect,0
    一旦我们取得了开始坐标,我们就使用 WORDINFO 结构中指定的颜色来设置正文颜色。跟着使用新颜色值重写该词。As the final words, 这个方法可以从几个方面提高。例如,我取得从第一个可见行到最后一个可见行的所有正文。如果那些行很长的话,处理那些不可见的词会降低性能。你可以通过一行一行地取得真正的可见行来进行优化。同样,搜索算法也可以使用更多的不同方法来提高速度。不要受我的错误影响(Don't take me wrong):这个例子用来进行语法高亮显示的方法是快,但是它可以更快!:)
      

  16.   

    用synEdit吧功能真得很强大
    http://service.lonetear.com/delphi/downfile.asp?ID=445上可下载,但需先注册