//dmd2.064.2
import win32.windows; //Binding for the WindowsApi
import core.runtime;
import std.string; //toStringz
extern(Windows)
int WinMain(HINSTANCE instance, HINSTANCE prevInstance,
LPSTR cmdArgs, int cmdShow)
{
int result;
try
{
Runtime.initialize();
result = myMain(instance, cmdShow);
Runtime.terminate();
}
catch(Throwable e)
{
MessageBoxA(NULL, e.toString.toStringz, "error", MB_OK | MB_ICONEXCLAMATION);
result = 0;
}
return result;
}
alias LPCTSTR winstr;
int myMain(HINSTANCE instance, int cmdShow)
{
auto cmdArgs = GetCommandLine(); //コマンドライン引数 WinMainからだとユニコード対応されてないため
winstr s = "あ";
MessageBox(NULL, s, s, MB_OK); //*1
MessageBox(NULL, "い", "い", MB_OK); //*2
/+ *3
string s2 = "あいうえお";
winstr ws = s2; //エラー
+/
return 0;
}
D公式そのままだと非推奨の警告が出るので少し改良。
それと自分に分かりやすいようにちょっと改造してあります。
まず、警告に対応。
メッセージは Deprecation: function core.runtime.Runtime.initialize is deprecated - Please use the overload of Runtime.initialize that takes no argument.
とこれのinitializeがterminateになったものの2つ。
"dmd.exeの場所"../../src/druntime/src/core/runtime.dを見てinitializeと検索してみるとRuntime構造体のなかに
static bool initialize()
{
return !!rt_init();
}
deprecated("Please use the overload of Runtime.initialize that takes no argument.")
static bool initialize(ExceptionHandler dg = null)
{
return !!rt_init();
}
とこれのterminate版を見つけました。
ということでWinMainの中身をRuntime.initialize();Runtime.terminate();に変更しました。
次に文字列。
"sample"となっている文字列は代入とか引数として渡すときに自動でうまいこと変換してくれるみたいです。(*1,*2)
注意点としてPTSTR(LPTSTR、char* or wchar*)には変換してくれません。たぶんimmutableからconstには暗黙的変換されるけどimmutableから普通の型には暗黙的変換してくれないのでその関係だと思います。
ということでPCTSTR(LPCTSTR、 const(char)* or const(wchar)*)をwinstrと名付けてます。
stringやwstringをPTSTRに変換しようとしていた苦労はいったい・・・
stringとかに代入されて型が確定されたものは自動で変換してくれない(*3)ので、そういうことがしたいときは、Aが最後に付いたメソッドを使ってstd.stringのtoStringzを使うと楽です。
Wが付いたほうを使いたいときは自分で変換するしかないと思います。
std.utfにtoUTF16zがありました。
Binding for the WindowsApiはAやWが省略されたときのAとWの自動判別に対応しています。
コンパイルのときに何もしないとA、-version=Unicodeとコンパイラに引数を渡すとWの方を使ってくれます。
またPTSTR、PCTSTRなどtchar関係の自動判別もしてくれます。