TextOut Object Class を作成する

Object Class の作成方法を説明するために、最も簡単な Text を表示する TextOut Object Class を使います。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの設定

  1. 空の新規プロジェクト(Textobj)を作成して Textobj.cpp をフォルダーに格納して下さい。
    Textobj.cpp の中で直接「TXTOUT Object Class」を定義しています。
  2. [プロジェクト] [既存項目の追加] からフォルダーに格納した Textobj.cpp をプロジェクトに追加します。
  3. ビルドに続いて実行を行います。
    "Text Out Object Class" が画面に表示されたら完成です。
  4. TXTOUT Object Class の Print() メンバー関数を使って、あなたの名前と住所が表示されるようにして下さい。

Textobj.cpp の全ソースコード

/*******************************************************/
/*★ TEXTOUT Object Class  Sample Program    前田 稔 ★*/
/*******************************************************/
#define     NAME    "Empty Program"
#include    <windows.h>

//★ TXTOUT Class Object Header
class TXTOUT
{ //★非公開部分
  protected:

  //★公開部分
  public:
    TXTOUT();                       //Constructor
    ~TXTOUT();                      //Destructor
    void  Print(HDC hdc,int x,int y,LPSTR str);
};

//★ TXTOUT Object Class のメンバ関数
// コンストラクタ(オブジェクトの初期化)
TXTOUT::TXTOUT()
{
}

// デストラクタ(オブジェクトの終了)
TXTOUT::~TXTOUT()
{
}

void  TXTOUT::Print(HDC hdc,int x,int y,LPSTR str)
{
    TextOut(hdc,x,y,str,strlen(str));
}

//★ Global Area
TXTOUT      TxtOut;             //TEXT OUT Object の定義
HINSTANCE   g_hInst;
HWND        g_hWnd;

//★ Function Prototype
LRESULT  CALLBACK   WndProc(HWND, UINT, WPARAM, LPARAM);
int      PASCAL     WinMain(HINSTANCE, HINSTANCE, LPSTR, int);

//★ CALLBACK 関数
LRESULT  CALLBACK  WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{   PAINTSTRUCT ps;
    HDC         hdc;

    //渡された message から、イベントの種類を解析する
    switch(msg)
    {   case WM_PAINT:
             hdc= BeginPaint (hWnd, &ps);
             TxtOut.Print(hdc,100,50,"Text Out Object Class");
             EndPaint(hWnd, &ps);
             break;
        case WM_DESTROY:
             PostQuitMessage(0);
             return 0L;
    }
    //デフォルトの処理
    return  DefWindowProc(hWnd,msg,wParam,lParam);
}

