浏览代码

CH: bug fixes + new features

Jean-Francois Goulet 20 年之前
父节点
当前提交
1398d5ab17

+ 5 - 2
LuaEdit/Breakpoints.dfm

@@ -136,6 +136,7 @@ object frmBreakpoints: TfrmBreakpoints
         item
         item
           Caption = 'Line'
           Caption = 'Line'
         end>
         end>
+      ColumnClick = False
       ReadOnly = True
       ReadOnly = True
       RowSelect = True
       RowSelect = True
       PopupMenu = popmBreakpoints
       PopupMenu = popmBreakpoints
@@ -147,13 +148,14 @@ object frmBreakpoints: TfrmBreakpoints
       OnChanging = lvwBreakpointsChanging
       OnChanging = lvwBreakpointsChanging
       OnDblClick = lvwBreakpointsDblClick
       OnDblClick = lvwBreakpointsDblClick
       ColumnsOrder = '0=265,1=120,2=100,3=50'
       ColumnsOrder = '0=265,1=120,2=100,3=50'
+      SortOnClick = False
     end
     end
   end
   end
   object imlBreakpoints: TImageList
   object imlBreakpoints: TImageList
     Left = 56
     Left = 56
     Top = 80
     Top = 80
     Bitmap = {
     Bitmap = {
-      494C01010A000E00040010001000FFFFFFFFFF00FFFFFFFFFFFFFFFF424D3600
+      494C01010A000E00040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
       0000000000003600000028000000400000004000000001002000000000000040
       0000000000003600000028000000400000004000000001002000000000000040
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
@@ -685,7 +687,8 @@ object frmBreakpoints: TfrmBreakpoints
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
-      00000000000000000000000000000000}
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000}
   end
   end
   object popmBreakpoints: TPopupMenu
   object popmBreakpoints: TPopupMenu
     OnPopup = popmBreakpointsPopup
     OnPopup = popmBreakpointsPopup

+ 2 - 0
LuaEdit/FindWindow1.dfm

@@ -39,6 +39,7 @@ object frmFindWindow1: TfrmFindWindow1
         AutoSize = True
         AutoSize = True
         Caption = 'Snipset'
         Caption = 'Snipset'
       end>
       end>
+    ColumnClick = False
     ReadOnly = True
     ReadOnly = True
     RowSelect = True
     RowSelect = True
     TabOrder = 0
     TabOrder = 0
@@ -46,6 +47,7 @@ object frmFindWindow1: TfrmFindWindow1
     OnCustomDrawSubItem = lvwResultCustomDrawSubItem
     OnCustomDrawSubItem = lvwResultCustomDrawSubItem
     OnDblClick = lvwResultDblClick
     OnDblClick = lvwResultDblClick
     ColumnsOrder = '0=100,1=50,2=188'
     ColumnsOrder = '0=100,1=50,2=188'
+    SortOnClick = False
   end
   end
   object JvDockClient1: TJvDockClient
   object JvDockClient1: TJvDockClient
     LRDockWidth = 100
     LRDockWidth = 100

+ 151 - 11
LuaEdit/FindWindow1.pas

@@ -4,22 +4,21 @@ interface
 
 
 uses
 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, ComCtrls, VirtualTrees, JvComponent, JvDockControlForm,
-  JvExComCtrls, JvListView, JvDotNetControls;
+  Dialogs, ComCtrls, CommCtrl, VirtualTrees, JvComponent, JvDockControlForm,
+  JvExComCtrls, JvListView, JvDotNetControls, StdCtrls;
 
 
 type
 type
   TfrmFindWindow1 = class(TForm)
   TfrmFindWindow1 = class(TForm)
     JvDockClient1: TJvDockClient;
     JvDockClient1: TJvDockClient;
     lvwResult: TJvDotNetListView;
     lvwResult: TJvDotNetListView;
-    procedure lvwResultCustomDrawSubItem(Sender: TCustomListView;
-      Item: TListItem; SubItem: Integer; State: TCustomDrawState;
-      var DefaultDraw: Boolean);
+    procedure lvwResultCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
     procedure lvwResultDblClick(Sender: TObject);
     procedure lvwResultDblClick(Sender: TObject);
   private
   private
     { Private declarations }
     { Private declarations }
   public
   public
     { Public declarations }
     { Public declarations }
     procedure AddResult(FileName: String; Line: Integer; Snipset: String);
     procedure AddResult(FileName: String; Line: Integer; Snipset: String);
+    function GetSubItemRect(const Item: TListItem; const SubItem: integer; Code: TDisplayCode = drBounds): TRect;
   end;
   end;
 
 
 var
 var
@@ -27,7 +26,7 @@ var
 
 
 implementation
 implementation
 
 
-uses Main;
+uses Main, Types;
 
 
 {$R *.dfm}
 {$R *.dfm}
 
 
@@ -41,17 +40,158 @@ begin
   pListitem.SubItems.Add(Snipset);
   pListitem.SubItems.Add(Snipset);
 end;
 end;
 
 
+function TfrmFindWindow1.GetSubItemRect(const Item: TListItem; const SubItem: integer; Code: TDisplayCode = drBounds): TRect;
+var
+  ARect: TRect;
+const
+  Codes: array[TDisplayCode] of Longint = (LVIR_BOUNDS, LVIR_ICON, LVIR_LABEL, LVIR_SELECTBOUNDS);
+begin
+  // Win32 macro defined in commctrl.pas (Retreive the boundary of a sub item in a given listview)
+  ListView_GetSubItemRect(Item.ListView.Handle, Item.Index, SubItem, Codes[Code], @ARect);
+  Result := ARect;
+end;
+
 procedure TfrmFindWindow1.lvwResultCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
 procedure TfrmFindWindow1.lvwResultCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
 var
 var
-  cx, cy: Integer;
+  pRect, pOutRect, pPrevOutRect: TRect;
+  sSnipset, sOut: String;
+  pTemp: array[0..5120] of Char;
+  StrPos: Integer;
+  IsFirst: Boolean;
 begin
 begin
-  {DefaultDraw := True;
+  DefaultDraw := True;
 
 
-  // Handle the snipset column
-  if SubItem = 1 then
+  // Only for the third column (code snipset)
+  if ((SubItem = 2) and (not Item.Selected)) then
   begin
   begin
+    IsFirst := True;
     DefaultDraw := False;
     DefaultDraw := False;
-  end;}
+    pRect := GetSubItemRect(Item, SubItem);
+    lvwResult.Canvas.FillRect(pRect);
+    pRect.Left := pRect.Left + 4;
+    pRect.Right := pRect.Right - 10;
+    StrPCopy(pTemp, Item.SubItems[SubItem - 1]);
+    sSnipset := pTemp;
+    pOutRect := Rect(0, 0, 0, 0);
+    pPrevOutRect := Rect(0, 0, 0, 0);
+    DrawText(lvwResult.Canvas.Handle, pTemp, Length(sSnipset), pRect, DT_END_ELLIPSIS or DT_SINGLELINE or DT_VCENTER or DT_LEFT or DT_MODIFYSTRING);
+    sSnipset := pTemp;
+
+    // Extract one by one the
+    while sSnipset <> '' do
+    begin
+      StrPos := Pos(frmMain.sSearchInFilesString, sSnipset);
+      if StrPos = 0 then
+      begin
+        // Retreive the rest of the string
+        sOut := sSnipset;
+        sSnipset := '';
+
+        // Reset font style and color
+        lvwResult.Canvas.Font.Style := [];
+
+        // Calculate text dimensions
+        SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+        DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_CALCRECT);
+
+        // Offset new calculated rect with previous one if required
+        if not IsFirst then
+        begin
+          pOutRect.Right := pOutRect.Right + pPrevOutRect.Right;
+          pOutRect.Left := pPrevOutRect.Right;
+          pOutRect.Top := pRect.Top;
+          pOutRect.Bottom := pRect.Bottom;
+        end
+        else
+        begin
+          pOutRect.Right := pOutRect.Right + pRect.Left;
+          pOutRect.Left := pOutRect.Left + pRect.Left;
+          pOutRect.Top := pRect.Top;
+          pOutRect.Bottom := pRect.Bottom;
+        end;
+
+        // Output the non bold part of string
+        SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+        DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE);
+        pPrevOutRect := pOutRect;
+        pOutRect := Rect(0, 0, 0, 0);
+        IsFirst := False;
+      end
+      else
+      begin
+        if StrPos <> 1 then
+        begin
+          // Retreive non bold part of string
+          sOut := Copy(sSnipset, 1, StrPos - 1);
+          sSnipset := Copy(sSnipset, StrPos, Length(sSnipset) - StrPos + 1);
+
+          // Reset font style and color
+          lvwResult.Canvas.Font.Style := [];
+
+          // Calculate text dimensions
+          SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+          DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_CALCRECT);
+
+          // Offset new calculated rect with previous one if required
+          if not IsFirst then
+          begin
+            pOutRect.Right := pOutRect.Right + pPrevOutRect.Right;
+            pOutRect.Left := pPrevOutRect.Right;
+            pOutRect.Top := pRect.Top;
+            pOutRect.Bottom := pRect.Bottom;
+          end
+          else
+          begin
+            pOutRect.Right := pOutRect.Right + pRect.Left;
+            pOutRect.Left := pOutRect.Left + pRect.Left;
+            pOutRect.Top := pRect.Top;
+            pOutRect.Bottom := pRect.Bottom;
+          end;
+
+          // Output the non bold part of string
+          SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+          DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE);
+          IsFirst := False;
+          pPrevOutRect := pOutRect;
+          pOutRect := Rect(0, 0, 0, 0);
+        end;
+
+        // Retreive bold part of string
+        sOut := frmMain.sSearchInFilesString;
+        sSnipset := Copy(sSnipset, Length(sOut) + 1, Length(sSnipset) - Length(sOut) + 1);
+
+        // Reset font style and color
+        lvwResult.Canvas.Font.Style := [fsBold];
+
+        // Calculate text dimensions
+        SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+        DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_CALCRECT);
+        
+        // Offset new calculated rect with previous one if required
+        if not IsFirst then
+        begin
+          pOutRect.Right := pOutRect.Right + pPrevOutRect.Right;
+          pOutRect.Left := pPrevOutRect.Right;
+          pOutRect.Top := pRect.Top;
+          pOutRect.Bottom := pRect.Bottom;
+        end
+        else
+        begin
+          pOutRect.Right := pOutRect.Right + pRect.Left;
+          pOutRect.Left := pOutRect.Left + pRect.Left;
+          pOutRect.Top := pRect.Top;
+          pOutRect.Bottom := pRect.Bottom;
+        end;
+
+        // Output the non bold part of string
+        SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+        DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE);
+        pPrevOutRect := pOutRect;
+        pOutRect := Rect(0, 0, 0, 0);
+        IsFirst := False;
+      end;
+    end;
+  end;
 end;
 end;
 
 
 procedure TfrmFindWindow1.lvwResultDblClick(Sender: TObject);
 procedure TfrmFindWindow1.lvwResultDblClick(Sender: TObject);

