Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei: CodeCompletion.pas   Sprache: Delphi

unit CodeCompletion;
interface
uses
  //----------------------------------------------------------
  //local
  //----------------------------------------------------------
  GenDefs,
  //----------------------------------------------------------
  //global
  //----------------------------------------------------------
  Windows,Forms,Classes,Messages,Sysutils,Controls,StdCtrls,ComCtrls,
  RichEdit,StrUtils,Graphics,Math,ClipBrd;
//------------------------------------------------------------------
//reagiert auf messages!!!
//------------------------------------------------------------------
const
  WMShowCodeCompletion=WM_USER+100;
  WMHideCodeCompletion=WM_USER+101;
  WMRemoveSpace=WM_USER+103;
  //------------------------------------------------------------------
  //
  //------------------------------------------------------------------
type
  TCodeWindow= class(TForm)
    VerbBox:TListBox;
    procedure setInvisible();
    procedure getCurrentWord();
    procedure getPartialWord();
    function getTextBetween(lpos,rpos:integer):JString;
    procedure WriteSelectedWord;
    procedure Msg_Show(var Msg:TMessage);message WMShowCodeCompletion;
    procedure Msg_Hide(var Msg:TMessage);message WMHideCodeCompletion;
    procedure Msg_Remove(var Msg:TMessage);message WMRemoveSpace;
    procedure VerbBoxKeyDown(Sender:TObject;var Key:Word;Shift:TShiftState);
    procedure VerbBoxMouseLeave(Sender:TObject);
  private
    //Private declarations
  public
    RE:TRichEdit;
    Org_KeyUp:TKeyEvent;
    Org_KeyDown:TKeyEvent;
    Org_KeyPress:TKeyPressEvent;
    KeysAssigned:boolean;
    PosRect:TRect;
    WordBeg:JString;
    WordFull:JString;
    WordStart,WordEnd:integer;
    REModif:boolean;
    Verbboxprefix:JString;
    procedure On_KeyUp(Sender:TObject;var Key:Word;Shift:TShiftState);
    procedure On_KeyDown(Sender:TObject;var Key:Word;Shift:TShiftState);
    procedure On_KeyPress(Sender:TObject;var Key:char);
    constructor Create(AOwner:TComponent);override;
    destructor Destroy;override;
    procedure setPosition();
    procedure setCodeCompletionVerbs(Keys:PAnsiChar);
    procedure setFont(FontName:JString;FontSize:integer);
    procedure setSize(codewidth:integer;codeheight:integer);
    procedure setColor(Col:TColor);
  end;
  //------------------------------------------------------------------
  //
  //------------------------------------------------------------------
implementation
{$R *.dfm}
//------------------------------------------------------------------
//
//------------------------------------------------------------------
const
  CH_Blank=' ';
  CH_Return=chr(Key_Return);
  CH_LineFeed=chr(Key_LineFeed);
  CH_Tab=chr(Key_Tab);
  unallowedchars:set of ansichar=[CH_Blank,CH_Return,CH_LineFeed,CH_Tab];
  //------------------------------------------------------------------
  //
  //------------------------------------------------------------------
constructor TCodeWindow.Create(AOwner:TComponent);
begin
  inherited Create(AOwner);
  RE:=AOwner as TRichEdit;
  width:=120;
  Height:=80;
  Org_KeyUp:=nil;
  Org_KeyDown:=nil;
  Org_KeyPress:=nil;
  setFont(RE.Font.Name,RE.Font.Size);
  setColor(RE.Color);
  setInvisible();
  KeysAssigned:=false;
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
destructor TCodeWindow.Destroy;
begin
  if Visible then
    setInvisible();
  inherited Free;
end;
//------------------------------------------------------------------
//add words found in editor                                          --
//--
//------------------------------------------------------------------
procedure TCodeWindow.setCodeCompletionVerbs(Keys:PAnsiChar);
var
  i,j,ll:integer;
  dup:boolean;
  ActKey:AnsiString;
