ListView_Arrange

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.

}

これだと、

これを削除すると、
これを削除すると、

これを削除すると、

こうなる。
こうなる。

こうなる。

こうすると、

これを削除すると
これを削除すると

これを削除すると

こうなる
こうなる

こうなる。

Sample/winapi/ListView_Arrange/ListView_Arrange/src/ListView_Arrange at master · bg1bgst333/Sample · GitHub