+ 2 - 0
LuaEdit/FindWindow2.dfm

@@ -39,6 +39,7 @@ object frmFindWindow2: TfrmFindWindow2
         AutoSize = True
         AutoSize = True
         Caption = 'Snipset'
         Caption = 'Snipset'
       end>
       end>
+    ColumnClick = False
     ReadOnly = True
     ReadOnly = True
     RowSelect = True
     RowSelect = True
     TabOrder = 0
     TabOrder = 0
@@ -46,6 +47,7 @@ object frmFindWindow2: TfrmFindWindow2
     OnCustomDrawSubItem = lvwResultCustomDrawSubItem
     OnCustomDrawSubItem = lvwResultCustomDrawSubItem
     OnDblClick = lvwResultDblClick
     OnDblClick = lvwResultDblClick
     ColumnsOrder = '0=100,1=50,2=188'
     ColumnsOrder = '0=100,1=50,2=188'
+    SortOnClick = False
   end
   end
   object JvDockClient1: TJvDockClient
   object JvDockClient1: TJvDockClient
     LRDockWidth = 100
     LRDockWidth = 100

+ 149 - 9
LuaEdit/FindWindow2.pas

@@ -4,22 +4,21 @@ interface
 
 
 uses
 uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
-  Dialogs, ComCtrls, VirtualTrees, JvComponent, JvDockControlForm,
+  Dialogs, ComCtrls, CommCtrl, VirtualTrees, JvComponent, JvDockControlForm,
   JvExComCtrls, JvListView, JvDotNetControls;
   JvExComCtrls, JvListView, JvDotNetControls;
 
 
 type
 type
   TfrmFindWindow2 = class(TForm)
   TfrmFindWindow2 = class(TForm)
     JvDockClient1: TJvDockClient;
     JvDockClient1: TJvDockClient;
     lvwResult: TJvDotNetListView;
     lvwResult: TJvDotNetListView;
-    procedure lvwResultCustomDrawSubItem(Sender: TCustomListView;
-      Item: TListItem; SubItem: Integer; State: TCustomDrawState;
-      var DefaultDraw: Boolean);
+    procedure lvwResultCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
     procedure lvwResultDblClick(Sender: TObject);
     procedure lvwResultDblClick(Sender: TObject);
   private
   private
     { Private declarations }
     { Private declarations }
   public
   public
     { Public declarations }
     { Public declarations }
     procedure AddResult(FileName: String; Line: Integer; Snipset: String);
     procedure AddResult(FileName: String; Line: Integer; Snipset: String);
+    function GetSubItemRect(const Item: TListItem; const SubItem: integer; Code: TDisplayCode = drBounds): TRect;
   end;
   end;
 
 
 var
 var
@@ -41,17 +40,158 @@ begin
   pListitem.SubItems.Add(Snipset);
   pListitem.SubItems.Add(Snipset);
 end;
 end;
 
 
+function TfrmFindWindow2.GetSubItemRect(const Item: TListItem; const SubItem: integer; Code: TDisplayCode = drBounds): TRect;
+var
+  ARect: TRect;
+const
+  Codes: array[TDisplayCode] of Longint = (LVIR_BOUNDS, LVIR_ICON, LVIR_LABEL, LVIR_SELECTBOUNDS);
+begin
+  // Win32 macro defined in commctrl.pas (Retreive the boundary of a sub item in a given listview)
+  ListView_GetSubItemRect(Item.ListView.Handle, Item.Index, SubItem, Codes[Code], @ARect);
+  Result := ARect;
+end;
+
 procedure TfrmFindWindow2.lvwResultCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
 procedure TfrmFindWindow2.lvwResultCustomDrawSubItem(Sender: TCustomListView; Item: TListItem; SubItem: Integer; State: TCustomDrawState; var DefaultDraw: Boolean);
 var
 var
-  cx, cy: Integer;
+  pRect, pOutRect, pPrevOutRect: TRect;
+  sSnipset, sOut: String;
+  pTemp: array[0..5120] of Char;
+  StrPos: Integer;
+  IsFirst: Boolean;
 begin
 begin
-  {DefaultDraw := True;
+  DefaultDraw := True;
 
 
-  // Handle the snipset column
-  if SubItem = 1 then
+  // Only for the third column (code snipset)
+  if ((SubItem = 2) and (not Item.Selected)) then
   begin
   begin
+    IsFirst := True;
     DefaultDraw := False;
     DefaultDraw := False;
-  end;}
+    pRect := GetSubItemRect(Item, SubItem);
+    lvwResult.Canvas.FillRect(pRect);
+    pRect.Left := pRect.Left + 4;
+    pRect.Right := pRect.Right - 10;
+    StrPCopy(pTemp, Item.SubItems[SubItem - 1]);
+    sSnipset := pTemp;
+    pOutRect := Rect(0, 0, 0, 0);
+    pPrevOutRect := Rect(0, 0, 0, 0);
+    DrawText(lvwResult.Canvas.Handle, pTemp, Length(sSnipset), pRect, DT_END_ELLIPSIS or DT_SINGLELINE or DT_VCENTER or DT_LEFT or DT_MODIFYSTRING);
+    sSnipset := pTemp;
+
+    // Extract one by one the
+    while sSnipset <> '' do
+    begin
+      StrPos := Pos(frmMain.sSearchInFilesString, sSnipset);
+      if StrPos = 0 then
+      begin
+        // Retreive the rest of the string
+        sOut := sSnipset;
+        sSnipset := '';
+
+        // Reset font style and color
+        lvwResult.Canvas.Font.Style := [];
+
+        // Calculate text dimensions
+        SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+        DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_CALCRECT);
+
+        // Offset new calculated rect with previous one if required
+        if not IsFirst then
+        begin
+          pOutRect.Right := pOutRect.Right + pPrevOutRect.Right;
+          pOutRect.Left := pPrevOutRect.Right;
+          pOutRect.Top := pRect.Top;
+          pOutRect.Bottom := pRect.Bottom;
+        end
+        else
+        begin
+          pOutRect.Right := pOutRect.Right + pRect.Left;
+          pOutRect.Left := pOutRect.Left + pRect.Left;
+          pOutRect.Top := pRect.Top;
+          pOutRect.Bottom := pRect.Bottom;
+        end;
+
+        // Output the non bold part of string
+        SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+        DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE);
+        pPrevOutRect := pOutRect;
+        pOutRect := Rect(0, 0, 0, 0);
+        IsFirst := False;
+      end
+      else
+      begin
+        if StrPos <> 1 then
+        begin
+          // Retreive non bold part of string
+          sOut := Copy(sSnipset, 1, StrPos - 1);
+          sSnipset := Copy(sSnipset, StrPos, Length(sSnipset) - StrPos + 1);
+
+          // Reset font style and color
+          lvwResult.Canvas.Font.Style := [];
+
+          // Calculate text dimensions
+          SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+          DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_CALCRECT);
+
+          // Offset new calculated rect with previous one if required
+          if not IsFirst then
+          begin
+            pOutRect.Right := pOutRect.Right + pPrevOutRect.Right;
+            pOutRect.Left := pPrevOutRect.Right;
+            pOutRect.Top := pRect.Top;
+            pOutRect.Bottom := pRect.Bottom;
+          end
+          else
+          begin
+            pOutRect.Right := pOutRect.Right + pRect.Left;
+            pOutRect.Left := pOutRect.Left + pRect.Left;
+            pOutRect.Top := pRect.Top;
+            pOutRect.Bottom := pRect.Bottom;
+          end;
+
+          // Output the non bold part of string
+          SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+          DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE);
+          IsFirst := False;
+          pPrevOutRect := pOutRect;
+          pOutRect := Rect(0, 0, 0, 0);
+        end;
+
+        // Retreive bold part of string
+        sOut := frmMain.sSearchInFilesString;
+        sSnipset := Copy(sSnipset, Length(sOut) + 1, Length(sSnipset) - Length(sOut) + 1);
+
+        // Reset font style and color
+        lvwResult.Canvas.Font.Style := [fsBold];
+
+        // Calculate text dimensions
+        SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+        DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_CALCRECT);
+        
+        // Offset new calculated rect with previous one if required
+        if not IsFirst then
+        begin
+          pOutRect.Right := pOutRect.Right + pPrevOutRect.Right;
+          pOutRect.Left := pPrevOutRect.Right;
+          pOutRect.Top := pRect.Top;
+          pOutRect.Bottom := pRect.Bottom;
+        end
+        else
+        begin
+          pOutRect.Right := pOutRect.Right + pRect.Left;
+          pOutRect.Left := pOutRect.Left + pRect.Left;
+          pOutRect.Top := pRect.Top;
+          pOutRect.Bottom := pRect.Bottom;
+        end;
+
+        // Output the non bold part of string
+        SelectObject(lvwResult.Canvas.Handle, lvwResult.Canvas.Font.Handle);
+        DrawText(lvwResult.Canvas.Handle, PChar(sOut), Length(sOut), pOutRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE);
+        pPrevOutRect := pOutRect;
+        pOutRect := Rect(0, 0, 0, 0);
+        IsFirst := False;
+      end;
+    end;
+  end;
 end;
 end;
 
 
 procedure TfrmFindWindow2.lvwResultDblClick(Sender: TObject);
 procedure TfrmFindWindow2.lvwResultDblClick(Sender: TObject);

