Board logo

Subject: [脚本] CnWizards 脚本交流 [Print This Page]

Author: zjy    Time: 2010-4-11 12:41     Subject: [脚本] CnWizards 脚本交流

欢迎大家在此分享自己编写的 CnWizards 脚本和使用经验。管理员将定期更新 RSS 源数据。

声明:由于本论坛的内容会发布给所有 CnWizards 用户,请勿在本论坛中回复无意义的回帖,否则一律删除!

如果确实需要针对某个帖子回帖,请点击帖子右下角的“引用”或“回复”来回帖。

回复前请先阅读注意事项:

http://bbs.cnpack.org/viewthread.php?tid=6440
Author: zjy    Time: 2010-4-11 21:51     Subject: 用 FormEventDemo.pas 去除新建 Edit 和 Memo 中默认文字的方法

VCL 的一些控件如 Edit、Memo、ComboBox 默认是用组件名来做编辑框内容的,而事实上我们经常希望编辑框为空。

使用 PSDemo\FormEventDemo.pas 脚本可以代替这种手工劳动。只要将这个脚本加到脚本列表中,并在关联事件中选中 smFormEditorNotify 下的 fetComponentCreated 项,就可以了。

如果对默认的处理规则不满意,还可以打开脚本手工编辑。

Image Attachment: FormEventDemo.png (2010-4-11 21:51, 21.3 K) / Download count 1874
http://bbs.cnpack.org/attachment.php?aid=722


Author: 不得闲    Time: 2010-4-12 10:35     Subject: 发一个Delphi编译了之后自动压缩EXE的脚本!

另外,咨询一下,如何获得当前编译之后的可执行程序的文件名,或者说,如何知道编译后生成的文件为PE文件,因为这样才执行压缩!目前的判断有点弱智!

这个UPX.exe,要设置添加到环境变量中去!不然无法运行的哈!

直接发代码:

[Copy to clipboard]
CODE:
{*******************************************************}
{                                                       }
{       Pascal Script Source File                       }
{       Run by RemObjects Pascal Script in CnWizards    }
{                                                       }
{       Generated by CnPack IDE Wizards                 }
{                                                       }
{*******************************************************}

program UPXEXE;

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ToolsAPI, CnWizUtils, CnWizIdeUtils;

function ShellExecute(hWnd: HWND; Operation, FileName, Parameters,
  Directory: PChar; ShowCmd: Integer): HINST; external 'ShellExecuteA@shell32.dll stdcall';

var
  CurPName,CurPath: Variant;
  tmps: string;
  Name1: string;
  IsFind: Boolean;
begin
   Name1 := CnOtaGetCurrentProjectFileName;
   CurPath := Name1;
   if IsBdsProject(Name1) or IsDpr(Name1) then //是PE工程
   begin
     CnOtaGetActiveProjectOption('OutputDir',CurPName); //先获得输出目录
     Name1 := ExtractFileName(Name1);
     if Trim(CurPName) = '' then
     begin
       CurPName := CnOtaGetCurrentProjectFileNameEx+'.exe';
       IsFind := FileExists(CurPName);
       if not IsFind then
         CurPName := CnOtaGetCurrentProjectFileNameEx+'.dll';
       IsFind := FileExists(CurPName);
       Name1 := CurPName;
     end
     else
     begin

       Name1 := Copy(Name1,1,Pos('.',Name1)-1);
       tmps := CurPName;
       if tmps[Length(tmps)] <> '\' then
         tmps := tmps + '\';
       if Pos(':',tmps) <> 0 then
       begin
         Name1 := tmps + Name1 + '.exe';
         IsFind := FileExists(Name1);
         if not IsFind then
           Name1 := tmps + Name1 + '.dll';
       end
       else
       begin
         CurPath := ExtractFilePath(CurPath);
         CurPName := CurPath + tmps +  Name1 + '.exe';
         IsFind := FileExists(CurPName);
         if not IsFind then
           CurPName := CurPath + tmps + Name1 + '.dll';
         Name1 := CurPName;
       end;
       IsFind := FileExists(Name1);
     end;
     if IsFind then
     begin
       Name1 := '"' + Name1 + '"';
       if MessageBox(Application.handle,'需要先在压缩吗?', '提示', MB_YESNO + MB_ICONQUESTION) = 6 then
       begin
         ShellExecute(Application.Handle,'open','upx.exe',PChar(Name1),'',1);
         ShowMessage('压缩成功');
       end;
     end;
   end;
end.

