当OS X中的某些应用程序有多个窗口(许多打开的文档,每个窗口都在自己的窗口中)时,它们似乎共享相同的系统菜单,至少在FLTK中。有没有办法找到最近选择的窗口从菜单发送事件?
这是我的设置(Mac OS X 10.6.2,FLTK 1.3.3):具有系统菜单的Shell
类。每次打开新文档时,都会创建新的Shell
:
#ifdef __APPLE__
void Shell::macOpen(const char *fileName)
{
// If there are empty shell, open the model in it
if (s_empty != 0)
{
...
s_empty = 0;
}
// Otherwise, create new shell with the model
else
{
char *args[1];
args[0] = (char *) fileName;
new Shell(1, args, s_conf, s_dct, fileName, 1);
}
}
#endif
然后,我会跟踪最近选择的Shell
将其保存到static Shell *Shell::s_current
:
int Shell::handle(int event)
{
...
case FL_FOCUS:
#ifdef __APPLE__
// We just selected some shell, it is current.
s_current = this;
cout << "Select shell with address: [" << s_current << "]" << endl;
#endif
return 1;
...
}
这篇文章似乎有效,因为每次选择Shell
时我都能看到痕迹:
Select shell with address: [0x8206db0]
Select shell with address: [0x82375f0]
Select shell with address: [0x5d20650]
Select shell with address: [0x82375f0]
现在,给定:
Shell *Shell::currentShell(Fl_Widget *w)
{
cout << "Widget address: [" << w << "]" << endl;
Shell *result = 0;
if (w != 0)
{
result = (Shell *) w->window();
cout << "Widget wingow address: [" << result << "]" << endl;
}
#ifdef __APPLE__
else
{
result = s_current;
cout << "Last selected shell address: [" << result << "]" << endl;
}
#endif
return result;
}
我有一些回调:
void Shell::shortcutCB(Fl_Widget *w, void *data)
{
cout << "Shortcut" << endl;
Shell *ref = currentShell(w);
if (ref != 0)
{
...
}
}
当从菜单执行此回调并且更多Shell
s打开时,我收到以下错误:
Bus error
没有来自Shell::shortcutCB
或Shell::currentShell
的跟踪。当唯一的Shell
打开时,一切都完美无缺。当更多Shell
打开并且我关闭除了一个之外的所有时,错误再次出现。从Shell
内的某个小部件调用相同的回调或从键盘快捷方式传递时,没有问题。
答案 0 :(得分:0)
通过以下3个步骤解决了问题:
在OS X中声明manu bar也是静态的(这是失败的):
#ifdef __APPLE__
static Fl_Sys_Menu_Bar *s_menubar;
#else
Fl_Sys_Menu_Bar *m_menubar;
#endif
不仅会在Shell::s_current
事件中保存当前FL_FOCUS
,还会保存Shell
处理的任何事件,即每次返回1:
int Shell::handle(int event)
{
int result = 0;
switch (event)
{
// Set result = 1 when handling the event
...
}
#ifdef __APPLE__
if (result == 1)
{
// We just selected some shell, it is current.
s_current = this;
cout << "Select shell with address: [" << s_current << "]" << endl;
}
#endif
return result;
}
在OS X上使用Shell::s_current
进行菜单回调,无论是否生成呼叫小部件:
Shell *Shell::currentShell(Fl_Widget *w)
{
Shell *result = 0;
#ifdef __APPLE__
result = s_current;
cout << "Last selected shell address: [" << result << "]" << endl;
#else
cout << "Widget address: [" << w << "]" << endl;
if (w != 0)
{
result = (Shell *) w->window();
cout << "Widget wingow address: [" << result << "]" << endl;
}
#endif
return result;
}