+ 1 - 1
LuaEdit/FunctionList.pas

@@ -127,7 +127,7 @@ end;
 procedure TfrmFunctionList.tbtnGotoDefClick(Sender: TObject);
 procedure TfrmFunctionList.tbtnGotoDefClick(Sender: TObject);
 begin
 begin
   if Assigned(lvwFunctions.Selected) then
   if Assigned(lvwFunctions.Selected) then
-    TLuaUnit(frmMain.jvUnitBar.SelectedTab.Data).synUnit.GotoLineAndCenter(TFctInfo(lvwFunctions.Selected.Data).Line);
+    frmMain.PopUpUnitToScreen(TLuaUnit(frmMain.jvUnitBar.SelectedTab.Data).sUnitPath, TFctInfo(lvwFunctions.Selected.Data).Line, False, HIGHLIGHT_STACK)
 end;
 end;
 
 
 end.
 end.

+ 1 - 1
LuaEdit/InternalBrowser.dfm

@@ -278,7 +278,7 @@ object frmInternalBrowser: TfrmInternalBrowser
     ControlData = {
     ControlData = {
       4C000000D8130000AE0B00000000000000000000000000000000000000000000
       4C000000D8130000AE0B00000000000000000000000000000000000000000000
       000000004C000000000000000000000001000000E0D057007335CF11AE690800
       000000004C000000000000000000000001000000E0D057007335CF11AE690800
-      2B2E126208000000000000004C0000000114020000000000C000000000000046
+      2B2E126209000000000000004C0000000114020000000000C000000000000046
       8000000000000000000000000000000000000000000000000000000000000000
       8000000000000000000000000000000000000000000000000000000000000000
       00000000000000000100000000000000000000000000000000000000}
       00000000000000000100000000000000000000000000000000000000}
   end
   end

+ 21 - 1
LuaEdit/InternalBrowser.pas

@@ -8,6 +8,16 @@ uses
   StdCtrls, SHDocVW, ActnList, ExtCtrls, Registry, DateUtils, JvExControls,
   StdCtrls, SHDocVW, ActnList, ExtCtrls, Registry, DateUtils, JvExControls,
   JvAnimatedImage, JvGIFCtrl, OleCtrls, ActiveX, JvOutlookBar;
   JvAnimatedImage, JvGIFCtrl, OleCtrls, ActiveX, JvOutlookBar;
 
 
+const
+  // Mouse click basic events
+  WM_XBUTTONDOWN  = $020B;
+  WM_XBUTTONUP    = $020C;
+  WM_XBUTTONDBLCLK= $020D;
+
+  // Extended mouse buttons
+  MOUSE_XBUTTONPREV  = $10000;
+  MOUSE_XBUTTONNEXT  = $20000;
+
 type
 type
   TURLDateTime = class(TObject)
   TURLDateTime = class(TObject)
   public
   public
@@ -157,7 +167,8 @@ end;
 procedure TfrmInternalBrowser.MsgHandler(var Msg: TMsg; var Handled: Boolean);
 procedure TfrmInternalBrowser.MsgHandler(var Msg: TMsg; var Handled: Boolean);
 const
 const
   StdKeys = [VK_BACK, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT];
   StdKeys = [VK_BACK, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT];
-var IOIPAO: IOleInPlaceActiveObject;
+var
+  IOIPAO: IOleInPlaceActiveObject;
   Dispatch: IDispatch;
   Dispatch: IDispatch;
 begin
 begin
   if InternalBrowser = nil then
   if InternalBrowser = nil then
@@ -179,6 +190,15 @@ begin
     end;
     end;
     if FOleInPlaceActiveObject <> nil then
     if FOleInPlaceActiveObject <> nil then
     begin
     begin
+      // Next/Previous mouse buttons handling
+      if Msg.message = WM_XBUTTONUP then
+      begin
+        if Msg.wParam = MOUSE_XBUTTONPREV then
+          actBackTo.Execute
+        else if Msg.wParam = MOUSE_XBUTTONNEXT then
+          actFowardTo.Execute;
+      end;
+
       if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
       if ((Msg.message = WM_KEYDOWN) or (Msg.message = WM_KEYUP)) and
         (Msg.wParam in StdKeys) then
         (Msg.wParam in StdKeys) then
         //nothing  -  do not pass on Backspace, Left, Right, Up, Down arrows
         //nothing  -  do not pass on Backspace, Left, Right, Up, Down arrows

+ 12 - 12
LuaEdit/LuaEdit.dof

@@ -3,21 +3,21 @@ Version=7.0
 [Compiler]
 [Compiler]
 A=8
 A=8
 B=0
 B=0
-C=1
-D=1
+C=0
+D=0
 E=0
 E=0
 F=0
 F=0
 G=1
 G=1
 H=1
 H=1
-I=1
+I=0
 J=0
 J=0
 K=0
 K=0
-L=1
+L=0
 M=0
 M=0
 N=1
 N=1
 O=0
 O=0
 P=1
 P=1
-Q=1
+Q=0
 R=0
 R=0
 S=0
 S=0
 T=0
 T=0
@@ -25,7 +25,7 @@ U=0
 V=1
 V=1
 W=0
 W=0
 X=1
 X=1
-Y=1
+Y=0
 Z=1
 Z=1
 ShowHints=1
 ShowHints=1
 ShowWarnings=1
 ShowWarnings=1
@@ -83,7 +83,7 @@ UnsafeCast=0
 MapFile=3
 MapFile=3
 OutputObjs=0
 OutputObjs=0
 ConsoleApp=1
 ConsoleApp=1
-DebugInfo=1
+DebugInfo=0
 RemoteSymbols=0
 RemoteSymbols=0
 MinStackSize=16384
 MinStackSize=16384
 MaxStackSize=1048576
 MaxStackSize=1048576
@@ -94,7 +94,7 @@ OutputDir=.\bin
 UnitOutputDir=
 UnitOutputDir=
 PackageDLLOutputDir=
 PackageDLLOutputDir=
 PackageDCPOutputDir=
 PackageDCPOutputDir=
-SearchPath=$(DELPHI)\Lib\Debug;C:\Prog\Delphi\Component\JEDI\jcl\lib\D7\debug;.\Syntax;.\LuaCore;C:\Prog\Delphi\Component\XPMenu;C:\Prog\Delphi\Component\SynEdit\Source
+SearchPath=.\Syntax;.\LuaCore;C:\Prog\Delphi\Component\XPMenu;C:\Prog\Delphi\Component\SynEdit\Source
 Packages=vcl;rtl;vclx;indy;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;dsnap;dsnapcon;vcldb;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webdsnap;websnap;adortl;ibxpress;teeui;teedb;tee;dss;visualclx;visualdbclx;vclactnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclOfficeXP;DJcl;JvStdCtrlsD7R;JvAppFrmD7R;JvCoreD7R;JvBandsD7R;JvDockingD7R;JvDotNetCtrlsD7R;JvEDID7R;qrpt;JvGlobusD7R;JvHMID7R;JvInspectorD7R;JvInterpreterD7R;JvJansD7R;JvManagedThreadsD7R;JvCmpD7R;JvMMD7R;JvNetD7R;JvPageCompsD7R;JvPluginD7R;JvPrintPreviewD7R;JvCtrlsD7R;JvSystemD7R;JvTimeFrameworkD7R;JvUIBD7R;JvValidatorsD7R;JvWizardD7R;JvXPCtrlsD7R;JvCryptD7R;JvCustomD7R;JvBDED7R;JvDBD7R;JvDlgsD7R
 Packages=vcl;rtl;vclx;indy;inet;xmlrtl;vclie;inetdbbde;inetdbxpress;dbrtl;dsnap;dsnapcon;vcldb;soaprtl;VclSmp;dbexpress;dbxcds;inetdb;bdertl;vcldbx;webdsnap;websnap;adortl;ibxpress;teeui;teedb;tee;dss;visualclx;visualdbclx;vclactnband;vclshlctrls;IntrawebDB_50_70;Intraweb_50_70;Rave50CLX;Rave50VCL;dclOfficeXP;DJcl;JvStdCtrlsD7R;JvAppFrmD7R;JvCoreD7R;JvBandsD7R;JvDockingD7R;JvDotNetCtrlsD7R;JvEDID7R;qrpt;JvGlobusD7R;JvHMID7R;JvInspectorD7R;JvInterpreterD7R;JvJansD7R;JvManagedThreadsD7R;JvCmpD7R;JvMMD7R;JvNetD7R;JvPageCompsD7R;JvPluginD7R;JvPrintPreviewD7R;JvCtrlsD7R;JvSystemD7R;JvTimeFrameworkD7R;JvUIBD7R;JvValidatorsD7R;JvWizardD7R;JvXPCtrlsD7R;JvCryptD7R;JvCustomD7R;JvBDED7R;JvDBD7R;JvDlgsD7R
 Conditionals=
 Conditionals=
 DebugSourceDirs=
 DebugSourceDirs=
@@ -115,7 +115,7 @@ AutoIncBuild=1
 MajorVer=2
 MajorVer=2
 MinorVer=2
 MinorVer=2
 Release=1
 Release=1
-Build=264
+Build=868
 Debug=0
 Debug=0
 PreRelease=0
 PreRelease=0
 Special=0
 Special=0
@@ -126,7 +126,7 @@ CodePage=1252
 [Version Info Keys]
 [Version Info Keys]
 CompanyName=Open Source
 CompanyName=Open Source
 FileDescription=IDE for Lua 5.0.2
 FileDescription=IDE for Lua 5.0.2
-FileVersion=2.2.1.264
+FileVersion=2.2.1.868
 InternalName=LuaEdit
 InternalName=LuaEdit
 LegalCopyright=LuaEdit Copyright 2004-2005 ©
 LegalCopyright=LuaEdit Copyright 2004-2005 ©
 LegalTrademarks=
 LegalTrademarks=
@@ -139,8 +139,8 @@ Count=1
 Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
 Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
 [HistoryLists\hlSearchPath]
 [HistoryLists\hlSearchPath]
 Count=4
 Count=4
