Linearstar

コードから MMD に任意のファイルを読み込ませる

Knowledge

MMD に、MMD が対応しているモデル、アクセサリ、モーション、ポーズ、プロジェクトなどを自動的に読ませたいときがあります。ありません。
例えばモーションを自動生成する何かを作ったとして、vmd に書き出さずに直接 MMD に張り付けられると便利だと思いませんか。

自動的にドロップ

まずは既に存在する任意のファイルを読み込ませる方法について。
プロセスの遠隔操作は面倒なものですが、幸い MMD はドラッグアンドドロップでファイルを読み込ませることができるので、
ファイルを自動的にドラッグアンドドロップさせるようにすれば良いわけです。
どうやるかというと、WM_DROPFILES というウィンドウメッセージを使用します。

前提としてターゲットアプリケーション (今回は MMD) のトップレベルウィンドウのハンドルを得ているものとします。

投げるファイルの一覧を用意する

あらかじめ投げたいファイルのフルパスを得ます。一つでも複数でも。
ANSI でも Unicode 表現でも良いのですが、今回は Unicode にします。ヌル文字で終端している必要があります。
そのパス達を連結して、最後にさらにヌル文字を追加したものを用意します。

例えば、

C:\...\foo.pmd
C:\...\bar.vmd
C:\...\battledome.pmx

の三つのパスを渡したい場合、

C:\...\foo.pmd(ヌル文字)C:\...\bar.vmd(ヌル文字)C:\...\battledome.pmx(ヌル文字)(ヌル文字)

のようになります。これのバイト表現をファイル一覧と称することにしましょう。
ところで、ワイド文字って 16 ビットだからヌル文字のバイト表現も 00 00 なんですね。

投げる構造体を作成する

ファイル一覧を得たら、次はそのバイト数 + 20 だけ GlobalAlloc しましょう。
なぜ 20 か。20 というよりは正確に言うと DROPFILES の長さなので sizeof(DROPFILES) です。
確保したら GlobalLock なりなんなりしてその HGLOBALDROPFILES として扱います。

そして構造体の値をセットしていきます。
pFiles には sizeof(DROPFILES) の値、
pt にはドロップ先座標の POINT
fNC には非クライアント領域であるかどうか、
fWide には 0 以外をセットします。

pt および fNC はターゲットアプリケーションによって都合が良い値をセットしてください。大抵は (0, 0) などの適当な値で良い気がしますが。

構造体を埋めてもまだ 20 バイト以降空きがありますから、そこにファイル一覧を書き込みます。
書き込み終わったら GlobalUnlock でもしましょう。

投げる

投げるための構造体を用意したら、この構造体の HGLOBALwParam として、相手ウィンドウハンドルに PostMessage します。
SendMessage ではなく PostMessage である必要があります。
すると自動的にドロップが実行されると思います!

使い終わった HGLOBALGlobalFree しておきましょう。たまにエラー出たりするので本当に必要なのかは知りません。

C# によるサンプル

参考にしたページ

この記事は次のページを参考に書かれました:
エクスプローラからのコピーについて