This page is written by Japanease and encoded UTF-8.
I'm trying to make full "windows.h" D version to replace windows.d in Phobos.
D付属のPhobosに含まれるwindows.dは、結構丁寧で、人の手で書いたとしか思えないのですが、それでは数多のWin32 APIを網羅することなど望めません。 D用のWin32 APIヘッダーは他にも幾つかあるのですが、文字コードやIME関係が抜けてたり、W版APIが含まれていなかったりと抜けが多いため…その抜けが、使わないようなのなら別に構わないのですが、僕は使うので…自分で変換を試みてみました。
単純に好みで#deinfe UNICODE
状態で作ってます。
ニュースグループを機にANSIバージョンも一応試みてますが…いいじゃん、9xなんて存在しないOSで。(ごめんなさいごめんなさいごめんなさい)
I welcome the feed back.
フィードバック歓迎。
windows.h for D (2004-07-09) *1
COM for D (2004-01-30)
converter script (2004-07-09)
Perlで変換したのをそのまま使えるのが理想。
そのため#define
の定数化、関数化なんかも全部win32sdk2d.pl中に含めています。
定数やヘッダ内で定義する関数などの外部リンケージは可能な限りデフォルトのextern(D)
にする…さもないとPhobosのwindows.dの同名のものがextern(Windows)
で宣言されているのでリンクエラーに。
どうでもいいといえばどうでもいいけど、整数定数はconstよりも無名のenumで宣言した方が.objに埋めこまれない分お得感があります。
COM関係は、実はIDLから変換した方が賢いんじゃないかと思いつつも、シンタックスをC++とあわせるために.hから手書き変換。 コンパイル通すのに必要な分だけ…。
interfaceはDではポインタになるため、インターフェースを引数に取る関数は、IUnknown*
→LPUNKNOWN
といった感じで置き換えてあります。
header | state | W | A | remark |
---|---|---|---|---|
windows.h | ok | O | O | |
winnt.h | ok | O | O | |
guiddef | working | O | O | handwriting |
windef.h | ok | O | O | including basetsd.h |
winbase.h | ok | O | O | |
winerror.h | ok | O | O | |
wingdi.h | ok | O | O | |
winuser.h | ok | O | O | |
winnls.h | ok | O | O | |
wincon.h | ok | O | O | |
winver.h | ok | O | O | |
winreg.h | ok | O | O | including reason.h |
dde.h | ok | O | O | |
ddeml.h | ok | O | O | |
dlgs.h | ok | O | O | |
mmsystem.h | ok | O | O | |
shellapi.h | ok | O | O | |
winspool.h | ok | O | O | |
commdlg.h | ok | O | O | including cderr.h |
imm.h | ok | O | O | |
commctrl.h | ok | O | O | including prsht.h |
winsock.h | never | O | X | not imported by windows.d |
winsock2.h | never | X | X | |
ole2.h | never | X | X | not imported by windows.d |
lzexpand.h | never | X | X | not imported by windows.d |
nb30.h | never | X | X | not imported by windows.d |
rpc.h | never | X | X | not imported by windows.d |
winnetwk.h | never | X | X | not imported by windows.d |
winperf.h | never | X | X | not imported by windows.d |
stralign.h | never | X | X | not imported by windows.d |
tvout.h | never | X | X | not imported by winuser.d |
basetsd.h | - | included windef.d | ||
reason.h | - | included winreg.d | ||
cderr.h | - | included commdlg.d | ||
prsht.h | - | included commctrl.d | ||
pshpack1.h | - | replaced by align(1): | ||
pshpack2.h | - | replaced by align(2): | ||
pshpack4.h | - | replaced by align(4): | ||
pshpack8.h | - | replaced by align(8): | ||
poppack.h | - | replaced by align: |
winsock.hはwindows.hから#includeされているのに、winsock2.hがされていないので、両方とも外しました。
header | state | W | A | remark |
---|---|---|---|---|
cguid.h | working | O | X | handwriting |
objbase.h | ok | O | X | |
objidl.h | working | O | X | handwriting |
propidl.h | working | O | X | handwriting |
unknwn.h | working | O | X | handwriting |
urlmon.h | working | O | X | handwriting |
wtypes.h | working | O | X | handwriting |
Compile all *.d files and create library. Use lib.exe of Digital Mars C++, NOT lib.exe of Microsoft.
const => enum 化によって、最終的な.libがかなり小さくなりましたので、一緒にアーカイブしてますが、自前でビルドしたい場合は、各ファイルをコンパイルしたら、こんな感じでまとめます。 libはDigital Mars C++付属のもの(OMF用)を使ってください。 試してないけどBorlandのでも可能なはず。 MSの(COFF用)を使わないように注意。
lib win32.lib +guiddef.obj +winbase.obj ... +winuser.obj, win32.lst,
Create a sub directory named "win32", and copy *.d to there.
sc.iniでDFLAGSに-Iとして渡しているディレクトリのどれかに、win32というサブディレクトリを作り、ソースをそこへ放り込めば使えるようになるはずです。 リンク時にwin32.libを渡してください。
Digital Mars C++ doesn't have several import libraries. If you need them, please ready yourself with implib or coff2omf.
DMC++にはSDKにはあるはずの幾つかのインポートライブラリが用意されていません。 implibで普通に.dllから生成した場合、名前の後ろの「@数字」が付いてくれません。 この数字は引数のサイズなので.dllから知る方法が無いのです。 方法としては、.defファイルを書いてimplibに渡せばOKです。
LIBRARY "shell32.dll" EXPORTS _ShellExecuteA@24 @369 ; ShellExecuteA
こんな方法もありますが、最近のMSのlib.exe(実際に処理するのはlink.exe)は、/CONVERTオプションを打ち切ってやがります。 旧バージョンのlink.exeを持っていたら、大切にしましょう。 DirectX9からBorlandの.libが付いて来なくなったり、最近のMicrosoftは他社の開発環境を締め出そうとしているのですか?
private import std.utf; version(ANSI){ private import win32.ansi.windows; char[] toT(char[] t){ wchar[] s = toUTF16(t); char[] result; result.length = WideCharToMultiByte(0, 0, s, s.length, null, 0, null, null); WideCharToMultiByte(0, 0, s, s.length, result, result.length, null, null); return t; } }else{ private import win32.windows; alias toUTF16 toT; } const int IDC_BTNCLICK = 101; const int IDC_BTNDONTCLICK = 102; extern(Windows) LRESULT WindowProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg){ case WM_COMMAND: switch (LOWORD(wParam)){ case IDC_BTNCLICK: if(HIWORD(wParam) == BN_CLICKED) MessageBox(hWnd, "Hello, world!", "Greeting", MB_OK | MB_ICONINFORMATION); break; case IDC_BTNDONTCLICK: if(HIWORD(wParam) == BN_CLICKED){ MessageBox(hWnd, "You've been warned...", "Prepare to GP fault", MB_OK | MB_ICONEXCLAMATION); *(cast(int*) null) = 666; } break; } break; case WM_PAINT: { static TCHAR[] text = "D Does Windows"; PAINTSTRUCT ps; HDC dc = BeginPaint(hWnd, &ps); RECT r; GetClientRect(hWnd, &r); HFONT font = CreateFont(80, 0, 0, 0, FW_EXTRABOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); HGDIOBJ old = SelectObject(dc, cast(HGDIOBJ)font); SetTextAlign(dc, TA_CENTER | TA_BASELINE); TextOut(dc, r.right / 2, r.bottom / 2, text, text.length); SelectObject(dc, old); EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } int doit() { HINSTANCE hInst = GetModuleHandle(NULL); WNDCLASS wc; wc.lpszClassName = "DWndClass"; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = &WindowProc; wc.hInstance = hInst; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_CROSS); wc.hbrBackground = cast(HBRUSH)(COLOR_BTNFACE); wc.lpszMenuName = NULL; wc.cbClsExtra = wc.cbWndExtra = 0; ATOM r = RegisterClass(&wc); assert(r); HWND hWnd, btnClick, btnDontClick; hWnd = CreateWindowEx(0/*WS_EX_WINDOWEDGE*/, "DWndClass", "Just a window", /*WS_THICKFRAME | */ WS_DLGFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP, NULL, hInst, NULL); assert(hWnd); btnClick = CreateWindow("BUTTON", "Click Me", WS_CHILD | WS_VISIBLE, 0, 0, 100, 25, hWnd, cast(HMENU)IDC_BTNCLICK, hInst, NULL); btnDontClick = CreateWindow("BUTTON", "DON'T CLICK!", WS_CHILD | WS_VISIBLE, 110, 0, 100, 25, hWnd, cast(HMENU)IDC_BTNDONTCLICK, hInst, NULL); MSG msg; while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } extern(C){ void gc_init(); void gc_term(); void _minit(); void _moduleCtor(); void _moduleUnitTests(); } extern(Windows) int WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { int result; gc_init(); _minit(); try{ _moduleCtor(); _moduleUnitTests(); result = doit(); }catch (Object o){ TCHAR[] msg = toT(o.toString() ~ "\0"); MessageBox(NULL, cast(TCHAR*)msg, "Error", MB_OK | MB_ICONEXCLAMATION); result = 1; } gc_term(); return result; }
DedicateD | FreePascal付属のwindows.pasからのポーティング ということでC言語の無茶な部分が見られず奇麗ですが、古いです |
Dig |
これに含まれるwindows.dはPhobosのwindows.dと大差無いです。 ただしXPのテーマAPIも付属しています。 |
Atari-Soldiers |
DIDEのサイト。 各種ポーティングライブラリ*2が収録されています。 |
D Win32 COM libraries 現在位置 |
COMも含めたインポートライブラリがあります。 構成から、全部手書きとしか思えないのですが…。(すげえ) |
We should use "private import" instead of "(public) import" for platform modules.
windows.dはこのように乱立状態です。 無論僕としてはこいつがデファクトスタンダードになってくれるとそれなりには嬉しいのですが、とりあえず、ポーティングライブラリをimportするときは、private importにしてください。 Dのimportはprivateにしない限り#includeよろしく連鎖するので、ポーティングライブラリをインポートしたソースをインポートしたソースが、ポーティングライブラリの選択という実装を強制的に見せられてしまうのは、単に好ましくないだけに留まらず、識別子の衝突やらで色々迷惑です。
2003-09-28 | I started. |
2003-09-30 | wingdi |
2003-10-01 | winuser |
2003-10-02 | winnls, wincon, winver, winreg, dde, ddeml, dlgs |
2003-10-03 | mmsystem |
2003-10-04 | shellapi, winspool |
2003-10-07 | commdlg |
2003-10-08 | imm, windows, add "Rtl.*Memory" in winnt |
2003-10-09 | commctrl |
2003-10-19 | some constants const => enum |
2003-10-28 | I started ANSI-version. |
2003-11-03 | ANSI-version |
2003-11-05 | recompiled with dmd 0.75. |
2003-11-19 | CallWindowProc and WM_MOUSEHOVER fixed. Thanks Charles. |
2003-11-25 | wsprintf and wvsprintf fixed. |
2004-01-03 | recompiled with dmd 0.77. |
2004-01-23 | recompiled with dmd 0.79. dmd 0.79 can compile HIWORD correctly. |
2004-01-30 | I started COM modules. |
2004-03-10 | winsock |
2004-03-14 | constants in winsock |
2004-05-07 | winuser maintenance. wvsprintf fixed. recompiled with dmd 0.86. |
2004-05-08 | insert "cast". recompiled with dmd 0.88. |
2004-07-09 | replace .size to .sizeof. recompiled with dmd 0.95. |
*2 「これ」も収録されてたり…。