//★ Windows Main 関数
int PASCAL  WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine,int nCmdShow)
{   MSG         msg;

    g_hInst= hInstance;
    // Set up and register window class
    WNDCLASS wc = { CS_CLASSDC,WndProc,0L,0L,hInstance,NULL,LoadCursor(NULL,IDC_ARROW),
                    (HBRUSH)GetStockObject(WHITE_BRUSH),NULL,NAME };
    if (RegisterClass(&wc)==0)    return FALSE;
    // Create a window
    g_hWnd= CreateWindow(NAME,NAME,WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,CW_USEDEFAULT,400,200,
            NULL,NULL,hInstance,NULL);
    if (!g_hWnd)  return FALSE;

    ShowWindow(g_hWnd,nCmdShow);    //Window を表示
    UpdateWindow(g_hWnd);           //表示を初期化
    SetFocus(g_hWnd);               //フォーカスを設定
    while (GetMessage(&msg,NULL,0,0))
    {   TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return S_OK;                    //return 0
}

プログラムの説明

TXTOUT Object Class の定義

Object Class で使用するデータやメンバ関数(メソッド)のプロトタイプを定義します。
今回の TXTOUT Class では実質的なメンバ関数(メソッド)は Print() だけです。
Constructor や Destructor では、何の処理もしていないので削除しても差し支えありません。
ヘッダファイルから Constructor や Destructor を削除したときは、関数の本体も削除して下さい。
class TXTOUT
{ //★非公開部分
  protected:

  //★公開部分
  public:
    TXTOUT();                       //Constructor
    ~TXTOUT();                      //Destructor
    void  Print(HDC hdc,int x,int y,LPSTR str);
};


TXTOUT Object Class のメンバ関数

TXTOUT Object Class のメンバ関数は、スコープ演算子(TXTOUT::)を付けて定義します。
スコープ演算子により Class で定義された領域やメンバ関数の参照ができるようになります。
ヘッダファイルから Constructor や Destructor を削除したときは、関数の本体も削除して下さい。
// コンストラクタ(オブジェクトの初期化)
TXTOUT::TXTOUT()
{
}

// デストラクタ(オブジェクトの終了)
TXTOUT::~TXTOUT()
{
}

void  TXTOUT::Print(HDC hdc,int x,int y,LPSTR str)
{
        TextOut(hdc,x,y,str,strlen(str));
}


メンバ関数の呼び出し

TEXT を表示するメンバ関数は WM_PAINT: に記述します。
Class で修飾して「TxtOut.メンバ関数名()」の形式で呼び出して下さい。
TXTOUT  TxtOut;             //TEXT OUT Object の定義

        TxtOut.Print(hdc,100,50,"Text Out Object Class");

ファイルを分ける

TextOut Object Class のファイルをメインプログラムと独立して作成します。
  1. TextObj.cpp を次のソースファイルに分けます。
    TextObj.cpp Main Program ファイル
    Txtout.h Object Class のヘッダファイル
    Txtout.cpp Object Class のソースファイル
  2. TextObj.cpp から TEXTOUT Object Class のヘッダとプログラム(関数)を削除して下さい。
    ファイルの先頭でコンパイルに必要なヘッダファイルを取り込みます。
    #include <windows.h>
    #include "Txtout.h"
  3. Txtout.h には TextObj.cpp に記述されていた TEXTOUT Object Class のヘッダ部を格納して下さい。
  4. Txtout.cpp には TEXTOUT Object Class のメンバ関数を格納して下さい。
    Txtout.cpp はメインとは独立してコンパイルされます。
    このときコンパイルに必要なヘッダファイルを取り込んで下さい。
    #include <windows.h>
    #include "Txtout.h"
  5. [プロジェクト] [既存項目の追加] から分割した二個のファイルをプロジェクトに追加します。
  6. ビルドに続いて実行を行うと "Text Out Object Class" が表示されます。

テンプレートを使った場合

  1. テンプレートを使ってプロジェクトを作成します。
    テンプレートを使うとヘッダーファイルのプリコンパイルが行われます。
  2. メインプログラムのファイルに TXTOUT Object Class のヘッダと関数を追加して下さい。
    追加するコードは「Textobj.cpp の全ソースコード」に記述されている TXTOUT Object Class の Header とメンバ関数です。
  3. TEXT OUT Object Class の定義と描画は、空から作成した場合に準じます。
    メインプログラムを表示して「// グローバル変数 :」の位置までスクロールして下さい。
    「TXTOUT TxtOut;」が Object の定義で、追加するのはこの一行だけです。
        // グローバル変数 :
        TXTOUT      TxtOut;                             // TEXT OUT Object の定義
        
  4. WM_PAINT: に TEXT 文字を表示するコードを追加します。
    TxtOut.Print() は TXTOUT Object で定義されているメンバー関数 Print() を呼び出しています。
        case WM_PAINT:
            hdc = BeginPaint(hWnd, &ps);
            // TODO: 描画コードをここに追加してください...
            TxtOut.Print(hdc,200,50,"Text Out Object Class");
            EndPaint(hWnd, &ps);
            break;
        
  5. TextOut Object Class のファイルを独立するときは、次のことに注意して下さい。
    1. stdafx.h の中で Object Class のヘッダファイルを取り込みます。
      // TODO: プログラムで必要なヘッダー参照を追加してください。
      #include "Txtout.h"
    2. Textout.cpp では "StdAfx.h" をインクルードします。
      #include "StdAfx.h"
    3. メインプログラムを表示して "StdAfx.h" がインクルードされていることを確認して下さい。
              #include "stdafx.h"
              #define MAX_LOADSTRING 100
      
              TXTOUT      TxtOut;             //TEXT OUT Object の定義
              
    4. stdafx.h を使わずに直接 "Txtout.h" を取り込むと、次のエラーが表示されることがあります。
      ...\txtout.cpp(23) : fatal error C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
  6. ビルドに続いて実行を行うと "Text Out Object Class" が画面に表示されます。

【演習】

Java と同じように Object Class をポインタを使って定義して下さい。
どちらかと言うと Object Class では、ポインタを使う方が主流です。
  1. このページで紹介した Object Class は、構造体と同じようにポインタを使わずに定義する方法です。
        TXTOUT      TxtOut;                             // TEXT OUT Object の定義
        TxtOut.Print(hdc,200,50,"Text Out Object Class");
        
  2. Java と同じようにポインタを使って定義する方法です。
    1. Object Class をポインタで定義します。
              TXTOUT      *TxtOut= NULL;             // TEXT OUT Object の定義
              
    2. new で Object Class を生成して、そのポインタを取得します。
              TxtOut= new TXTOUT();
              
    3. メンバ関数の呼び出しは次のように書きます。
              TxtOut->Print(hdc,200,50,"Text Out Object Class");
              
    4. 最後に生成した Object を開放します。
              if (TxtOut)
              {   delete(TxtOut);
                  TxtOut= NULL;
              }  
              

超初心者のプログラム入門(Win32API C++)