代码修改了下,以前没有考虑到编译程序的输出路径,同时也加入了对于相对路径的判断,现在加进去了!
但是有个问题,如何判断工程是否编译成功!看了下专家包的代码!发现貌似没有写!希望能够加入进去,或者说,在执行的时候,能够获得当前的事件对象!
以作相应的处理!

[ 本帖最后由 不得闲 于 2010-4-13 13:53 编辑 ]
Author: zjy    Time: 2010-4-12 11:28     Subject: 一个加载语言文件来切换设计期窗体语言的脚本

CnWizards 使用 CnPack 的多语控件,以前窗体上的文本都是中文的,前段时间改成英文,写了这个小脚本:

[Copy to clipboard]
CODE:
{*******************************************************}
{                                                       }
{       Pascal Script Source File                       }
{       Run by RemObjects Pascal Script in CnWizards    }
{                                                       }
{       Generated by CnPack IDE Wizards                 }
{                                                       }
{*******************************************************}

program Trans;

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

var
  DesignContainer: TComponent;

begin
  DesignContainer := IdeGetDesignedForm(nil);
  if DesignContainer = nil then
  begin
    ErrorDlg('NO Designer Found.');
    Exit;
  end;

  // 以下需要修改为相应的 语言文件目录、语言文件名、要切换的目标语种
  TranslateFormFromLangFile(TForm(DesignContainer), 'D:\cnpack\cnwizards\Bin\Lang',
    'CnWizards.txt', 1033);
  CnOtaNotifyFormDesignerModified(nil);
end.


Author: zjy    Time: 2010-4-12 11:32     Subject: 可将选择的类字段定义转成属性声明的脚本

使用时先选择要转换的字段,执行脚本后变成
property XXX read FXXX write XXX;
的格式

[Copy to clipboard]
CODE:
{*******************************************************}
{                                                       }
{       Pascal Script Source File                       }
{       Run by RemObjects Pascal Script in CnWizards    }
{                                                       }
{       Generated by CnPack IDE Wizards                 }
{                                                       }
{*******************************************************}

program FieldToProperty;

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

var
  Text: string;
  Lines: TStringList;
  I: Integer;
  Name, AType: string;
begin
  Lines := TStringList.Create;
  try
    IdeGetEditorSelectedLines(Lines);
    for I := 0 to Lines.Count - 1 do
    begin
      Text := Lines[I];
      if (Pos(':', Text) > 0) and (Pos('//', Text) = 0) then
      begin
        Name := Trim(Copy(Text, 1, Pos(':', Text) - 1));
        AType := Trim(Copy(Text, Pos(':', Text) + 1, MaxInt));
        AType := StringReplace(AType, ';', '', [rfReplaceAll]);
        Text := Copy(Text, 1, Pos(Name, Text) - 1) + 'property ' + Name + ': ' +
          AType + ' read F' + Name + ' write F' + Name + ';';
        Lines[I] := Text;
      end;
    end;
    IdeSetEditorSelectedLines(Lines);
  finally
    Lines.Free;
  end;
end.


Author: 不得闲    Time: 2010-5-4 14:11     Subject: 再发 一个编译后修改编译文件名称的脚本

某日,一个好友问我有没有什么办法,在某工程编译之后自动将工程生成的exe文件改成别的名字,我想也不想的就说了cnpack脚本,嘿嘿,这个东西其实还真是蛮好用的哈!然后随手在我上次的那个压缩脚本上修改了一下

[Copy to clipboard]
CODE:
{*******************************************************}
{                                                       }
{       Pascal Script Source File                       }
{       Run by RemObjects Pascal Script in CnWizards    }
{                                                       }
{       Generated by CnPack IDE Wizards                 }
{                                                       }
{*******************************************************}

program RenameScript;

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

var
  CurPName,CurPath: Variant;
  tmps: string;
  Name1: string;
  IsFind: Boolean;