-Item0=$(DELPHI)\Lib\Debug;C:\Prog\Delphi\Component\JEDI\jcl\lib\D7\debug;.\Syntax;.\LuaCore;C:\Prog\Delphi\Component\XPMenu;C:\Prog\Delphi\Component\SynEdit\Source
-Item1=.\Syntax;.\LuaCore;C:\Prog\Delphi\Component\XPMenu;C:\Prog\Delphi\Component\SynEdit\Source
+Item0=.\Syntax;.\LuaCore;C:\Prog\Delphi\Component\XPMenu;C:\Prog\Delphi\Component\SynEdit\Source
+Item1=$(DELPHI)\Lib\Debug;C:\Prog\Delphi\Component\JEDI\jcl\lib\D7\debug;.\Syntax;.\LuaCore;C:\Prog\Delphi\Component\XPMenu;C:\Prog\Delphi\Component\SynEdit\Source
 Item2=C:\Prog\Delphi\Component\SynEdit\Packages;C:\Prog\Delphi\Component\SynEdit\Source
 Item2=C:\Prog\Delphi\Component\SynEdit\Packages;C:\Prog\Delphi\Component\SynEdit\Source
 Item3=C:\Prog\Delphi\Component\SynEdit\Packages
 Item3=C:\Prog\Delphi\Component\SynEdit\Packages
 [HistoryLists\hlOutputDirectorry]
 [HistoryLists\hlOutputDirectorry]

二进制
LuaEdit/LuaEdit.res


+ 1 - 2
LuaEdit/LuaEditMessages.dfm

@@ -23,7 +23,7 @@ object frmLuaEditMessages: TfrmLuaEditMessages
     Left = 0
     Left = 0
     Top = 0
     Top = 0
     Width = 460
     Width = 460
-    Height = 169
+    Height = 176
     Align = alClient
     Align = alClient
     Font.Charset = ANSI_CHARSET
     Font.Charset = ANSI_CHARSET
     Font.Color = clWindowText
     Font.Color = clWindowText
@@ -34,7 +34,6 @@ object frmLuaEditMessages: TfrmLuaEditMessages
     ReadOnly = True
     ReadOnly = True
     ScrollBars = ssBoth
     ScrollBars = ssBoth
     TabOrder = 0
     TabOrder = 0
-    OnChange = memMessagesChange
   end
   end
   object JvDockClient1: TJvDockClient
   object JvDockClient1: TJvDockClient
     LRDockWidth = 100
     LRDockWidth = 100

+ 0 - 7
LuaEdit/LuaEditMessages.pas

@@ -10,7 +10,6 @@ type
   TfrmLuaEditMessages = class(TForm)
   TfrmLuaEditMessages = class(TForm)
     memMessages: TMemo;
     memMessages: TMemo;
     JvDockClient1: TJvDockClient;
     JvDockClient1: TJvDockClient;
-    procedure memMessagesChange(Sender: TObject);
   private
   private
     { Private declarations }
     { Private declarations }
   public
   public
@@ -26,10 +25,4 @@ uses Main;
 
 
 {$R *.dfm}
 {$R *.dfm}
 
 
-procedure TfrmLuaEditMessages.memMessagesChange(Sender: TObject);
-begin
-  LastMessage := memMessages.Lines.Strings[memMessages.Lines.Count - 1];
-  frmMain.stbMain.Refresh;
-end;
-
 end.
 end.

+ 9 - 5
LuaEdit/Main.dfm

@@ -239,7 +239,7 @@ object frmMain: TfrmMain
     object tlbBaseFile: TToolBar
     object tlbBaseFile: TToolBar
       Left = 11
       Left = 11
       Top = 2
       Top = 2
-      Width = 296
+      Width = 283
       Height = 22
       Height = 22
       Align = alLeft
       Align = alLeft
       AutoSize = True
       AutoSize = True
@@ -916,7 +916,7 @@ object frmMain: TfrmMain
     Left = 48
     Left = 48
     Top = 217
     Top = 217
     Bitmap = {
     Bitmap = {
-      494C01013C004000040010001000FF00FF00FF00FFFFFFFFFFFFFFFF424D3600
+      494C01013C004000040010001000FF00FF00FF10FFFFFFFFFFFFFFFF424D3600
       0000000000003600000028000000400000000001000001002000000000000000
       0000000000003600000028000000400000000001000001002000000000000000
       0100000000000000000000000000000000000000000000000000000000000000
       0100000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
@@ -3032,7 +3032,8 @@ object frmMain: TfrmMain
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
-      00000000000000000000000000000000}
+      0000000000000000000000000000000000000000000000000000000000000000
+      000000000000}
   end
   end
   object odlgOpenUnit: TOpenDialog
   object odlgOpenUnit: TOpenDialog
     Filter = 
     Filter = 
@@ -3428,7 +3429,7 @@ object frmMain: TfrmMain
     Left = 16
     Left = 16
     Top = 342
     Top = 342
     Bitmap = {
     Bitmap = {
-      494C01010E001300040010001000FFFFFFFFFF00FFFFFFFFFFFFFFFF424D3600
+      494C01010E001300040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
       0000000000003600000028000000400000005000000001002000000000000050
       0000000000003600000028000000400000005000000001002000000000000050
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000000000000000
@@ -4092,7 +4093,8 @@ object frmMain: TfrmMain
       0C3FE781C00380010C3FC781CFF380010000A000C813800180006000CFF38001
       0C3FE781C00380010C3FC781CFF380010000A000C813800180006000CFF38001
       C0006000C8138001C0006000CFF38001C0006000C8138001C0006000CFF38001
       C0006000C8138001C0006000CFF38001C0006000C8138001C0006000CFF38001
       C000E000CE738001C00000008C318001C00000008E718001C0000000FE7F8001
       C000E000CE738001C00000008C318001C00000008E718001C0000000FE7F8001
-      C0000000FE7FFFFFC0000000F87FFFFF}
+      C0000000FE7FFFFFC0000000F87FFFFF00000000000000000000000000000000
+      000000000000}
   end
   end
   object jvModernUnitBarPainter: TJvModernTabBarPainter
   object jvModernUnitBarPainter: TJvModernTabBarPainter
     ControlDivideColor = clBtnFace
     ControlDivideColor = clBtnFace
@@ -4395,12 +4397,14 @@ object frmMain: TfrmMain
       end
       end
       object HeaderBuilder1: TMenuItem
       object HeaderBuilder1: TMenuItem
         Caption = 'Header Builder'
         Caption = 'Header Builder'
+        Visible = False
         object Functions1: TMenuItem
         object Functions1: TMenuItem
           Action = actFunctionHeader
           Action = actFunctionHeader
         end
         end
       end
       end
       object N13: TMenuItem
       object N13: TMenuItem
         Caption = '-'
         Caption = '-'
+        Visible = False
       end
       end
       object EditorSettings1: TMenuItem
       object EditorSettings1: TMenuItem
         Action = actEditorSettings
         Action = actEditorSettings

+ 135 - 100
LuaEdit/Main.pas

@@ -14,7 +14,7 @@ uses
   JvChangeNotify, JvClipboardMonitor, JvMenus, JvExComCtrls, JvToolBar,
   JvChangeNotify, JvClipboardMonitor, JvMenus, JvExComCtrls, JvToolBar,
   JvInspector, XPStyleActnCtrls, ActnMan, ActnCtrls, CustomizeDlg,
   JvInspector, XPStyleActnCtrls, ActnMan, ActnCtrls, CustomizeDlg,
   ActnMenus, ActnColorMaps, StdStyleActnCtrls, XPMenu, Clipbrd, JvLookOut,
   ActnMenus, ActnColorMaps, StdStyleActnCtrls, XPMenu, Clipbrd, JvLookOut,
-  JvExControls, FileCtrl, MiscClasses, VirtualTrees
+  JvExControls, FileCtrl, VirtualTrees
   {$ifdef RTASSERT}  , RTDebug  {$endif}
   {$ifdef RTASSERT}  , RTDebug  {$endif}
   , JvDragDrop, JvAppEvent, JvExStdCtrls, JvButton, JvCtrls, JvComCtrls;
   , JvDragDrop, JvAppEvent, JvExStdCtrls, JvButton, JvCtrls, JvComCtrls;
 
 
@@ -84,6 +84,7 @@ type
 
 
   TDebugSupportPlugin = class(TSynEditPlugin)
   TDebugSupportPlugin = class(TSynEditPlugin)
   protected
   protected
+    procedure PaintDebugGlyphs(ACanvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer);
     procedure AfterPaint(ACanvas: TCanvas; const AClip: TRect; FirstLine, LastLine: integer); override;
     procedure AfterPaint(ACanvas: TCanvas; const AClip: TRect; FirstLine, LastLine: integer); override;
     procedure LinesInserted(FirstLine, Count: integer); override;
     procedure LinesInserted(FirstLine, Count: integer); override;
     procedure LinesDeleted(FirstLine, Count: integer); override;
     procedure LinesDeleted(FirstLine, Count: integer); override;
@@ -541,8 +542,7 @@ type
     procedure actUpperCaseExecute(Sender: TObject);
     procedure actUpperCaseExecute(Sender: TObject);
     procedure actLowerCaseExecute(Sender: TObject);
     procedure actLowerCaseExecute(Sender: TObject);
     procedure actShowInternalBrowserExecute(Sender: TObject);
     procedure actShowInternalBrowserExecute(Sender: TObject);
-    procedure jvUnitBarTabSelecting(Sender: TObject; Item: TJvTabBarItem;
-      var AllowSelect: Boolean);
+    procedure jvUnitBarTabSelecting(Sender: TObject; Item: TJvTabBarItem; var AllowSelect: Boolean);
     procedure jvUnitBarTabClosed(Sender: TObject; Item: TJvTabBarItem);
     procedure jvUnitBarTabClosed(Sender: TObject; Item: TJvTabBarItem);
     procedure actPrjSettingsExecute(Sender: TObject);
     procedure actPrjSettingsExecute(Sender: TObject);
     procedure actStopExecute(Sender: TObject);
     procedure actStopExecute(Sender: TObject);
