第4章 テキストの表示 その3


さて、今回はテキスト表示のさらに別な方法を示します。 SDKでいうところのスタティックコントロールを使います。 もともと、スタティックコントロールはダイアログボックスに 単に文字を表示するのが主な仕事でした。 16ビット時代のダイアログボックスのバックグラウンドの色は 白でした。従ってこの時代のスタティックコントロールの地色は 白でした。しかし、32ビット時代になってダイアログボックスの 地色はウィンドウの枠の色と同じになりました。 そこで、普通のウィンドウにスタティックコントロールを 貼り付けると色つきの四角形として表示されます。 特別な目的のためには効果的です。しかし、単に クライアント領域に文字を表示する目的からはちょっと 陳腐な感じがします。(好き嫌いの問題です)

それと、今回はWM_LBUTTONDOWNとWM_RBUTTONDOWNメッセージの処理を 行います。右クリックと、左クリックの回数を親ウィンドウの クライアント領域に表示するプログラムを作ります。


スタティックコントロールの部分が色つきになっています。 これが嫌な人はエジットコントロールを使うという手もあります。

では、スタティックコントロールを親ウィンドウに貼り付けるには どうしたらよいでしょうか。これには、いくつかの方法が 考えられます。その中の1つをまず紹介してその後他の方法を解説します。

1.CStaticクラスのポインタを保存する変数を   クラスのメンバ変数として宣言する 2.適当なタイミングでnewでオブジェクトを生成して   ポインタ変数にそのアドレスを保存する 3.Create()メンバ関数を使ってスタティックコントロールを作成する 4.この時、ウィンドウスタイルは最低限   WS_CHILD | WS_VISIBLE の属性を持たせる 5.newしたものはdeleteする

次に、WM_LBUTTONDOWNとWM_RBUTTONDOWNメッセージの処理は どうしたらよいでしょうか?

これも類推から想像できますね。CWndクラスにはWM_何とかメッセージを 受け取ったときに動作するOn何とか関数をメンバに持っていました。 従ってOnLButtonDown()とかOnLButtonDown()関数なんていうのが きっとあるに違いありません。

CWnd::OnLButtonDown afx_msg void OnLButtonDown( UINT nFlags, CPoint point );

あ、やっぱりありました。引数のnFlagsはどの仮想キーが 押されたかを示します。pointはマウスの位置ですね。 OnRButtonDown()関数も同じです。 また、引数はSDKのときのWPARAMとかLPARAMみたいなものですね。 (WM_LBUTTONDOWNのwParamは仮想キー、lParamはカーソル位置でした) では、実際のプログラムを見てみましょう。

// text02.cpp #include <afxwin.h> class CMyWindow : public CFrameWnd { CStatic *pMyStatic1; CStatic *pMyStatic2; public: CMyWindow(); //コンストラクタ virtual ~CMyWindow();//デストラクタ afx_msg void OnPaint(); afx_msg void OnLButtonDown(UINT, CPoint); afx_msg void OnRButtonDown(UINT, CPoint); DECLARE_MESSAGE_MAP() };

型どおりクラス宣言時にポインタを保存する変数 pMyStatic1, pMyStatic2をクラスのメンバ変数にします。 今回はデストラクタも宣言します。 デストラクタはvirtualで宣言するのが一般的です。

BEGIN_MESSAGE_MAP(CMyWindow, CFrameWnd) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_RBUTTONDOWN() END_MESSAGE_MAP()

メッセージマップです。

CMyWindow::CMyWindow() { Create(NULL, "猫でもわかるテキスト表示"); pMyStatic1 = new CStatic(); pMyStatic1->Create("", WS_CHILD | WS_VISIBLE, CRect(20, 20, 40, 40), this); pMyStatic2 = new CStatic(); pMyStatic2->Create("", WS_CHILD | WS_VISIBLE, CRect(20, 40, 40, 60), this); }

今回は、簡単のためにコンストラクタでスタティックコントロールを 作ってみました。(他にWM_CREATEメッセージの時に作るという方法も よく行われます。) ここでは、単にコントロールを作るだけでまだ何も文字を表示していません。

CStatic::Create BOOL Create( LPCTSTR lpszText, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID = 0xffff );

エジットコントロールをCreateする場合、ちょっと引数が 違うので注意してください。

CMyWindow::~CMyWindow() { delete pMyStatic1; delete pMyStatic2; CFrameWnd::~CFrameWnd(); }

newしたものをdeleteするのはデストラクタで行うのが一般的です。 最後に本来のCFrameWndクラスのデストラクタを呼んでおきます。

void CMyWindow::OnPaint() { CPaintDC dc(this); CString str1 = "回 左クリックされました"; CString str2 = "回 右クリックされました"; dc.TextOut(40, 20, str1); dc.TextOut(40, 40, str2); }

WM_PAINTメッセージの処理です。

void CMyWindow::OnLButtonDown(UINT nFlags, CPoint pt) { static int n = 1; char *szNum = "%d"; char str[8]; wsprintf(str, szNum, n++); pMyStatic1->SetWindowText(str); }

左クリックされたときの処理です。 クリックされる度にnを1ずつ増やしていきます。 スタティックコントロールにテキストを表示するのは SetWindowTextで行います。

CWnd::SetWindowText void SetWindowText( LPCTSTR lpszString );

ま、これは説明不要ですね。 MFCのメンバ関数は同名のAPI関数とよく似ていますが、 APIの場合、第1引数はウィンドウハンドルや、デバイスコンテキスト ハンドルのことが多いでしたね。逆に言うとAPI関数の 第1引数をとってしまったものがメンバ関数であることが多いようです。

void CMyWindow::OnRButtonDown(UINT nFlags, CPoint pt) { static int n = 1; char *szNum = "%d"; char str[8]; wsprintf(str, szNum, n++); pMyStatic2->SetWindowText(str); }

右ボタンが押されたときの処理です。

class CMyApp : public CWinApp { public: virtual BOOL InitInstance(); }; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWindow(); m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; } CMyApp MyApp;

これは、前回と全く同じです。

さて、コントロール類を親ウィンドウに貼り付ける (子供ウィンドウとして取り扱う)方法は どれも大体同じです。ボタンとか、エジットコントロールを 貼り付けてみてください。

では、もう少し違う方法を説明します。

それは、グローバルな位置にstatic CStatic MyStatic;と宣言してしまうことです そして、適当なタイミングの時にCreateします。 このときMyStaticはポインタではないのでMyStatic.Create(...); となることに注意してください。


[MFC Index] [総合Index] [Previous Chapter] [Next Chapter]

Update 08/Jan/1998 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。