Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Mini-Calc

Part of WindowsGuiCategory

Description

Simple Windows GUI example with additional functionality beyond winsamp.d and winsamp2.d provided with dmd.zip. Uses Win32 api (no gui framework) with several TextEdit controls.

Example

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

import std.string;
import std.c.windows.windows;

extern (Windows) BOOL IsDialogMessage(HWND hDlg, LPMSG lpMsg);

const int IDC_BTN_PLUS = 103;
const int IDC_BTN_MINUS = 104;
const int IDC_EDIT_FIRST_NUMBER = 105;
const int IDC_EDIT_SECOND_NUMBER = 106;
const int IDC_EDIT_RESULT_NUMBER = 107;

static HINSTANCE ghInstance;
static HWND      ghPlusBtn;
static HWND      ghMinusBtn;
static HWND      ghFirstNumberEdit;
static HWND      ghSecondNumberEdit;
static HWND      ghResultNumberEdit;
static HWND      ghWndMain;

void CreateControls()
{
  HWND hChapSelectorTree;

  ghPlusBtn = CreateWindowA("BUTTON", "Plus",
                 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_TEXT,
                 5, 5, 53, 25, ghWndMain, cast(HMENU) IDC_BTN_PLUS,
                 ghInstance, null);

  ghMinusBtn = CreateWindowA("BUTTON", "Minus",
                 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON | BS_TEXT,
                 60, 5, 53, 25, ghWndMain,
                 cast(HMENU) IDC_BTN_MINUS,
                 ghInstance, null);

  ghFirstNumberEdit = CreateWindowA("EDIT", "0",
                 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_LEFT,
                 5, 32, 110, 25, ghWndMain,
                 cast(HMENU) IDC_EDIT_FIRST_NUMBER, ghInstance, null);

  ghSecondNumberEdit = CreateWindowA("EDIT", "20",
                 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_LEFT,
                 5, 60, 110, 25, ghWndMain,
                 cast(HMENU) IDC_EDIT_SECOND_NUMBER, ghInstance, null);

  ghResultNumberEdit = CreateWindowA("EDIT", "",
                 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | ES_LEFT,
                 5, 87, 110, 25, ghWndMain,
                 cast(HMENU) IDC_EDIT_RESULT_NUMBER,
                 ghInstance, null);

  SendMessageA(ghFirstNumberEdit, EM_LIMITTEXT, 9, 0);
  SendMessageA(ghSecondNumberEdit, EM_LIMITTEXT, 9, 0);
}

void DoMessagePump()
{
  MSG msg;
  while (GetMessageA(&msg, cast(HWND) null, 0, 0)) {
    if (!IsDialogMessage(ghWndMain, &msg)) {
      TranslateMessage(&msg);
      DispatchMessageA(&msg);
	}
  }
}

void CreateMainWindow()
{
  HWND hWnd;
  hWnd = CreateWindowA("DWndClass",
               "MiniCalc",
               WS_THICKFRAME | WS_MAXIMIZEBOX
               | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE,
               CW_USEDEFAULT, CW_USEDEFAULT,
               125, 150, HWND_DESKTOP,
               cast(HMENU) null, ghInstance, null);
  assert(hWnd);
  ghWndMain = hWnd;
}

void InitApplication()
{
  WNDCLASS wc;
  wc.lpszClassName = "DWndClass";
  wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  wc.lpfnWndProc = &WindowProc;
  wc.hInstance = ghInstance;
  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;

  ATOM classRegistered = RegisterClassA(&wc);
  assert(classRegistered);
}

void InitInstance()
{
  ghInstance = GetModuleHandleA(null);
  InitApplication();

  CreateMainWindow();

  CreateControls();
}

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

/* 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 = 1;

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

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

    InitInstance();
    DoMessagePump();
  }
  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;
}

extern(Windows)
int WindowProc(HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam)
{
  char[10] firstNumber;
  char[10] secondNumber;
  int count;
  long num1;
  long num2;

  switch (uMsg) {
    case WM_COMMAND: {
      switch (LOWORD(wParam)) {
        case IDC_BTN_PLUS:
          if (HIWORD(wParam) == BN_CLICKED) {
            count = SendMessageA(ghFirstNumberEdit, WM_GETTEXT,
                                 10, cast(int)cast(char*)firstNumber);
            count = SendMessageA(ghSecondNumberEdit, WM_GETTEXT,
                                 10, cast(int)cast(char*)secondNumber);
            num1 = atoi(cast(char[])firstNumber);
            num2 = atoi(cast(char[])secondNumber);
            SendMessageA(ghResultNumberEdit, WM_SETTEXT,
                         0, cast(int) toStringz(toString(num1 + num2)));
          }
          break;
        case IDC_BTN_MINUS:
          if (HIWORD(wParam) == BN_CLICKED) {
            count = SendMessageA(ghFirstNumberEdit,
                                 WM_GETTEXT, 10,
                                 cast(int)cast(char*)firstNumber);
            count = SendMessageA(ghSecondNumberEdit,
                                 WM_GETTEXT, 10,
                                 cast(int)cast(char*)secondNumber);
            num1 = atoi(cast(char[])firstNumber);
            num2 = atoi(cast(char[])secondNumber);
            SendMessageA(ghResultNumberEdit, WM_SETTEXT,
                         0, cast(int) toStringz(toString(num1 - num2)));
          }
          break;
        case IDC_EDIT_FIRST_NUMBER:

          break;
        case IDC_EDIT_SECOND_NUMBER:
          break;
        case IDC_EDIT_RESULT_NUMBER:
          break;
      }
      break;
    }
    case WM_DESTROY:
      PostQuitMessage(0);
      break;

    case WM_NOTIFY:
      break;

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

Source

Posted by Lynn
Date/Time Thu Oct 14, 2004 10:35 am