@@ -604,7 +604,6 @@ type
     procedure btnXClipboardClick(Sender: TObject);
     procedure btnXClipboardClick(Sender: TObject);
     function IsProjectOpened(sProjectPath: String): Boolean;
     function IsProjectOpened(sProjectPath: String): Boolean;
     procedure SynEditReplaceText(Sender: TObject; const ASearch, AReplace: String; Line, Column: Integer; var Action: TSynReplaceAction);
     procedure SynEditReplaceText(Sender: TObject; const ASearch, AReplace: String; Line, Column: Integer; var Action: TSynReplaceAction);
-    procedure PaintDebugGlyphs(ACanvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer);
     procedure synEditSpecialLineColors(Sender: TObject; Line: Integer; var Special: Boolean; var FG, BG: TColor);
     procedure synEditSpecialLineColors(Sender: TObject; Line: Integer; var Special: Boolean; var FG, BG: TColor);
     procedure synEditGutterClick(Sender: TObject; Button: TMouseButton; X, Y, Line: Integer; Mark: TSynEditMark);
     procedure synEditGutterClick(Sender: TObject; Button: TMouseButton; X, Y, Line: Integer; Mark: TSynEditMark);
     procedure synEditMouseCursor(Sender: TObject; const aLineCharPos: TBufferCoord; var aCursor: TCursor);
     procedure synEditMouseCursor(Sender: TObject; const aLineCharPos: TBufferCoord; var aCursor: TCursor);
@@ -612,6 +611,7 @@ type
     procedure synEditClick(Sender: TObject);
     procedure synEditClick(Sender: TObject);
     procedure synEditDblClick(Sender: TObject);
     procedure synEditDblClick(Sender: TObject);
     procedure synEditMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
     procedure synEditMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
+    procedure synEditScroll(Sender: TObject; ScrollBar: TScrollBarKind);
     procedure synCompletionExecute(Kind: SynCompletionType; Sender: TObject; var CurrentInput: String; var x, y: Integer; var CanExecute: Boolean);
     procedure synCompletionExecute(Kind: SynCompletionType; Sender: TObject; var CurrentInput: String; var x, y: Integer; var CanExecute: Boolean);
     function GetBaseCompletionProposal: TSynCompletionProposal;
     function GetBaseCompletionProposal: TSynCompletionProposal;
     function GetBaseParamsProposal: TSynCompletionProposal;
     function GetBaseParamsProposal: TSynCompletionProposal;
@@ -752,7 +752,6 @@ var
   lstStack: TStringList;
   lstStack: TStringList;
   lstLuaStack: TStringList;
   lstLuaStack: TStringList;
   IsCompiledComplete: Boolean;
   IsCompiledComplete: Boolean;
-  LastMessage: String;
   IsRunning: Boolean;
   IsRunning: Boolean;
   FirstLineStop: Boolean;
   FirstLineStop: Boolean;
   StepOverPressed: Boolean;
   StepOverPressed: Boolean;
@@ -784,7 +783,7 @@ function GetFileLastTimeModified(const sFileName: PChar): TDateTime; cdecl; exte
 function GetFileReadOnlyAttr(const sFileName: PChar): Boolean; cdecl; external 'LuaEditSys.dll';
 function GetFileReadOnlyAttr(const sFileName: PChar): Boolean; cdecl; external 'LuaEditSys.dll';
 procedure ToggleFileReadOnlyAttr(const sFileName: PChar); cdecl; external 'LuaEditSys.dll';
 procedure ToggleFileReadOnlyAttr(const sFileName: PChar); cdecl; external 'LuaEditSys.dll';
 
 
-function FunctionHeaderBuilder(OwnerAppHandle: HWND; sLine: PChar): PChar; cdecl; external 'HdrBld.dll';
+//function FunctionHeaderBuilder(OwnerAppHandle: HWND; sLine: PChar): PChar; cdecl; external 'HdrBld.dll';
 
 
 implementation
 implementation
 
 
@@ -955,7 +954,50 @@ end;
 ///////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////
 procedure TDebugSupportPlugin.AfterPaint(ACanvas: TCanvas; const AClip: TRect; FirstLine, LastLine: integer);
 procedure TDebugSupportPlugin.AfterPaint(ACanvas: TCanvas; const AClip: TRect; FirstLine, LastLine: integer);
 begin
 begin
-  frmMain.PaintDebugGlyphs(ACanvas, AClip, FirstLine, LastLine);
+  PaintDebugGlyphs(ACanvas, AClip, FirstLine, LastLine);
+end;
+
+procedure TDebugSupportPlugin.PaintDebugGlyphs(ACanvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer);
+var
+  LH, X, Y: integer;
+  ImgIndex: integer;
+  pLuaUnit: TLuaUnit;
+begin
+  pLuaUnit := TLuaUnit(frmMain.jvUnitBar.SelectedTab.Data);
+
+  FirstLine := pLuaUnit.synUnit.RowToLine(FirstLine);
+  LastLine := pLuaUnit.synUnit.RowToLine(LastLine);
+  X := 14;
+  LH := pLuaUnit.synUnit.LineHeight;
+  while FirstLine <= LastLine do
+  begin
+    ImgIndex := -1;
+    Y := (LH - frmMain.imlActions.Height) div 2 + LH * (pLuaUnit.synUnit.LineToRow(FirstLine) - pLuaUnit.synUnit.TopLine);
+
+    if pLuaUnit.pDebugInfos.IsBreakPointLine(FirstLine) then
+    begin
+      if pLuaUnit.pDebugInfos.GetBreakpointStatus(FirstLine) = BKPT_ENABLED then
+        ImgIndex := 27
+      else
+        ImgIndex := 28;
+    end;
+
+    if TLuaUnit(frmMain.jvUnitBar.SelectedTab.Data).pDebugInfos.iCurrentLineDebug = FirstLine then
+      ImgIndex := 29;
+
+    if ((pLuaUnit.pDebugInfos.IsBreakPointLine(FirstLine)) and (TLuaUnit(frmMain.jvUnitBar.SelectedTab.Data).pDebugInfos.iCurrentLineDebug = FirstLine)) then
+    begin
+      if pLuaUnit.pDebugInfos.GetBreakpointStatus(FirstLine) = BKPT_ENABLED then
+        ImgIndex := 30
+      else
+        ImgIndex := 43;
+    end;
+
+    if ImgIndex > 0 then
+      frmMain.imlActions.Draw(ACanvas, X, Y, ImgIndex);
+
+    Inc(FirstLine);
+  end;
 end;
 end;
 
 
 procedure TDebugSupportPlugin.LinesInserted(FirstLine, Count: integer);
 procedure TDebugSupportPlugin.LinesInserted(FirstLine, Count: integer);
@@ -1503,7 +1545,6 @@ begin
 
 
     // Reinitialize stuff...
     // Reinitialize stuff...
     frmMain.RefreshOpenedUnits;
     frmMain.RefreshOpenedUnits;
-    LastMessage := '';
     frmProjectTree.BuildProjectTree;
     frmProjectTree.BuildProjectTree;
     frmMain.stbMain.Panels[5].Text := '';
     frmMain.stbMain.Panels[5].Text := '';
     frmMain.stbMain.Refresh;
     frmMain.stbMain.Refresh;
@@ -1594,7 +1635,6 @@ begin
 
 
     // Initialize stuff...
     // Initialize stuff...
     frmMain.RefreshOpenedUnits;
     frmMain.RefreshOpenedUnits;
-    LastMessage := '';
     frmProjectTree.BuildProjectTree;
     frmProjectTree.BuildProjectTree;
     frmMain.stbMain.Panels[5].Text := '';
     frmMain.stbMain.Panels[5].Text := '';
     frmMain.stbMain.Refresh;
     frmMain.stbMain.Refresh;
@@ -1888,11 +1928,13 @@ var
   pJvTab: TJvTabBarItem;
   pJvTab: TJvTabBarItem;
 begin
 begin
   Screen.Cursor := crHourGlass;
   Screen.Cursor := crHourGlass;
-  
+
+  // Create the tab and associate the synedit control to its data property
   pJvTab := jvUnitBar.AddTab(pLuaUnit.sName);
   pJvTab := jvUnitBar.AddTab(pLuaUnit.sName);
   pJvTab.Data := pLuaUnit;
   pJvTab.Data := pLuaUnit;
   pJvTab.Visible := False;
   pJvTab.Visible := False;
 
 
+  // Set some properties
   synEdit := TSynEdit.Create(pnlMain);
   synEdit := TSynEdit.Create(pnlMain);
   synEdit.Parent := pnlMain;
   synEdit.Parent := pnlMain;
   synEdit.Visible := True;
   synEdit.Visible := True;
@@ -1902,7 +1944,9 @@ begin
   synEdit.ShowHint := True;
   synEdit.ShowHint := True;
   synEdit.PopupMenu := ppmEditor;
   synEdit.PopupMenu := ppmEditor;
 
 
+  // Set event handlers
   synEdit.OnChange := synEditChange;
   synEdit.OnChange := synEditChange;
+  synEdit.OnScroll := synEditScroll;
   synEdit.OnDblClick := synEditDblClick;
   synEdit.OnDblClick := synEditDblClick;
   synEdit.OnMouseMove := synEditMouseMove;
   synEdit.OnMouseMove := synEditMouseMove;
   synEdit.OnMouseCursor := synEditMouseCursor;
   synEdit.OnMouseCursor := synEditMouseCursor;
@@ -1912,12 +1956,15 @@ begin
   synEdit.OnSpecialLineColors := synEditSpecialLineColors;
   synEdit.OnSpecialLineColors := synEditSpecialLineColors;
   synEdit.OnGutterClick := synEditGutterClick;
   synEdit.OnGutterClick := synEditGutterClick;
 
 
+  // Initialize lua highlighter engine
   HR := TSynLuaSyn.Create(nil);
   HR := TSynLuaSyn.Create(nil);
   synEdit.Highlighter := HR;
   synEdit.Highlighter := HR;
-  
+
+  // Load content in the synedit control if required
   if not pLuaUnit.IsNew then
   if not pLuaUnit.IsNew then
     synEdit.Lines.LoadFromFile(pLuaUnit.sUnitPath);
     synEdit.Lines.LoadFromFile(pLuaUnit.sUnitPath);
 
 
