前回までの話。
項目情報管理画面作成
今回は項目情報関連を。
まずメイン画面から「項目情報管理」を押すと現れる画面を作成します。
ユーザ情報管理画面と同じ感じですが、
一つの画面で「グループ」と「項目」の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を開いて、項目情報管理画面を開きます。
初期表示は

ちゃんとグループテーブルの内容が表示されています。
タブを変更して項目にセットすると

こちらもちゃんと取得できているようです。
今回は一発合格。
終わりに
今回は項目情報変更画面を作成しました。
次回はユーザ管理と同様、テーブル操作の画面と処理を作成します。
これって、ユーザ情報変更画面でもマップを使用したら
あのへんな取得結果を解消できないかな?
もしできそうなら、リストコントロール関連は全部マップ使った方がいいかも。
今回はここまで。

コメント