delphi – 我可以更改观察列表中字符串的显示格式吗?

前端之家收集整理的这篇文章主要介绍了delphi – 我可以更改观察列表中字符串的显示格式吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我现在使用watch窗口来显示包含sql语句的字符串.

现在我从上下文菜单中选择复制值并获取

'SELECT NAME FROM SAMPLE_TABLE WHERE  FIRST_NAME = ''George'''#$D#$A

当然,如果我想在显示结果的sql工具中执行该语句,则必须重新格式化此语句.这有点恼人.

有没有一个技巧/解决方法

解决方法

我认为通过在IDE中添加一些东西来尝试和设计出一个方法是有趣的,主要是因为当你发布你的q时,我没有一个线索.事实证明,您可以轻松地使用包含以下单元的自定义OTA包来做到这一点.

Btw,我特别强调Rob Kennedy指出另一个SO问题,IDE有一个Screen对象就像其他的一样.这提供了一个简单的方法解决这个问题,绕过了我通常不得不使用的OTA接口的迷宫来编写一个IDE加载项.

它工作

>查找手表窗口,
>在其上下文菜单&在它之后添加一个新的菜单
>使用新项目的OnClick处理程序从Watch Window的关注项目中获取该值,根据需要重新格式化它,然后将其粘贴到剪贴板.

就使用OTA服务而言,它并没有任何幻想,但是对于IDE,我认为KISS原则是适用的.

码:

unit IdeMenuProcessing;

interface

uses
  Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,StdCtrls,ExtCtrls,ToolsAPI,Menus,ClipBrd,ComCtrls;

type
  TOtaMenuForm = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    OurMenuItem : TMenuItem;
    WatchWindow : TForm;
    WWListView : TListView;
    procedure GetWatchValue(Sender : TObject);
  end;

var
  OtaMenuForm: TOtaMenuForm;

procedure Register;

implementation

{$R *.dfm}

procedure ShowMenus;
begin
  OtaMenuForm := TOtaMenuForm.Create(Nil);
  OtaMenuForm.Show;
end;

procedure Register;
begin
  ShowMenus;
end;

procedure TOtaMenuForm.FormCreate(Sender: TObject);
var
  i : Integer;
  S : String;
  PM : TPopUpMenu;
  Item : TMenuItem;
begin

  // First create a menu item to insert in the Watch Window's context menu
  OurMenuItem := TMenuItem.Create(Self);
  OurMenuItem.OnClick := GetWatchValue;
  OurMenuItem.Caption := 'Get processed watch value';

  WatchWindow := Nil;
  WWListView := Nil;

  //  Next,iterate the IDE's forms to find the Watch Window
  for i := 0 to Screen.FormCount - 1 do begin
    S := Screen.Forms[i].Name;
    if CompareText(S,'WatchWindow') = 0 then begin  // < Localize if necessary
      WatchWindow := Screen.Forms[i];
      Break;
    end;
  end;

  Assert(WatchWindow <> Nil);

  if WatchWindow <> Nil then begin
    //  Next,scan the Watch Window's context menu to find the existing "Copy watch value" entry
    //  and insert our menu iem after it
    PM := WatchWindow.PopUpMenu;
    for i:= 0 to PM.Items.Count - 1 do begin
      Item := PM.Items[i];
      if CompareText('Copy Watch &Value',Item.Caption) = 0 then begin // < Localize if necessary
        PM.Items.Insert(i + 1,OurMenuItem);
        Break;
      end;
    end;

    //  Now,find the TListView in the Watch Window
    for i := 0 to WatchWindow.ComponentCount - 1 do begin
      if WatchWindow.Components[i] is TListView then begin
        WWListView := WatchWindow.Components[i] as TListView;
        Break;
      end;
    end;
    Assert(WWListView <> Nil);
  end;
end;

procedure TOtaMenuForm.GetWatchValue(Sender: TObject);
var
  WatchValue : String;