+  // Initialize some stuff in the TLuaUnit class members
   pLuaUnit.pDebugPlugin := TDebugSupportPlugin.Create(synEdit);
   pLuaUnit.pDebugPlugin := TDebugSupportPlugin.Create(synEdit);
   pLuaUnit.pDebugInfos.iCurrentLineDebug := -1;
   pLuaUnit.pDebugInfos.iCurrentLineDebug := -1;
   pLuaUnit.PrevLineNumber := synEdit.Lines.Count;
   pLuaUnit.PrevLineNumber := synEdit.Lines.Count;
@@ -1929,12 +1976,12 @@ begin
   pLuaUnit.synCompletion.Editor := pLuaUnit.synUnit;
   pLuaUnit.synCompletion.Editor := pLuaUnit.synUnit;
   LuaOpenedUnits.Add(pLuaUnit);
   LuaOpenedUnits.Add(pLuaUnit);
 
 
+  // Initialize visually the synedit control and other stuff
   synEditClick(synEdit);
   synEditClick(synEdit);
   jvTabTabBarChange(jvUnitBar);
   jvTabTabBarChange(jvUnitBar);
   jvUnitBar.SelectedTab := pJvTab;
   jvUnitBar.SelectedTab := pJvTab;
   ApplyValuesToEditor(pLuaUnit.synUnit, EditorColors);
   ApplyValuesToEditor(pLuaUnit.synUnit, EditorColors);
   pJvTab.Visible := True;
   pJvTab.Visible := True;
-
   pLuaUnit.GetBreakpoints();
   pLuaUnit.GetBreakpoints();
   frmBreakpoints.RefreshBreakpointList;
   frmBreakpoints.RefreshBreakpointList;
 
 
@@ -1991,7 +2038,7 @@ begin
     if FindFirst(Dir+'\*.*', faAnyFile, srSearchRec) = 0 then
     if FindFirst(Dir+'\*.*', faAnyFile, srSearchRec) = 0 then
     begin
     begin
       bNeedPrjTreeRebuild := False;
       bNeedPrjTreeRebuild := False;
-         
+
       repeat
       repeat
         sFileName := Dir+'\'+srSearchRec.Name;
         sFileName := Dir+'\'+srSearchRec.Name;
 
 
@@ -3688,6 +3735,9 @@ begin
       end
       end
       else
       else
       begin
       begin
+        // Initialize actions before executing
+        DoMainMenuViewExecute;
+        
         // Popup the corresponding find window if not already opened
         // Popup the corresponding find window if not already opened
         if srSearchInFilesOutput = 0 then
         if srSearchInFilesOutput = 0 then
         begin
         begin
@@ -4155,6 +4205,7 @@ begin
 
 
         if (E.Msg <> 'STOP') then
         if (E.Msg <> 'STOP') then
         begin
         begin
+          stbMain.Panels[5].Text := '[ERROR]: '+E.Msg+' ('+IntToStr(E.Line)+') - '+DateTimeToStr(Now);
           frmLuaEditMessages.memMessages.Lines.Add('[ERROR]: '+E.Msg+' ('+IntToStr(E.Line)+') - '+DateTimeToStr(Now));
           frmLuaEditMessages.memMessages.Lines.Add('[ERROR]: '+E.Msg+' ('+IntToStr(E.Line)+') - '+DateTimeToStr(Now));
           frmLuaEditMessages.memMessages.Lines.Add('[HINT]:  End of Script - '+DateTimeToStr(Now));
           frmLuaEditMessages.memMessages.Lines.Add('[HINT]:  End of Script - '+DateTimeToStr(Now));
           raise;
           raise;
@@ -4408,7 +4459,7 @@ begin
       Result.synUnit.GotoLineAndCenter(iLine);
       Result.synUnit.GotoLineAndCenter(iLine);
 
 
       // Highlight the specified line if required
       // Highlight the specified line if required
-      if HighlightMode > 0 then
+      if HighlightMode >= 0 then
       begin
       begin
         case HighlightMode of
         case HighlightMode of
           HIGHLIGHT_STACK:      Result.pDebugInfos.iStackMarker := iLine;
           HIGHLIGHT_STACK:      Result.pDebugInfos.iStackMarker := iLine;
@@ -4416,6 +4467,8 @@ begin
           HIGHLIGHT_BREAKLINE:  Result.pDebugInfos.iCurrentLineDebug := iLine;
           HIGHLIGHT_BREAKLINE:  Result.pDebugInfos.iCurrentLineDebug := iLine;
         end;
         end;
       end;
       end;
+
+      Result.synUnit.Refresh;
     end;
     end;
   end;
   end;
 end;
 end;
@@ -4756,49 +4809,6 @@ begin
     Application.MessageBox(PChar('The file "'+ExtractFilePath(Application.ExeName)+'Help\refman-5.0.pdf" does not exists!'), 'LuaEdit', MB_OK+MB_ICONERROR);
     Application.MessageBox(PChar('The file "'+ExtractFilePath(Application.ExeName)+'Help\refman-5.0.pdf" does not exists!'), 'LuaEdit', MB_OK+MB_ICONERROR);
 end;
 end;
 
 
-procedure TfrmMain.PaintDebugGlyphs(ACanvas: TCanvas; AClip: TRect; FirstLine, LastLine: integer);
-var
-  LH, X, Y: integer;
-  ImgIndex: integer;
-  pLuaUnit: TLuaUnit;
-begin
-  pLuaUnit := TLuaUnit(frmMain.jvUnitBar.SelectedTab.Data);
-
-  FirstLine := pLuaUnit.synUnit.RowToLine(FirstLine);
-  LastLine := pLuaUnit.synUnit.RowToLine(LastLine);
-  X := 14;
-  LH := pLuaUnit.synUnit.LineHeight;
-  while FirstLine <= LastLine do
-  begin
-    ImgIndex := -1;
-    Y := (LH - frmMain.imlActions.Height) div 2 + LH * (pLuaUnit.synUnit.LineToRow(FirstLine) - pLuaUnit.synUnit.TopLine);
-
-    if pLuaUnit.pDebugInfos.IsBreakPointLine(FirstLine) then
-    begin
-      if pLuaUnit.pDebugInfos.GetBreakpointStatus(FirstLine) = BKPT_ENABLED then
-        ImgIndex := 27
-      else
-        ImgIndex := 28;
-    end;
-
-    if TLuaUnit(frmMain.jvUnitBar.SelectedTab.Data).pDebugInfos.iCurrentLineDebug = FirstLine then
-      ImgIndex := 29;
-
-    if ((pLuaUnit.pDebugInfos.IsBreakPointLine(FirstLine)) and (TLuaUnit(frmMain.jvUnitBar.SelectedTab.Data).pDebugInfos.iCurrentLineDebug = FirstLine)) then
-    begin
-      if pLuaUnit.pDebugInfos.GetBreakpointStatus(FirstLine) = BKPT_ENABLED then
-        ImgIndex := 30
-      else
-        ImgIndex := 43;
-    end;
-
-    if ImgIndex > 0 then
-      frmMain.imlActions.Draw(ACanvas, X, Y, ImgIndex);
-
-    Inc(FirstLine);
-  end;
-end;
-
 function TfrmMain.DoAddWatchExecute(): Boolean;
 function TfrmMain.DoAddWatchExecute(): Boolean;
 var
 var
   sTemp: string;
   sTemp: string;
