返回首页

简介
组合框成为一个标准的工具栏功能。组合框是方便显示一个频繁访问设置的​​选择,或保持一个用户输入的历史(例如,最近的搜索模式)。
在工具栏嵌入一个标准的组合框是相当简单的。但是,结果可能会不看令人满意的,除非你执行几个步骤。在这篇文章中,我们将展示这些步骤,因此您将能够达到以下:添加到工具栏上的一个或多个组合框;调整组合框的字体; 使组合框响应用户命令;创建一个历史记录的组合框,其中包含最新的用户条目。组合框嵌入到工具栏
嵌入到一个组合框工具栏youll需要添加代码在CMainFrame::OnCreate中的消息处理程序。为了避免低层次的工具栏的细节OnCreate方法,可以将其封装在一个专用的方法CreateComboBox添加到您的自定义CToolBar类:

class CToolBarWithCombo : public CToolBar

{

public:

    CComboBox m_comboBox;



// Overrides

    // ClassWizard generated virtual function overrides

    //{{AFX_VIRTUAL(CToolBarWithCombo)

    //}}AFX_VIRTUAL



    BOOL CreateComboBox(class CComboBox& comboBox, 

                        UINT nIndex, 

                        UINT nID, 

                        int nWidth, 

                        int nDropHeight);



// Generated message map functions

protected:

    //{{AFX_MSG(CToolBarWithCombo)

    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()

};



BOOL CToolBarWithCombo::CreateComboBox(CComboBox& comboBox, 

                                       UINT nIndex, 

                                       UINT nID, 

                                       int nWidth, 

                                       int nDropHeight)

{

    // Create the combo box

    SetButtonInfo(nIndex, nID, TBBS_SEPARATOR, nWidth);



    CRect rect;

    GetItemRect(nIndex, &rect);

    rect.top = 1;

    rect.bottom = rect.top + nDropHeight;

    if (!comboBox.Create(CBS_DROPDOWN|WS_VISIBLE|WS_TABSTOP|WS_VSCROLL,

                         rect, this, nID))

    {

        TRACE("Failed to create combo-box\n");

        return FALSE;

    }



    return TRUE;

}

然后你可以调用CreateComboBox方法之后创建您的自定义工具栏(里面的CMainFrame::OnCreate中):{C}
另一种方法是重写CToolBarWithCombo:OnCreate和地方的CreateComboBox有呼叫。字体调整
默认情况下,组合框分配系统字体看起来并不很好的工具栏。因此,下一步是使组合框的更好看。您可以直接添加字体选择代码CreateComboBox方法,但由于有更多的功能,我们计划添加到我们的组合框,以及从CComboBox派生一个新类:
class CSmartComboBox : public CComboBox

{

protected:

    CFont m_font;



public:

    CSmartComboBox();



    LONG    m_lfHeight;

    LONG    m_lfWeight;

    CString m_strFaceName;



    BOOL CreateFont(LONG lfHeight, LONG lfWeight, LPCTSTR lpszFaceName);



// Generated message map functions

protected:

    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

    DECLARE_MESSAGE_MAP()

};



CSmartComboBox::CSmartComboBox()

{

    m_lfHeight = -10;

    m_lfWeight = FW_NORMAL;

    m_strFaceName = _T("MS Sans Serif");

    m_nMaxStrings = 10;

}



BEGIN_MESSAGE_MAP(CSmartComboBox, CComboBox)

    ON_WM_CREATE()

END_MESSAGE_MAP()



int CSmartComboBox::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

    if (CComboBox::OnCreate(lpCreateStruct) == -1)

        return -1;



    if( !CreateFont(m_lfHeight, m_lfWeight, m_strFaceName) )

    {

        TRACE0("Failed to create font for combo box\n");

	return -1;      // fail to create

    }



    return 0;

}



BOOL CSmartComboBox::CreateFont(LONG lfHeight, LONG lfWeight, LPCTSTR lpszFaceName)

{

    //  Create a font for the combobox

    LOGFONT logFont;

    memset(&logFont, 0, sizeof(logFont));



    if (!::GetSystemMetrics(SM_DBCSENABLED))

    {

        // Since design guide says toolbars are fixed height so is the font.

        logFont.lfHeight = lfHeight;

        logFont.lfWeight = lfWeight;

        CString strDefaultFont = lpszFaceName;

        lstrcpy(logFont.lfFaceName, strDefaultFont);

        if (!m_font.CreateFontIndirect(&logFont))

        {

            TRACE("Could Not create font for combo\n");

            return FALSE;

        }

        SetFont(&m_font);

    }

    else

    {

        m_font.Attach(::GetStockObject(SYSTEM_FONT));

        SetFont(&m_font);

    }

    return TRUE;

}

