MFCで物品購入承認システム作成 8

前回までの話。

MFCで物品購入承認システム作成 1

MFCで物品購入承認システム作成 2

MFCで物品購入承認システム作成 3

MFCで物品購入承認システム作成 4

MFCで物品購入承認システム作成 5

MFCで物品購入承認システム作成 6

MFCで物品購入承認システム作成 7

項目情報管理画面作成

今回は項目情報関連を。

まずメイン画面から「項目情報管理」を押すと現れる画面を作成します。

ユーザ情報管理画面と同じ感じですが、
一つの画面で「グループ」と「項目」の2種類を表示させたいため、
タブで切り替えを行います。

毎度同じく、リソースビューからDialogを右クリック、リソースの追加から新規作成を行います。

ダイアログIDはIDD_DIALOG_KOUMOKU_MANAGE。
ここにきていきなり日本語KOUMOKUですが、
気にしない気にしない(ヾノ・∀・`)。

必要なのはタブコントロールと、表示用のリストコントロール、
後はユーザ情報管理画面と同じくテーブル操作する画面を呼び出すボタンですね。

では作成。

タブは画面いっぱいに広げました。
リストコントロールは例のごとく、プロパティからビューをレポートにします。
右下、実はキャンセルボタンはあります。
「戻る」として流用します。
上の変更ボタンのキャプションがButton1のままですが、
これは処理で対応させます。

配置やIDはこんな感じ。

IDD_DIALOG_KOUMOKU_MANAGE DIALOGEX 0, 0, 232, 160
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    PUSHBUTTON      "戻る",IDCANCEL,160,137,50,14
    CONTROL         "",IDC_TAB_GROUP_KOUMOKU,"SysTabControl32",0x0,7,7,218,146
    CONTROL         "",IDC_LIST_GROUP_KOUMOKU,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,20,45,190,90
    PUSHBUTTON      "Button1",IDC_BUTTON_KOUMOKUMG_CHG,20,25,50,14
END

最後に、コントロールをダブルクリックして
MFCクラスを新規作成します。

今回のクラス名やファイル名は…

OKを押すとファイルが追加されます。

今のうちに、クラスビューからCKoumokuManagerを選択し、
プロパティのオーバーライドからOnInitDialogをAddしてクラス作成完了。

項目情報表示処理作成

リソースビューから先ほど作ったダイアログ(IDD_DIALOG_KOUMOKU_MANAGE)を表示します。
キャプションがButton1になっているIDC_BUTTON_KOUMOKUMG_CHGのボタンと、
タブコントロールをダブルクリックして、押下時に呼ばれる関数を追加しておきます。

上記IDだと以下のような関数が追加されるはず。

void CKoumokuManager::OnBnClickedButtonKoumokumgChg()
{
	// TODO: ここにコントロール通知ハンドラー コードを追加します。
}

void CKoumokuManager::OnTcnSelchangeTabGroupKoumoku(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: ここにコントロール通知ハンドラー コードを追加します。
	*pResult = 0;
}

さて、KoumokuManager.hを開き、変数や関数を追加しておきます。

private:
	CTabCtrl m_ctrlTabGroupKoumoku;	// グループか項目化を切り替えるタブ
	CListCtrl m_ctrlListKoumoku;	// リストコントロール
	std::unordered_map<int, CString> m_MapGroup;			// グループマップ
	std::unordered_map<int, KoumokuValue> m_MapKoumoku;		// 項目マップ
private:
	void ListUpdate();				// リスト再表示関数

public:
	void GetGroupMap(std::unordered_map<int, CString> MapGroup);			// グループマップ取得
	void GetKoumokuMap(std::unordered_map<int, KoumokuValue> MapKoumoku);	// 項目マップ取得
	std::unordered_map<int, CString> SetGroupMap();							// グループマップ設定
	std::unordered_map<int, KoumokuValue> SetKoumokuMap();					// 項目マップ設定

マップはメイン画面との受け渡しを行います。

KoumokuManager.cppを開き、処理を書いていきます。

今回、この画面ではSQL操作を行うクラスを呼び出す必要はないので、
MySQLManager.hをインクルードしません。

DoDataExchangeに、メンバ変数とIDを関連付け。

void CKoumokuManager::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_TAB_GROUP_KOUMOKU, m_ctrlTabGroupKoumoku);
	DDX_Control(pDX, IDC_LIST_GROUP_KOUMOKU, m_ctrlListKoumoku);
}

OnInitDialogで初期化処理を書きます。

BOOL CKoumokuManager::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO: ここに初期化を追加してください
	// タブコントロールに新しいタブ追加
	m_ctrlTabGroupKoumoku.InsertItem(0, _T("グループ"));
	m_ctrlTabGroupKoumoku.InsertItem(1, _T("項目"));

	// グループに初期表示セット
	m_ctrlTabGroupKoumoku.SetCurSel(0);

	// リスト表示
	ListUpdate();

	//ボタンキャプション
	CButton* pButton = (CButton*)GetDlgItem(IDC_BUTTON_KOUMOKUMG_CHG);
	pButton->SetWindowText(_T("グループ管理"));

	SetWindowText(_T("物品リスト"));

	UpdateData(FALSE);

	return TRUE;  // return TRUE unless you set the focus to a control
	// 例外 : OCX プロパティ ページは必ず FALSE を返します。
}

ゲット関数セット関数は1行で済むので、一気に。

/**
 * @fn
 * @brief	グループマップゲット関数
 * @param	std::unordered_map<int, CString>	グループマップ
 * @return	なし
 */
void CKoumokuManager::GetGroupMap(std::unordered_map<int, CString> MapGroup)
{
	m_MapGroup = MapGroup;
}

/**
 * @fn
 * @brief	項目マップゲット関数
 * @param	std::unordered_map<int, KoumokuValue>	項目マップ
 * @return	なし
 */
void CKoumokuManager::GetKoumokuMap(std::unordered_map<int, KoumokuValue> MapKoumoku)
{
	m_MapKoumoku = MapKoumoku;
}

/**
 * @fn
 * @brief	グループマップセット関数
 * @param	なし
 * @return	std::unordered_map<int, CString>	グループマップ
 */
std::unordered_map<int, CString> CKoumokuManager::SetGroupMap()
{
	return m_MapGroup;
}

/**
 * @fn
 * @brief	項目マップセット関数
 * @param	なし
 * @return	std::unordered_map<int, KoumokuValue>	項目マップ
 */
std::unordered_map<int, KoumokuValue> CKoumokuManager::SetKoumokuMap()
{
	return m_MapKoumoku;
}

続いて、タブが切り替わった時に、
グループのリストか項目のリストかを切り替えるので、
OnTcnSelchangeTabGroupKoumoku内の処理を書きます。
ついでに、ボタンのキャプションも変えておきます。

/**
 * @fn
 * @brief	タブ変更時
 * @param	あるけど特記必要なし
 * @return	なし
 */
void CKoumokuManager::OnTcnSelchangeTabGroupKoumoku(NMHDR* pNMHDR, LRESULT* pResult)
{
	// TODO: ここにコントロール通知ハンドラー コードを追加します。
	*pResult = 0;

	int iTabIndex = m_ctrlTabGroupKoumoku.GetCurSel();	// タブ位置を取得
	CButton* pButton = (CButton*)GetDlgItem(IDC_BUTTON_KOUMOKUMG_CHG);

	if (iTabIndex == 0)
	{
		// グループタブが選択されている
		pButton->SetWindowText(_T("グループ管理"));
	}
	else
	{
		// 項目タブが選択されている
		pButton->SetWindowText(_T("項目管理"));
	}

	//リスト再表示
	ListUpdate();
}

最後に、リスト再表示関数の中身を書きます。
今回、タブが切り替わった瞬間にも
グループのテーブルか項目のテーブルかの表示も切り替えるので、
そもそもリストの列数もそのたびに切り替えます。

少し長いですが、やってることは単純。

/**
 * @fn
 * @brief	リスト内再表示関数
 * @param	なし
 * @return	なし
 */
void CKoumokuManager::ListUpdate()
{
	// すべてのアイテム(行)を削除
	m_ctrlListKoumoku.DeleteAllItems();

	// 既存の列を削除
	int columnCount = m_ctrlListKoumoku.GetHeaderCtrl()->GetItemCount();
	for (int i = columnCount - 1; i >= 0; i--)
	{
		m_ctrlListKoumoku.DeleteColumn(i);
	}

	int iTabIndex = m_ctrlTabGroupKoumoku.GetCurSel();	// タブ位置を取得

	int iRow = 0;	// 行番号
	LVITEM lvItem{};
	lvItem.mask = LVIF_TEXT;

	if (iTabIndex == 0)
	{
		// グループタブ
		// 新しい列を追加
		m_ctrlListKoumoku.InsertColumn(0, _T("ID"), LVCFMT_LEFT, 50);
		m_ctrlListKoumoku.InsertColumn(1, _T("グループ名"), LVCFMT_LEFT, 200);

		for (const auto& pair : m_MapGroup)
		{
			lvItem.iItem = iRow;	// 行番号

			// ID列
			lvItem.iSubItem = 0;
			CString strTemp;
			strTemp.Format(_T("%d"), pair.first);
			lvItem.pszText = strTemp.GetBuffer();
			m_ctrlListKoumoku.InsertItem(&lvItem);

			// 名称列
			lvItem.iSubItem = 1;
			strTemp = pair.second;
			lvItem.pszText = strTemp.GetBuffer();
			m_ctrlListKoumoku.SetItem(&lvItem);

			iRow++;
		}
	}
	else
	{
		// 項目タブ
		// 新しい列を追加
		m_ctrlListKoumoku.InsertColumn(0, _T("ID"), LVCFMT_LEFT, 50);
		m_ctrlListKoumoku.InsertColumn(1, _T("項目名"), LVCFMT_LEFT, 200);
		m_ctrlListKoumoku.InsertColumn(2, _T("グループID"), LVCFMT_LEFT, 100);
		m_ctrlListKoumoku.InsertColumn(3, _T("値段"), LVCFMT_LEFT, 150);

		for (const auto& pair : m_MapKoumoku)
		{
			const KoumokuValue& value = pair.second;

			lvItem.iItem = iRow;	// 行番号

			// ID列
			lvItem.iSubItem = 0;
			CString strTemp;
			strTemp.Format(_T("%d"), pair.first);
			lvItem.pszText = strTemp.GetBuffer();
			m_ctrlListKoumoku.InsertItem(&lvItem);

			// 名称列
			lvItem.iSubItem = 1;
			strTemp = pair.second.strKoumokuName;
			lvItem.pszText = strTemp.GetBuffer();
			m_ctrlListKoumoku.SetItem(&lvItem);

			//グループID列
			lvItem.iSubItem = 2;
			strTemp.Format(_T("%d"), pair.second.iGroupID);
			lvItem.pszText = strTemp.GetBuffer();
			m_ctrlListKoumoku.SetItem(&lvItem);

			//グループID列
			lvItem.iSubItem = 3;
			strTemp = pair.second.strKoumokuPrice;
			lvItem.pszText = strTemp.GetBuffer();
			m_ctrlListKoumoku.SetItem(&lvItem);

			iRow++;
		}
	}
}
  • ~17行目:リスト内全削除。
  • 25~51行目:グループタブが選択されている場合は
    グループマップから表示させる。
  • 54~95行目:項目タブが選択されている場合は
    項目マップから表示させる。

これで、このダイアログの処理は終わりました。

最後に、このダイアログを表示させる準備を。

SuppluRequestManagerDlg.cppを開きます。

まずはいつも通り、ヘッダーのインクルード。

#include "KoumokuManager.h"

「項目情報管理」ボタンが押下された時に呼ばれる関数内で、
ダイアログを呼び出す処理を。

void CSupplyRequestManagerDlg::OnBnClickedButtonMainItemlist()
{
	// TODO: ここにコントロール通知ハンドラー コードを追加します。
	CKoumokuManager dlgKoumokuManage;
	dlgKoumokuManage.GetGroupMap(m_MapGroup);		// グループマップを渡す
	dlgKoumokuManage.GetKoumokuMap(m_MapKoumoku);	// 項目マップを渡す
	dlgKoumokuManage.DoModal();
}

マップを渡すゲット関数を使って、項目情報管理画面へ渡します。
セット関数は次回使用するので、ここの処理は次回もう少し変わってきます。
今回はここまでで大丈夫です。

これでビルド。

動作確認

exeを開いて、項目情報管理画面を開きます。
初期表示は

ちゃんとグループテーブルの内容が表示されています。

タブを変更して項目にセットすると

こちらもちゃんと取得できているようです。
今回は一発合格。

終わりに

今回は項目情報変更画面を作成しました。

次回はユーザ管理と同様、テーブル操作の画面と処理を作成します。

これって、ユーザ情報変更画面でもマップを使用したら
あのへんな取得結果を解消できないかな?
もしできそうなら、リストコントロール関連は全部マップ使った方がいいかも。

今回はここまで。

MFCで物品購入承認システム作成 9
前回までの話。MFCで物品購入承認システム作成 1MFCで物品購入承認システム作成 2MFCで物品購入承認システム作成 3MFCで物品購入承認システム作成 4MFCで物品購入承認システム作成 5MFCで物品購入承認システム作成 6MFCで物...

コメント

タイトルとURLをコピーしました