2012年11月27日火曜日

ActiveX.Exeもどき

マイクロソフトさんのCodeRecipeサイトに.EXEにあるクラスを動的に呼び出して使う例が載っていたのでこれをPrismでやってみた。

以下ソース

まずは、EXEのメインルーチン

  1. unit DirZipImp;  
  2.   
  3. namespace ConsoleApplication1;  
  4.   
  5. interface  
  6.   
  7.   
  8.   
  9. type  
  10.   ConsoleApp = class  
  11.   public  
  12.     class method Main(args: array of String);  
  13.   end;  
  14.   
  15. implementation  
  16.   
  17. class method ConsoleApp.Main(args: array of String);  
  18. begin  
  19.   // add your own code here  
  20.   Console.WriteLine('ならやめれば、うそよ');  
  21.  Console.ReadLine();  
  22. end;  
  23.   
  24. end.  

次に、EXEに含まれるクラス
  1. namespace ActiveXExeLib;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   System.Collections.Generic,  
  7.   System.Text;  
  8.   
  9. type  
  10.   Class1 = public class  
  11.   private  
  12.   protected  
  13.   public  
  14.   method CallYourName : String;  
  15.   end;  
  16.   
  17. implementation  
  18.   
  19. method Class1.CallYourName: String;  
  20. begin  
  21.  result := 'いーや';  
  22. end;  

最後に上記のクラスライブラリを動的に呼び足してるExe
  1. namespace ConsoleApplication2;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.  System.Reflection;  
  7.   
  8.   
  9.   
  10. type  
  11.   ConsoleApp = class  
  12.   public  
  13.     class method Main(args: array of String);  
  14.   end;  
  15.   
  16. implementation  
  17.   
  18. class method ConsoleApp.Main(args: array of String);  
  19. var  
  20.  m : &Assembly;  
  21.   
  22. begin  
  23.   
  24.   // add your own code here  
  25.   //Console.WriteLine('Hello World.');  
  26.   
  27.  m := &Assembly.LoadFrom(args[0]);  
  28.  var instance1: Dynamic := Activator.CreateInstance(m.GetType('ActiveXExeLib.Class1'));  
  29.  Console.WriteLine(instance1.CallYourName());  
  30.  Console.ReadLine();  
  31.   
  32. end;  
  33.   
  34. end.  
ConsoleApplication1.exeを呼び出すと

'ならやめれば、うそよ'

と表示され

ConsoleApplication2.Exeを引数に ConsoleApplication1.exe を与えて呼び出すと

'いーや'

と表示されます。


なお、Assemblyは、Prism(Oxgene)の予約語なので、手前&をつけないと.Netのクラスと
認識されないので注意が必要です。

また、Dynamicを型推論の意味でつかうには、RemObjects.Oxgene.Dynamic.dllの
参照登録が必要となります。


2011年4月3日日曜日

Guid文字列を得る

Delphi PrismでGuidを得るには、System.Guidを使用します。

  1. method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);  
  2. begin  
  3.   var myguid := System.Guid.NewGuid;  
  4.   label1.Text := myguid.ToString();   
  5. end;  

DelphiXE(Wi32)には、System.Guid構造体と同じように動作するHelperが実装されて
います。

2010年4月17日土曜日

Processのリストを表示する。

最近、VBAでプロセスを列挙する必要があったので、Prism(というか.Net)でやってみた

以下、コード(ボタンを押すとリストボックスにプロセスリストを表示する。)

  1. method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);  
  2. var  
  3. ProcessList : array of  System.Diagnostics.Process;  
  4. begin  
  5.   
  6. ProcessList := System.Diagnostics.Process.GetProcesses();  
  7.   
  8. for each ps : System.Diagnostics.Process in ProcessList do  
  9. begin  
  10. listbox1.Items.Add(ps.ProcessName);  
  11. end;  
  12. end;  

簡単すぎて涙が出てきた。Enum系のCallbackを使用する場合の
煩雑さがなくてよいです。

追記

Delphi Win32版で書いてみました。NT4.0をサポートしないといけない場合は、
やっぱり結構大変ですね。

2009年10月26日月曜日

ファイルリストを取取得する。

.NetFramworkでは、ファイル名のリストを取得するだけなら
System.IO.Directory.GetFilesメソッドで簡単に取得できます。

以下、サンプル

  1. method MainForm.buttonExecGetFile_Click(sender: System.Object; e: System.EventArgs);  
  2. var  
  3.   FileList : Array of String;  
  4.   FileName : String;  
  5. begin  
  6.     
  7.   Self.listBoxResult.Items.Clear();  
  8.   
  9.   if Self.checkBoxFindSubDir.Checked then  
  10.   begin  
  11.     FileList := System.IO.Directory.GetFiles(Self.textBoxStartPath.Text,'*',System.IO.SearchOption.AllDirectories);  
  12.   end  
  13.   else  
  14.   begin  
  15.     FileList := System.IO.Directory.GetFiles(Self.textBoxStartPath.Text,'*',System.IO.SearchOption.TopDirectoryOnly);  
  16.   end;  
  17.   
  18.   For FileName in FileList do  
  19.   begin  
  20.     listBoxResult.Items.Add(FileName);   
  21.   end;  
  22. end;  

2009年9月5日土曜日

Tem Japanのソースを移植してみる(RTTI)

Team JapanブログのDelphi2010のRTTI機能に関するポストのソースを
Delphi Prismで記述してみた。