现在的组合框可以方便地进行调整,以反映应用程序的风格。添加响应用户命令
一旦组合框嵌入到工具栏,它的属性,可以在传统的方式访问。但为了提供迅速响应用户命令,嵌入式组合框需要配合其容器,即工具栏。然后,用户将能够键入一些文字组合框,按下"Enter",以及相应的命令发送到应用程序。
,我们会证明这一点有两个组合嵌入工具栏框与应用程序的步骤。这一点很重要,以验证该命令是正确的组合框获取。
class CToolBarWithCombo : public CToolBar

{

public:



    CSmartComboBox	m_comboBox1;

    CSmartComboBox	m_comboBox2;



// Overrides

    // ClassWizard generated virtual function overrides

    //{{AFX_VIRTUAL(CToolBarWithCombo)

    virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);

    //}}AFX_VIRTUAL



    // The rest of the code is skipped

}



BOOL CToolBarWithCombo::OnCommand(WPARAM wParam, LPARAM lParam) 

{

    if( wParam == IDOK && lParam == 0 )

    {

        CString strText;

	CString strCommand;

	CComboBox* rgComboBox[] = {&m_comboBox1, &m_comboBox2};

	for( int index = 0; 

             index < sizeof(rgComboBox) / sizeof(rgComboBox[0]); 

             ++index )

        {

            if( rgComboBox[index]->GetEditSel() != 0 )

            {

                rgComboBox[index]->GetWindowText(strText);

                strCommand.Format(_T("Command from ComboBox[%d]: %s"), 

                                  index+1, 

                                  (LPCTSTR)strText);

                AfxMessageBox(strCommand);

		rgComboBox[index]->AddString(strText);

		rgComboBox[index]->SetWindowText(_T(""));

            }

        }

    }

	

    return CToolBar::OnCommand(wParam, lParam);

}

正如你可以看到,找到组合框具有焦点的伎俩是调用的GetEditSel功能。除非游标放置在一个组合框,该函数将返回0。管理组合框条目
最后我们改进的是创建一个组合框,将管理最近的用户条目。这种组合框通常人口与最近的搜索模式历史,已拨电话号码等,它们具有以下共同的特点:项目的最大数量是有限的,一旦达到此数量,新条目取代了最早的条目;条目被添加到列表的顶部;列表中不包含重复。
下面是代码,你会需要添加到CSmartComboBox:
class CSmartComboBox : public CComboBox

{

    // Only new code is shown

public:



    int m_nMaxStrings;



    int	AddString(LPCTSTR str);

    int	InsertString(int index, LPCTSTR str);

};



int CSmartComboBox::AddString(LPCTSTR str)

{

    if( _tcslen(str) == 0 )

        return -1;



    int oldIndex = FindStringExact(-1, str);

    if( oldIndex >= 0 )



        DeleteString(oldIndex);



    if( GetCount() == m_nMaxStrings )

        DeleteString(m_nMaxStrings-1);



    return CComboBox::InsertString(0, str);

}



int CSmartComboBox::InsertString(int index, LPCTSTR str)

{

    if( _tcslen(str) == 0 )

        return -1;



    int oldIndex = FindStringExact(-1, str);

    if( oldIndex >= 0 )



    {

        DeleteString(oldIndex);

	if( index >= oldIndex )

	    --index;

    }



    if( GetCount() == m_nMaxStrings )

        DeleteString(m_nMaxStrings-1);



    return CComboBox::InsertString(index, str);

}


如下这篇文章中的示例项目,包含源代码和测试的应用程序,演示嵌入式组合框。

回答

评论会员:XHK 时间:2011/11/29
非常好
但这是很容易的事情
评论会员:OliParent 时间:2011/11/29
您好,

我试图处理Escape和箭头键。我试图在工具栏和我的派生的CComboBox类的消息很多,这是行不通的!!

请帮帮忙!

奥利弗

奥利弗
评论会员:drobus 时间:2011/11/29
主旨
评论会员:GSL3 时间:2011/11/29
非常有趣!如何将组合框后

我按照你的设计,但看起来像我必须重建的工具栏和移动ComboBox的,如果我选择显示/隐藏按钮标签。

如何移动呢?

SetWindowPos (...)似乎并没有将它在所有!

谢谢!

