禁用CMFCRibbonBar的按钮(变灰)

昨天很纠结,一直上网搜索如何令CMFCRibbonBar的按钮变灰,刚开始以为获得了按钮的指针,里面一定有方法或者接口达到我想要的功能,刚开始以为那些按钮和Checkbox等元素是我们普通的控件元素,谁知道用SPY++查了一下,这些都不是继承于CWnd的元素,只是一张一张的图片。后来在认真看了一下MSDN就写了如下代码获得里面的某一按钮元素。

CArray<CMFCRibbonBaseElement* ,CMFCRibbonBaseElement*> arButtons;
m_wndRibbonBar.GetElementsByID(IDC_BUTTON_BRIMIN,arButtons);
arButtons.ElementAt(0)->SetVisible(enableTag);
谁知道写了这些后,发觉一点效果都没有,那时就纳闷了。接着就打开MFC的源码一句一句调试,发现原来是保护成员里的m_bIsDisable的控制量控制,那可简单了,只需要设成TRUE吗,那就搜搜哪一个接口能更改这个值,谁知道还没有呢,这是就想到有没有方法能更改保护成员的值呢,想到更改这个值是编译器有一个选项阻止了这样的动作,没道理要更改这个配置嘛,后来在网上搜到一个很强大的宏如下:

My Approch :

 

#define PROTECTED_CAST_DECL (CLASS_TYPE ,MEMBER_TYPE ,MEMBER_NAME )          /
template <typename ClassType , typename MemberType >                   /
class C ##MEMBER_NAME ##Accessor                                        /
{                                                                    /
	class CAccessor : public ClassType                                 /
	{                                                                /
		 friend class C ##MEMBER_NAME ##Accessor ;                       /
	};                                                               /
public :                                                              /
	static MemberType & GetMember (ClassType * pClass )                 /
	{                                                                /
		return ((CAccessor *)pClass )->MEMBER_NAME ;                    /
	}                                                                /
};

 

#define PROTECTED_CAST (CLASS_TYPE ,CLASS_OBJECT_PTR ,MEMBER_TYPE ,MEMBER_NAME ) (C ##MEMBER_NAME ##Accessor <CLASS_TYPE , MEMBER_TYPE >::GetMember (CLASS_OBJECT_PTR ))

 

Sample :

   以下示例代码展示了 PROTECTED_CAST 的使用方法,代码在 VC++ 2008 下测试通过。

class CPrivateMemberWrapper

{

protected :

         int m_iValue ;

         double m_dValue ;

         string m_sValue ;

public :

         CPrivateMemberWrapper (int i , double d , const char * lps ):

           m_iValue (i ), m_dValue (d ), m_sValue (lps )

         {}

         ~CPrivateMemberWrapper () {}

};

PROTECTED_CAST_DECL (CPrivateMemberWrapper , int , m_iValue )

PROTECTED_CAST_DECL (CPrivateMemberWrapper , double , m_dValue )

PROTECTED_CAST_DECL (CPrivateMemberWrapper , string , m_sValue )
这样确实可以令到那个按钮变灰,但是毕竟这是投机取巧的方法。后来又想到当这个元素没有绑定特定的事件时也是呈现灰色状态的,就想那有没有能动态增删事件绑定的方法,谁知道感觉这么一个简单的方法,居然还搜不到所要的答案,没办法了,看来只有按照自己的思路写一下吧,看了一下,BeginMessage和EndMessage的宏,了解到消息链表也只是一个有结尾项的数组,那我所要实现的只不过是在这个数组上面增删项目(疯了,没办法就什么都要尝试),代码如下:

