#include "FGWindowsMenuBar.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include
#include
#include #include using namespace simgear; namespace { HWND getMainViewerHWND() { osgViewer::Viewer::Windows windows; if (!globals->get_renderer() || !globals->get_renderer()->getViewer()) { return 0; } globals->get_renderer()->getViewer()->getWindows(windows); osgViewer::Viewer::Windows::const_iterator it = windows.begin(); for(; it != windows.end(); ++it) { if (strcmp((*it)->className(), "GraphicsWindowWin32")) { continue; } osgViewer::GraphicsWindowWin32* platformWin = static_cast(*it); return platformWin->getHWND(); } return 0; } bool labelIsSeparator(const std::string& s) { std::string t = "---"; if (s.compare(0, t.length(), t) == 0) return true; else return false; } LRESULT CALLBACK menubarWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { SG_LOG(SG_GENERAL, SG_INFO, "called window proc"); return ::DefWindowProc(hwnd, uMsg, wParam, lParam); } } // of anonymous namespace // class FGWindowsMenuBar::WindowsMenuBarPrivate { public: WindowsMenuBarPrivate(); ~WindowsMenuBarPrivate(); void fireBindingsForItem(UINT commandId) { fireBindingList(itemBindings[commandId]); } HWND mainWindow; HMENU menuBar; bool visible; WNDPROC baseMenuProc; typedef std::vector MenuItemBindings; MenuItemBindings itemBindings; }; FGWindowsMenuBar::FGWindowsMenuBar() : p(new WindowsMenuBarPrivate) { } FGWindowsMenuBar::~FGWindowsMenuBar() { } FGWindowsMenuBar::WindowsMenuBarPrivate::WindowsMenuBarPrivate() : visible(true) { mainWindow = getMainViewerHWND(); menuBar = 0; } FGWindowsMenuBar::WindowsMenuBarPrivate::~WindowsMenuBarPrivate() { if (menuBar) { SetMenu(mainWindow, NULL); DestroyMenu(menuBar); } } void FGWindowsMenuBar::init() { int menuIndex = 0; SGPropertyNode_ptr props = fgGetNode("/sim/menubar/default",true); p->menuBar = CreateMenu(); // p->baseMenuProc = (WNDPROC) ::SetWindowLongPtr((HWND) p->mainWindow, GWL_WNDPROC, (LONG_PTR) menubarWindowProc); BOOST_FOREACH(SGPropertyNode_ptr n, props->getChildren("menu")) { // synchronise menu with properties std::string l = getLocalizedLabel(n); std::string label = strutils::simplify(l).c_str(); HMENU menuItems = CreatePopupMenu(); if (!n->hasValue("enabled")) { n->setBoolValue("enabled", true); } bool enabled = n->getBoolValue("enabled"); UINT flags = MF_POPUP; AppendMenu(p->menuBar, flags, (UINT) menuItems, label.c_str()); // submenu int subMenuIndex = 0; SGPropertyNode* menuNode = n; BOOST_FOREACH(SGPropertyNode_ptr n2, menuNode->getChildren("item")) { if (!n2->hasValue("enabled")) { n2->setBoolValue("enabled", true); } std::string l2 = getLocalizedLabel(n2); std::string label2 = strutils::simplify(l2).c_str(); std::string shortcut = n2->getStringValue("key"); SGBindingList bl = readBindingList(n->getChildren("binding"), globals->get_props()); UINT commandId = p->itemBindings.size(); p->itemBindings.push_back(bl); if (labelIsSeparator(label2)) { AppendMenu(menuItems, MF_SEPARATOR, NULL, NULL); } else { if (!shortcut.empty()) { label2 += "\t"+shortcut; } BOOL enabled = n2->getBoolValue("enabled"); UINT flags = MF_STRING; AppendMenu(menuItems, flags, commandId, label2.c_str()); } subMenuIndex++; } menuIndex++; } show(); } bool FGWindowsMenuBar::isVisible() const { return p->visible; } void FGWindowsMenuBar::show() { SetMenu(p->mainWindow, p->menuBar); p->visible = true; } void FGWindowsMenuBar::hide() { SetMenu(p->mainWindow, NULL); p->visible = false; } #if 0 LRESULT CALLBACK WndProcedure(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) { switch(Msg) { case WM_COMMAND: switch(LOWORD(wParam)) { case MY_MENU: MessageBox(hwnd, "Menu Item Selected = Large", "Message", MB_OK); break; } return 0; case WM_DESTROY: PostQuitMessage(WM_QUIT); break; default: return DefWindowProc(hwnd, Msg, wParam, lParam); } return 0; } #endif