程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 讓你的軟件界面更漂亮(3)

讓你的軟件界面更漂亮(3)

編輯:關於VC++

實現令人滿意的風格統一的軟件界面確實很難, 象網友提到的MessageBox、FileDialog、FontDialog、目錄選擇對話框等MFC內部甚至系統DLL內的對話框,要想讓它變臉可不容易。有人說HOOK技術可以,HOOK技術確實可以,HOOK可以說是無孔不入,但HOOK的使用效率卻是令人難以滿意的,從目前大多數采HOOK技術的換膚軟件使用情況來看,完全可以證明這一點。今天我們將討論另外一技術來實現FileDialog的變臉,這種技術叫替換窗口過程法(注:本人杜撰)。

窗口過程函數是大多窗口都有的,它處理窗口中(包括子窗口)的每一個事件,替換窗口過程法與HOOK技術比起來孰強誰弱是很顯然的,因為同一個HOOK只能攔截一個事件,處理起來相當費時,HOOK也有它的優勢,但不是本文要討論的。這裡先讓大家眼見為實,請看下圖:

一、原理說明:

替換對話框的窗口過程要用到這個函數SetWindowLong()其原型如下:

LONG SetWindowLong(HWND hWnd, int nIndex , long dwLongNewProc)
hWnd為指定窗口的句柄,
nIndex 為 GWL_WNDPROC時才可設定新的窗口過程
dwLongNewProc 為指定新的窗口過程函數地址

反回值為一個long的數值,此值為舊的窗口過程函數地址。

如果要替換某個窗口的窗口過程函數,首先要想法弄到它的窗口的句柄,當然還得有窗口過程。

二、CFileDialog文件對話框界面設計

a. 從CFileDialog派生類CMyFileDialog;

b. 添加Protected 型虛成員函數:OnInitDone();

此函是實際上是CFileDialog一個虛函數,它在文件對話框創後建後被調用,它給我們留下了一個入口,因些重載現實替換其窗口過程函數;

c. 添加成員函數MyWindowProcNew()

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

在這函數實現的時候你可大顯身手,處理得好不好決定你是否能變臉成功。 d. 實現代碼及說明如下:

WNDPROC m_MyWndProc; //定義全局變量保存舊的窗口過程函數地址
void CMyFileDialog::OnInitDone()
{
  CWnd* pDialog = GetParent();
  m_MyWndProc=(WNDPROC)SetWindowLong(pDialog->m_hWnd,GWL_WNDPROC,(long)MyWindowProcNew);
}
LRESULT CALLBACK CMyFileDialog::MyWindowProcNew(HWND hwnd,
                        UINT message,
                        WPARAM wParam,
                        LPARAM lParam)
{
  switch (message)
  {
  case WM_NOTIFY:
  case WM_MOUSEMOVE:
  case WM_MOVE:
    break;
  case WM_NCACTIVATE:
    break;
  case WM_NCPAINT:
    break;
  case WM_NCMOUSEMOVE:
    break;
  case WM_PAINT:
    break;
  case WM_COMMAND:
    break;
  case WM_SIZE:
    break;
  case WM_XX:
  default:
    break;  
  }
  //這時要恢復調用舊的窗口函數,當然必時可要忽略它
  return CallWindowProc(m_MyWndProc, hwnd, message, wParam, lParam);
}

這個函數CallWindowProc()用來恢調用復舊窗口過程函數,當然這並不意味取消了新的窗口過程。你也可跳過它不去執行,那為什要恢復舊的窗口過程函數?因為舊的窗口過程函數它處理了太多的事件,而新窗口過程函數只處理我們關心的事件,如果你樂意的話你完全可不要調用舊的窗口過程函數,那可是要付出大的代價的。具體細節請大家去實現,可參“讓你的軟件界面更漂亮(一)”。

三、CMyFileDialog的用法

我把CMyFileDialog寫成一個DLL,有Debug和Release兩個版,請用時分別選擇 a.先把.lib .dll .h 文件持拷到工程目錄。在要使用處加如代碼:

#include "MyFileDialg.h"
#pragam comment(lib,"user.lib")

b.顯示文件對話框:

CMyFileDialog MyFileDlg(TRUE, 1, _T("對話框標題"));
  MyFileDlg.DoModal();
  CString FileName = MyFileDlg.GetPathName()
  FileName是反回的結果

c. CMyFileDialog有一個超值的功能,不知有沒有從上圖看出來?它能夠用來代替 SHBrowseForFoler 作為目錄選擇對話框。這也是我寫CMyFileDialog的初終。構造函數第一個參數和CfileDialg 一樣,第二個參數為TRUE時可作為目錄選擇 對話框, 此時第一個參數可BOOL的任意值建議設為TRUE,第三個參數為對話框標題,如為NULL則顯示默認標題,其它參數和CFileDialog一樣。

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved