爲對話框程序添加工具條和狀態欄

爲對話框程序添加工具條和狀態欄
 
2002-07-30· ·信息產業部電子第二十二研究所青島分所郎銳··yesky

摘要:本文介紹了在對話框程序基礎上通過程序控制來動態添加工具條和狀態條的實現過程和方法。

  一、 引言

  對於不需要文檔/視圖結構支持的程序一般都採用對話框做爲程序的基礎框架。雖然在對話框程序上可以通過修改其屬性來添加系統菜單,但對比SDI和MDI程序的工具條和狀態欄未免使界面顯得簡單、單調。雖然在Visual Basic 中提供有獨立的工具條和狀態欄標準控件可以直接在對話框上使用,但Visual C++ 6.0所提供的26種基本Windows標準控件卻沒有將它們包含其中。因此要在對話框程序中實現工具條和狀態欄只能通過編程來動態實現。

  二、 工具條的實現過程

  MFC對於工具條和狀態欄分別提供了CToolBar和CStatusBar兩個基本類庫,但由於在實現時MFC對其做了過多的封裝,以至無法瞭解內部的一些核心技術。因此本文在實現過程中放棄了相對比較方便的CToolBar和CStatusBar類的使用,而是通過SDK(Software Developers Kit,軟件開發工具箱)式的WinAPI應用程序接口來實現的。在API函數中經常需要用到對話框的窗口句柄和當前的實例句柄,在SDK程序設計中以上兩個句柄可以直接從入口函數WinMain()中引出,而在MFC下也對其做了封裝,不能直接獲取。但MFC也爲其留有接口:CWnd窗口類提供的GetSafeHwnd()可以返回對話框的窗口句柄;函數AfxGetInstanceHandle()則可以獲取當前應用程序的實例句柄。由於對話框和狀態欄屬於程序界面的一部分,需要程序啓動時就顯示出來,因此獲取句柄的代碼和後面創建顯示工具條、狀態欄的全部代碼都應當放在對話框初始化消息WM_INITDIALOG的響應函數OnInitDialog()中進行:

HWND hDlg=GetSafeHwnd();
HINSTANCE hInstance=AfxGetInstanceHandle();

  對於待添加的工具條按鈕可以根據情況細分爲兩種:

  一種是Windows標準的一些工具條按鈕比如打開文件、打印預覽、在線幫助等等,這類工具條按鈕可以直接使用預定義好的按鈕圖標的ID號,在VC自帶的CommCtrl.h頭文件中有詳細定義;

  另一種就是用戶自己添加的工具欄按鈕,只能由用戶在資源視圖中爲其指定相應的圖標。不論是那種工具條按鈕的創建都是通過對TBBUTTON結構的設置來決定每一個工具條按鈕的狀態,對於第一個填充好的工具條按鈕可以用CreateToolbarEx()來直接將其加入到工具條上,並返回指向工具條的窗口句柄,而對於以後工具條按鈕的添加則只能通過向工具條發送TB_ADDBUTTONS消息來實現:

……
//填充工具條按鈕結構:
TBBUTTON ptoolbar[30]={{STD_HELP, //指定Windows的標準幫助圖標
MU_ONE, //工具條按鈕的ID
TBSTATE_ENABLED, //可用狀態
TBSTYLE_BUTTON, //指定創建一個可以下按的按鈕
0, //保留,由應用程序定義該參數意義
0}, //按鈕字串索引
//創建一個分割按鈕用的豎線
{0,0,TBSTATE_ENABLED,TBSTYLE_SEP,0,0}};

//在對話框上動態創建工具條,並添加工具條按鈕:
HWND hToolsWindow=::CreateToolbarEx(hDlg, //指定對話框爲父窗口,將工具條創建在對話框上
WS_CHILD|WS_VISIBLE|TBSTYLE_WRAPABLE|TBSTYLE_TOOLTIPS|
TBSTYLE_FLAT|CCS_ADJUSTABLE,//指定工具條的創建風格
IDB_TOOLBAR,//預定義的工具條資源ID
30,HINST_COMMCTRL, //包含圖片資源的可執行文件的實例句柄
IDB_STD_SMALL_COLOR,//圖片的資源ID
ptoolbar, //待添加的按鈕
2, //加入到工具條的按鈕的個數
0,0,0,0,sizeof(TBBUTTON));
……
//從IDR_TOOLBAR1資源中裝載按鈕圖標到對話框的工具條上
TBADDBITMAP tab;
tab.hInst=hInstance;
tab.nID=IDR_TOOLBAR1;
iBmp=::SendMessage(hToolsWindow,TB_ADDBITMAP,(WPARAM)3,(LPARAM)&tab);

  向工具條添加工具條按鈕的關鍵在於對TBBUTTON數據結構的填充,該數據結構也是在CommCtrl.h頭文件中定義的,原形爲:

typedef struct _TBBUTTON {
int iBitmap;
int idCommand;
BYTE fsState;
BYTE fsStyle;
DWORD dwData;
int iString;
} TBBUTTON, NEAR* PTBBUTTON, FAR* LPTBBUTTON;

  該結構的數據成員包含了處在工具條裏的按鈕的相關信息:成員iBitmap是從0開始記數的按鈕圖象的索引;idCommand標識了匹配的按鈕,當按鈕被按下產生WM_COMMAND消息的時候會用到該標識;fsState指定了按鈕的狀態標誌,可以是以下8種標誌的邏輯組合TBSTATE_CHECKED、TBSTATE_ELLIPSES、TBSTATE_ENABLED、TBSTATE_HIDDEN、TBSTATE_INDETERMINATE、TBSTATE_MARKED、TBSTATE_PRESSED、TBSTATE_WRAP。至於以上各標誌的具體含義在MSDN的在線幫助中有詳細說明;fsStyle成員指定了按鈕的風格;dwData是應用程序定義的值,通常爲0;iString爲從0開始技術的按鈕字串的索引。下面這段代碼用於向工具條添加自定義的工具條按鈕:

TBBUTTON tb;
tb.iBitmap=iBmp+0;
tb.idCommand=MU_TWO;
tb.fsState=TBSTATE_ENABLED;
tb.fsStyle=TBSTYLE_BUTTON;
tb.dwData=0;
tb.iString=0;

  完成對TBBUTTON結構的設置後可以通過窗口句柄hToolsWindow向工具條發送TB_ADDBUTTONS消息來添加按鈕到工具條,如想添加按鈕之間的分割條,只需將TBBUTTON結構的fsStyle成員變量取值爲TBSTYLE_SEP即可:

::SendMessage(hToolsWindow,TB_ADDBUTTONS,(WPARAM)1,(LPARAM)&tb);

  三、 狀態欄的實現

  狀態欄的實現與工具條的實現相比非常簡單,只需在CreateStatusWindow()函數中對其參數進行設置即可實現:

HWND hStatusWindow=CreateStatusWindow(WS_CHILD|WS_VISIBLE|WS_BORDER,
TEXT("狀態欄"),//顯示在狀態欄上的信息
hDlg, //父窗口句柄
IDS_STATUS); //預定義的資源ID

  此時創建的狀態欄只是一個位於對話框底部的長條,如需要將其分割爲幾部分可以在數組中設定好分割點的X座標,然後通過向狀態欄發送SB_SETPARTS消息即可,該消息的wParam參數指定了要將狀態欄分割爲幾部分,lParam參數指定了各分割點的座標值:

int pint[4]={110,250,300,-1};//110,250,300設定間隔
::SendMessage(hStatusWindow,SB_SETPARTS,4,(LPARAM)pint);

  如需向分割後的狀態欄內填寫信息,可以通過hStatusWindow向狀態條發送消息SB_SETTEXT來完成,該消息的兩個參數分別用來標識在第幾個窗格顯示和待顯示的信息內容:

::SendMessage(hStatusWindow,SB_SETTEXT,1,(LPARAM)TEXT("信息一"));
……

  小結:本文以SDK的方式實現了在MFC對話框程序下工具條和狀態欄的動態添加,使普通的對話框程序也可以象SDI和MDI程序一樣擁有自定義風格的工具條和狀態欄。全部實現過程的重點是在對相關結構的設置和消息的發送以及控件的動態創建。至於本文所涉及到的結構和函數的詳細內容請參閱Microsoft 的MSDN Library 6.0。本文所述程序在Windows 98下,由Microsoft Visual C++ 6.0編譯通過。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章