首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ Builder 實作開啟檔案對話方塊預設大圖示檢視模式

     編輯:關於C++

預設情況下,TOpenDialog 的檔案清單採用「清單」檢視。若希望對話方塊一開啟即顯示「大圖示」模式,需在對話方塊顯示前找到內部的 SysListView32 控制項並修改其視窗樣式。本文提供兩種做法:子類化攔截 WM_UPDATEUISTATE、以及發送 WM_COMMAND 切換檢視模式。

方法一:子類化對話方塊攔截訊息

在 OnShow 事件設定子類化程序,OnClose 還原:

FARPROC OldDlgOpenProc = NULL;

static LRESULT CALLBACK NewDlgOpenProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_UPDATEUISTATE) {
        HWND hShell = FindWindowEx(GetParent(hWnd), NULL, L"SHELLDLL_DefView", NULL);
        HWND hListView = FindWindowEx(hShell, NULL, L"SysListView32", NULL);
        if (hListView) {
            SetWindowLong(hListView, GWL_STYLE,
                (GetWindowLong(hListView, GWL_STYLE) & 0xFFFFFFF0) | LVS_ICON);
        }
    }
    return CallWindowProc((WNDPROC)OldDlgOpenProc, hWnd, uMsg, wParam, lParam);
}

void __fastcall TForm1::OpenDialogShow(TObject *Sender)
{
    OldDlgOpenProc = (FARPROC)SetWindowLong(OpenDialog1->Handle, GWL_WNDPROC, (LONG)NewDlgOpenProc);
}

void __fastcall TForm1::OpenDialogClose(TObject *Sender)
{
    SetWindowLong(OpenDialog1->Handle, GWL_WNDPROC, (LONG)OldDlgOpenProc);
}

關鍵點:LVS_ICON (0x0000) 為大圖示樣式,先以 & 0xFFFFFFF0 清除低 4 位元原有檢視樣式位,再 | LVS_ICON 設定新模式。

方法二:發送 WM_COMMAND 切換 Shell 檢視模式(更簡潔)

Shell 控制項支援特定命令 ID 切換檢視:

const DWORD FCIDM_SHVIEW_LARGEICON = 28713; // 大圖示
const DWORD FCIDM_SHVIEW_SMALLICON = 28714; // 小圖示
const DWORD FCIDM_SHVIEW_LIST      = 28715; // 清單
const DWORD FCIDM_SHVIEW_REPORT    = 28716; // 詳細資料
const DWORD FCIDM_SHVIEW_THUMBNAIL = 28717; // 縮圖
const DWORD FCIDM_SHVIEW_TILE      = 28718; // 並排

實作步驟

  1. 表單覆寫 WndProc,處理自訂訊息 WM_USER+1。
  2. OnShow 事件發送自訂訊息給表單,WParam 傳遞對話方塊父視窗控制代碼。
  3. 自訂訊息處理中:FindWindowEx 找到 SHELLDLL_DefView,發送 WM_COMMAND 配合命令 ID。
void __fastcall TForm1::WndProc(TMessage &Msg)
{
    if (Msg.Msg == WM_USER + 1) {
        HWND hDlg = (HWND)Msg.WParam;
        HWND hCtrl = FindWindowEx(hDlg, NULL, L"SHELLDLL_DefView", NULL);
        if (hCtrl)
            SendMessage(hCtrl, WM_COMMAND, FCIDM_SHVIEW_LARGEICON, 0);
    }
    TForm::WndProc(Msg);
}

void __fastcall TForm1::dlgOpenOnShow(TObject *Sender)
{
    HWND hDlg = GetParent(((TOpenDialog*)Sender)->Handle);
    PostMessage(Handle, WM_USER + 1, (WPARAM)hDlg, 0);
}

完整測試程式碼

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    OpenDialog1->Execute();
}

適用版本與注意事項

  • 測試環境:C++ Builder 5/6,Windows XP/7/10。
  • Vista 之後對話方塊架構改為 IFileDialog,傳統 TOpenDialog 仍相容但內部結構可能不同,若失效請改用 IFileDialog::SetOptions(FOS_FORCEFILESYSTEM | ...) 搭配 IFileDialogCustomize。
  • 命令 ID 為 Shell 內部定義,微軟未公開文件化,未來版本可能變更。

結語

方法二僅需幾行程式碼即可達成預設大圖示檢視,維護性優於子類化做法。開發者可依專案相容性需求選擇適當方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved