一、前言
對話框是使用VC編程時最常用的形式之一,然而VC 6.0對程序運行時控件布局的支持力度不夠,當對話框改變大小時,要想對話框上的控件的行為相應的發生變化需要添加代碼來控制, 最可恨的是每次為支持這個必須寫類似的"無意義"的代碼。
一次見到有人用一套宏實現了對話框控件大小和位置隨對話框大小改變而改變,但不能產生類似單文檔程序的分割條效果。
於是我想寫自己的布局管理器,依照功能定名為DynamicLayout(動態布局)。
二、效果
也許說了半天大家不明白是怎麼回事,那先貼幾張程序同一次運行時的截圖吧,請留意圖片之間的區別:
圖1VC6.0對話框程序原始運行效果
圖2在1的基礎上加入DynamicLayout管理
圖3在2的基礎上改變對話框大小
圖4 在3基礎上將分割條A移動到最左
圖5正在移動中的分隔條C(截圖時光標被隱藏)
圖6程序運行時的一種布局
三、使用
要實現普通對話框的DynamicLayout支持很簡單,首先在對話框類裡聲明一個CDynamicLayout類對象做成員變量;然後在對話框的OnInitDialog()函數裡調用接口將對話框控件注冊到CDynamicLayout對象;再重載對話框類的虛函數WindowProc(...),在該函數裡調用CDynamicLayout接口FilterDynamicLayoutMessage(...)即可。當然如果用動態庫的方式使用DynamicLayout,還須對VC工程做一些設置。 如上圖1所示對話框,實現圖2、3、4、5、6效果需要添加如下代碼:
1.對話框頭文件
#include"DynamicLayoutExport.h"//包含DynamicLayout頭文件
2.對話框CPP文件
/////////////////////////////////////////////////////////////////////////////
//CDynamicLayoutTestDlgdialog
classCDynamicLayoutTestDlg:publicCDialog
{
......
private:
DynamicLayout::CDynamicLayoutm_DLayout;//聲明動態布局對象
};
BOOLCDynamicLayoutTestDlg::OnInitDialog()
{
......
//TODO:Addextrainitializationhere
m_DLayout.InitLayout(this);
m_DLayout.SetDialogMaxSize(800,600);//限制對話框最大800*600
m_DLayout.SetDialogMinSize(200,100);//限制最小200*100
m_DLayout.AddPanel("上","",1,1,1,1);//添加一個Panel到對話框,參數1、1、1、1表示控件邊框上下左右分別與父布局對應邊框鎖定
m_DLayout.AddPanel("下","",0,1,1,1);
m_DLayout.AddPanel("上右","上",1,1,1,1);//添加Panel到Panel("上")內
m_DLayout.AddControl(IDC_LIST_LIST,"上右",1,1,1,1);
m_DLayout.AddPanel("上右下","上右",0,1,1,0);
m_DLayout.AddControl(IDC_BTN_MODAL,"上右下",1,1,1,0);
m_DLayout.AddControl(IDC_BTN_MODALNESS,"上右下",1,1,1,0);
m_DLayout.AddControl(IDOK,"上右下",1,1,1,0);
m_DLayout.AddPanel("上左","上",1,1,1,0);
m_DLayout.AddControl(IDC_TREE1,"上左",1,1,1,1);
m_DLayout.AddPanel("下左","下",1,1,1,0);
m_DLayout.AddControl(IDC_LIST2,"下左",1,1,1,1);
m_DLayout.AddPanel("下右","下",1,1,1,1);
m_DLayout.AddControl(IDC_EDIT1,"下右",1,1,1,1);
m_DLayout.AddControl(IDC_STATIC_COMMAND,"下右",1,0,1,0);
m_DLayout.AddControl(IDC_EDIT2,"下右",1,0,1,1);
m_DLayout.SetBkColor("上", RGB(160,160,255));//指定Panel的背景顏色
m_DLayout.SetBkColor("上右", RGB(128,128,255));
m_DLayout.SetBkColor("上右下",RGB(128,255,128));
m_DLayout.ShowPanel("",TRUE);//顯示Panel(見圖2)
m_DLayout.SetSplit(""); //設置分割條B(參看圖4)
m_DLayout.SetSplit("上"); //設置分割條A
m_DLayout.SetSplit("下");//設置分割條C
//////////////////////////////////////////////////////////////////////////
returnTRUE; //returnTRUE unlessyousetthefocustoacontrol
}
LRESULTCDynamicLayoutTestDlg::WindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)
{
//TODO:Addyourspecializedcodehereand/orcallthebaseclass
m_DLayout.FilterDynamicLayoutMessage(message,wParam,lParam);//讓CDynamicLayout對象參與對話框消息處理
returnCDialog::WindowProc(message,wParam,lParam);
}
四、結束語
程序構思仿制了微軟.net平台的布局方案,特別是Panel的概念,用過.net的朋友一定很熟悉。不過我只實現了幾個簡單的功能,文章名取得有點大,請勿見笑。
DynamicLayout工程和測試工程都是在VC6.0下調試通過的,如有問題歡迎指正。