65.9K
CodeProject 正在变化。 阅读更多。
Home

列分隔符控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.79/5 (31投票s)

2004年4月28日

CPOL

3分钟阅读

viewsIcon

73369

downloadIcon

2782

一个将文本拆分为固定宽度列的控件

前言

我最近在整理旧项目时,发现了一个多年前编写但从未真正使用过的有趣控件。我不确定现在是否还有人对 MFC 控件感兴趣,但以防万一,我决定发布这个控件。也许你会觉得它有用。我希望你会发现它很有价值。

引言

你是否曾使用过 Microsoft® Excel 的功能,以固定宽度导入文本数据,其中字段通过空格对齐在列中(图 1)?

The import text dialog of Microsoft Excel

图 1. Microsoft Excel 的导入文本对话框

你是否曾经需要/想要在自己的应用程序中使用类似的功能,允许用户将文本拆分为固定宽度的列?通过本文介绍的 Separator 控件,你可以轻松地将此功能引入你的应用程序。Separator 控件的一个示例可以在图 2 中看到。

An example of separator control in use

图 2. Separator 控件的示例

总体外观

  • CSeparatorsCtrl 是一个 MFC 控件,它提供了请求用户选择/拆分固定宽度文本列的功能。
  • CScaleLine 是一个控件,它代表一个位于 Separator 控件顶部的带有数字的刻度线,并由 CSeparatorsCtrl 使用。
  • CFlatDisplay 是一个控件,它显示文本以及用户拆分成的列。它也由 CSeparatorsCtrl 使用。

你可以将 CSeparatorsCtrl 视为一个外观模式(Facade pattern),它利用 CScaleLineCFlatDisplay 控件的扩展功能,隐藏它们的复杂性,并为开发人员提供一个单一控件的简洁接口。

CSeparatorsCtrl 控件的实例可以在 Visual Studio 的窗体设计器中通过自定义控件在设计时创建,也可以在运行时动态创建。

此控件利用了 Jamie Nordmeyer 编写的 CAutoFont 类,你可以在此处找到:https://codeproject.org.cn/gdi/autofont.asp

CSeparatorsCtrl 类提供的功能

void SetDisplayFontSize(long size) 设置显示文本的字体大小。
void SetDisplayColor(COLORREF txtColor, COLORREF lineColor, COLORREF bgColor) 设置 CFlatDisplay 控件的颜色。
  • txtColor - 文本颜色(默认颜色为黑色);
  • lineColor - 分隔线颜色(默认颜色为黑色);
  • bgColor - 文本区域的背景颜色(默认颜色为白色)。
void SetScaleColor(COLORREF value) 设置 CScaleLine 控件的颜色。
void SetScaleIntervals(long nBig, long nSmall) 设置刻度间隔。nBig 定义显示数字的大间隔,nSmall 定义仅通过笔触大小标记的小间隔。
void SetShowFrame(bool value) 定义是否在分隔符控件周围显示边框。
void SetText(CString text) 设置分隔符控件中显示的文本。
long GetCharHeight() 返回显示字符的高度(使用等宽字体)。
long GetCharWidth() 返回显示字符的宽度。
CDWordArray * GetSeparators() 返回用户选择的分隔符的 DWORD 动态数组的引用。
virtual bool OnBeforeAddColumn(long nPos) 在用户单击鼠标添加列之前调用的事件处理程序。声明为 virtual,以便你可以继承此控件并在派生类中重写它。如果此方法返回 false,则不会添加新的列分隔符。
virtual bool OnBeforeRemoveColumn(long nPos) 在用户单击鼠标移除列之前调用的事件处理程序。如果此方法返回 false,则不会移除列分隔符。

控件的使用

要使用 Separator 控件,只需将一个自定义控件放在你的对话框上,并声明一个属性作为 CSeparatorsCtrl 类的实例。然后,你可以在对话框创建后使用此属性,例如,在对话框的 OnCreate 方法中放置以下代码来设置 Separator 控件的初始属性:

int CSepCtrlTestDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CDialog::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    m_SepCtrl.SetShowFrame(true);
    m_SepCtrl.SetText("Text to fill up the content of separator control");
    m_SepCtrl.SetDisplayFontSize(12);
    
    return 0;
}

你也可以在运行时创建一个 Separator 控件实例并将其放在你的对话框上,例如:

void CTestDynamicDlg::OnCreateCtrl()
{
    if (m_pSepCtrl == NULL)
    {
        m_pSepCtrl = new CSeparatorsCtrl;
        m_pSepCtrl->Create("MFCSeparatorsCtrl", 
            "Doesn't matter", 
            WS_CHILD | WS_VISIBLE,
            CRect(0, 0, 400, 150),
            this,
            1);
        
        //m_pSepCtrl->SetShowFrame(true);
        m_pSepCtrl->SetText("something for test -------->>>> ----->>>");
        m_pSepCtrl->GetSeparators()->Add(9);
        m_pSepCtrl->GetSeparators()->Add(13);
        m_pSepCtrl->SetScaleIntervals(5, 0);
        
        m_pSepCtrl->SetScaleColor(RGB(0,0,155));
        m_pSepCtrl->SetDisplayColor(RGB(0,0,0), RGB(0,155,0), RGB(200,200,200));
        m_pSepCtrl->SetDisplayFontSize(18);
    }
}

要列出用户选择的所有列,你可以使用 CSeparatorsCtrl 类提供的 GetSeparators 方法,如下所示:

void CSepCtrlTestDlg::OnShowSeparators() 
{
    CDWordArray * pX = m_SepCtrl.GetSeparators();
    CString str;
    for (int i = 0; i < pX->GetSize(); i++)
    {
        str.Format("Col: %d", pX->GetAt(i));
        AfxMessageBox(str);
    }
}

历史

  • 版本 1.0 - 2001 年的某个时候,发布于 2004 年 4 月 28 日。
© . All rights reserved.