以下ソース

  1. method MainForm.BuildSql(obj : System.Object) : String;  
  2. var  
  3.   FldList : String;  
  4.   ValList : String;  
  5.   t : System.Type;  
  6.   PropArry : Array of PropertyInfo;  
  7.   pv : Object;  
  8.   
  9. begin  
  10.      
  11.   //渡された型を取り出して  
  12.   t := obj.GetType();  
  13.   
  14.   //プロパティの一覧を取得する  
  15.   PropArry := t.GetProperties();  
  16.    
  17.   //全てのフィールド(プロパティ)を操作してInsert分を作成  
  18.   FldList := '';  
  19.   ValList := '';  
  20.   for each Prop : PropertyInfo in PropArry do  
  21.   begin  
  22.       FldList := FldList  + Prop.Name + ',';  
  23.       pv := Prop.GetValue(obj, nil);  
  24.       //Value句 文字列は''で囲  
  25.       if (pv.GetType().Name = 'String'then  
  26.       begin  
  27.         ValList := ValList + ''''+ pv.ToString() + ''',';  
  28.       end  
  29.       else  
  30.       begin  
  31.           ValList := ValList + pv.ToString() + ",";  
  32.       end;  
  33.   
  34.   end;  
  35.   
  36.   Var Sb := new System.Text.StringBuilder();  
  37.   Sb.AppendLine('INSERT INTO ' + t.Name + '(' + FldList.Remove(FldList.Length - 1) + ')');  
  38.   Sb.AppendLine('Values (' + ValList.Remove(ValList.Length - 1) + ')');  
  39.   
  40.   Result := Sb.ToString();  
  41.   
  42. end;  


ちなみにC#で書くと

  1. private String BuildSQL(object o)  
  2. {  
  3.    //渡された型を取り出して  
  4.    Type t = o.GetType();  
  5.   
  6.    //プロパティの一覧を取得する  
  7.    System.Reflection.PropertyInfo[] PropArry = t.GetProperties();  
  8.   
  9.    //全てのフィールド(プロパティ)を操作してInsert分を作成  
  10.    string FldList = "";  
  11.    string ValList = "";  
  12.               
  13.    foreach (PropertyInfo Prop in PropArry)  
  14.    {  
  15.       FldList = FldList  + Prop.Name + ",";  
  16.       Object pv = Prop.GetValue(o, null);  
  17.                   
  18.       //Value句 文字列は''で囲  
  19.       if (pv.GetType().Name == "String")  
  20.       {  
  21.          ValList = ValList + "'" + pv.ToString() + "',";  
  22.       }  
  23.       else  
  24.       {  
  25.          ValList = ValList + pv.ToString() + ",";  
  26.       }  
  27.    }  
  28.   
  29.    StringBuilder Sb = new StringBuilder();  
  30.    Sb.AppendLine("INSERT INTO " + t.Name + "(" + FldList.Remove(FldList.Length - 1) + ")");  
  31.    Sb.AppendLine("Values (" + ValList.Remove(ValList.Length - 1) + ")");  
  32.   
  33.    return (Sb.ToString());  
  34.   
  35. }  

こんな感じかな

2009年8月31日月曜日

クラスのインスタンスを動的に作成する。

Delphi2010と同じ動きをするDelphi Prismのソースです。

まずは、実行用のフォームの処理です。

  1. namespace WindowsApplication1;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   System.Drawing,  
  7.   System.Collections,  
  8.   System.Collections.Generic,  
  9.   System.Linq,  
  10.   System.Windows.Forms,  
  11.   System.ComponentModel,  
  12.   System.Reflection,  
  13.   SakaTestSpace;  
  14.   
  15. type  
  16.   /// <summary>  
  17.   /// Summary description for MainForm.  
  18.   /// </summary>  
  19.   MainForm = partial class(System.Windows.Forms.Form)  
  20.   private  
  21.     method button1_Click(sender: System.Object; e: System.EventArgs);  
  22.   protected  
  23.     method Dispose(disposing: Boolean); override;  
  24.   public  
  25.     constructor;  
  26.   end;  
  27.   
  28.   
  29.   
  30. implementation  
  31.   
  32.   
  33. {$REGION Construction and Disposition}  
  34. constructor MainForm;  
  35. begin  
  36.   //  
  37.   // Required for Windows Form Designer support  
  38.   //  
  39.   InitializeComponent();  
  40.   
  41.   //  
  42.   // TODO: Add any constructor code after InitializeComponent call  
  43.   //  
  44. end;  
  45.   
  46. method MainForm.Dispose(disposing: Boolean);  
  47. begin  
  48.   if disposing then begin  
  49.     if assigned(components) then  
  50.       components.Dispose();  
  51.   
  52.     //  
  53.     // TODO: Add custom disposition code here  
  54.     //  
  55.   end;  
  56.   inherited Dispose(disposing);  
  57. end;  
  58. {$ENDREGION}  
  59.   
  60. method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);  
  61. var  
  62.   SakaTestIntf : SakaTestSpace.ISakaTest;  
  63.   CreateClassName : String;  
  64.   t : System.Type;  
  65.   obj : System.Object;  
  66.   Assem  : System.Reflection.Assembly;  
  67.   
  68. begin  
  69.   
  70.   //使用するアセンブリをロードする  
  71.   Assem := System.Reflection.Assembly.Load('ClassLibrary1');  
  72.   
  73.   t := Assem.GetType('SakaTestSpace.' + textBox1.Text);  
  74.   
  75.   obj := Activator.CreateInstance(t);  
  76.   
  77.   if obj <> nil then  
  78.   begin  
  79.     SakaTestIntf := (obj As  SakaTestSpace.ISakaTest);  
  80.     if SakaTestIntf <> nil then  
  81.     begin  
  82.       label3.Text := SakaTestIntf.SayMessage();  
  83.     end;  
  84.   end;  
  85. end;  
  86.   
  87. end.  