const AFX_MSGMAP* message = this->GetMessageMap();
AFX_MSGMAP_ENTRY* mePtr = const_cast<AFX_MSGMAP_ENTRY*>((const_cast<AFX_MSGMAP*>(message))->lpEntries);
if(enableTag)
{
	//绑定消息
	int reduce = 1;
	bool haveTag = false;
	while(mePtr->nSig != AfxSig_end)
	{
		if(mePtr->nID == IDC_BUTTON_BRIMIN)
		{
			haveTag = true;
			break;
		}
		++mePtr;
	}
	if(!haveTag)
	{
		mePtr[reduce] = mePtr[0];
		AFX_MSGMAP_ENTRY tmpMA[] = {ON_COMMAND(IDC_BUTTON_BRIMIN, &CMainFrame::OnButtonBrimin){0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }};
		*mePtr = tmpMA[0];
	}
}
else
{
	//移除消息绑定
	int reduce = 0;
	int index = 0;
	while(mePtr->nSig != AfxSig_end)
	{
		if(mePtr->nID == IDC_BUTTON_BRIMIN)
		{
			++reduce;
		}

		*mePtr = *(mePtr + reduce);
		++mePtr;
		++index;
	}
}
经测试这样确实能动态增删事件绑定,而且按钮也会变灰,好像达到了要求,哎,不过本人还是比较纠结为什么这样的方法网上没有贴出来,肯定是或多或少有点问题,所以还是不满足,就继续找资料,又找了一个早上,才在一篇文章里看到必须要响应ON_UPDATE_COMMAND_UI或者ON_UPDATE_COMMAND_UI_RANGE事件达到这样的功能,而且那里的作者还写着是基础知识,后悔自己基础唔牢固,郁闷了,写了一年多C++的我也完全没了解过这个事件。后来就改成了这样

ON_UPDATE_COMMAND_UI_RANGE(ID_BUTTON_BRIMIN,ID_BUTTON_TEST, &CMainFrame::OnUpdateIdrRibbonI)

void CMainFrame::OnUpdateIdrRibbonI(CCmdUI *pCmdUI)
{
	BOOL enableTag = (BOOL)czDevs->czSelSect.size();
	pCmdUI->Enable(enableTag);\\还能设置SetChecked等功能呢
}
这样就完美解决了这个问题,原来这两个消息是用来更新像菜单、工具栏、状态栏、属性窗口等UI界面的。哎,应该以后不会再犯如何更改m_bIsDisable的成员了。



  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: 要将 tkinter 按钮变灰色,可以使用按钮的 `state` 属性并将其设置为 `"disabled"`。例如: ```python import tkinter as tk root = tk.Tk() # 创建一个按钮 btn = tk.Button(root, text="按钮") # 将按钮的状态设置为禁用 btn.config(state="disabled") # 显示按钮 btn.pack() root.mainloop() ``` 这样,按钮就会变为灰色,且无法被点击。如果要恢复按钮的可用状态,可以将 `state` 属性设置为 `"normal"`。例如: ```python # 将按钮的状态设置为可用 btn.config(state="normal") ``` ### 回答2: 要使python tkinter按钮变灰色,可以使用configure()方法来更改按钮的属性。具体步骤如下: 1. 导入tkinter模块: ```python import tkinter as tk ``` 2. 创建主窗口: ```python window = tk.Tk() ``` 3. 创建按钮: ```python button = tk.Button(window, text="按钮") ``` 4. 定义变灰按钮的函数: ```python def make_button_gray(): button.configure(state="disabled") # 设置按钮禁用状态 ``` 5. 创建变灰按钮按钮: ```python gray_button = tk.Button(window, text="变灰按钮", command=make_button_gray) ``` 6. 显示按钮变灰按钮: ```python button.pack() gray_button.pack() ``` 7. 进入主循环,启动程序: ```python window.mainloop() ``` 以上代码创建了一个窗口并包含一个普通按钮和一个变灰按钮。当点击变灰按钮时,普通按钮会变为灰色并且无法点击。你也可以通过更改按钮的其他属性,如foreground和background来改变按钮的外观效果。这些属性可以在configure()方法中进行更改。 ### 回答3: Python的Tkinter库是Python内置的一个GUI(图形用户界面)工具,可以用来创建窗口应用程序。要使Tkinter按钮变灰色,可以使用按钮的属性来设置其状态。 首先,导入Tkinter库和相关模块: ```python from tkinter import * from tkinter import ttk ``` 然后,创建一个窗口: ```python window = Tk() window.title("按钮变灰色示例") ``` 接下来,创建按钮并设置其初始状态: ```python button = ttk.Button(window, text="点击我变灰色") button.state(['!disabled']) button.grid(row=0, column=0, padx=10, pady=10) ``` 然后,定义一个函数来处理按钮点击事件,并在函数中设置按钮的状态为禁用: ```python def disable_button(): button.state(['disabled']) ``` 最后,将函数与按钮的"command"属性关联起来: ```python button.config(command=disable_button) ``` 这样,当按钮被点击时,按钮的状态将被设置为禁用状态,即变为灰色。 最后,运行窗口的主循环,使窗口保持显示: ```python window.mainloop() ``` 以上就是使用Python的Tkinter库实现按钮变灰色的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值