TTBase http://ttbase.sourceforge.jp/
逆P/Invoke http://www.artonx.org/diary/20081124.html#p01
これでC#でTTBaseのプラグイン作れるんじゃね?と思った。
TTBase.cs TTBaseで使用する構造体とか定数とか
using System;
using System.Runtime.InteropServices;
namespace TTBasePlugInTest {
//プラグインのロードタイプ
public enum LoadType {
ptAlwayLoad = 0,
ptLoadAtUse = 1,
ptSpecViolation = 0xFFFF
}
//メニューに関する定数
public enum Menu {
dmNone = 0,
dmSystemMenu = 1,
dmToolMenu = 2,
dmHotKeyMenu = 4,
dmMenuChecked = 8
}
public enum LogOut {
elNever = 0,
elError = 1,
elWarning = 2,
elInfo = 3,
elDebug = 4
}
[StructLayout(LayoutKind.Sequential,CharSet = CharSet.Ansi)]
public struct PLUGIN_COMMAND_INFO {
[MarshalAs(UnmanagedType.LPStr)]
public string Name;
[MarshalAs(UnmanagedType.LPStr)]
public string Caption;
public int CommandID;
public int Attr;
public int ResID;
public int DispMenu;
public uint TimerInterval;
public uint TimerCounter;
}
[StructLayout(LayoutKind.Sequential,CharSet= CharSet.Ansi)]
public struct PLUGIN_INFO {
public ushort NeedVersion;
[MarshalAs(UnmanagedType.LPStr)]
public string Name;
[MarshalAs(UnmanagedType.LPStr)]
public string FileName;
public ushort PluginType;
public uint VersionMS;
public uint VersionLS;
public uint CommandCount;
[MarshalAs(UnmanagedType.LPStruct)]
public IntPtr Commands;
//public PLUGIN_COMMAND_INFO Commands;
public uint LoadTime;
}
}
Class1.cs TTBaseに公開するメソッドを実装
using System;
using System.Runtime.InteropServices;
namespace TTBasePlugInTest {
public class Class1 {
public static IntPtr TTBEVent_InitPluginInfo(string PluginFilename) {
PLUGIN_INFO r = new PLUGIN_INFO();
r.FileName = PluginFilename;
r.NeedVersion = 0;
r.Name = "テスト";
r.PluginType = (int)LoadType.ptAlwayLoad;
r.CommandCount = 1;
PLUGIN_COMMAND_INFO pci = new PLUGIN_COMMAND_INFO();
pci.Name = "test";
pci.Caption = "てすてす、テストのテストです";
pci.CommandID = 0;
pci.DispMenu = (int)(Menu.dmToolMenu | Menu.dmHotKeyMenu);
IntPtr pciPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pci));
Marshal.StructureToPtr(pci, pciPtr, false);
r.Commands = pciPtr;
//r.Commands = pci;
IntPtr iPtr = Marshal.AllocHGlobal(Marshal.SizeOf(r));
Marshal.StructureToPtr(r, iPtr, false);
return iPtr;
}
public static void TTBEvent_FreePluginInfo(IntPtr PluginInfo) {
Marshal.FreeHGlobal(PluginInfo);
}
public static int TTBEvent_Init(string PluginFilename, int hPlugin) {
return 1;
}
public static void TTBEvent_Unload() {
}
static int i;
public static int TTBEvent_Execute(int CommandID, IntPtr hWnd) {
i++;
System.Windows.Forms.MessageBox.Show(i.ToString());
return 1;
}
public static void TTBEvent_WindowsHook(int Msg, int wParam, int lParam) {
}
}
}
上のコードをビルドしたら
D:\My Documents\Visual Studio 2008\Projects\TTBasePlugInTest\TTBasePlugInTest\bi
n\Release>ildasm /OUT=TTBasePlugInTest.il TTBasePlugInTest.dll
でILにする。
逆P/Invokeを参考にILを編集
D:\My Documents\Visual Studio 2008\Projects\TTBasePlugInTest\TTBasePlugInTest\bi
n\Release>c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ilasm.exe /DLL TTBasePlu
gInTest.il
Microsoft (R) .NET Framework IL Assembler. Version 2.0.50727.3053
Copyright (c) Microsoft Corporation. All rights reserved.
Assembling 'TTBasePlugInTest.il' to DLL --> 'TTBasePlugInTest.dll'
Source file is ANSI
Assembled method TTBasePlugInTest.Class1::TTBEVent_InitPluginInfo
Assembled method TTBasePlugInTest.Class1::TTBEvent_FreePluginInfo
Assembled method TTBasePlugInTest.Class1::TTBEvent_Init
Assembled method TTBasePlugInTest.Class1::TTBEvent_Unload
Assembled method TTBasePlugInTest.Class1::TTBEvent_Execute
Assembled method TTBasePlugInTest.Class1::TTBEvent_WindowsHook
Assembled method TTBasePlugInTest.Class1::.ctor
Creating PE file
Emitting classes:
Class 1: TTBasePlugInTest.Class1
Class 2: TTBasePlugInTest.PLUGIN_INFO
Class 3: TTBasePlugInTest.PLUGIN_COMMAND_INFO
Class 4: TTBasePlugInTest.LoadType
Class 5: TTBasePlugInTest.Menu
Class 6: TTBasePlugInTest.LogOut
Emitting fields and methods:
Global
Class 1 Fields: 1; Methods: 7;
Class 2 Fields: 9;
Class 3 Fields: 8;
Class 4 Fields: 4;
Class 5 Fields: 6;
Class 6 Fields: 6;
Resolving local member refs: 13 -> 13 defs, 0 refs, 0 unresolved
Emitting events and properties:
Global
Class 1
Class 2
Class 3
Class 4
Class 5
Class 6
Resolving local member refs: 0 -> 0 defs, 0 refs, 0 unresolved
Writing PE file
Operation completed successfully
とILからDLLを作成。メッセージの意味はよくわからないけど、多分成功してる。
これで出来たDLLをTTBaseのディレクトリにコピーしてTTBaseを起動するも…プラグインとして認識されない。
どこが上手く行ってないのかもわからない状態。
http://twitter.com/takeshik/statuses/2419234928
とか言われたけどC++/CLIとかキモいし。
http://twitter.com/takeshik/statuses/2419254967
とか突っ込まれたけどその通りだと思う。
C#でやることに意味があるのですよ。C#可愛いよ、C#可愛い。
でもC#で出来て無いから何の意味も無いという…。