@@ -4849,15 +4859,21 @@ procedure TfrmMain.stbMainDrawPanel(StatusBar: TStatusBar; Panel: TStatusPanel;
 var
 var
   InflatedRect: TRect;
   InflatedRect: TRect;
 begin
 begin
-  if not IsCompiledComplete then
+  if ((Panel.Text <> '') and (Panel.Index = 5)) then
   begin
   begin
+    // Special handling for error messages
     StatusBar.Canvas.Font.Color := clWhite;
     StatusBar.Canvas.Font.Color := clWhite;
     StatusBar.Canvas.Brush.Color := clNavy;
     StatusBar.Canvas.Brush.Color := clNavy;
     StatusBar.Canvas.FillRect(Rect);
     StatusBar.Canvas.FillRect(Rect);
-    StatusBar.Canvas.TextRect(Rect, Rect.Left, rect.Top, '  '+LastMessage);
+    InflatedRect := Rect;
+    DrawText(StatusBar.Canvas.Handle, PChar('  '+Panel.Text), Length('  '+Panel.Text), InflatedRect, DT_VCENTER or DT_LEFT or DT_SINGLELINE or DT_END_ELLIPSIS);
+    InflateRect(InflatedRect, 1, 1);
+    StatusBar.Canvas.Brush.Color := clGrayText;
+    StatusBar.Canvas.FrameRect(Rect);
   end
   end
   else
   else
   begin
   begin
+    // Regualar handling
     StatusBar.Canvas.Font.Color := clBlack;
     StatusBar.Canvas.Font.Color := clBlack;
     StatusBar.Canvas.FillRect(Rect);
     StatusBar.Canvas.FillRect(Rect);
     StatusBar.Canvas.TextRect(Rect, Rect.Left, Rect.Top, '  '+Panel.Text);
     StatusBar.Canvas.TextRect(Rect, Rect.Left, Rect.Top, '  '+Panel.Text);
@@ -4868,45 +4884,6 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TfrmMain.synEditSpecialLineColors(Sender: TObject; Line: Integer; var Special: Boolean; var FG, BG: TColor);
-var
-  pLuaUnit: TLuaUnit;
-begin
-  if Assigned(jvUnitBar.SelectedTab) then
-  begin
-    pLuaUnit := TLuaUnit(jvUnitBar.SelectedTab.Data);
-    Special := False;
-
-    if pLuaUnit.pDebugInfos.IsBreakPointLine(Line) then
-    begin
-      Special := True;
-      BG := StringToColor(TEditorColors(EditorColors.Items[9]).Background);
-      FG := StringToColor(TEditorColors(EditorColors.Items[9]).Foreground);
-    end;
-
-    if TLuaUnit(jvUnitBar.SelectedTab.Data).pDebugInfos.iCurrentLineDebug = Line then
-    begin
-      Special := True;
-      BG := StringToColor(TEditorColors(EditorColors.Items[3]).Background);
-      FG := StringToColor(TEditorColors(EditorColors.Items[3]).Foreground);
-    end;
-
-    if TLuaUnit(jvUnitBar.SelectedTab.Data).pDebugInfos.iLineError = Line then
-    begin
-      Special := True;
-      BG := StringToColor(TEditorColors(EditorColors.Items[2]).Background);
-      FG := StringToColor(TEditorColors(EditorColors.Items[2]).Foreground);
-    end;
-
-    if TLuaUnit(jvUnitBar.SelectedTab.Data).pDebugInfos.iStackMarker = Line then
-    begin
-      Special := True;
-      BG := clNavy;
-      FG := clWhite;
-    end;
-  end;
-end;
-
 procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
 procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
 var
 var
   x, y, Answer: Integer;
   x, y, Answer: Integer;
@@ -5228,6 +5205,61 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TfrmMain.synEditScroll(Sender: TObject; ScrollBar: TScrollBarKind);
+var
+  pLuaUnit: TLuaUnit;
+begin
+  if Assigned(jvUnitBar.SelectedTab.Data) then
+  begin
+    pLuaUnit := TLuaUnit(jvUnitBar.SelectedTab.Data);
+
+    // Reset line painting variables
+    pLuaUnit.pDebugInfos.iLineError := -1;
+    pLuaUnit.pDebugInfos.iStackMarker := -1;
+    stbMain.Panels[5].Text := '';
+    pLuaUnit.synUnit.Refresh;
+  end;
+end;
+
+procedure TfrmMain.synEditSpecialLineColors(Sender: TObject; Line: Integer; var Special: Boolean; var FG, BG: TColor);
+var
+  pLuaUnit: TLuaUnit;
+begin
+  if Assigned(jvUnitBar.SelectedTab) then
+  begin
+    pLuaUnit := TLuaUnit(jvUnitBar.SelectedTab.Data);
+    Special := False;
+
+    if pLuaUnit.pDebugInfos.IsBreakPointLine(Line) then
+    begin
+      Special := True;
+      BG := StringToColor(TEditorColors(EditorColors.Items[9]).Background);
+      FG := StringToColor(TEditorColors(EditorColors.Items[9]).Foreground);
+    end;
+
+    if TLuaUnit(jvUnitBar.SelectedTab.Data).pDebugInfos.iCurrentLineDebug = Line then
+    begin
+      Special := True;
+      BG := StringToColor(TEditorColors(EditorColors.Items[3]).Background);
+      FG := StringToColor(TEditorColors(EditorColors.Items[3]).Foreground);
+    end;
+
+    if TLuaUnit(jvUnitBar.SelectedTab.Data).pDebugInfos.iLineError = Line then
+    begin
+      Special := True;
+      BG := StringToColor(TEditorColors(EditorColors.Items[2]).Background);
+      FG := StringToColor(TEditorColors(EditorColors.Items[2]).Foreground);
+    end;
+
+    if TLuaUnit(jvUnitBar.SelectedTab.Data).pDebugInfos.iStackMarker = Line then
+    begin
+      Special := True;
+      BG := clNavy;
+      FG := clWhite;
+    end;
+  end;
+end;
+
 procedure TfrmMain.synEditChange(Sender: TObject);
 procedure TfrmMain.synEditChange(Sender: TObject);
 var
 var
   pLuaUnit: TLuaUnit;
   pLuaUnit: TLuaUnit;
@@ -5255,8 +5287,11 @@ begin
       stbMain.Panels[4].Text := 'Read Only'
       stbMain.Panels[4].Text := 'Read Only'
     else
     else
       stbMain.Panels[4].Text := '';
       stbMain.Panels[4].Text := '';
-      
+
+    // Reset line painting variables and other stuff
     pLuaUnit.pDebugInfos.iLineError := -1;
     pLuaUnit.pDebugInfos.iLineError := -1;
+    pLuaUnit.pDebugInfos.iStackMarker := -1;
+    stbMain.Panels[5].Text := '';
     HasChangedWhileCompiled := True;
     HasChangedWhileCompiled := True;
     pLuaUnit.LastEditedLine := pLuaUnit.synUnit.CaretY;
     pLuaUnit.LastEditedLine := pLuaUnit.synUnit.CaretY;
     pLuaUnit.PrevLineNumber := pLuaUnit.synUnit.Lines.Count;
     pLuaUnit.PrevLineNumber := pLuaUnit.synUnit.Lines.Count;
@@ -7475,7 +7510,7 @@ begin
     if Assigned(jvUnitBar.SelectedTab.Data) then
     if Assigned(jvUnitBar.SelectedTab.Data) then
     begin
     begin
       sLine := TLuaUnit(jvUnitBar.SelectedTab.Data).synUnit.Lines[TLuaUnit(jvUnitBar.SelectedTab.Data).synUnit.CaretY - 1];
       sLine := TLuaUnit(jvUnitBar.SelectedTab.Data).synUnit.Lines[TLuaUnit(jvUnitBar.SelectedTab.Data).synUnit.CaretY - 1];
-      FunctionHeaderBuilder(Application.Handle, PChar(sLine));
+      //FunctionHeaderBuilder(Application.Handle, PChar(sLine));
     end;
     end;
   end;
   end;
 end;
 end;

+ 14 - 1
LuaEdit/Watch.dfm

@@ -8,6 +8,9 @@ object frmWatch: TfrmWatch
   Color = clBtnFace
   Color = clBtnFace
   Constraints.MinHeight = 200
   Constraints.MinHeight = 200
   Constraints.MinWidth = 300
   Constraints.MinWidth = 300
+  DockSite = True
+  DragKind = dkDock
+  DragMode = dmAutomatic
   Font.Charset = DEFAULT_CHARSET
   Font.Charset = DEFAULT_CHARSET
   Font.Color = clWindowText
   Font.Color = clWindowText
   Font.Height = -11
   Font.Height = -11
@@ -34,7 +37,7 @@ object frmWatch: TfrmWatch
     Width = 292
     Width = 292
     Height = 149
     Height = 149
     Align = alClient
     Align = alClient
-    EditDelay = 200
+    EditDelay = 20
     Header.AutoSizeIndex = 1
     Header.AutoSizeIndex = 1
     Header.Font.Charset = DEFAULT_CHARSET
     Header.Font.Charset = DEFAULT_CHARSET
     Header.Font.Color = clWindowText
     Header.Font.Color = clWindowText
@@ -49,6 +52,7 @@ object frmWatch: TfrmWatch
     TreeOptions.MiscOptions = [toEditable, toFullRepaintOnResize, toInitOnSave, toReportMode, toToggleOnDblClick, toWheelPanning]
     TreeOptions.MiscOptions = [toEditable, toFullRepaintOnResize, toInitOnSave, toReportMode, toToggleOnDblClick, toWheelPanning]
     TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowHorzGridLines, toShowRoot, toShowTreeLines, toShowVertGridLines, toThemeAware, toUseBlendedImages]
     TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowHorzGridLines, toShowRoot, toShowTreeLines, toShowVertGridLines, toThemeAware, toUseBlendedImages]
     OnAfterItemPaint = vstWatchAfterItemPaint
     OnAfterItemPaint = vstWatchAfterItemPaint
+    OnChange = vstWatchChange
     OnCreateEditor = vstWatchCreateEditor
     OnCreateEditor = vstWatchCreateEditor
     OnDragOver = vstWatchDragOver
     OnDragOver = vstWatchDragOver
     OnDragDrop = vstWatchDragDrop
     OnDragDrop = vstWatchDragDrop
@@ -103,6 +107,15 @@ object frmWatch: TfrmWatch
       OnClick = tbtnRefreshWatchClick
       OnClick = tbtnRefreshWatchClick
     end
     end
   end
   end
+  object FEdit: TEdit
+    Left = 56
+    Top = 96
+    Width = 121
+    Height = 21
+    TabOrder = 3
+    Visible = False
+    OnKeyDown = FEditKeyDown
+  end
   object ppmWatch: TPopupMenu
   object ppmWatch: TPopupMenu
     Images = frmMain.imlActions
     Images = frmMain.imlActions
     Left = 48
     Left = 48

+ 99 - 62
LuaEdit/Watch.pas

@@ -8,6 +8,10 @@ uses
   JvComponent, JvDockControlForm, JvDragDrop, VirtualTrees, ActiveX,
   JvComponent, JvDockControlForm, JvDragDrop, VirtualTrees, ActiveX,
   ImgList, ToolWin;
   ImgList, ToolWin;
 
 
+const
+  // Helper message to decouple node change handling from edit handling.
+  WM_STARTEDITING = WM_USER + 778;
+
 type
 type
   PWatchNodeData = ^TWatchNodeData;
   PWatchNodeData = ^TWatchNodeData;
   TWatchNodeData = record
   TWatchNodeData = record
@@ -19,13 +23,11 @@ type
   // Our own edit link to implement several different node editors.
   // Our own edit link to implement several different node editors.
   TEditLinker = class(TInterfacedObject, IVTEditLink)
   TEditLinker = class(TInterfacedObject, IVTEditLink)
   private
   private
-    FEdit: TWinControl;        // One of the property editor classes.
     FTree: TVirtualStringTree; // A back reference to the tree calling.
     FTree: TVirtualStringTree; // A back reference to the tree calling.
     FNode: PVirtualNode;       // The node being edited.
     FNode: PVirtualNode;       // The node being edited.
     FColumn: Integer;          // The column of the node being edited.
     FColumn: Integer;          // The column of the node being edited.
-  protected
-    procedure EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
   public
   public
+    constructor Create;
     destructor Destroy; override;
     destructor Destroy; override;
 
 
     function BeginEdit: Boolean; stdcall;
     function BeginEdit: Boolean; stdcall;
@@ -47,6 +49,7 @@ type
     ToolButton1: TToolButton;
     ToolButton1: TToolButton;
     tbtnRefreshWatch: TToolButton;
     tbtnRefreshWatch: TToolButton;
     imlWatch: TImageList;
     imlWatch: TImageList;