begin
   Name1 := CnOtaGetCurrentProjectFileName;
   CurPath := Name1;
   if IsBdsProject(Name1) or IsDpr(Name1) then //是PE工程
   begin
     CnOtaGetActiveProjectOption('OutputDir',CurPName); //先获得输出目录
     Name1 := ExtractFileName(Name1);
     if Trim(CurPName) = '' then
     begin
       CurPName := CnOtaGetCurrentProjectFileNameEx+'.exe';
       IsFind := FileExists(CurPName);
       if not IsFind then
         CurPName := CnOtaGetCurrentProjectFileNameEx+'.dll';
       IsFind := FileExists(CurPName);
       Name1 := CurPName;
     end
     else
     begin

       Name1 := Copy(Name1,1,Pos('.',Name1)-1);
       tmps := CurPName;
       if tmps[Length(tmps)] <> '\' then
         tmps := tmps + '\';
       if Pos(':',tmps) <> 0 then
       begin
         Name1 := tmps + Name1 + '.exe';
         IsFind := FileExists(Name1);
         if not IsFind then
           Name1 := tmps + Name1 + '.dll';
       end
       else
       begin
         CurPath := ExtractFilePath(CurPath);
         CurPName := CurPath + tmps +  Name1 + '.exe';
         IsFind := FileExists(CurPName);
         if not IsFind then
           CurPName := CurPath + tmps + Name1 + '.dll';
         Name1 := CurPName;
       end;
       IsFind := FileExists(Name1);
     end;
     if IsFind then
     begin
       if MessageBox(Application.handle,'需要改名吗?', '提示', MB_YESNO + MB_ICONQUESTION) = 6 then
       begin
         tmps := ExtractFileName(Name1);
         tmps := InputBox('输入','请输入新名字',tmps);
         tmps := ExtractFilePath(Name1) + tmps;
         if (tmps <> '') and (CompareText(tmps,Name1) <> 0) then
         begin
           RenameFile(Name1,tmps);
           ShowMessage('改名成功');
         end;
       end;
     end;
   end;
end.

[ 本帖最后由 不得闲 于 2010-5-4 14:16 编辑 ]
Author: zjy    Time: 2010-5-4 20:30



QUOTE:
原帖由 不得闲 于 2010-5-4 14:11 发表
某日,一个好友问我有没有什么办法,在某工程编译之后自动将工程生成的exe文件改成别的名字,我想也不想的就说了cnpack脚本,嘿嘿,这个东西其实还真是蛮好用的哈!然后随手在我上次的那个压缩脚本上修改了一下