次に検証に使ったクラスです。

  1. namespace SakaTestSpace;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   System.Collections.Generic,  
  7.   System.Linq,  
  8.   System.Text;  
  9.   
  10. type  
  11.   ISakaTest = public interface  
  12.     method SayMessage : String;  
  13.   end;  
  14.   
  15. type  
  16.   TSakaTest = public class(ISakaTest)  
  17.   private  
  18.   protected  
  19.   public  
  20.     method SayMessage : String ; virtual;  
  21.   end;  
  22.   
  23.   TSakaTest1 = public class(TSakaTest)  
  24.   private  
  25.   protected  
  26.   public  
  27.     method SayMessage : String; override;  
  28.   end;  
  29.   
  30.   TSakaTest2 = public class(TSakaTest)  
  31.   private  
  32.   protected  
  33.   public  
  34.     method SayMessage : String; override;  
  35.   end;  
  36.   
  37.    
  38. implementation  
  39.   
  40. method TSakaTest.SayMessage : String;  
  41. begin  
  42.   Result := "";  
  43. end;  
  44.   
  45. method TSakaTest1.SayMessage : String;  
  46. begin  
  47.   Result := 'Delphi Prism First Message';  
  48. end;  
  49.   
  50. method TSakaTest2.SayMessage : String;  
  51. begin  
  52.   Result := 'Delphi Prism Second Message';  
  53. end;  
  54.   
  55. end.  


PrismのほうがActivatorクラスが使える分、楽だ(短い処理で実現可能)と思う

2009年8月29日土曜日

Rttiを試して見るその2(プリズム版)

別ブログで書いたDelphi2010のメソッドコール
ソースと同等のソースをDelphi Prismで書いてみた。

  1. namespace WindowsApplication1;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   System.Drawing,  
  7.   System.Collections,  
  8.   System.Collections.Generic,  
  9.   System.Linq,  
  10.   System.Windows.Forms,  
  11.   System.ComponentModel,  
  12.   System.Reflection;  
  13.   
  14.   
  15. type  
  16.   /// <summary>  
  17.   /// Summary description for MainForm.  
  18.   /// </summary>  
  19.   MainForm = partial class(System.Windows.Forms.Form)  
  20.   private  
  21.     method button1_Click(sender: System.Object; e: System.EventArgs);  
  22.   protected  
  23.     method Dispose(disposing: Boolean); override;  
  24.   public  
  25.     constructor;  
  26.     method SakaSum(a, b : Integer) : Integer;  
  27.   end;  
  28.   
  29. implementation  
  30.   
  31. {$REGION Construction and Disposition}  
  32. constructor MainForm;  
  33. begin  
  34.   //  
  35.   // Required for Windows Form Designer support  
  36.   //  
  37.   InitializeComponent();  
  38.   
  39.   //  
  40.   // TODO: Add any constructor code after InitializeComponent call  
  41.   //  
  42. end;  
  43.   
  44. method MainForm.Dispose(disposing: Boolean);  
  45. begin  
  46.   if disposing then begin  
  47.     if assigned(components) then  
  48.       components.Dispose();  
  49.   
  50.     //  
  51.     // TODO: Add custom disposition code here  
  52.     //  
  53.   end;  
  54.   inherited Dispose(disposing);  
  55. end;  
  56. {$ENDREGION}  
  57.   
  58. method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);  
  59. var  
  60.   rtm : System.Reflection.MethodInfo;  
  61.   Args : Array of System.Object;  
  62.   Rst : System.Object;  
  63.   MyType : System.Type;  
  64. begin  
  65.   MyType := System.Type.GetType('WindowsApplication1.' + Self.Name);  
  66.     
  67.   rtm := MyType.GetMethod('SakaSum');  
  68.     
  69.   if rtm <> nil Then  
  70.   begin  
  71.   
  72.     Args := new System.Object[2];  
  73.     Args[0] := Convert.ToInt32(textBox1.Text);  
  74.     Args[1] := Convert.ToInt32(textBox2.Text);  
  75.     Rst := rtm.Invoke(Self,Args);  
  76.     label5.Text := Rst.ToString();  
  77.   
  78.   end;  
  79. end;  
  80.   
  81. method MainForm.SakaSum(a, b : Integer) : Integer;  
  82. begin  
  83.   Result := a + b;  
  84. end;  
  85.   
  86. end.