洛克伍德乔治
GSL3@Prodigy.net
glockwood@lumenare.com

GSL
评论会员:基督教切尼 时间:2011/11/29
东西,我是,当你使用一个按钮的大小大于16像素平面样式的工具栏分隔线上显示组合框的顶部或底部的错误。任何人都知道如何隐藏行?
评论会员:罗伯特马歇尔 时间:2011/11/29
该方法CreateComboBox TBBS_SEPARATOR
SetButtonInfo为什么TBBS_SEPARATOR使用?

为什么不TBBS_DROPDOWN呢?

布尔CToolBarWithCombo:CreateComboBox(CComboBox的ComboBox,
UINT参数nIndex,
 60; UINT的NID,
&# 160; INT nWidth,
 0; INT nDropHeight)
{
/ /创建组合框{BR​​} SetButtonInfo(参数nIndex,NID,TBBS_SEPARATOR,nWidth);
评论会员:Filomela 时间:2011/11/29
我的控制是在错误的place.Why推杆也许是因为我有很多的按钮31按钮,我想我的控制,以32??
评论会员:verinder_bindra 时间:2011/11/29
大家好,
我想知道如何插入一个CDateTimeCtrl(的DateTimePicker)我的工具栏。我用这样的方式:

BOOL CMyToolBar::CreateDTPicker(CDateTimeCtrl dtPicker,INT nWidth,UINT参数nIndex,UINT的NID)
{
/ /创建DateTimePicker控件:

SetButtonInfo(参数nIndex,NID,TBBS_SEPARATOR,nWidth);
CRECT RECT;

GetItemRect(参数nIndex,RECT); (dtPicker.Create(DTS_RIGHTALIGN |!DTS_UPDOWN | WS_TABSTOP,矩形,这一点,NID))
 60; {
TRACE("无法创建DateTimePicker控件\ N");
返回FALSE;
}

返回TRUE;}

但它不工作的CDateTimeCtrl,控制不出现。

有人能帮助我吗?

在此先感谢,
BrutalDeath0


评论会员:BarrettoVN 时间:2011/11/29
!!hmmmmm,SH * T,我只是忘了WS_VISIBLE风格创建函数
因此,它的工作原理现在。

BrutalDeath0
评论会员:VagifAbilov 时间:2011/11/29
问题是分离器控制显示在组合框的中间,而不是在一旁...我们使用的是显示的组合,但改变分离器的宽度,移动宽度和控制中期的分离器,在左侧所示,这就是为什么它出现在一旁的分离器CTRL ..

verinder

没有
评论会员:BarrettoVN 时间:2011/11/29
大约一年回本蠕变发布了colourfull评论我最早的文章之一,它仅仅是今天我看到了什么愚蠢的东西,这自认专家写的


评论会员:VagifAbilov 时间:2011/11/29
我只是请读者上述评论的作者已经发布的文章,是我关键的话的原因:
http://www.codeproject.com/useritems/simplewordpad.asp

我想这是值得任何进一步的评论。

#1042#1072#1075#1080#1092#1040#1073#1080#1083#1086#1074;
(MCP的Visual C)
挪威的奥斯陆,

十六进制sissies。真正的男人使用二进制。而最铁杆类型只使用零 - 大写的零和小写零
Tomasz Sowinski
评论会员:BarrettoVN 时间:2011/11/29
为什么你提供的链接,只是网页,您有
之一
发布什么其他的意见,发生了什么?? ,你

害怕您的名字将玷污??


以下是其他页面,你还发布专家意见

http://www.codeproject.com/useritems/ledchars.asp

您的评论... / ledchrs.asp需要蛋糕沿
和烘烤
你说"很长一段时间... ..."

我不知道如何你(专家)不知道,这篇文章

在从微软的Win32示例MFC港口和数量

变量是在微软样本一样,我想你应该

作为顾问的工作,微软你可能只是能够来帮助

在一些较旧的样本进行微调(传播中的变量

不同的文件)

&# 160; 另一位专家"秧子"由RF和谁
的缩写云
最初用来搭载后回复您的意见已超过

在一个案件有一段时间转冷,并删除了他的回复,
是因挂此删除评论。
你张贴这些意见时,我是新本网站思维,

张贴这样的评论,你将我的耻辱,并可能迫使我

停止写作,但你失败 - 不幸的是

评论会员:CrazyOwl 时间:2011/11/29
你显然有非常多的空闲时间,如果你决定使用这些事项。看看你的这些文章的其他意见,你会发现在其质量有严重缺陷。我重读了我的意见,并不能说与他们有什么错。如果你提高你的写作风格,现在我只能向你表示祝贺。

无论如何,我觉得很奇怪,而不是讨论这个问题,在你决定一个专业的方式侮辱其他人,像"一个愚蠢的文章"没有一个单一的澄清张贴意见。

我不能相信你真的认为其他人想的耻辱和强制停止写作。没有人得到报酬,这里的文章,你不走别人的面包,我的写作你。但是,如果人们在这里发表文章,缺乏良好的努力和编程风格,在CodeProject将很快成为一个地方充满了无用的员工。这是我(和其他)想告诉你。

成长和发展自我批评位。如果你有我写的有关工作人员的宝贵意见,我会感谢讨论。

关于

#1042#1072#1075#1080#1092#1040#1073#1080#1083#1086#1074;
(MCP的Visual C)
挪威的奥斯陆,

十六进制sissies。真正的男人使用二进制。而最铁杆类型只使用零 - 大写的零和小写零
Tomasz Sowinski
评论会员:VagifAbilov 时间:2011/11/29
为什么要提供链接只是一个您曾经参与过意见的网页,对他人,发生了什么事??你害怕,你的名字将受损吗??


以下是其他页面,你还发布专家意见

http://www.codeproject.com/useritems/ledchars.asp

您的评论... / ledchrs.asp需要的蛋糕和贝克

你说"很长一段时间... ..."
 60;
我不知道如何(专家)不知道,这篇文章在从微软和数量变量的Win32示例MFC端口在Microsoft样品相同,我觉得你应该担任顾问工作微软可能只是能够帮助在微调一些较旧的样品(分散在不同的文件中的变量)

另一位专家"秧子"射频的首字母缩写,最初用来搭载后回复您的意见已上交了一段时间,寒冷和删除他的回复,在一个案例中,有一个挂评论,因为这个删除。{ BR}
你张贴这些意见,当我是新来这个网站的思想,通过张贴您将我的耻辱,并可能迫使我停止写作,但你没有这样的评论 - 的不幸

评论会员:布伦丹Tregear 时间:2011/11/29
Barretto VN写道:
以下是其他页面,你还发布专家意见

http://www.codeproject.com/useritems/ledchars.asp

您的评论... / ledchrs.asp需要的蛋糕和贝克

Barretto VN写道:
我不知道如何(专家)不知道,这篇文章在从微软和数量变量的Win32示例MFC端口在Microsoft样品相同,我觉得你应该担任顾问工作微软可能只是能够帮助在微调一些较旧的样品(分散在不同的文件中的变量)

在读的文章和Vagif的意见,我没有看到你抱怨有什么理由。
你的文章不包含任何提及这个被移植的​​代码,也不该移植的代码不被C标准。
你会做以及从错误中学习,而不是投掷侮辱左右。

安娜

{A}

"自己 - 不是别人认为你应该"
- 玛西娅Graesch

"安娜只是一个性感的前瞻性女同志挞"
- 一位朋友,试图风我。它没有工作。

资源ID的麻烦?尝试
评论会员:flyingxu 时间:2011/11/29
您好,

我一直在寻找正是我来到这里。我的问题是,现在如果允许我在我的项目中使用这个类学校。的事情,我不知道如果此应用程序,它不是在此刻,获取商业,但它可以在未来。
我希望你给我在我的应用程序中使用它的权限。

非常感谢,马丁梅斯特,奥地利

PS:伟大的工作
评论会员:肯Keray 时间:2011/11/29
你可以用我的代码,如你所愿,除非你说这是你的{S2}我不介意,包括在商业应用。这些都只是小积木。

祝你好运!

#1042#1072#1075#1080#1092#1040#1073#1080#1083#1086#1074;
(MCP的Visual C)
挪威的奥斯陆,

十六进制sissies。真正的男人使用二进制。而最铁杆类型只使用零 - 大写的零和小写零
Tomasz Sowinski
评论会员:梅尔Feik 时间:2011/11/29
可能我一个dummie {S2},但我停留配售CToolBarWithCombo CreateComboBox呼叫:OnCreate中,我一直在调试的assert调用生成。诀窍是你要删除的呼叫:
m_wndToolBar.LoadToolBar(IDR_MAINFRAME);
从内的CMainFrame和地点,CToolBarWithCombo::OnCreate中,在调用CreateComboBox之前。断言是因为_GetButtonInfo()没有找到工具栏的按钮,因为尚未加载。