+    FEdit: TEdit;
     procedure vstWatchGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
     procedure vstWatchGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: WideString);
     procedure vstWatchEditing(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
     procedure vstWatchEditing(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; var Allowed: Boolean);
     procedure vstWatchCreateEditor(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
     procedure vstWatchCreateEditor(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; out EditLink: IVTEditLink);
@@ -56,10 +59,13 @@ type
     procedure vstWatchDragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState; Pt: TPoint; Mode: TDropMode; var Effect: Integer; var Accept: Boolean);
     procedure vstWatchDragOver(Sender: TBaseVirtualTree; Source: TObject; Shift: TShiftState; State: TDragState; Pt: TPoint; Mode: TDropMode; var Effect: Integer; var Accept: Boolean);
     procedure tbtnRefreshWatchClick(Sender: TObject);
     procedure tbtnRefreshWatchClick(Sender: TObject);
     procedure tbtnAddWatchClick(Sender: TObject);
     procedure tbtnAddWatchClick(Sender: TObject);
-    procedure vstWatchEdited(Sender: TBaseVirtualTree; Node: PVirtualNode;
-      Column: TColumnIndex);
+    procedure vstWatchEdited(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex);
+    procedure vstWatchChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
+    procedure FEditKeyDown(Sender: TObject; var Key: Word;
+      Shift: TShiftState);
   private
   private
     { Private declarations }
     { Private declarations }
+    procedure WMStartEditing(var Message: TMessage); message WM_STARTEDITING;
   public
   public
     { Public declarations }
     { Public declarations }
   end;
   end;
@@ -69,79 +75,48 @@ var
 
 
 implementation
 implementation
 
 
-uses Main;
+uses Main, Types;
 
 
 {$R *.dfm}
 {$R *.dfm}
 
 
 ////////////////////////////////////// TEditLinker implementation //////////////////////////////////////
 ////////////////////////////////////// TEditLinker implementation //////////////////////////////////////
 
 
-destructor TEditLinker.Destroy;
-
+constructor TEditLinker.Create;
 begin
 begin
-  FreeAndNil(FEdit);
-  inherited;
+  FTree := nil;
+  FNode := nil;
+  FColumn := 0;
 end;
 end;
 
 
-procedure TEditLinker.EditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
-var
-  CanAdvance: Boolean;
-begin
-  CanAdvance := true;
-
-  case Key of
-    VK_ESCAPE:
-      if CanAdvance then
-      begin
-        FTree.CancelEditNode;
-        Key := 0;
-      end;
-    VK_RETURN:
-      if CanAdvance then
-      begin
-        FTree.EndEditNode;
-        Key := 0;
-      end;
-
-    VK_UP,
-    VK_DOWN:
-      begin
-        // Consider special cases before finishing edit mode.
-        CanAdvance := Shift = [];
+destructor TEditLinker.Destroy;
 
 
-        if CanAdvance then
-        begin
-          // Forward the keypress to the tree. It will asynchronously change the focused node.
-          PostMessage(FTree.Handle, WM_KEYDOWN, Key, 0);
-          Key := 0;
-        end;
-      end;
-  end;
+begin
+  // nothing for now...
+  inherited;
 end;
 end;
 
 
 function TEditLinker.BeginEdit: Boolean;
 function TEditLinker.BeginEdit: Boolean;
 begin
 begin
   Result := True;
   Result := True;
-  FEdit.Show;
-  FEdit.SetFocus;
+  frmWatch.FEdit.Show;
+  frmWatch.FEdit.SetFocus;
 end;
 end;
 
 
 function TEditLinker.CancelEdit: Boolean;
 function TEditLinker.CancelEdit: Boolean;
 begin
 begin
   Result := True;
   Result := True;
-  FEdit.Hide;
+  frmWatch.FEdit.Hide;
 end;
 end;
 
 
 function TEditLinker.EndEdit: Boolean;
 function TEditLinker.EndEdit: Boolean;
 var
 var
   Data: PWatchNodeData;
   Data: PWatchNodeData;
-  Buffer: array[0..1024] of Char;
   S: String;
   S: String;
 begin
 begin
   Result := True;
   Result := True;
 
 
   Data := FTree.GetNodeData(FNode);
   Data := FTree.GetNodeData(FNode);
-  GetWindowText(FEdit.Handle, Buffer, 1024);
-  S := Buffer;
+  S := frmWatch.FEdit.Text;
 
 
   if S <> Data.Name then
   if S <> Data.Name then
   begin
   begin
@@ -149,7 +124,7 @@ begin
     FTree.InvalidateNode(FNode);
     FTree.InvalidateNode(FNode);
   end;
   end;
 
 
-  FEdit.Hide;
+  frmWatch.FEdit.Hide;
   FTree.SetFocus;
   FTree.SetFocus;
 end;
 end;
 
 
@@ -160,12 +135,12 @@ begin
   // Since we don't want to activate grid extensions in the tree (this would influence how the selection is drawn)
   // Since we don't want to activate grid extensions in the tree (this would influence how the selection is drawn)
   // we have to set the edit's width explicitly to the width of the column.
   // we have to set the edit's width explicitly to the width of the column.
   FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right);
   FTree.Header.Columns.GetColumnBounds(FColumn, Dummy, R.Right);
-  FEdit.BoundsRect := R;
+  frmWatch.FEdit.BoundsRect := R;
 end;
 end;
 
 
 function TEditLinker.GetBounds: TRect;
 function TEditLinker.GetBounds: TRect;
 begin
 begin
-  Result := FEdit.BoundsRect;
+  Result := frmWatch.FEdit.BoundsRect;
 end;
 end;
 
 
 function TEditLinker.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
 function TEditLinker.PrepareEdit(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
@@ -176,26 +151,22 @@ begin
   FTree := Tree as TVirtualStringTree;
   FTree := Tree as TVirtualStringTree;
   FNode := Node;
   FNode := Node;
   FColumn := Column;
   FColumn := Column;
-
-  // determine what edit type actually is needed
-  FreeAndNil(FEdit);
+    
   Data := FTree.GetNodeData(Node);
   Data := FTree.GetNodeData(Node);
-  FEdit := TEdit.Create(Tree);
-  with FEdit as TEdit do
+  with frmWatch.FEdit do
   begin
   begin
     Visible := False;
     Visible := False;
-    Parent := Tree;
+    Parent := FTree;
     AutoSize := False;
     AutoSize := False;
     MaxLength := 1000;
     MaxLength := 1000;
     Ctl3D := False;
     Ctl3D := False;
     Text := Data.Name;
     Text := Data.Name;
-    OnKeyDown := EditKeyDown;
   end;
   end;
 end;
 end;
 
 
 procedure TEditLinker.ProcessMessage(var Message: TMessage);
 procedure TEditLinker.ProcessMessage(var Message: TMessage);
 begin
 begin
-  // Do nothing
+  frmWatch.FEdit.WindowProc(Message);
 end;
 end;
 
 
 ////////////////////////////////////// TfrmWatch implementation //////////////////////////////////////
 ////////////////////////////////////// TfrmWatch implementation //////////////////////////////////////
@@ -306,8 +277,9 @@ var
   pData: PWatchNodeData;
   pData: PWatchNodeData;
   sVarName: String;
   sVarName: String;
 begin
 begin
-  sVarName := InputBox('Add Watch', 'Enter the name of the variable to watch:', 'VarName');
-  if 'VarName' <> sVarName then
+  sVarName := 'VarName';
+
+  if InputQuery('Add Watch', 'Enter the name of the variable to watch:', sVarName) then
   begin
   begin
     vstWatch.RootNodeCount := vstWatch.RootNodeCount + 1;
     vstWatch.RootNodeCount := vstWatch.RootNodeCount + 1;
     pNode := vstWatch.GetLast;
     pNode := vstWatch.GetLast;
@@ -321,4 +293,69 @@ begin
   frmMain.PrintWatch(frmMain.LuaState);
   frmMain.PrintWatch(frmMain.LuaState);
 end;
 end;
 
 
+procedure TfrmWatch.WMStartEditing(var Message: TMessage);
+// This message was posted by ourselves from the node change handler above to decouple that change event and our
+// intention to start editing a node. This is necessary to avoid interferences between nodes editors potentially created
+// for an old edit action and the new one we start here.
+var
+  Node: PVirtualNode;
+begin
+  Node := Pointer(Message.WParam);
+  // Note: the test whether a node can really be edited is done in the OnEditing event.
+  vstWatch.EditNode(Node, 1);
+end;
+
+procedure TfrmWatch.vstWatchChange(Sender: TBaseVirtualTree; Node: PVirtualNode);
+begin
+  with Sender do
+  begin
+    // Start immediate editing as soon as another node gets focused.
+    if Assigned(Node) and (Node.Parent <> RootNode) then
+    begin
+      // We want to start editing the currently selected node. However it might well happen that this change event
+      // here is caused by the node editor if another node is currently being edited. It causes trouble
+      // to start a new edit operation if the last one is still in progress. So we post us a special message and
+      // in the message handler we then can start editing the new node. This works because the posted message
+      // is first executed *after* this event and the message, which triggered it is finished.
+      PostMessage(Self.Handle, WM_STARTEDITING, Integer(Node), 0);
+    end;
+  end;
+end;
+
+procedure TfrmWatch.FEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
+var
+  CanAdvance: Boolean;
+begin
+  CanAdvance := True;
+
+  case Key of
+    VK_ESCAPE:
+      if CanAdvance then
+      begin
+        vstWatch.CancelEditNode;
+        Key := 0;
+      end;
+    VK_RETURN:
+      if CanAdvance then
+      begin
+        vstWatch.EndEditNode;
+        Key := 0;
+      end;
+
+    VK_UP,
+    VK_DOWN:
+      begin
+        // Consider special cases before finishing edit mode.
+        CanAdvance := Shift = [];
+
+        if CanAdvance then
+        begin
+          // Forward the keypress to the tree. It will asynchronously change the focused node.
+          PostMessage(vstWatch.Handle, WM_KEYDOWN, Key, 0);
+          Key := 0;
+        end;
+      end;
+  end;
+end;
+
 end.
 end.