MenuShortcut::MenuShortcut() { _Key = 0; } MenuShortcut::MenuShortcut(const String &S) { _Shift = S.StartsWith("Shift+"); _Ctrl = S.StartsWith("Ctrl+"); _Alt = S.StartsWith("Alt+"); Vector Result; S.Partition('+', Result); String StringKey = Result.Last(); if(StringKey.Length() == 1 && StringKey[0] >= 'A' && StringKey[0] <= 'Z') { _Key = KEY_A + UINT(StringKey[0]) - UINT('A'); } else if(StringKey.Length() == 1 && StringKey[0] >= '0' && StringKey[0] <= '9') { _Key = KEY_0 + UINT(StringKey[0]) - UINT('0'); } else if(StringKey == "Enter") { _Key = KEY_ENTER; } else if(StringKey == "End") { _Key = KEY_END; } else if(StringKey == "Pause") { _Key = KEY_PAUSE; } else if(StringKey == "Left") { _Key = KEY_LEFT; } else if(StringKey == "Right") { _Key = KEY_RIGHT; } else if(StringKey == "Up") { _Key = KEY_UP; } else if(StringKey == "Down") { _Key = KEY_DOWN; } else { SignalError(String("Invalid Menu Shortcut: ") + S); } } void MenuShortcut::Dispatch(InputManager &I, UINT Id) { if(_Key != 0) { if( (!_Shift || I.KeyCheck(KEY_SHIFT)) && (!_Ctrl || I.KeyCheck(KEY_CTRL)) ) { if(I.KeyCheckOnce(_Key)) { I.PushEvent(InputEvent(InputEventMenu, Id)); } } } } MenuEntry::MenuEntry() { _SubMenu = NULL; } MenuEntry::MenuEntry(Menu *SubMenu, const String &Name, UINT Id) { _SubMenu = SubMenu; _Name = Name; _Id = Id; Vector Partition; Name.Partition('\t', Partition); if(Partition.Length() == 2) { _Shortcut = MenuShortcut(Partition.Last()); } } MenuEntry::~MenuEntry() { FreeMemory(); } void MenuEntry::FreeMemory() { /*if(_SubMenu) { _SubMenu->FreeMemory(); delete _SubMenu; _SubMenu = NULL; } _Name.FreeMemory();*/ } void MenuEntry::DispatchKeyboardShortcuts(InputManager &I) { if(_SubMenu != NULL) { _SubMenu->DispatchKeyboardShortcuts(I); } else { _Shortcut.Dispatch(I, _Id); } } Menu::Menu() { _Handle = NULL; } Menu::Menu(HMENU Handle) { _Handle = Handle; } Menu::~Menu() { FreeMemory(); } void Menu::FreeMemory() { for(UINT Index = 0; Index < _Entries.Length(); Index++) { _Entries[Index].FreeMemory(); } _Entries.FreeMemory(); if(_Handle != NULL) { DestroyMenu(_Handle); _Handle = NULL; } } Menu& Menu::AddSubMenu(ApplicationWindow &WM, UINT Id, const String &Name) { HMENU NewHandle = CreatePopupMenu(); Assert(NewHandle != NULL, "CreatePopupMenu failed"); _Entries.PushEnd(MenuEntry(new Menu(NewHandle), Name, Id)); BOOL Success = AppendMenu(_Handle, MF_POPUP, UINT_PTR(NewHandle), Name.CString()); Assert(Success != 0, "AppendMenu failed"); Success = DrawMenuBar(WM.Handle()); Assert(Success != 0, "DrawMenuBar failed"); return _Entries.Last().SubMenu(); } void Menu::AddSeperator(ApplicationWindow &WM, UINT Id) { BOOL Success = AppendMenu(_Handle, MF_SEPARATOR, Id, NULL); Assert(Success != 0, "SetMenu failed"); Success = DrawMenuBar(WM.Handle()); Assert(Success != 0, "DrawMenuBar failed"); } void Menu::AddString(ApplicationWindow &WM, UINT Id, const String &Name) { BOOL Success = AppendMenu(_Handle, MF_STRING, Id, Name.CString()); Assert(Success != 0, "SetMenu failed"); Success = DrawMenuBar(WM.Handle()); Assert(Success != 0, "DrawMenuBar failed"); _Entries.PushEnd(MenuEntry(NULL, Name, Id)); } void Menu::SetItemName(ApplicationWindow &WM, UINT Id, const String &Name) { String NameCopy = Name; MENUITEMINFO Info; Info.cbSize = sizeof(MENUITEMINFO); Info.fMask = MIIM_STRING; Info.dwTypeData = NameCopy.CString(); BOOL Success = SetMenuItemInfo(_Handle, Id, FALSE, &Info); Assert(Success != 0, "SetMenuItemInfo failed"); } void Menu::SetItemState(ApplicationWindow &WM, UINT Id, bool Enabled, bool Checked) { MENUITEMINFO Info; Info.cbSize = sizeof(MENUITEMINFO); Info.fMask = MIIM_STATE; Info.fState = 0; if(Enabled) { Info.fState |= MFS_ENABLED; } else { Info.fState |= MFS_DISABLED; } if(Checked) { Info.fState |= MFS_CHECKED; } else { } BOOL Success = SetMenuItemInfo(_Handle, Id, FALSE, &Info); Assert(Success != 0, "SetMenuItemInfo failed"); //Success = DrawMenuBar(WM.GetHWND()); //Assert(Success != 0, "DrawMenuBar failed"); } bool Menu::HasSubMenu(const String &Name) { for(UINT Index = 0; Index < _Entries.Length(); Index++) { MenuEntry &CurEntry = _Entries[Index]; if(CurEntry.Name() == Name) { return true; } } return false; } Menu& Menu::GetSubMenu(const String &Name) { for(UINT Index = 0; Index < _Entries.Length(); Index++) { MenuEntry &CurEntry = _Entries[Index]; if(CurEntry.Name() == Name) { return CurEntry.SubMenu(); } } SignalError("Sub menu not found"); return _Entries[0].SubMenu(); } void Menu::DispatchKeyboardShortcuts(InputManager &I) { for(UINT Index = 0; Index < _Entries.Length(); Index++) { MenuEntry &CurEntry = _Entries[Index]; CurEntry.DispatchKeyboardShortcuts(I); } } void MenuInterface::Init(ApplicationWindow &WM) { HMENU MenuBarHandle = CreateMenu(); Assert(MenuBarHandle != NULL, "CreateMenu failed"); BOOL Success = SetMenu(WM.Handle(), MenuBarHandle); Assert(Success != 0, "SetMenu failed"); Success = DrawMenuBar(WM.Handle()); Assert(Success != 0, "DrawMenuBar failed"); _MenuBar = new Menu(MenuBarHandle); } void MenuInterface::DispatchKeyboardShortcuts(InputManager &I) { if(_MenuBar != NULL) { _MenuBar->DispatchKeyboardShortcuts(I); } }