【问题标题】:How to implement a Snipping Tool like split button in MFC?如何在 MFC 中实现像拆分按钮这样的截图工具?
【发布时间】:2016-06-08 07:09:24
【问题描述】:

我想使用 MFC 创建一个拆分按钮,其行为与 Windows 中 Snipping Tool 的绘图笔按钮相同(下图中红色圈出的按钮)。

为了在点击后保持CButton处于推送状态,可以通过以下代码(C++ Win32 How to Create a "toggle" Pushbutton)设置样式轻松完成:

button.SetButtonStyle(BS_CHECKBOX | BS_PUSHLIKE)

直观地说,我认为应该有简单的 API 调用来使其工作。我尝试使用 CSplitButton 来完成 Snipping Tool 实现的功能。但是,我找不到任何简单的方法来实现我的目标。目前,我想避免使用复杂的DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 实现我自己的拆分按钮。

我尝试在OnBnClickedSplit 函数中使用CButton::SetState(BOOL bHighlight)。我可以保持按钮突出显示,直到

  1. 用户点击按钮,
  2. 用户点击其他控件,
  3. 或用户点击程序外的区域。
int MySnippingTool::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    //...

    m_splitBtnPen.Create(NULL, WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_PUSHBUTTON|BS_ICON, rect, this, IDC_SPLITBUTTON_PEN);
    hIcon = (HICON)LoadImage(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON_PEN),IMAGE_ICON, 0,0,0);
    m_splitBtnPen.SetIcon(hIcon);
    m_splitBtnPen.SetState(TRUE);

    //...
}

void MySnippingTool::OnBnClickedSplit()
{
    // This button click method will be triggered when this button or
    // other controls is clicked. Or user clicks area outside the program
    m_pressed = !m_pressed;
    if (m_pressed )
        m_splitBtnPen.SetState(TRUE);
    else
        m_splitBtnPen.SetState(FALSE);

    OutputDebugStringA(m_pressed ? "Pressed On\n" : "Pressed Off\n");
}

但这仍然不是我想要的。我认为原因在 MSDN 中已经提到。

按钮控件在用户单击并自动突出显示 按住鼠标左键。当用户删除突出显示时 释放鼠标按钮。 https://msdn.microsoft.com/en-us/library/ebw1hfe8.aspx

有谁知道任何 API 调用都可以让它工作吗?有什么简单的方法吗?还是我必须自己实现整个拆分按钮和DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)

【问题讨论】:

  • 感谢您的指导。我浏览了您给我的示例,并再次阅读了有关 CButtonCSplitButton 的 API。我还研究了这两个类是如何在 VC2008、VC2010 VC\atlmfc\src 文件夹中实现的。 CButton 和 CSplitButton 的外观和视图都隐藏在 Win32 API 调用 CreateEx() 中。 atlmfc 文件夹中的两个类都没有实现 OnDraw() 或 DrawItem()。看来我需要在自定义拆分按钮中实现 OnDraw() 或 DrawItem 才能使拆分按钮推送效果类似于BS_CHECKBOX | BS_PUSHLIKE
  • 我也在考虑通过对拥有拆分按钮的窗口接收的消息添加控制来进行地下工作。可能是鼠标不释放按钮并一直按住按钮的拆分按钮。
  • 您尝试改用CMFCMenuButton 吗?重要提示:在这种情况下,您的对话框类应派生自 CDialogEx!

标签: c++ windows mfc


【解决方案1】:

我设法使用基于图像的下拉菜单创建了一个基于图像的 CSplitterButton 派生控件,如下所示:

您需要创建一个从 CSplitButton 派生的自定义类。

class SGSplitImageButton : public CSplitButton
{
    DECLARE_DYNAMIC(SGSplitImageButton)

public:
    SGSplitImageButton();
    virtual ~SGSplitImageButton();
    CMenu *menu;

    void InsertMenu(CString title, UINT imgId, UINT menuID);
    void SetDropDown();

protected:
    DECLARE_MESSAGE_MAP()
public:
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};

参见this 文章。

【讨论】:

  • 优秀的答案!
猜你喜欢
  • 2011-11-18
  • 1970-01-01
  • 2012-01-04
  • 2012-03-06
  • 1970-01-01
  • 2015-12-20
  • 2012-05-10
  • 2023-02-23
  • 1970-01-01
相关资源
最近更新 更多