では、早速プログラムを見てみます。
これは、普通のリソース・スクリプトです。// dlg04.rcの一部 ///////////////////////////////////////////////////////////////////////////// // // Dialog // MYDLG DIALOG DISCARDABLE 0, 0, 215, 93 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "入力用ダイアログ" FONT 9, "MS Pゴシック" BEGIN EDITTEXT IDC_EDIT1,55,7,97,17,ES_AUTOHSCROLL COMBOBOX IDC_COMBO1,55,33,97,53,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP LISTBOX IDC_LIST1,55,55,97,31,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK",IDOK,158,7,50,14 PUSHBUTTON "キャンセル",IDCANCEL,158,28,50,14 PUSHBUTTON "氏名欄クリア",IDC_CLEAR,158,49,50,14 LTEXT "氏名:",IDC_STATIC,15,7,18,8 LTEXT "本籍地:",IDC_STATIC,15,33,25,8 LTEXT "ペット:",IDC_STATIC,15,57,20,8 END ///////////////////////////////////////////////////////////////////////////// // // Menu // MYMENU MENU DISCARDABLE BEGIN POPUP "ファイル(&F)" BEGIN MENUITEM "終了(&X)", IDM_END END POPUP "オプション(&O)" BEGIN MENUITEM "ダイアログ(&D)", IDM_DLG END END
CMyWindowクラスに、str, ListStr, ComboStrなどの 表示用メンバを持たせます。前回同様CMyDlgクラスにはこのような メンバはありません。// dlg04.h class CMyApp : public CWinApp { public: virtual BOOL InitInstance(); }; class CMyWindow : public CFrameWnd { public: CMyWindow(); CString str; CString ListStr; CString ComboStr; protected: afx_msg void OnPaint(); afx_msg void OnClose(); afx_msg void OnEnd(); afx_msg void OnDlg(); DECLARE_MESSAGE_MAP() }; class CMyDlg : public CDialog { public: CMyDlg(CWnd *pParentWnd = NULL) : CDialog("MYDLG", pParentWnd) {} protected: virtual void OnOK(); virtual BOOL OnInitDialog(); void OnClear(); DECLARE_MESSAGE_MAP() };
これは、いつもと同じです。// dlg04.cpp #include <afxwin.h> #include "dlg04.h" #include "resource.h" CMyApp myApp; BOOL CMyApp::InitInstance() { m_pMainWnd = new CMyWindow; m_pMainWnd->ShowWindow(m_nCmdShow); m_pMainWnd->UpdateWindow(); return TRUE; }
222*106の大きさで親ウィンドウを作ります。 また、"MYMENU"メニューを付けます。BEGIN_MESSAGE_MAP(CMyWindow, CFrameWnd) ON_WM_PAINT() ON_WM_CLOSE() ON_COMMAND(IDM_END, OnEnd) ON_COMMAND(IDM_DLG, OnDlg) END_MESSAGE_MAP() CMyWindow::CMyWindow() { Create(NULL, "猫でもわかるダイアログ", WS_OVERLAPPEDWINDOW, CRect(100, 100, 100 + 222, 100 + 106), NULL, "MYMENU"); }
メニューから「終了」が選択されたときの処理です。void CMyWindow::OnEnd() { SendMessage(WM_CLOSE); }
メニューの「ダイアログ」が選択されたときの処理です。 ダイアログボックスを表示します。void CMyWindow::OnDlg() { CMyDlg dlg(this); if(dlg.DoModal() == IDOK) Invalidate(); }
WM_PAINメッセージが来たときの処理です。 Format()については第12章を参照してください。void CMyWindow::OnPaint() { CPaintDC dc(this); CString MyStr; MyStr.Format("氏 名=%s", str); dc.TextOut(0, 0, MyStr); MyStr.Format("本籍地=%s", ComboStr); dc.TextOut(0, 20, MyStr); MyStr.Format("ペット=%s", ListStr); dc.TextOut(0, 40, MyStr); }
WM_CLOSEメッセージが来たときの処理です。 CWnd::OnClose()をオーバーライドしているので最後に本家本元の OnClose()を呼んでいることに注意してください。void CMyWindow::OnClose() { int id; id = MessageBox("終了しますか", "終了の確認", MB_OKCANCEL | MB_ICONQUESTION); if (id == IDOK) CWnd::OnClose(); }
ダイアログボックスの初期設定です。単にリストボックスやらコンボボックスを 作っても項目は何も表示されません。ここでAddString()で文字列を追加します。BEGIN_MESSAGE_MAP(CMyDlg, CDialog) ON_COMMAND(IDC_CLEAR, OnClear) END_MESSAGE_MAP() BOOL CMyDlg::OnInitDialog() { CDialog::OnInitDialog(); CMyWindow *pParent; CEdit *pEdit; CComboBox *pCombo; CListBox *pList; pCombo = (CComboBox *)GetDlgItem(IDC_COMBO1); pCombo->AddString("北海道"); pCombo->AddString("本州"); pCombo->AddString("四国"); pCombo->AddString("九州"); pList = (CListBox *)GetDlgItem(IDC_LIST1); pList->AddString("猫"); pList->AddString("犬"); pList->AddString("ネズミ"); pList->AddString("鳥"); pList->AddString("ウサギ"); //前回の入力や設定を再現 pParent = (CMyWindow *)GetParent(); pEdit = (CEdit *)GetDlgItem(IDC_EDIT1); pEdit->SetWindowText(pParent->str); pCombo->SetCurSel(pCombo->FindStringExact(0, pParent->ComboStr)); pList->SetCurSel(pList->FindStringExact(0, pParent->ListStr)); return TRUE; }
コンボボックスに文字列を追加します。CComboBox::AddString int AddString( LPCTSTR lpszString );
リストボックスに文字列を追加します。 戻り値はどちらもリスト内での0から始まるインデックスを返します。CListBox::AddString int AddString( LPCTSTR lpszItem );
さて、文字列を追加したら前回の入力を表示した方が 親切です。前回の表示はCMyWindowのstr, ComboStr, ListStrに格納されて いるので、これを使います。 エジットコントロールの場合はそのまま使えばよいのですが リストボックスやコンボボックスの場合はその文字列のインデックスを 知らないといけないのでFindStringExact関数で調べています。 そして、インデックスがわかったらSetCurSel関数で表示します。
lpszFindに見つけたい文字列を指定します。CComboBox::FindStringExact int FindStringExact( int nIndexStart, LPCTSTR lpszFind ) const;
これも使い方は全く同じです。CListBox::FindStringExact int FindStringExact( int nIndexStart, LPCTSTR lpszFind ) const;
nSelectに選択させたいインデックス番号を指定します。 CListBox::SetCurSel()も同じです。CComboBox::SetCurSel int SetCurSel( int nSelect );
ダイアログボックスで「OK」ボタンが押されたときの処理です。 まず親のウィンドウのポインタを取得しておきます。これは、 親のメンバに直接文字列をコピーするので必要です。void CMyDlg::OnOK() { CEdit *pStr; CMyWindow *pParent; CListBox *pList; CComboBox *pCombo; int index; pParent = (CMyWindow *)GetParent(); pStr = (CEdit *)GetDlgItem(IDC_EDIT1); pStr->GetWindowText(pParent->str); pList = (CListBox *)GetDlgItem(IDC_LIST1); index = pList->GetCurSel(); pList->GetText(index, pParent->ListStr); pCombo = (CComboBox *)GetDlgItem(IDC_COMBO1); index = pCombo->GetCurSel(); pCombo->GetLBText(index, pParent->ComboStr); CDialog::OnOK(); }
コンボボックスの現在選択されている項目のインデックスを 返します。CComboBox::GetCurSel int GetCurSel( ) const;
リストボックスで現在選択されている項目のインデックスを 返します。CListBox::GetCurSel int GetCurSel( ) const;
リストボックスのnIndexで指定された文字列を取得します。 Cstringオブジェクトでも受け取ることができます。CListBox::GetText int GetText( int nIndex, LPTSTR lpszBuffer ) const; void GetText( int nIndex, CString& rString ) const;
注意すべき点はCComboBox::GetTextというのはないという点です。 かわりに、
を使います。使い方はリストボックスの時と同じです。CComboBox::GetLBText int GetLBText( int nIndex, LPTSTR lpszText ) const; void GetLBText( int nIndex, CString& rString ) const;
最後に本家本元のCDialog::OnOK()を呼んでダイアログボックスを 閉じます。
「指名欄クリア」ボタンを押したときの処理です。void CMyDlg::OnClear() { CEdit *pEdit; pEdit = (CEdit *)GetDlgItem(IDC_EDIT1); pEdit->SetWindowText(""); }
Update 16/May/1998 By Y.Kumei