ようやく dfl.resources モジュールのサンプルコードに着手した。
リソースコンパイラ rc.exe が必要なので、この記事のコードは、Visual Studio がインストールされていないと実行できない。
リソースのバイナリファイルもリポジトリに含めてあるので、プロジェクト全体をこちらからダウンロードして試した方がよい。
sample.rc リソースファイル
こういうリソースファイルを作成したとする。
256 ICON "image/icon.ico" 257 BITMAP "image/dman-error.bmp" 258 RCDATA { "Here is an ANSI string\0", // explicitly null-terminated L"Here is a Unicode string\0", // explicitly null-terminated 1024, // integer, stored as WORD 7L, // integer, stored as DWORD 0x0010, // hex integer as WORD 0o010, // octal integerr as WORD } 259 CURSOR "image/d-cursor.cur" STRINGTABLE { 260, "Hoge\0" 261, "Fuga\0" }
この sample.rc が ./resource フォルダに入っているとして、次を実行すると、 sample.res ファイルが作成される。 もちろん rc.exe にパスが通っていないとダメ。
> rc /v resource\sample.rc
resources_sample.d
メインのコードはこちら。
import dfl; import dfl.internal.dlib; import core.sys.windows.winnt; import core.sys.windows.winuser; import std.conv; version(Have_dfl) // For DUB. { } else { pragma(lib, "dfl.lib"); } // RCDATA の項目に合わせて定義した構造体 struct RCData { string ansiString; wstring unicodeString; WORD wordInt; DWORD dwordInt; WORD wordHexInt; WORD wordOctInt; } // リソースファイルから読み出して構造体に埋めていく // RCData* dat = cast(RCData*)pBuffer; みたいなことはできないので頑張る RCData parseRCData(const(ubyte)* ptr, size_t size) { RCData data; size_t offset; // string ansiString: ANSI null-terminated string auto start = offset; while (offset < size && ptr[offset] != 0) offset += char.sizeof; data.ansiString = cast(string)ptr[start .. offset]; offset += char.sizeof; // skip null terminator // wstring unicodeString: Unicode null-terminated string start = offset; while (offset + 1 < size && (ptr[offset] != 0 || ptr[offset + 1] != 0)) offset += wchar.sizeof; data.unicodeString = cast(wstring)ptr[start .. offset]; offset += wchar.sizeof; // skip null terminator // WORD wordInt data.wordInt = *cast(WORD*)&ptr[offset]; offset += WORD.sizeof; // DWORD dwordInt data.dwordInt = *cast(DWORD*)&ptr[offset]; offset += DWORD.sizeof; // WORD wordHexIn data.wordHexInt = *cast(WORD*)&ptr[offset]; offset += WORD.sizeof; // WORD wordOctInt data.wordOctInt = *cast(WORD*)&ptr[offset]; offset += WORD.sizeof; return data; } class MainForm : Form { Bitmap _bmp; Cursor _cur; Icon _ico; string[] _str; RCData _rcdata; public this() { this.text = "Resources example"; this.size = Size(600, 600); Resources r = new Resources(Application.getInstance()); _bmp = r.getBitmap(257); _cur = r.getCursor(259); _ico = r.getIcon(256, 32, 32); this.icon = _ico; _str = [r.getString(260), r.getString(261)]; void[] dat = r.getData(RT_RCDATA, 258); _rcdata = parseRCData(cast(ubyte*)dat, dat.length); } override void onPaint(PaintEventArgs e) { Font fon = new Font("msgothic", 12); e.graphics.drawText(_str[0] ~ " " ~ _str[1], fon, Color.black, Rect(0, 0, width, height)); e.graphics.drawText(_rcdata.ansiString, fon, Color.black, Rect(0, 50, width, height)); e.graphics.drawText(_rcdata.unicodeString.to!string(), fon, Color.black, Rect(0, 70, width, height)); e.graphics.drawText(_rcdata.wordInt.to!string(), fon, Color.black, Rect(0, 90, width, height)); e.graphics.drawText(_rcdata.dwordInt.to!string(), fon, Color.black, Rect(0, 110, width, height)); e.graphics.drawText(_rcdata.wordHexInt.to!string(), fon, Color.black, Rect(0, 130, width, height)); e.graphics.drawText(_rcdata.wordOctInt.to!string(), fon, Color.black, Rect(0, 150, width, height)); _bmp.draw(e.graphics, Point(100, 200)); } override void wndProc(ref Message msg) { if (msg.msg == WM_SETCURSOR) { Cursor.current = _cur; return; // Returns so that the class cursor is not displayed. } super.wndProc(msg); } } static this() { Application.enableVisualStyles(); // おまけ import dfl.internal.dpiaware; // SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE); // OK // SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED); // OK // SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); // Windows suppresses the display of balloon tips. SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); // ditto. } void main() { Application.run(new MainForm()); }
dub.json
DUB でビルドするときにリソースファイルがリンクされるように;
"lflags-windows": ["resource/sample.res"]
を追記している。
- dub.json
{ "authors": ["haru-s"], "copyright": "Copyright (C) 2025 haru-s", "description": "DFL sample code.", "name": "resources_sample", "targetType": "executable", "targetPath": "bin", "dependencies": { "dfl": { "path": "../../../dfl" } }, "lflags-windows": ["resource/sample.res"], "lflags-windows-x86_mscoff-dmd": ["/SUBSYSTEM:WINDOWS", "/ENTRY:mainCRTStartup"], "lflags-windows-x86_64-dmd": ["/SUBSYSTEM:WINDOWS", "/ENTRY:mainCRTStartup"] }