MFC 抜きで GUI プログラミングをする

[戻る]

先日, 提供先でもコンパイルできるコードを作らなくてはならないことがありました. 先方の環境は Visual C++ のExpress Edition のため, 普段私が使う MFC は使えません. 一方で私が普段作るプログラムはシンプルなダイアログベースばかりです. というわけで, MFC 抜きでダイアログベースのプログラムをどのように作ればいいのか調べましたので, 忘れないよう書いておきます.

  1. Visual C++ Express Edition を立ち上げ, プロジェクトを新規作成する. ここではテンプレートをコンソールアプリとして, SampleDlg という名で作ったとして話を進めます.
  2. プロパティページを開き と変更する.
  3. SampleDlg.cpp をプロジェクトから除外する
  4. stdafx.h を開いて次のように書き換える
    #pragma once

    #include "targetver.h"

    #define WIN32_LEAN_AND_MEAN
    #define _CRT_SECURE_NO_DEPRECATE

    #include <windows.h>
    #include <stdio.h>
  5. targetver.h を開いて, 次のように書き換える
    #pragma once

    #ifndef WINVER
    #define WINVER 0x0501
    #endif

    #ifndef _WIN32_WINNT
    #define _WIN32_WINNT 0x0501
    #endif

    #ifndef _WIN32_WINDOWS
    #define _WIN32_WINDOWS 0x0410
    #endif

    #ifndef _WIN32_IE
    #define _WIN32_IE 0x0700
    #endif
  6. 以下のような main.cpp ファイルを作り, プロジェクトに追加する
    #include "stdafx.h"
    #include "MainDlg.h"
    #include "messageIDs.h"

    CMainDlg g_MainDlg;
    LRESULT CALLBACK MainDlgProc(HWND, UINT, WPARAM, LPARAM);

    int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) {
      g_MainDlg.m_pCmdLine=lpsCmdLine;

      DialogBox(hCurInst, "SAMPLEDLG", NULL, (DLGPROC)MainDlgProc);
      return 0;
    }

    LRESULT CALLBACK MainDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp){
      switch(msg){
        case WM_INITDIALOG:
          {
            HWND hDeskWnd=GetDesktopWindow();
            RECT deskrc, rc;
            GetWindowRect(hDeskWnd, (LPRECT)&deskrc);
            GetWindowRect(hDlgWnd, (LPRECT)&rc);
            int x = (deskrc.right - (rc.right-rc.left)) / 2;
            int y = (deskrc.bottom - (rc.bottom-rc.top)) / 2;
            SetWindowPos(hDlgWnd, HWND_TOP, x, y, (rc.right-rc.left), (rc.bottom-rc.top),SWP_SHOWWINDOW);

            g_MainDlg.m_hWnd=hDlgWnd;
            return g_MainDlg.InitDlg(hDlgWnd);
          }
        case WM_CLOSE:
          if (g_MainDlg.DestoryWnd(hDlgWnd)){
            DestroyWindow(hDlgWnd);
            return TRUE;
          }
          return FALSE;
      }

      return g_MainDlg.Proc(msg, wp, lp);
    }
  7. 以下のような MainDlg.h フィアルを作り, プロジェクトに追加する.
    #ifndef _MAIN_DLG_H_
    #define _MAIN_DLG_H_

    class CMainDlg{
    public:
      char *m_pCmdLine;

      HWND m_hWnd;

      CMainDlg();
      ~CMainDlg();

      BOOL InitDlg(HWND);
      BOOL DestoryWnd(HWND);
      LRESULT Proc(UINT, WPARAM, LPARAM);
    };
    #endif
  8. 以下のような MainDlg.cpp ファイルを作り, プロジェクトに追加する.
    #include "stdafx.h"
    #include "messageIDs.h"
    #include "MainDlg.h"

    CMainDlg::CMainDlg(){
      m_hWnd=NULL;
    }

    CMainDlg::~CMainDlg(){
    }

    LRESULT CMainDlg::Proc(UINT msg, WPARAM wp, LPARAM lp){
      switch (msg) {
        case WM_COMMAND:
          return FALSE;
        case WM_CLOSE:
          return TRUE;
      }
      return FALSE;
    }

    BOOL CMainDlg::InitDlg(HWND hWnd){
      return TRUE;
    }

    BOOL CMainDlg::DestoryWnd(HWND){
      return TRUE;
    }
  9. 以下のような messageIDs.h を作り, プロジェクトに追加する
    #pragma once

    #define IDC_STATIC 3000
    #define IDC_STATUS 4000
    #define ID_START 4001
  10. 以下のような SampldDlg.rc ファイルを作り, プロジェクトに追加する
    #include "windows.h"
    #include "messageIDs.h"
    
    SAMPLEDLG DIALOG DISCARDABLE  0, 0, 110, 78
    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
    CAPTION "SampleDlg"
    FONT 9, "MS Pゴシック"
    BEGIN
        LTEXT           "Text Line",IDC_STATIC,8,5,94,8
        EDITTEXT        IDC_STATUS,8,18,94,36,ES_MULTILINE  | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN 
        DEFPUSHBUTTON   "Button",ID_START,55,59,50,14
    END
      
ここまで出来たら, 一回ビルドして起動させてみましょう. 上手くいくと次のようなダイアログが立ち上がるはずです

でもこれはただ, 画面が立ち上がっただけです. 何もしません. というわけで, 少し反応するようにしてみます.

ここまで分かれば, 後は適当です. MFC で培った感覚を総動員すればなんとかなるものです.
2011.1