begin
  //  This is called when the Watch Window menu item we added is clicked
  if WWListView.ItemFocused = Nil then begin
    Memo1.Lines.Add('no Watch selected');
    exit;
  end;
  WatchValue := WWListView.ItemFocused.SubItems[0];
  WatchValue := StringReplace(WatchValue,#$D#$A,' ',[rfreplaceAll]);
  if WatchValue[1] = '''' then
    Delete(WatchValue,1,1);

  if WatchValue[Length(WatchValue)] = '''' then
    WatchValue := Copy(WatchValue,Length(WatchValue) - 1);
  // [etc]  
  ClipBoard.AsText := WatchValue;
  Memo1.Lines.Add('>' +  WatchValue + '<');
end;

initialization

finalization
  if Assigned(OTAMenuForm) then begin
    OTAMenuForm.Close;
    FreeAndNil(OTAMenuForm);
  end;
end.

Btw,我在D7写了这个,因为我用它作为SO答案的一个最低的共同点,因为很明显,这里的很多人还在使用它.后来的版本有额外的字符串功能,如注释中提到的AniDequotedStr,可能有助于重新格式化手表值.

更新:根据OP,上述不适用于XE3,因为观察窗口是使用TVirtualStringTree而不是TListView实现的.我使用ListView的原因是我发现从剪贴板拾取Watch值(模拟点击上下文菜单的复制观察值)来处理它不是很可靠.这在XE4中似乎有所改进(我没有XE3测试),所以这里有一个在XE4中可以使用的版本:

更新#2:OP提到以前的代码版本失败WatchWindow<>当Delphi第一次启动时,没有断言.我想象的原因是代码在IDE中创建Watch Window之前被调用.我重新安排了代码,添加了一个OTANotifier,用于获取项目桌面已经加载的通知,广告使用它来调用新的SetUp例程.

unit IdeMenuProcessing;

interface

uses
  Windows,ComCtrls;

type
  TIdeNotifier = class(TNotifierObject,IOTANotifier,IOTAIDENotifier)
  protected
    procedure AfterCompile(Succeeded: Boolean);
    procedure BeforeCompile(const Project: IOTAProject; var Cancel: Boolean);
    procedure FileNotification(NotifyCode: TOTAFileNotification;
      const FileName: string; var Cancel: Boolean);
  end;

  TOtaMenuForm = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    IsSetUp : Boolean;
    ExistingMenuItem,OurMenuItem : TMenuItem;
    WatchWindow : TForm;
    Services: IOTAServices;
    Notifier : TIdeNotifier;
    NotifierIndex: Integer;
    procedure GetWatchValue(Sender : TObject);
    procedure SetUp;
  end;

var
  OtaMenuForm: TOtaMenuForm;

procedure Register;

implementation

{$R *.dfm}

procedure ShowMenus;
begin
  OtaMenuForm := TOtaMenuForm.Create(Nil);
  OtaMenuForm.Services := BorlandIDEServices as IOTAServices;
  OtaMenuForm.NotifierIndex := OtaMenuForm.Services.AddNotifier(TIdeNotifier.Create);
  OtaMenuForm.Show;
end;

procedure Register;
begin
  ShowMenus;
end;

procedure TOtaMenuForm.SetUp;
var
  i : Integer;
  S : String;
  PM : TPopUpMenu;
  Item : TMenuItem;
begin
  if IsSetUp then exit;

  // First create a menu item to insert in the Watch Window's context menu
  OurMenuItem := TMenuItem.Create(Self);
  OurMenuItem.OnClick := GetWatchValue;
  OurMenuItem.Caption := 'Get processed watch value';

  WatchWindow := Nil;

  //  Next,'WatchWindow') = 0 then begin
      WatchWindow := Screen.Forms[i];
      Break;
    end;
  end;

  Assert(WatchWindow <> Nil);

  if WatchWindow <> Nil then begin
    //  Next,scan the Watch Window's context menu to find the existing "Copy watch value" entry
    //  and insert our menu item after it
    PM := WatchWindow.PopUpMenu;
    for i:= 0 to PM.Items.Count - 1 do begin
      Item := PM.Items[i];
      if CompareText('Copy Watch &Value',Item.Caption) = 0 then begin
        ExistingMenuItem := Item;
        PM.Items.Insert(i + 1,OurMenuItem);
        if ExistingMenuItem.Action <> Nil then
          Memo1.Lines.Add('Has action')
        else
          Memo1.Lines.Add('No action');
        Break;
      end;
    end;
  end;
  Caption := 'Setup complete';
  IsSetUp := True;
end;

procedure TOtaMenuForm.FormCreate(Sender: TObject);
begin
  IsSetUp := False;
end;

procedure TOtaMenuForm.GetWatchValue(Sender: TObject);
var
  S,WatchValue : String;
  TL : TStringList;
  i : Integer;
begin
  //  This is called when the Watch Window menu item we added is clicked

  ExistingMenuItem.Click;

  WatchValue := ClipBoard.AsText;
  WatchValue := StringReplace(WatchValue,'#$D#$A',[rfreplaceAll]);

  if WatchValue <> '' then begin
    TL := TStringList.Create;
    try
      TL.Text := WatchValue;
      WatchValue := '';
      for i := 0 to TL.Count - 1 do begin
        S := TL[i];
        if S[1] = '''' then
          Delete(S,1);
        if S[Length(S)] = '''' then
          S := Copy(S,Length(S) - 1);
         if WatchValue <> '' then
           WatchValue := WatchValue + ' ';
         WatchValue := WatchValue + S;
      end;
    finally
      TL.Free;
    end;
    // [etc]
  end;

  ClipBoard.AsText := WatchValue;
  Memo1.Lines.Add('>' +  WatchValue + '<');
end;

{ TIdeNotifier }

procedure TIdeNotifier.AfterCompile(Succeeded: Boolean);
begin

end;

procedure TIdeNotifier.BeforeCompile(const Project: IOTAProject;
  var Cancel: Boolean);
begin

end;

procedure TIdeNotifier.FileNotification(NotifyCode: TOTAFileNotification;
  const FileName: string; var Cancel: Boolean);
begin
  if NotifyCode = ofnProjectDesktopLoad then
    OTAMenuForm.SetUp
end;

initialization

finalization
  if Assigned(OTAMenuForm) then begin
    OTAMenuForm.Services.RemoveNotifier(OTAMenuForm.NotifierIndex);
    OTAMenuForm.Close;
    FreeAndNil(OTAMenuForm);
  end;
end.

猜你在找的Delphi相关文章