{************** ...

如果只是修改编译出来的文件扩展名,倒是有个简单的方法:
打开 Project Options 对话框,在 Application 页下方,有一个 Target file extention 编辑框,可以直接修改输出文件的扩展名。
当然,如果是要改文件名的话,就只有用脚本或其它方法了。
Author: 不得闲    Time: 2010-5-4 21:42



QUOTE:
原帖由 zjy 于 2010-5-4 20:30 发表

如果只是修改编译出来的文件扩展名,倒是有个简单的方法:
打开 Project Options 对话框,在 Application 页下方,有一个 Target file extention 编辑框,可以直接修改输出文件的扩展名。
当然,如果是要改文件名的话,就只有用脚 ...

恩,确实如此,我每回都用{$E }这个编译指令!本来还有个办法的,那个啥工程选项中的最后一项有一个编译之后的事件,Build Events,这里可以写批处理的,不过我用的阉割版本的,没这个选项!所以要通用起来还是只有用脚本了!
Author: zjy    Time: 2010-5-7 23:24     Subject: 在脚本中操作非标准控件属性的方法

如果需要在脚本中操作非标准控件,需要 uses IdeInstComp 单元,例子脚本如下:

[Copy to clipboard]
CODE:
{*******************************************************}
{                                                       }
{       Pascal Script Source File                       }
{       Run by RemObjects Pascal Script in CnWizards    }
{                                                       }
{       Generated by CnPack IDE Wizards                 }
{                                                       }
{*******************************************************}

program Test;

// 当脚本在 uses 列表中指定了 IdeInstComp 时,脚本可以使用在 IDE 中安装的所有组件。
// 对于没有在 PSDecl 目录下的声明文件中列出的组件,只能访问其 published 的属性。

// 其它没有特别声明的单元如 Windows, Classes,不需要 uses 即可使用其声明的内容,
// 不过如果 uses 他们,在 IDE 代码编辑器中编辑脚本时,可以使用 IDE 的代码自动完成。
// 不将 IdeInstComp 直接导入,是因为当 IDE 安装了很多包时,导入的速度可能较慢

uses
  Windows, SysUtils, IdeInstComp; // uses IdeInstComp is needed.

var
  DB: TDataBase;    // TDataBase is not imported by script engine expressly.
  Timer: TCnTimer;  // TCnTimer is a 3rd component (in CnPack) installed in IDE.

begin
  DB := TDataBase.Create(nil);
  try
    DB.AliasName := 'Test';  // You can access published properties only!!!
  finally
    DB.Free;
  end;

  Timer := TCnTimer.Create(nil);
  try
    Timer.Enabled := True;
  finally
    Timer.Free;
  end;
end.


Author: zjy    Time: 2010-5-9 00:00     Subject: 自动将当前日期时间加入到编译代码中的方法

这是在一个西班牙语论坛上看到的一个帖子,原帖见:
http://www.clubdelphi.com/foros/showthread.php?t=65520
作者是 16楼 的 Lord Delfos

先创建一个脚本:

[Copy to clipboard]
CODE:
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

var Lineas: TStringList;

begin
  Lineas:= TStringList.Create;
  try
    Lineas.Add('const FechaCompilacion = ''' + FormatDatetime('dd/mm/yyyy', Now) + ''';');
    Lineas.Add('const HoraCompilacion = ''' + FormatDatetime('hh:nn', Now) + ''';');
    Lineas.SaveToFile('C:\Delphi\Utils\FechaCompilacion.inc');
  finally
    Lineas.Free;
  end;
end.

保存脚本后增加到脚本库中,并在右边的事件列表中选中 fmBeforeCompile 项,这样在每次编译代码时都会根据当前日期时间生成这个一样 inc 文件。

然后在需要包含编译时间的工程中,使用如下的代码:

[Copy to clipboard]
CODE:
unit Unit1;

type TForm1 = class(TForm)

[...]

end

implementation

{$R *.res}

{$I 'C:\Delphi\Utils\FechaCompilacion.inc'}


procedure TForm1.OnCreate(Sender: TObject);
begin
  ShowMessage('Compilado el ' + FechaCompilacion + ' a las ' + HoraCompilacion);
end;

PS,在这个帖子的 #22楼,还有位牛人大哥做了一个 PDF 格式的 CnScript 的教程(西班牙语):
http://www.terawiki.com/clubdelphi/archivos/Delphi/Otros%20documentos/CnWizards%20-%20CnScripts%20y%20tutorial.zip
里面用脚本实现了自动向源代码函数中插入 CnDebugger 调用来进行代码调试的多个功能,老外们的 DIY 精神,不服不行
Author: zjy    Time: 2010-5-16 22:05     Subject: Build 573 增加了在脚本中调用 RegExpr 正则函数的功能

RegExprReplace.pas 这个脚本可以创建一个窗口,对当前选择的代码块进行正则搜索替换,并可在执行前预览替换结果。
脚本内置了一个替换规则,可以将 tblData.FieldByName('FName').AsString 这样的代码替换成 tblFName.Value
Author: lonebone    Time: 2011-2-18 08:21

删除光标所在行代码、段复制、剪切、粘贴代码。对需要整体移动代码段很方便。
建议快捷键:删除行(ctrl+D);段复制(ctrl+shift+C)这个和系统快捷键冲突,不过可以夺过来;段剪切(ctrl+shift+X);段粘贴(ctrl+shift+V)
删除行

[Copy to clipboard]
CODE:
program DeletePlus;
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Clipbrd;
var
  Lines: TStringList;
  Clipboard: TClipboard;
begin
  Lines := TStringList.Create;
  Clipboard := TClipboard.Create;
  try
    Lines.Clear;
    IdeSetEditorSelectedLines(Lines);
  finally
    Lines.Free;
    Clipboard.Free;
  end;
end.

段复制

[Copy to clipboard]
CODE:
program CopyPlus;
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Clipbrd;
var
  Lines: TStringList;
  Clipboard: TClipboard;
  i: Integer;
begin
  Lines := TStringList.Create;
  Clipboard := TClipboard.Create;
  try
    if IdeGetEditorSelectedLines(Lines) then
    begin
      Clipboard.Clear;
      Clipboard.AsText := Lines.Text;
    end;
  finally
    Lines.Free;
    Clipboard.Free;
  end;
end.

段剪切

[Copy to clipboard]
CODE:
program CutPlus;
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Clipbrd;
var
  Lines: TStringList;
  Clipboard: TClipboard;
  i: Integer;
begin
  Lines := TStringList.Create;
  Clipboard := TClipboard.Create;
  try
    if IdeGetEditorSelectedLines(Lines) then
    begin
      Clipboard.Clear;
      Clipboard.AsText := Lines.Text;
      Lines.Clear;
      IdeSetEditorSelectedLines(Lines);
    end;
  finally
    Lines.Free;
    Clipboard.Free;
  end;
end.

段粘贴

[Copy to clipboard]
CODE:
program PastePlus;
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Clipbrd;
var
  Lines: TStringList;
  Clipboard: TClipboard;
begin
  Lines := TStringList.Create;
  Clipboard := TClipboard.Create;
  try
    if Clipboard.HasFormat(1)   then
    begin
      if IdeGetEditorSelectedLines(Lines) then
      begin
        Lines.Text := Clipboard.AsText + Lines.Text;
        IdeSetEditorSelectedLines(Lines);
      end;
    end;
  finally
    Lines.Free;
    Clipboard.Free;
  end;
end.






Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0