为了我自己的喜悦,我正在尝试想出一种更好的方法来简化使用 Windows API 菜单的方法。虽然我确实找到了这个,并且实际上可能会按类别区分菜单项的类型,但我有点像这样:
描述
class MenuItem {...};
class MenuBar { //for the main menu of a window (file, help, etc)
std::list<MenuItem> items; //and whatever else
};
class PopupMenu { //for dropdown (and possibly context) menus
std::list<MenuItem> items; //and whatever else
};
该类MenuItem
具有check()
, disable()
,等功能setText()
,以及更通用的功能,例如setType()
(字符串、位图、分隔符)和setState
(启用、检查、默认)。
在我看来,这些Menu
类本身会提供类似appendStringItem()
、appendItem
、的功能insertBitmapItem()
,并提供对项目本身的访问。我也在争论是否要有一个Menu
基类,虽然很欣赏输入,但这不是问题的主题。
通缉用途
如果这只是 C++,我不会有问题。但是,我的问题出现在将我的菜单项与 Windows 使用的菜单项同步时,因为我的类中的更改不会自动更改真正的菜单项。为了改变菜单项,必须给它一个菜单,以及该菜单中的位置,或者该项目的 ID。这是有道理的,但从使用的角度来看,为什么我不能这样做:
MenuBar menuBar; //pretend this is filled
menuBar.itemAt(2).setText("New text");
问题
好吧,问题是我希望这会更改实际菜单上的菜单项,但不会。我需要某种方式来了解拥有该项目的菜单,因为每个项目都有内部存储的 ID。
我可以在以下适当的插入函数中执行此操作MenuBar
:
bool MenuBar::someInsertionFunction(unsigned index, MenuItem newItem) {
newItem.setOwner(*this); //owner as a raw HMENU type, with *this converting
items.emplace_back(index, newItem); //index checked, of course
}
完成后,我必须MenuItem
检查每个 setter 以确保所有者有效,如果有效,则使用 API 函数更新项目。同样,在 getter 中,我会调用 API 函数来获取当前状态,但前提是所有者有效。这允许用户创建自己的MenuItem
s 列表并通过它初始化 a Menu
。此方法还允许用户完全访问以修改内部项目列表而不会产生任何后果,因为MenuItem
该类在保护自己方面做得很好。
但这与我发现的一个好概念背道而驰:为什么包含的对象应该知道包含它们的内容?是否有处理这个问题的设计模式,或者我最好的选择是打破这个“规则”,以便能够让菜单项控制自己(以及其他菜单项),而不是由菜单?