ListView_Arrangeは、アイコン表示の時に再整列などの指示を与える。
ListView_Arrange マクロ (commctrl.h) - Win32 apps | Microsoft Learn
ListView_Arrange.rcで、
スタイルをLVS_ICONにする。
ListView_Arrange.cppで、
// DialogProc関数の定義 INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam){ // ダイアログの処理をするコールバック関数. // 変数の宣言. static HWND hEdit; static TCHAR *ptszBuf = NULL; static HIMAGELIST hLarge = NULL; static HBITMAP hBitmap1 = NULL; static HBITMAP hBitmap2 = NULL; // ダイアログのメッセージ処理 switch (uMsg){ // uMsgの内容で判断. // ダイアログの初期化時. case WM_INITDIALOG: // ダイアログの初期化時.(uMsgがWM_INITDIALOGの時.) // WM_INITDIALOGブロック { // 変数の宣言 LVCOLUMN column1; // 挿入するカラム情報(Name)を格納するLVCOLUMN構造体変数column1.. HWND hList; // リストビューのハンドルhList. // カラムNameの設定. column1.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; // このカラムには, 列の形式, 列の幅, テキスト, サブアイテムのインデックスをセットする. column1.fmt = LVCFMT_LEFT; // 左寄せ column1.cx = 100; // 幅100 column1.pszText = _T("Name"); // 項目名"Name" column1.iSubItem = 0; // サブアイテムのインデックスは0. // カラムの挿入. hList = GetDlgItem(hwndDlg, IDC_LIST1); // GetDlgItemでIDC_LIST1のハンドル取得. ListView_InsertColumn(hList, 0, &column1); // ListView_InsertColumnでcolumn1の内容のカラムを挿入. // イメージリストの作成. HINSTANCE hInstance = (HINSTANCE)GetWindowLong(hwndDlg, GWL_HINSTANCE); hLarge = ImageList_Create(32, 32, ILC_COLOR24, 2, 1); ListView_SetImageList(hList, hLarge, LVSIL_NORMAL); hBitmap1 = (HBITMAP)LoadImage(hInstance, _T("image1.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); hBitmap2 = (HBITMAP)LoadImage(hInstance, _T("image2.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); ImageList_Add(hLarge, hBitmap1, NULL); ImageList_Add(hLarge, hBitmap2, NULL); // LVITEM構造体変数nameに設定. LVITEM name = {0}; name.mask = LVIF_TEXT | LVIF_IMAGE; // 表示テキストと小さい画像をセット. name.iItem = 0; // 一番上から挿入. name.iSubItem = 0; name.pszText = _T("Taro"); // 表示テキストは"Taro". name.iImage = 0; ListView_InsertItem(hList, &name); // ListView_InsertItemでhListにnameを挿入. // LVITEM構造体変数nameに設定. ZeroMemory(&name, sizeof(name)); name.mask = LVIF_TEXT | LVIF_IMAGE; // 表示テキストと小さい画像をセット. name.iItem = 1; // 二番目から挿入. name.iSubItem = 0; name.pszText = _T("Jiro"); // 表示テキストは"Jiro". name.iImage = 1; ListView_InsertItem(hList, &name); // ListView_InsertItemでhListにnameを挿入. // LVITEM構造体変数nameに設定. ZeroMemory(&name, sizeof(name)); name.mask = LVIF_TEXT | LVIF_IMAGE; // 表示テキストと小さい画像をセット. name.iItem = 2; // 三番目から挿入. name.iSubItem = 0; name.pszText = _T("Saburo"); // 表示テキストは"Saburo". name.iImage = 0; ListView_InsertItem(hList, &name); // ListView_InsertItemでhListにnameを挿入. // LVITEM構造体変数nameに設定. ZeroMemory(&name, sizeof(name)); name.mask = LVIF_TEXT | LVIF_IMAGE; // 表示テキストと小さい画像をセット. name.iItem = 3; // 四番目から挿入. name.iSubItem = 0; name.pszText = _T("Shiro"); // 表示テキストは"Shiro". name.iImage = 1; ListView_InsertItem(hList, &name); // ListView_InsertItemでhListにnameを挿入. // LVITEM構造体変数nameに設定. ZeroMemory(&name, sizeof(name)); name.mask = LVIF_TEXT | LVIF_IMAGE; // 表示テキストと小さい画像をセット. name.iItem = 4; // 五番目から挿入. name.iSubItem = 0; name.pszText = _T("Goro"); // 表示テキストは"Goro". name.iImage = 0; ListView_InsertItem(hList, &name); // ListView_InsertItemでhListにnameを挿入. // TRUEを返す. return TRUE; // 処理できたのでTRUE. } // 抜ける. break; // breakで抜ける. // ダイアログが閉じられた時. case WM_CLOSE: // ダイアログが閉じられた時.(uMsgがWM_CLOSEの時.) // WM_CLOSEブロック { // ビットマップの破棄. if (hBitmap2 != NULL){ DeleteObject(hBitmap2); hBitmap2 = NULL; } if (hBitmap1 != NULL){ DeleteObject(hBitmap1); hBitmap1 = NULL; } // イメージリストの破棄. if (hLarge != NULL){ ImageList_Destroy(hLarge); hLarge = NULL; } // 終了処理. if (ptszBuf != NULL){ // バッファが残っている. delete[] ptszBuf; // deleteで解放. ptszBuf = NULL; // ポインタにNULLをセット. } // ダイアログを終了する. EndDialog(hwndDlg, IDOK); // EndDialogでダイアログを終了する. // TRUEを返す. return TRUE; // 処理できたのでTRUE. } // 抜ける. break; // breakで抜ける. // コモンコントロールから通知が来た時. case WM_NOTIFY: // WM_NOTIFYブロック { // 変数の宣言・初期化 HWND hList; // リストビューのハンドルhList. // リストビューのハンドルを取得. hList = GetDlgItem(hwndDlg, IDC_LIST1); // GetDlgItemでIDC_LIST1のハンドル取得. // リストビューの時. if ((int)wParam == IDC_LIST1){ // wParamがIDC_LIST1の時. LV_DISPINFO *lvi = (LV_DISPINFO *)lParam; // lParamをLV_DISPINFOのポインタに変換. switch (lvi->hdr.code){ // 通知コードごとに分ける. case LVN_BEGINLABELEDIT: // 編集開始. // デバッグ出力. OutputDebugString(_T("LVN_BEGINLABELEDIT\n")); // OutputDebugStringで"LVN_BEGINLABELEDIT"を出力. hEdit = ListView_GetEditControl(hList); // ListView_GetEditControlで編集する要素のエディットコントロールハンドルを取得. break; case LVN_ENDLABELEDIT: // 編集終了. // LVN_ENDLABELEDITブロック. { // デバッグ出力. OutputDebugString(_T("LVN_ENDLABELEDIT\n")); // OutputDebugStringで"LVN_ENDLABELEDIT"を出力. if (ptszBuf != NULL){ // バッファが残っている. delete[] ptszBuf; // deleteで解放. ptszBuf = NULL; // ポインタにNULLをセット. } int iLen = GetWindowTextLength(hEdit); // GetWindowTextLengthでテキストの長さを取得. ptszBuf = new TCHAR[iLen + 1]; // iLen + 1分のTCHAR配列確保. ZeroMemory(ptszBuf, sizeof(TCHAR) * (iLen + 1)); // ptszBufのクリア. GetWindowText(hEdit, ptszBuf, iLen + 1); // テキスト取得. ListView_SetItemText(hList, lvi->item.iItem, 0, ptszBuf); // ListView_SetItemTextでテキストをセット. OutputDebugString(ptszBuf); // OutputDebugStringでptszBufを出力. OutputDebugString(_T("\n")); // OutputDebugStringで改行を出力. delete[] ptszBuf; // deleteで解放. ptszBuf = NULL; // ポインタにNULLをセット. } break; default: // それ以外. break; } } } // 既定の処理へ向かう. break; // メニュー項目が選択されたり, ボタンなどのコントロールが押されたりして, コマンドが発生した時. case WM_COMMAND: // メニュー項目が選択されたり, ボタンなどのコントロールが押されたりして, コマンドが発生した時.(uMsgがWM_COMMANDの時.) // WM_COMMANDブロック { // どのコントロールかを判定する. switch (LOWORD(wParam)){ // LOWORD(wParam)でコントロールのリソースIDが取得できるので, その値で判定する. // Button1の時. case ID_BUTTON1: // ID_BUTTON1ブロック { // 変数の宣言・初期化. HWND hEditName; // Nameを入力するエディットボックスのハンドルhEditName. HWND hEditAddress; // Addressを入力するエディットボックスのハンドルhEditAddress. HWND hEditPhoneNumber; // PhoneNumberを入力するエディットボックスのハンドルhEditPhoneNumber. TCHAR tszName[64]; // 名前(長さ64) TCHAR tszAddress[128]; // 住所(長さ128) TCHAR tszPhoneNumber[32]; // 電話番号(長さ32) HWND hList; // リストビューのハンドルhList. LVITEM name = {0}; // 項目を格納するLVITEM構造体変数nameを0で初期化. LVITEM address = {0}; // 項目を格納するLVITEM構造体変数addressを0で初期化. LVITEM phonenumber = {0}; // 項目を格納するLVITEM構造体変数phonenumberを0で初期化. // エディットボックスの内容を取得. hEditName = GetDlgItem(hwndDlg, ID_EDIT_NAME); // GetDlgItemでNameを入力するエディットボックスのハンドル取得. GetWindowText(hEditName, tszName, 64); // GetWindowTextでエディットボックスの内容をtszNameに格納. hEditAddress = GetDlgItem(hwndDlg, ID_EDIT_ADDRESS); // GetDlgItemでAddressを入力するエディットボックスのハンドル取得. GetWindowText(hEditAddress, tszAddress, 128); // GetWindowTextでエディットボックスの内容をtszAddressに格納. hEditPhoneNumber = GetDlgItem(hwndDlg, ID_EDIT_PHONENUMBER); // GetDlgItemでPhoneNumberを入力するエディットボックスのハンドル取得. GetWindowText(hEditPhoneNumber, tszPhoneNumber, 32); // GetWindowTextでエディットボックスの内容をtszPhoneNumberに格納. // LVITEM構造体変数nameに設定. name.mask = LVIF_TEXT; // 表示テキストのみセット. name.iItem = 0; // 一番上から挿入. name.pszText = tszName; // 表示テキストはtszName. // nameの挿入. hList = GetDlgItem(hwndDlg, IDC_LIST1); // GetDlgItemでIDC_LIST1のハンドル取得. ListView_InsertItem(hList, &name); // ListView_InsertItemでhListにnameを挿入. // LVITEM構造体変数addressに設定. address.mask = LVIF_TEXT; // 表示テキストのみセット. address.iItem = 0; // 一番上のにセット. address.iSubItem = 1; // 0から数えて1番目にセット. address.pszText = tszAddress; // 表示テキストはtszAddress. // addressの挿入. ListView_SetItem(hList, &address); // ListView_SetItemでhListにaddressをセット. // LVITEM構造体変数phonenumberに設定. phonenumber.mask = LVIF_TEXT; // 表示テキストのみセット. phonenumber.iItem = 0; // 一番上のにセット. phonenumber.iSubItem = 2; // 0から数えて2番目にセット. phonenumber.pszText = tszPhoneNumber; // 表示テキストはtszPhoneNumber. // phonenumberの挿入. ListView_SetItem(hList, &phonenumber); // ListView_SetItemでhListにphonenumberをセット. // TRUEを返す. return TRUE; // 処理できたのでTRUE. } // 既定の処理へ向かう. break; // breakで抜ける. // Button2の時. case ID_BUTTON2: // ID_BUTTON2ブロック { // 変数の宣言・初期化 HWND hList; // リストビューのハンドルhList. int idx = -1; // 選択されている項目のインデックスを格納するint型変数idxを-1に初期化. TCHAR tszName[256]; // 選択行のNameを格納するtszName.(長さ256) TCHAR tszAddress[256]; // 選択行のAddressを格納するtszAddress.(長さ256) TCHAR tszPhoneNumber[256]; // 選択行のPhoneNumberを格納するtszPhoneNumber.(長さ256) HWND hEditName; // NameのエディットボックスのハンドルhEditName. HWND hEditAddress; // AddressのエディットボックスのハンドルhEditAddress. HWND hEditPhoneNumber; // PhoneNumberのエディットボックスのハンドルhEditPhoneNumber. // リストビューのハンドルを取得. hList = GetDlgItem(hwndDlg, IDC_LIST1); // GetDlgItemでIDC_LIST1のハンドル取得. // 選択されている行(最初の1つのみ)のインデックスを取得. if ((idx = ListView_GetNextItem(hList, idx, LVNI_SELECTED)) != -1){ // ListView_GetNextItemで選択項目のインデックス取得. // 選択されている行の各テキストを取得し, 表示. ListView_GetItemText(hList, idx, 0, tszName, 256); // ListView_GetItemTextでi行目の0列目のテキストをtszNameに格納. hEditName = GetDlgItem(hwndDlg, ID_EDIT_NAME); // GetDlgItemでID_EDIT_NAMEのハンドルを取得. SetWindowText(hEditName, tszName); // SetWindowTextでエディットボックスにセット. ListView_GetItemText(hList, idx, 1, tszAddress, 256); // ListView_GetItemTextでi行目の1列目のテキストをtszAddressに格納. hEditAddress = GetDlgItem(hwndDlg, ID_EDIT_ADDRESS); // GetDlgItemでID_EDIT_ADDRESSのハンドルを取得. SetWindowText(hEditAddress, tszAddress); // SetWindowTextでエディットボックスにセット. ListView_GetItemText(hList, idx, 2, tszPhoneNumber, 256); // ListView_GetItemTextでi行目の2列目のテキストをtszPhoneNumberに格納. hEditPhoneNumber = GetDlgItem(hwndDlg, ID_EDIT_PHONENUMBER); // GetDlgItemでID_EDIT_PHONENUMBERのハンドルを取得. SetWindowText(hEditPhoneNumber, tszPhoneNumber); // SetWindowTextでエディットボックスにセット. } // TRUEを返す. return TRUE; // 処理できたのでTRUE. } // 既定の処理へ向かう. break; // breakで抜ける. // Button3の時. case ID_BUTTON3: // ID_BUTTON3ブロック { // 変数の宣言・初期化 HWND hList; // リストビューのハンドルhList. int idx = -1; // 選択されている項目のインデックスを格納するint型変数idxを-1に初期化. // リストビューのハンドルを取得. hList = GetDlgItem(hwndDlg, IDC_LIST1); // GetDlgItemでIDC_LIST1のハンドル取得. // 選択されている行(最初の1つのみ)のインデックスを取得. if ((idx = ListView_GetNextItem(hList, idx, LVNI_SELECTED)) != -1){ // ListView_GetNextItemで選択項目のインデックス取得. // 選択されている行の削除. ListView_DeleteItem(hList, idx); // ListView_DeleteItemで選択行の削除. ListView_Arrange(hList, LVA_ALIGNLEFT); // ListView_Arrangeで左から整列. } } // 既定の処理へ向かう. break; // breakで抜ける. // 上記以外の時. default: // 既定の処理へ向かう. break; // breakで抜ける. } } // 抜ける. break; // breakで抜ける. // 上記以外の時. default: // 抜ける. break; // breakで抜ける. } // ここに来るときは処理できていない. return FALSE; // 処理できていないのでFALSE. }
これだと、

これを削除すると、

こうなる。
こうすると、

これを削除すると

こうなる。