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

替換視窗程序實作 CFileDialog 介面美化(三)

     編輯:關於VC++

MessageBox、FileDialog、FontDialog 等系統對話框美化向來困難。Hook 技術雖可行但效率低。本文介紹「替換視窗程序法」:攔截對話框建立後的 OnInitDone 虛函式,以 SetWindowLong(GWL_WNDPROC) 替換視窗程序,實現檔案對話框換膚,並支援目錄選擇模式。

核心原理

LONG SetWindowLong(HWND hWnd, int nIndex, long dwLongNewProc);
// nIndex = GWL_WNDPROC 時設定新視窗程序
// 回傳值為舊視窗程序位址

實作步驟

1. 繼承 CFileDialog 建立 CMyFileDialog

2. 加入 Protected 虛函式 OnInitDone()

此為 CFileDialog 內部虛函式,對話框建立後自動呼叫,作為替換視窗程序的切入點。

3. 定義新視窗程序

static LRESULT CALLBACK WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

4. 實作替換邏輯

WNDPROC m_MyWndProc;  // 全域/成員變數保存舊程序位址

void CMyFileDialog::OnInitDone()
{
    CWnd* pDialog = GetParent();
    m_MyWndProc = (WNDPROC)SetWindowLong(pDialog->m_hWnd, GWL_WNDPROC, (long)WindowProcNew);
}

LRESULT CALLBACK CMyFileDialog::WindowProcNew(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_NOTIFY: case WM_MOUSEMOVE: case WM_MOVE:
    case WM_NCACTIVATE: case WM_NCPAINT: case WM_NCMOUSEMOVE:
    case WM_PAINT: case WM_COMMAND: case WM_SIZE:
        // 此處加入自訂繪製/處理代碼
        break;
    default: break;
    }
    // 呼叫舊視窗程序處理其餘訊息
    return CallWindowProc(m_MyWndProc, hwnd, message, wParam, lParam);
}

使用方式

編譯為 DLL(含 Debug/Release 版),專案加入 .lib .dll .h:

#include "MyFileDialog.h"
#pragma comment(lib, "user.lib")

// 開啟檔案對話框
CMyFileDialog dlg(TRUE, 1, _T("對話框標題"));
dlg.DoModal();
CString path = dlg.GetPathName();

// 目錄選擇模式:第二參數 TRUE
CMyFileDialog dirDlg(TRUE, TRUE, _T("選擇目錄"));
dirDlg.DoModal();

超值功能:替代 SHBrowseForFolder

建構子第二參數為 TRUE 時即為目錄選擇模式,解決 MFC 目錄選擇對話框難美化的痛點。

詳細原始碼請下載本文附帶範例專案。

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