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

VC 6.0 對話框動態佈局解決方案:DynamicLayout 實作指南

     編輯:關於VC++

前言

在 VC 6.0 開發中,對話框是最常用的 UI 形式之一。然而,VC 6.0 對執行期控制項佈局的支援極為有限:當使用者調整對話框大小,控制項不會自動適應,開發者必須手寫大量重複、枯燥的代碼來處理位置與大小的變化。這不僅增加維護成本,也讓程式碼顯得雜亂無章。

曾見有人利用巨集實現控制項隨對話框縮放,但缺乏類似單一文件介面(SDI)分割條的拖曳調整效果。為此,我設計並實作了一套完整的佈局管理器——DynamicLayout(動態佈局),支援面板巢狀、分割條拖曳、最大/最小尺寸限制等功能,極大簡化動態 UI 的開發。

效果展示

以下截圖展示同一程式在不同階段的運行效果,請留意控制項隨視窗變化的行為:

原始對話框運行效果

圖 1 VC 6.0 對話框程式原始運行效果

加入 DynamicLayout 管理後

圖 2 在圖 1 基礎上加入 DynamicLayout 管理

改變對話框大小

圖 3 在圖 2 基礎上改變對話框大小

分割條 A 移至最左

圖 4 在圖 3 基礎上將分割條 A 移動到最左側

正在移動分隔條 C

圖 5 正在移動中的分隔條 C(截圖時游標被隱藏)

運行時的一种佈局

圖 6 程式運行時的另一種佈局狀態

使用方法

要在普通對話框中啟用 DynamicLayout,只需三個步驟:

  1. 在對話框類別中宣告 CDynamicLayout 成員變數。
  2. 在 OnInitDialog() 中呼叫介面註冊控制項,並設定面板、分割條等佈局規則。
  3. 覆寫 WindowProc(),將訊息轉發給 FilterDynamicLayoutMessage()。

若以動態庫方式使用,還需對 VC 專案進行相應設定。以下以圖 1 所示對話框為例,實現圖 2~6 效果的核心代碼:

1. 對話框標頭檔

#include "DynamicLayoutExport.h" // 包含 DynamicLayout 標頭檔
/////////////////////////////////////////////////////////////////////////////
// CDynamicLayoutTestDlg 對話框
class CDynamicLayoutTestDlg : public CDialog
{
// ...
private:
    DynamicLayout::CDynamicLayout m_DLayout; // 宣告動態佈局物件
};

2. 對話框實作檔

BOOL CDynamicLayoutTestDlg::OnInitDialog()
{
    // ... 原有初始化代碼 ...
    m_DLayout.InitLayout(this);
    m_DLayout.SetDialogMaxSize(800, 600); // 限制對話框最大 800x600
    m_DLayout.SetDialogMinSize(200, 100); // 限制最小 200x100

    // 建立面板結構:參數 1,1,1,1 表示上下左右皆鎖定父佈局邊框
    m_DLayout.AddPanel(_T("上"), _T(""), 1, 1, 1, 1);
    m_DLayout.AddPanel(_T("下"), _T(""), 0, 1, 1, 1);
    m_DLayout.AddPanel(_T("上右"), _T("上"), 1, 1, 1, 1); // 加入子面板
    m_DLayout.AddControl(IDC_LIST_LIST, _T("上右"), 1, 1, 1, 1);
    m_DLayout.AddPanel(_T("上右下"), _T("上右"), 0, 1, 1, 0);
    m_DLayout.AddControl(IDC_BTN_MODAL, _T("上右下"), 1, 1, 1, 0);
    m_DLayout.AddControl(IDC_BTN_MODALNESS, _T("上右下"), 1, 1, 1, 0);
    m_DLayout.AddControl(IDOK, _T("上右下"), 1, 1, 1, 0);
    m_DLayout.AddPanel(_T("上左"), _T("上"), 1, 1, 1, 0);
    m_DLayout.AddControl(IDC_TREE1, _T("上左"), 1, 1, 1, 1);
    m_DLayout.AddPanel(_T("下左"), _T("下"), 1, 1, 1, 0);
    m_DLayout.AddControl(IDC_LIST2, _T("下左"), 1, 1, 1, 1);
    m_DLayout.AddPanel(_T("下右"), _T("下"), 1, 1, 1, 1);
    m_DLayout.AddControl(IDC_EDIT1, _T("下右"), 1, 1, 1, 1);
    m_DLayout.AddControl(IDC_STATIC_COMMAND, _T("下右"), 1, 0, 1, 0);
    m_DLayout.AddControl(IDC_EDIT2, _T("下右"), 1, 0, 1, 1);

    // 設定面板背景色
    m_DLayout.SetBkColor(_T("上"), RGB(160, 160, 255));
    m_DLayout.SetBkColor(_T("上右"), RGB(128, 128, 255));
    m_DLayout.SetBkColor(_T("上右下"), RGB(128, 255, 128));

    m_DLayout.ShowPanel(_T(""), TRUE); // 顯示根面板(見圖 2)
    m_DLayout.SetSplit(_T(""));  // 設定分割條 B(參看圖 4)
    m_DLayout.SetSplit(_T("上")); // 設定分割條 A
    m_DLayout.SetSplit(_T("下")); // 設定分割條 C

    return TRUE;
}

LRESULT CDynamicLayoutTestDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
    m_DLayout.FilterDynamicLayoutMessage(message, wParam, lParam); // 讓 CDynamicLayout 參與訊息處理
    return CDialog::WindowProc(message, wParam, lParam);
}

結語

DynamicLayout 的設計靈感來源於 Microsoft .NET 平台的佈局機制,特別是 Panel 概念;熟悉 .NET 的開發者定會感到親切。本專案僅實作核心功能,命名或嫌大膽,請多包涵。DynamicLayout 專案與測試專案均在 VC 6.0 下除錯通過,若有問題歡迎指正交流。

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