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


Quellcode-Bibliothek

© Kompilation durch diese Firma

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

Datei:   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.

[ Seitenstruktur0.26Drucken  etwas mehr zur Ethik  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


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