begin
  if (Keys=nil)or(Keys=''then begin
    VerbBox.Items.Clear;
  end
  else begin
    if not KeysAssigned then begin //Already done
      Org_KeyUp:=RE.OnKeyUp;
      Org_KeyDown:=RE.OnKeyDown;
      Org_KeyPress:=RE.OnKeyPress;
      with RE do begin
        OnKeyUp:=On_KeyUp;
        OnKeyDown:=On_KeyDown;
        OnKeyPress:=On_KeyPress;
      end;
      KeysAssigned:=true;
    end;
    VerbBox.Items.Clear;
    i:=0;
    ll:=Length(Keys);
    while i<ll do begin
      ActKey:='';
      while (i<ll)and(Keys[i]<>';'do begin
        ActKey:=ActKey+Keys[i];
        i:=succ(i);
      end;
      if (i<ll) then
        i:=succ(i);
      if ActKey>'' then begin
        dup:=false;
        for j:=0 to pred(VerbBox.Items.Count) do
          if LowerCase(VerbBox.Items.Strings[j])=LowerCase(ActKey) then
            dup:=true;
        if not dup then
          VerbBox.Items.add(LowerCase(ActKey));
      end;
    end;
  end;
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.setFont(FontName:JString;FontSize:integer);
begin
  Font.Name:=FontName;
  Font.Size:=FontSize
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.setSize(codewidth:integer;codeheight:integer);
begin
  width:=codewidth;
  Height:=codeheight
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.VerbBoxKeyDown(Sender:TObject;var Key:Word;
  Shift:TShiftState);
var
  i,llb,ll:integer;
  next:JString; found:boolean;
begin
  case Key of
    vk_Escape:
      Visible:=false;
    vk_Down:begin
        if VerbBox.ItemIndex<pred(VerbBox.Items.Count) then
          VerbBox.ItemIndex:=(VerbBox.ItemIndex+1);
        Key:=0;
      end;
    vk_Up:begin
        if (VerbBox.ItemIndex>0) then
          VerbBox.ItemIndex:=(VerbBox.ItemIndex-1);
        Key:=0;
      end;
    VK_RIGHT:begin
        llb:=Length(WordBeg);
        ll:=Length(WordFull);
        if llb<ll then begin
          WordBeg:=MidStr(WordFull,1,llb+1);
          getPartialWord();
        end;
      end;
    VK_left:begin
        llb:=Length(WordBeg);
        if llb>1 then begin
          WordBeg:=MidStr(WordFull,1,llb-1);
          getPartialWord();
        end;
      end;
    vk_Return:begin
        Key:=0;
        setInvisible();
        WriteSelectedWord;
      end;
    vk_Prior:begin
        Key:=0;
        PostMessage(Handle,wm_VScroll,SB_PAGEUP,VerbBox.TopIndex);
        with VerbBox do
          i:=(ClientHeight div ItemHeight);
        i:=max(0,VerbBox.ItemIndex-i);
        if VerbBox.Items.Count=0 then
          i:=-1;
        VerbBox.ItemIndex:=i;
      end;
    vk_Next:begin
        Key:=0;
        PostMessage(Handle,wm_VScroll,SB_PAGEDOWN,VerbBox.ItemIndex);
        with VerbBox do
          i:=(ClientHeight div ItemHeight);
        i:=VerbBox.ItemIndex+i;
        if i>=VerbBox.Items.Count then
          i:=pred(VerbBox.Items.Count);
        VerbBox.ItemIndex:=i;
      end;
  else begin
      if (VerbBox.SelCount=0) then begin
        for i:=0 to VerbBox.Items.Count-1 do
          if ord(MidStr(VerbBox.Items[i],1,1))=Key then begin
            VerbBox.ItemIndex:=i;
            Verbboxprefix:=chr(Key);
          end;
      end
      else begin
        Verbboxprefix:=Verbboxprefix+chr(Key);
        i:=0; found:=false;
        next:='';
        while not found and(i<VerbBox.Items.Count-1) do begin
          next:=VerbBox.Items[i+1];
          if pos(LowerCase(Verbboxprefix),LowerCase(next))=1 then begin
            found:=true;
            VerbBox.ItemIndex:=i+1;
          end;
          i:=i+1
        end;
        if not found then
          Verbboxprefix:=midstr(Verbboxprefix,1,length(Verbboxprefix)-1);
      end;
    end;
  end;
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.VerbBoxMouseLeave(Sender:TObject);
begin
  PostMessage(Handle,WMHideCodeCompletion,0,0);
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.setColor(Col:TColor);
begin
  Color:=Col
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.setPosition();
var
  tp:tpoint;
  fh:integer;
begin
  //determine popup location
  SendMessage(RE.Handle,EM_POSFROMCHAR,integer(@tp),RE.SelStart);
  tp:=RE.ClientToScreen(tp);
  fh:=abs(RE.Font.Height);
  //spacer
  fh:=fh+4;
  tp.y:=tp.y+fh;
  if tp.y+Height>=Screen.DesktopHeight then
    tp.y:=tp.y-Height-(fh*2);
  if tp.x+width>=Screen.DesktopWidth then
    tp.x:=tp.x-width-20;
  with PosRect do begin
    Left:=tp.x;
    Top:=tp.y;
    Right:=Left+width;
    Bottom:=Top+Height;
  end;
  BoundsRect:=PosRect;
  if VerbBox.Items.Count>0 then
    VerbBox.ItemIndex:=0;
  OnKeyDown:=On_KeyDown;
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.On_KeyDown(Sender:TObject;var Key:Word;Shift:TShiftState);
begin
  if not Visible and(VerbBox.Items.Count>0) then begin
    if (Key=vk_space)and(ssCtrl in Shift) then begin
      Key:=0;
      Shift:=[];
      REModif:=RE.Modified;
      PostMessage(Handle,WMRemoveSpace,(Sender as TRichEdit).SelStart,0);
      PostMessage(Handle,WMShowCodeCompletion,0,0);
    end
  end
  else
    PostMessage(Handle,WMHideCodeCompletion,0,0);
  if assigned(Org_KeyDown) then
    Org_KeyDown(Sender,Key,Shift);
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.On_KeyUp(Sender:TObject;var Key:Word;Shift:TShiftState);
begin
  if assigned(Org_KeyUp) then
    Org_KeyUp(Sender,Key,Shift);
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.On_KeyPress(Sender:TObject;var Key:char);
begin
  if assigned(Org_KeyPress) then
    Org_KeyPress(Sender,Key);
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.getPartialWord();
var
  j:integer;
  found:boolean;
  Partword:JString;
begin
  Partword:=LowerCase(WordBeg);
  VerbBox.ItemIndex:=0;
  j:=0;
  found:=false;
  while not found and(j<VerbBox.Items.Count)and(VerbBox.ItemIndex=0) do begin
    if MidStr(LowerCase(VerbBox.Items[j]),1,Length(Partword))=Partword then
      VerbBox.ItemIndex:=j;
    j:=j+1
  end;
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
function TCodeWindow.getTextBetween(lpos,rpos:integer):JString;
var
  tr:textrange;
  Res:JString;
  c:ansichar;
  ll:integer;
begin
  Res:='';
  if rpos>=lpos then begin
    tr.chrg.cpMin:=lpos;
    tr.chrg.cpMax:=rpos;
    ll:=(rpos-lpos)+4;
    ll:=((ll div 4)+1)*4;
    GetMem(tr.lpstrText,ll);
    SendMessage(RE.Handle,EM_GETTEXTRANGE,0,integer(@tr));
    Res:=tr.lpstrText;
    c:=ansichar(Res[1]);
    if (c in unallowedchars) then
      Res:='';
  end;
  getTextBetween:=Res
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.getCurrentWord();
var
  startpos,endpos,allendpos:integer;
begin
  WordBeg:='';
  WordStart:=RE.SelStart;
  WordEnd:=RE.SelStart;
  endpos:=RE.SelStart;
  startpos:=SendMessage(RE.Handle,EM_FINDWORDBREAK,WB_MOVEWORDLEFT,endpos);
  WordBeg:=getTextBetween(startpos,endpos);
  if WordBeg>'' then begin
    WordFull:=WordBeg;
    WordStart:=startpos;
    WordEnd:=endpos;
    if WordBeg>'' then begin
      allendpos:=SendMessage(RE.Handle,EM_FINDWORDBREAK,WB_MOVEWORDRIGHT,
        startpos);
      if allendpos>-1 then begin
        WordFull:=getTextBetween(startpos,allendpos);
        WordStart:=startpos;
        WordEnd:=allendpos;
      end;
    end;
  end;
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.setInvisible();
begin
  //RE.WantReturns:=not Visible;
  //RE.WantTabs:=Visible;
  hide();
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.WriteSelectedWord;
var
  NewWord:JString;
begin
  if VerbBox.ItemIndex>-1 then begin
    NewWord:=VerbBox.Items[VerbBox.ItemIndex];
    if Length(WordBeg)>0 then begin
      RE.SelStart:=WordStart;
      RE.SelLength:=WordEnd-WordStart
    end
    else begin
      RE.SelStart:=WordStart-1;
      RE.SelLength:=0;
    end;
    RE.SelText:=NewWord;
    RE.SetFocus;
  end;
  PostMessage(Handle,WMHideCodeCompletion,0,0);
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.Msg_Show(var Msg:TMessage);
begin
  Visible:=true;
  setPosition();
  getCurrentWord();
  getPartialWord();
  Verbboxprefix:=WordBeg;
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.Msg_Hide(var Msg:TMessage);
begin
  Visible:=false;
end;
//------------------------------------------------------------------
//
//------------------------------------------------------------------
procedure TCodeWindow.Msg_Remove(var Msg:TMessage);
begin
  RE.SelStart:=RE.SelStart-1;
  RE.SelLength:=1;
  RE.CutToClipboard;
  RE.Modified:=REModif;
end;
//------------------------------------------------------------------
//--
//Ende dieser Quelle                                           --
//--
//------------------------------------------------------------------
end.

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ¤





Download des
Quellennavigators
Download des
sprechenden Kalenders

in der Quellcodebibliothek suchen




Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.


Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.


Bot Zugriff



                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik