看图学习用D语言编写包含资源的win32 GUI程序

这篇文章教大家用D语言写一个具有资源文件的Win 32 GUI 程序。
如果有不会使用D语言的,请看我写过的《看图配置D语言集成开发环境》这篇文章。
首先了解一下基础知识。
D语言的源代码默认是用UTF8 编写的。
如果
char szMsg[] = "我们";//这么写,就是UTF8的字符串
string sMsg="什么";//这么写,就是UTF8的字符串
MessageBoxW(null,cast(char *)toUTF16(szMsg),null,MB_OK);

wchar szMsg[] = "我们";//这么写,就是unicode/UTF16的字符串
wstring sMsg="什么";//这么写,就是unicode/UTF16的字符串
MessageBoxW(null,cast(char *)szMsg,null,MB_OK);

传递给win32 API 时类型不匹配,强制转换是必须的
我的建议是不要使用A后缀的函数。

如果你要直接写个常字符串在API调用中,有点麻烦
MessageBoxW(null,cast(char *)toUTF16(cast(char[])"我们ddd我么"),null,MB_OK);
--------------------------------------------------------------------------------------------------------------
windows.d 的API 申明 不全,有时候我们 要自己声明像下面这样
//===================================================
//D语言的std.c.windows.windows没申明的win32 API函数,要用的话自己加上。
extern (Windows)
{
 int LoadStringA(HINSTANCE hInstance,UINT uID,LPTSTR lpBuffer,int nBufferMax);
 BOOL DestroyWindow(HWND hWnd);
 BOOL Rectangle(HDC hdc,int nLeftRect,int nTopRect,int nRightRect,int nBottomRect);
}
//===================================================
--------------------------------------------------------------------------------------------------------------

建一个下图的项目,再次提醒“项目路径必须是已存在的目录”


然后 去 D:/dmd/samples/d (就是放dmd编译器的地方)目录把 winsamp.d 的内容 复制到 我们项目中的 main.d 中。复制下面的也行。


/* Compile with:
 * dmd winsamp gdi32.lib winsamp.def
 */

import std.c.windows.windows;
import std.c.stdio;

const int IDC_BTNCLICK = 101;
const int IDC_BTNDONTCLICK = 102;

extern(Windows)
int 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)
    MessageBoxA(hWnd, "Hello, world!", "Greeting",
     MB_OK | MB_ICONINFORMATION);
   break;
      case IDC_BTNDONTCLICK:
   if (HIWORD(wParam) == BN_CLICKED)
   {
       MessageBoxA(hWnd, "You've been warned...", "Prepare to GP fault",
        MB_OK | MB_ICONEXCLAMATION);
       *(cast(int*) null) = 666;
   }
   break;
  }
  break;
     }

     case WM_PAINT:
     {
  static char[] text = "D Does Windows";
  PAINTSTRUCT ps;
  HDC dc = BeginPaint(hWnd, &ps);  
  RECT r;
  GetClientRect(hWnd, &r);
  HFONT font = CreateFontA(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);
  TextOutA(dc, r.right / 2, r.bottom / 2, text.ptr, text.length);
  SelectObject(dc, old);
  EndPaint(hWnd, &ps);
  break;
     }
     case WM_DESTROY:
  PostQuitMessage(0);
  break;

     default:
  break;
 }
 return DefWindowProcA(hWnd, uMsg, wParam, lParam);
}

int doit()
{
 HINSTANCE hInst = GetModuleHandleA(null);
 WNDCLASS wc;
 wc.lpszClassName = "DWndClass";
 wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
 wc.lpfnWndProc = &WindowProc;
 wc.hInstance = hInst;
 wc.hIcon = LoadIconA(cast(HINSTANCE) null, IDI_APPLICATION);
 wc.hCursor = LoadCursorA(cast(HINSTANCE) null, IDC_CROSS);
 wc.hbrBackground = cast(HBRUSH) (COLOR_WINDOW + 1);
 wc.lpszMenuName = null;
 wc.cbClsExtra = wc.cbWndExtra = 0;
 auto a = RegisterClassA(&wc);
 assert(a);
 
 HWND hWnd, btnClick, btnDontClick;
 hWnd = CreateWindowA("DWndClass", "Just a window", WS_THICKFRAME |
  WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE,
  CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP,
  cast(HMENU) null, hInst, null);
 assert(hWnd);
 
 btnClick = CreateWindowA("BUTTON", "Click Me", WS_CHILD | WS_VISIBLE,
  0, 0, 100, 25, hWnd, cast(HMENU) IDC_BTNCLICK, hInst, null);

 btnDontClick = CreateWindowA("BUTTON", "DON'T CLICK!", WS_CHILD | WS_VISIBLE,
  110, 0, 100, 25, hWnd, cast(HMENU) IDC_BTNDONTCLICK, hInst, null);

 MSG msg;
 while (GetMessageA(&msg, cast(HWND) null, 0, 0))
 {
  TranslateMessage(&msg);
  DispatchMessageA(&msg);
 }
 
 return 1;
}

/**********************************************************/

/* Note the similarity of this code to the console D startup
 * code in /dmd/src/phobos/dmain2.d
 * You'll also need a .def file with at least the following in it:
 * EXETYPE NT
 * SUBSYSTEM WINDOWS
 */

extern (C) void gc_init();
extern (C) void gc_term();
extern (C) void _minit();
extern (C) void _moduleCtor();
extern (C) void _moduleUnitTests();

extern (Windows)
int WinMain(HINSTANCE hInstance,
 HINSTANCE hPrevInstance,
 LPSTR lpCmdLine,
 int nCmdShow)
{
    int result;

    gc_init();   // initialize garbage collector
    _minit();   // initialize module constructor table

    try
    {
 _moduleCtor();  // call module constructors
 _moduleUnitTests(); // run unit tests (optional)

 result = doit(); // insert user code here
    }

    catch (Object o)  // catch any uncaught exceptions
    {
 MessageBoxA(null, cast(char *)o.toString(), "Error",
      MB_OK | MB_ICONEXCLAMATION);
 result = 0;  // failed
    }

    gc_term();   // run finalizers; terminate garbage collector
    return result;
}

然后“生成并运行”,问题来了,下图状况。

看样子是少个 *.lib ,看到源代码前面的
/* Compile with:
 * dmd winsamp gdi32.lib winsamp.def
 */
了吧,少个gdi32.lib
进入“项目属性”的导入路径及程序库选项卡,程序库点击添加 找到 gdi32

好了,“生成并运行”没问题了,D语言的demo编译成功了。
去这个网站 下载 Resource Builder,只有30天试用,凑合用。
http://www.resource-builder.com/download.html
http://www.onlinedown.net/soft/12422.htm

安装了以后 把 “工具”-》“选项”-》“编译器”里的 "Res Tool" 指向 我们 安装 的Resource Builder,
默认是"C:/Program Files/SiComponents/Resource Builder/Resbldr2.exe"

在Resource 上面右键 新建 main.res 文件,在IDE里面把main.res关闭了。

然后双击 打开 Resource Builder 进行 资源 编辑。
建立菜单 和 图标。
我这里建立了一个图标和一个菜单,图标里面含有3个子项是windows标准要求的我们要拿这个做程序及窗体上的图标,注意ID值图标40001,菜单40002程序中要用。这个res文件是编译后的2进制文件了。

在程序 的 前面 加上
const int IDI_ICON = 40001;
const int IDM_MENU = 40002;
窗口结构填充处修改成
 wc.hIcon = LoadIconW(hInst,cast(wchar*)IDI_ICON);
 wc.lpszMenuName = cast(LPCSTR) IDM_MENU;

效果如下,资源 文件的 使用,请参考其他书籍。

我用D语言写了个完整 的 《汉诺塔》游戏,需要看源代码的去这里看看,我发的资源里面也有
http://bbs.gameres.com/showthread.asp?threadid=98142

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值