[[戻る>DoldoWorkz#delphi]]

*DelphiでCharu3プラグインを作る [#b6d19f99]
DelphiでCharu3プラグインを作る際にハマった事や参照した場所等をメモしていきます。
#hr
#contents
#hr

*Charu3とは? [#se519ac2]
ケイジさんが作成した、クリップボード拡張+入力支援ソフトです。~
[[■KeiziWeb ver 4.3>http://keijiweb.com/software.html]]~
※2010/2/4あたりに移転した様です~
[[■Keijiweb ver β - どうしてkeijiweb.comになったのか?>http://keijiweb.com/dView.pl?m=1&user=keizi&thid=20100207032344&tid=20100207050103]]~

*ソフト公開 [#x9c3e32b]
**DelphiでCharu3プラグインを作るサンプルソース&DLL [#d4e7533a]
DelphiでCharu3のプラグインを作る方法が書かれているソースが入っています。~
&color(red){''2008/3/2修正 Unicodeに完全対応''};(今まではShift-JISで処理していたのをUnicodeに完全対応)~
~
ダウンロード
#ref(CharuPlugInTest.LZH)
-サンプルソースの著作権~
[[&ref(http://i.creativecommons.org/l/by/2.1/jp/80x15.png);>http://creativecommons.org/licenses/by/2.1/jp/]]
この作品は[[クリエイティブ・コモンズ・ライセンス>http://creativecommons.org/licenses/by/2.1/jp/]]の下でライセンスされています。~
-TntWare Delphi Unicode Controls の著作権~
Copyright (c) 2002-2007, Troy Wolbrink (www.tntware.com) 

**DelphiTControlToName [#ic824452]
 DelphiのIDE(統合開発環境)で、TControlから派生したクラス(見えているコンポーネント全てです)をコピーして、このプラグインを通すと、コピーしたクラスのNameプロパティのリストが改行区切りで返されます。~

ダウンロード
#ref(DelphiTControlToName100.LZH)
[[&ref(http://i.creativecommons.org/l/by/2.1/jp/80x15.png);>http://creativecommons.org/licenses/by/2.1/jp/]]
この作品は[[クリエイティブ・コモンズ・ライセンス>http://creativecommons.org/licenses/by/2.1/jp/]]の下でライセンスされています。

**LoadHtmlHelp [#s8731a16]
 設定されたHtmlHelpファイルを開いて指定したキーワードで検索します。~
 コマンドライン版もありますので、他の環境でも使えると思います。~
 プログラミング言語のリファーレンスマニュアルがHtmlHelpファイルだった場合、エディタ上で文字列を選択してヘルプを引くような使い方を想定しています。~

ダウンロード~
#ref(LoadHtmlHelp.ZIP)
[[&ref(http://i.creativecommons.org/l/by/2.1/jp/80x15.png);>http://creativecommons.org/licenses/by/2.1/jp/]]
この作品は[[クリエイティブ・コモンズ・ライセンス>http://creativecommons.org/licenses/by/2.1/jp/]]の下でライセンスされています。

*はまり雑記 [#pcd7570c]
**参考にしたページ [#ge61672d]
-[[KeiziWeb ver 4.3 Charu3>http://keiziweb.com/software.html]]~
クリップボード拡張+入力支援ソフト「Charu3」のダウンロードページです。~
ここに一緒にある「プラグイン開発キット」の内容を元しています。~

-[[Delphiメーリングリスト>http://www.users.gr.jp/content/delphiml.aspx]]~
Delphiのメーリングリストです。~
今回プラグインを作るに当たって、はまっていた内容をこのメーリングリストで教えていただきました。~

-[[About Delphi>http://www2.big.or.jp/~osamu/Delphi/]]~
Delphiのメーリングリストの過去ログが置いてあります。~

**DelphiでCharu3プラグインを作るサンプルソース [#c31fbdb3]
*S-JIS版 [#b32a2c2d]
 library CharuPlugInTest;
 
 { DLL でのメモリ管理について:
   もしこの DLL が引数や返り値として String 型を使う関数/手続きをエクスポー
   トする場合、以下の USES 節とこの DLL を使うプロジェクトソースの USES 節
   の両方に、最初に現れるユニットとして ShareMem を指定しなければなりません。
   (プロジェクトソースはメニューから[プロジェクト|ソース表示] を選ぶこと
   で表示されます)
   これは構造体やクラスに埋め込まれている場合も含め String 型を DLL とやり
   取りする場合に必ず必要となります。
   ShareMem は共用メモリマネージャである BORLNDMM.DLL とのインターフェース
   です。あなたの DLL と一緒に配布する必要があります。BORLNDMM.DLL を使うの
   を避けるには、PChar または ShortString 型を使って文字列のやり取りをおこ
   なってください。}
 
 uses
   SysUtils,
   Classes,
   Windows,
   System,
   Messages;
 
 {$R *.res}
 
 (*
 // Charu3DLL_SRC\Plugins\addBR\replace.cppのソース引用
 // Cの場合の構造体
 //---------------------------------------------------
 // データ構造体
 //---------------------------------------------------
 struct STRING_DATA
 {
 	char	m_cKind;		//データ種別
 	char	m_cIcon;		//アイコン種別
 	int		m_nMyID;		//データのID
 	int		m_nParentID;	//親データのID
 	time_t	m_timeCreate;	//作成日時
 	time_t	m_timeEdit;		//変更日時
 	CString  m_strTitle;	//設定データタイトル
 	CString  m_strData;		//設定データ文字列
 	CString  m_strMacro;	//拡張用文字列データ
 };
 *)
 
 // Delphiの場合の構造体
 // ---------------------------------------------------
 type
   TSTRING_DATA = record
     m_cKind: Char;         // データ種別         (Charu3:種類)
                            //   1:一時データ 2:ロック
     m_cIcon: Char;         // アイコン種別       (Charu3:アイコン)
                            //   0:普通ロック項目 1:日時 時間系 2:ファイル実行
                            //   3:関連付け実行 4:文字列選択 5:クリップボード
                            //   6:プラグイン 7:キー入力 255:自動選択
     m_nMyID: Integer;      // データのID         (何を示したIDなのか不明)
     m_nParentID: Integer;  // 親データのID       (何を示したIDなのか不明)
     m_timeCreate: LongInt; // 作成日時
                            //   (暦時間(カレンダー時間)形式の作成日時)
     m_timeEdit: LongInt;   // 変更日時
                            //   (暦時間(カレンダー時間)形式の変更日時)
     m_strTitle: Pointer;   // 設定データタイトル (Charu3:名前)
     m_strData: Pointer;    // 設定データ文字列   (Charu3:テキスト編集のテキスト)
     m_strMacro: Pointer;   // 拡張用文字列データ (Charu3:拡張マクロ)
   end;
   PSTRING_DATA = ^TSTRING_DATA;
 // ---------------------------------------------------
 
 
 // [Delphi-ML:20584] Re: time_t -> TDateTime ?
 // を参考にしたtime_t -> TDateTimeの関数。
 // ---------------------------------------------------
 const
   cStart    = 25569.0;  // = EncodeDate( 1970, 1, 1 )
   cSecPerDay = 86400.0;  // 1日あたりの秒数
   cAdjust    = 9 / 24;  // 時間帯の調整
 
 function time_tToDateTime(t: LongInt): TDateTime;
 begin
   Result := (cStart * cSecPerDay + t) / cSecPerDay + cAdjust;
 end;
 
 function DateTimeTotime_t(d: TDateTime): LongInt;
 begin
   Result := Round((d - cStart - cAdjust) * cSecPerDay);
 end;
 // ---------------------------------------------------
 
 (*
 // Cの場合の関数宣言
 // Charu3DLL_SRC\Plugins\addBR\replace.cppのソース引用
 extern "C" __declspec (dllexport) bool CharuPlugIn
 	(TCHAR *strSource,TCHAR *strResult,int nSize,STRING_DATA *data,void *pVoid)
 *)
 
 (*
 // Charu3DLL_SRC\readme.htmlのマニュアル引用
 ■テキスト処理プラグイン
  簡単な関数を一つ実装すればテキスト処理プラグインを作ることが出来ます。
  TCHARはMBCSの時はcharになり、Unicodeの場合はwchar_tになります。
 
 bool CharuPlugIn(TCHAR *strSource,TCHAR *strResult,int nSize,STRING_DATA *data,void *pVoid);
 □TCHAR *strSource 
  処理の元になるテキストデータが入ってきます。$SELなどのマクロは置換されたあとです。
 
 □TCHAR *strResult
  結果のテキストを格納します。 
 
 □int nSize
  結果のテキストを格納するバッファのサイズです。最低で10kbあります。
  大きなテキストを扱う場合は、このバッファのサイズも大きく確保されます。
 
 □STRING_DATA *data
  選択していたデータの元です。
  拡張マクロやID、作成時間や変更時間などのデータも取れます。$SELなどのマクロも置換前の状態です。拡張マクロにオリジナルの機能を持たせたりすることも出来ます。
 
 □void *pVoid
  拡張用ポインタでしたが、現在は貼り付けのターゲットになるウィンドウのハンドルが
 入ってきます。使う場合はキャストして使ってください。
  将来変更される可能性もなきにしもあらずですけど。
 *)
 
 
 // [Delphi:89848] Re: VC++で作られたソフトのプラグインDLLの作成
 // を参考にして、関数の呼び出し規約をcdeclにしています
 
 // Delphiの場合、TCHARはMBCSの時はPCharになり、Unicodeの場合はPWideCharになる?
 
 // Charu3 S-JIS版
 function CharuPlugIn(
   strSource: PChar; strResult: PChar; nSize: integer;
   data: PSTRING_DATA; pVoid: Pointer): BOOL; cdecl;
 var
   WkStrSource: string;
   WkStrResult: string;
 
   Wkm_strTitle: string;
   Wkm_strData: string;
   WKm_strMacro: string;
 
   Wkm_cKind: Char;
   Wkm_cIcon: Char;
 
   Wkm_nMyID: Integer;
   Wkm_nParentID: Integer;
 
   Wkm_timeCreate2: TDateTime;
   Wkm_timeEdit2: TDateTime;
 
   WkpVoid: HWND;
 begin
   try
     // String型にコピーする
     WkStrSource := strSource;
 
     // data.m_cKindの保持
     Wkm_cKind := data.m_cKind;
     // data.m_cIconの保持
     Wkm_cIcon := data.m_cIcon;
 
     // data.m_nMyIDの保持
     Wkm_nMyID := data.m_nMyID;
     // data.m_nParentIDの保持
     Wkm_nParentID := data.m_nParentID;
 
     // data.m_timeCreateはCのtime_t型なのでTDateTime型に変換&コピー
     Wkm_timeCreate2 := time_tToDateTime(data.m_timeCreate);
     // data.m_timeEditはCのtime_t型なのでTDateTime型に変換&コピー
     Wkm_timeEdit2 := time_tToDateTime(data.m_timeEdit);
 
     // String型にコピーする
     Wkm_strTitle := PChar(data.m_strTitle);
     // String型にコピーする
     Wkm_strData := PChar(data.m_strData);
     // String型にコピーする
     Wkm_strMacro := PChar(data.m_strMacro);
 
     // pVoidをHWND型に変換する
     WkpVoid := HWND(pVoid^);
 
     //---------------ここからコードを書くといいです---------------------
 
     // strSourceがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('strSource [' + WkStrSource + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // data.m_cKindがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_cKind [' + IntToStr(Integer(Wkm_cKind)) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // data.m_cIconがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_cIcon [' + IntToStr(Integer(Wkm_cIcon)) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // data.m_nMyIDがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_nMyID [' + IntToStr(Wkm_nMyID) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // data.m_nParentIDがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_nParentID [' + IntToStr(Wkm_nParentID) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // TDateTime型に変換されたdata.m_timeCreateがきちんと受け取れているかのテストコード
     MessageBox(0, PChar(
       'data.m_timeCreate(TDateTime) [' + DateTimeToStr(Wkm_timeCreate2) + ']'),
       '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // TDateTime型に変換されたdata.m_timeEditがきちんと受け取れているかのテストコード
     MessageBox(0, PChar(
       'data.m_timeEdit(TDateTime) [' + DateTimeToStr(Wkm_timeEdit2) + ']'),
       '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // data.m_strTitleがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_strTitle [' + Wkm_strTitle + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // data.m_strDataがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_strData [' + Wkm_strData + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // data.m_strMacroがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_strMacro [' + Wkm_strMacro + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // pVoidがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('pVoid [' + IntToStr(WkpVoid) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // 受け取ったstrSourceの文字列を'<'で囲う加工をするテストコード
     WkStrResult := '<' +  WkStrSource + '>';
 
     // 加工後のWkStrResultを表示するテストコード
     MessageBox(0, PChar('strSource [' + WkStrResult + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     //---------------ここまでコードを書くといいです---------------------
 
     // 値は直接strResultに入れる
     StrLCopy(strResult, PChar(WkStrResult), nSize);
 
     result := True;
   except
     result := False;
     Exit;
   end;
 end;
 
 exports
   CharuPlugIn;
 
 end.

**Unicode版 [#ud3e427d]
 library CharuPlugInTestu;
 
 { DLL でのメモリ管理について:
   もしこの DLL が引数や返り値として String 型を使う関数/手続きをエクスポー
   トする場合、以下の USES 節とこの DLL を使うプロジェクトソースの USES 節
   の両方に、最初に現れるユニットとして ShareMem を指定しなければなりません。
   (プロジェクトソースはメニューから[プロジェクト|ソース表示] を選ぶこと
   で表示されます)
   これは構造体やクラスに埋め込まれている場合も含め String 型を DLL とやり
   取りする場合に必ず必要となります。
   ShareMem は共用メモリマネージャである BORLNDMM.DLL とのインターフェース
   です。あなたの DLL と一緒に配布する必要があります。BORLNDMM.DLL を使うの
   を避けるには、PChar または ShortString 型を使って文字列のやり取りをおこ
   なってください。}
 
 uses
   SysUtils,
   Classes,
   Windows,
   System,
   Messages,
   {以下 TntWare Delphi Unicode Controls フリー版ライブラリを使用}
   TntSystem,
   TntSysUtils,
   TntDialogs,
   TntWideStrUtils;
 
 {$R *.res}
 
 (*
 // Charu3DLL_SRC\Plugins\addBR\replace.cppのソース引用
 // Cの場合の構造体
 //---------------------------------------------------
 // データ構造体
 //---------------------------------------------------
 struct STRING_DATA
 {
 	char	m_cKind;		//データ種別
 	char	m_cIcon;		//アイコン種別
 	int		m_nMyID;		//データのID
 	int		m_nParentID;	//親データのID
 	time_t	m_timeCreate;	//作成日時
 	time_t	m_timeEdit;		//変更日時
 	CString  m_strTitle;	//設定データタイトル
 	CString  m_strData;		//設定データ文字列
 	CString  m_strMacro;	//拡張用文字列データ
 };
 *)
 
 // Delphiの場合の構造体
 // ---------------------------------------------------
 type
   TSTRING_DATA = record
     m_cKind: Char;         // データ種別         (Charu3:種類)
                            //   1:一時データ 2:ロック
     m_cIcon: Char;         // アイコン種別       (Charu3:アイコン)
                            //   0:普通ロック項目 1:日時 時間系 2:ファイル実行
                            //   3:関連付け実行 4:文字列選択 5:クリップボード
                            //   6:プラグイン 7:キー入力 255:自動選択
     m_nMyID: Integer;      // データのID         (何を示したIDなのか不明)
     m_nParentID: Integer;  // 親データのID       (何を示したIDなのか不明)
     m_timeCreate: LongInt; // 作成日時
                            //   (暦時間(カレンダー時間)形式の作成日時)
     m_timeEdit: LongInt;   // 変更日時
                            //   (暦時間(カレンダー時間)形式の変更日時)
     m_strTitle: Pointer;   // 設定データタイトル (Charu3:名前)
     m_strData: Pointer;    // 設定データ文字列   (Charu3:テキスト編集のテキスト)
     m_strMacro: Pointer;   // 拡張用文字列データ (Charu3:拡張マクロ)
   end;
   PSTRING_DATA = ^TSTRING_DATA;
 // ---------------------------------------------------
 
 
 // [Delphi-ML:20584] Re: time_t -> TDateTime ?
 // を参考にしたtime_t -> TDateTimeの関数。
 // ---------------------------------------------------
 const
   cStart    = 25569.0;  // = EncodeDate( 1970, 1, 1 )
   cSecPerDay = 86400.0;  // 1日あたりの秒数
   cAdjust    = 9 / 24;  // 時間帯の調整
 
 function time_tToDateTime(t: LongInt): TDateTime;
 begin
   Result := (cStart * cSecPerDay + t) / cSecPerDay + cAdjust;
 end;
 
 function DateTimeTotime_t(d: TDateTime): LongInt;
 begin
   Result := Round((d - cStart - cAdjust) * cSecPerDay);
 end;
 // ---------------------------------------------------
 
 (*
 // Cの場合の関数宣言
 // Charu3DLL_SRC\Plugins\addBR\replace.cppのソース引用
 extern "C" __declspec (dllexport) bool CharuPlugIn
 	(TCHAR *strSource,TCHAR *strResult,int nSize,STRING_DATA *data,void *pVoid)
 *)
 
 (*
 // Charu3DLL_SRC\readme.htmlのマニュアル引用
 ■テキスト処理プラグイン
  簡単な関数を一つ実装すればテキスト処理プラグインを作ることが出来ます。
  TCHARはMBCSの時はcharになり、Unicodeの場合はwchar_tになります。
 
 bool CharuPlugIn(TCHAR *strSource,TCHAR *strResult,int nSize,STRING_DATA *data,void *pVoid);
 □TCHAR *strSource 
  処理の元になるテキストデータが入ってきます。$SELなどのマクロは置換されたあとです。
 
 □TCHAR *strResult
  結果のテキストを格納します。 
 
 □int nSize
  結果のテキストを格納するバッファのサイズです。最低で10kbあります。
  大きなテキストを扱う場合は、このバッファのサイズも大きく確保されます。
 
 □STRING_DATA *data
  選択していたデータの元です。
  拡張マクロやID、作成時間や変更時間などのデータも取れます。$SELなどのマクロも置換前の状態です。拡張マクロにオリジナルの機能を持たせたりすることも出来ます。
 
 □void *pVoid
  拡張用ポインタでしたが、現在は貼り付けのターゲットになるウィンドウのハンドルが
 入ってきます。使う場合はキャストして使ってください。
  将来変更される可能性もなきにしもあらずですけど。
 *)
 
 
 // [Delphi:89848] Re: VC++で作られたソフトのプラグインDLLの作成
 // を参考にして、関数の呼び出し規約をcdeclにしています
 
 // Delphiの場合、TCHARはMBCSの時はPCharになり、Unicodeの場合はPWideCharになる?
 
 // Charu3 Unicode版
 function CharuPlugIn(
   strSource: PWideChar; strResult: PWideChar; nSize: integer;
   data: PSTRING_DATA; pVoid: Pointer): BOOL; cdecl;
 var
   WkStrSource: WideString;
   WkStrResult: WideString;
 
   Wkm_strTitle: WideString;
   Wkm_strData: WideString;
   WKm_strMacro: WideString;
 
   Wkm_cKind: Char;
   Wkm_cIcon: Char;
 
   Wkm_nMyID: Integer;
   Wkm_nParentID: Integer;
 
   Wkm_timeCreate2: TDateTime;
   Wkm_timeEdit2: TDateTime;
 
   WkpVoid: HWND;
 begin
   try
     // strSourceはUNICODEなのでWideString型にコピーする
     WkStrSource := strSource;
 
     // data.m_cKindの保持
     Wkm_cKind := data.m_cKind;
     // data.m_cIconの保持
     Wkm_cIcon := data.m_cIcon;
 
     // data.m_nMyIDの保持
     Wkm_nMyID := data.m_nMyID;
     // data.m_nParentIDの保持
     Wkm_nParentID := data.m_nParentID;
 
     // data.m_timeCreateはCのtime_t型なのでTDateTime型に変換&コピー
     Wkm_timeCreate2 := time_tToDateTime(data.m_timeCreate);
     // data.m_timeEditはCのtime_t型なのでTDateTime型に変換&コピー
     Wkm_timeEdit2 := time_tToDateTime(data.m_timeEdit);
 
     // data.m_strTitleはUNICODEなのでWideString型にコピーする
     Wkm_strTitle := PWideChar(data.m_strTitle);
     // data.m_strDataはUNICODEなのでWideString型にコピーする
     Wkm_strData := PWideChar(data.m_strData);
     // data.m_strMacroはUNICODEなのでWideString型にコピーする
     Wkm_strMacro := PWideChar(data.m_strMacro);
 
     // pVoidをHWND型に変換する
     WkpVoid := HWND(pVoid^);
 
     //---------------ここからコードを書くといいです---------------------
 
     // strSourceがきちんと受け取れているかのテストコード
     // UNICODEなのでMessageBoxW使用
     MessageBoxW(0, PWideChar('strSource [' + WkStrSource + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // data.m_cKindがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_cKind [' + IntToStr(Integer(Wkm_cKind)) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // data.m_cIconがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_cIcon [' + IntToStr(Integer(Wkm_cIcon)) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // data.m_nMyIDがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_nMyID [' + IntToStr(Wkm_nMyID) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // data.m_nParentIDがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('data.m_nParentID [' + IntToStr(Wkm_nParentID) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // TDateTime型に変換されたdata.m_timeCreateがきちんと受け取れているかのテストコード
     MessageBox(0, PChar(
       'data.m_timeCreate(TDateTime) [' + DateTimeToStr(Wkm_timeCreate2) + ']'),
       '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // TDateTime型に変換されたdata.m_timeEditがきちんと受け取れているかのテストコード
     MessageBox(0, PChar(
       'data.m_timeEdit(TDateTime) [' + DateTimeToStr(Wkm_timeEdit2) + ']'),
       '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // data.m_strTitleがきちんと受け取れているかのテストコード
     // UNICODEなのでMessageBoxW使用
     MessageBoxW(0, PWideChar('data.m_strTitle [' + Wkm_strTitle + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // data.m_strDataがきちんと受け取れているかのテストコード
     // UNICODEなのでMessageBoxW使用
     MessageBoxW(0, PWideChar('data.m_strData [' + Wkm_strData + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
     // data.m_strMacroがきちんと受け取れているかのテストコード
     // UNICODEなのでMessageBoxW使用
     MessageBoxW(0, PWideChar('data.m_strMacro [' + Wkm_strMacro + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // pVoidがきちんと受け取れているかのテストコード
     MessageBox(0, PChar('pVoid [' + IntToStr(WkpVoid) + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     // 受け取ったstrSourceの文字列を'<'で囲う加工をするテストコード
     WkStrResult := '<' +  WkStrSource + '>';
 
     // 加工後のWkStrResultを表示するテストコード
     // UNICODEなのでMessageBoxW使用
     MessageBoxW(0, PWideChar('strSource [' + WkStrResult + ']'), '情報',
       MB_OK or MB_ICONINFORMATION or MB_TASKMODAL);
 
     //---------------ここまでコードを書くといいです---------------------
 
     // 値は直接strResultに入れる
     WStrLCopy(strResult, PWideChar(WkStrResult), nSize);
 
     result := True;
   except
     result := False;
     Exit;
   end;
 end;
 
 exports
   CharuPlugIn;
 
 end.