From 0f6b30741da4089ac1759cfa1b85e711174843d6 Mon Sep 17 00:00:00 2001 From: nitsuja Date: Sun, 6 Dec 2009 19:20:50 +0000 Subject: [PATCH] lots of emulator features were missing from the french/danish/chinese menus... added them (untranslated) fix missing accent marks and broken chinese characters resulting from the recent japanese language patch fix UpdateHotkeyAssignment not working for many hotkeys and possibly breaking chinese/japanese menu items --- desmume/src/windows/main.cpp | 196 +++++++++---------------------- desmume/src/windows/resources.rc | Bin 811722 -> 824892 bytes 2 files changed, 54 insertions(+), 142 deletions(-) diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 17f28c6e7..a82d5301c 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -3473,8 +3473,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM { SPU_Pause(1); - UpdateHotkeyAssignments(); //Add current hotkey mappings to menu item names - MENUITEMINFO mii; TCHAR menuItemString[256]; ZeroMemory(&mii, sizeof(MENUITEMINFO)); @@ -3635,6 +3633,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM DesEnableMenuItem(mainMenu, IDM_SCREENSEP_COLORBLACK, false); } + UpdateHotkeyAssignments(); //Add current hotkey mappings to menu item names + return 0; } @@ -5589,15 +5589,17 @@ void ResetGame() } //adelikat: This function changes a menu item's text -void ChangeMenuItemText(int menuitem, string text) +void ChangeMenuItemText(int menuitem, wstring text) { - MENUITEMINFO moo; + MENUITEMINFOW moo; moo.cbSize = sizeof(moo); moo.fMask = MIIM_TYPE; moo.cch = NULL; - GetMenuItemInfo(mainMenu, menuitem, FALSE, &moo); - moo.dwTypeData = (LPSTR)text.c_str(); - SetMenuItemInfo(mainMenu, menuitem, FALSE, &moo); + if(GetMenuItemInfoW(mainMenu, menuitem, FALSE, &moo)) + { + moo.dwTypeData = (LPWSTR)text.c_str(); + SetMenuItemInfoW(mainMenu, menuitem, FALSE, &moo); + } } const char* GetModifierString(int num) @@ -5640,146 +5642,56 @@ static void TranslateKeyForMenu(WORD keyz,char *out) } } +void UpdateHotkeyAssignment(const SCustomKey& hotkey, DWORD menuItemId) +{ + //Update all menu items that can be called from a hotkey to include the current hotkey assignment + char str[256]; //Temp string + wchar_t wstr[256]; //Temp string + wstring text; //Used to manipulate menu item text + wstring keyname; //Used to hold the name of the hotkey + int truncate; //Used to truncate the hotkey config from the menu item + + HMENU menu = GetMenuItemParent(menuItemId); + if(!GetMenuStringW(menu,menuItemId, wstr, 255, MF_BYCOMMAND)) //Get menu item text + return; + text = wstr; //Store in string object + truncate = text.find(L"\t"); //Find the tab + if (truncate >= 1) //Truncate if it exists + text = text.substr(0,truncate); + TranslateKeyForMenu(hotkey.key, str); + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, wstr, 255); + keyname = wstr; + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, GetModifierString(hotkey.modifiers), -1, wstr, 255); + keyname.insert(0,wstr); + text.append(L"\t" + keyname); + ChangeMenuItemText(menuItemId, text); +} + //adelikat: This function find the current hotkey assignments for corresponding menu items // and appends it to the menu item. This function works correctly for all language menus // However, a Menu item in the Resource file must NOT have a /t (tab) in its caption. void UpdateHotkeyAssignments() { - //Update all menu items that can be called from a hotkey to include the current hotkey assignment - char str[255]; //Temp string - string text; //Used to manipulate menu item text - string keyname; //Used to hold the name of the hotkey - int truncate; //Used to truncate the hotkey config from the menu item - //-------------------------------FILE--------------------------------------- - - - //Open ROM - GetMenuString(mainMenu,IDM_OPEN, str, 255, IDM_OPEN); //Get menu item text - text = str; //Store in string object - truncate = text.find("\t"); //Find the tab - if (truncate >= 1) //Truncate if it exists - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.OpenROM.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.OpenROM.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(IDM_OPEN, text); - - //Save Screenshot As... - GetMenuString(mainMenu,IDM_PRINTSCREEN, str, 255, IDM_PRINTSCREEN); - text = str; - truncate = text.find("\t"); - if (truncate >= 1) - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.PrintScreen.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.PrintScreen.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(IDM_PRINTSCREEN, text); - - //adelikat: Why don't these work? GetMenuString returns null for these IDs yet those are the valid ID numbers - /* - //Record AVI - GetMenuString(mainMenu,IDM_FILE_RECORDAVI, str, 255, IDM_FILE_RECORDAVI); - text = str; - truncate = text.find("\t"); - if (truncate >= 1) - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.RecordAVI.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.RecordAVI.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(IDM_FILE_RECORDAVI, text); - - //Stop AVI - GetMenuString(mainMenu,IDM_FILE_STOPAVI, str, 255, IDM_FILE_STOPAVI); - text = str; - truncate = text.find("\t"); - if (truncate >= 1) - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.StopAVI.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.StopAVI.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(IDM_FILE_STOPAVI, text); -*/ - - //-------------------------------EMULATION---------------------------------- - - //Pause - GetMenuString(mainMenu,IDM_PAUSE, str, 255, IDM_PAUSE); - text = str; - truncate = text.find("\t"); - if (truncate >= 1) - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.Pause.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.Pause.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(IDM_PAUSE, text); - - //Reset - GetMenuString(mainMenu,IDM_RESET, str, 255, IDM_RESET); - text = str; - truncate = text.find("\t"); - if (truncate >= 1) - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.Reset.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.Reset.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(IDM_RESET, text); - - //-------------------------------EMULATION---------------------------------- -/* - //Display Frame Counter - GetMenuString(mainMenu,ID_VIEW_FRAMECOUNTER, str, 255, ID_VIEW_FRAMECOUNTER); - text = str; - truncate = text.find("\t"); - if (truncate >= 1) - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.ToggleFrameCounter.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.ToggleFrameCounter.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(ID_VIEW_FRAMECOUNTER, text); - - //Display FPS - GetMenuString(mainMenu,ID_VIEW_DISPLAYFPS, str, 255, ID_VIEW_DISPLAYFPS); - text = str; - truncate = text.find("\t"); - if (truncate >= 1) - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.ToggleFPS.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.ToggleFPS.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(ID_VIEW_DISPLAYFPS, text); - - //Display Input - GetMenuString(mainMenu,ID_VIEW_DISPLAYINPUT, str, 255, ID_VIEW_DISPLAYINPUT); - text = str; - truncate = text.find("\t"); - if (truncate >= 1) - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.ToggleInput.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.ToggleInput.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(ID_VIEW_DISPLAYINPUT, text); - - //Display Lag Counter - GetMenuString(mainMenu,ID_VIEW_DISPLAYLAG, str, 255, ID_VIEW_DISPLAYLAG); - text = str; - truncate = text.find("\t"); - if (truncate >= 1) - text = text.substr(0,truncate); - TranslateKeyForMenu(CustomKeys.ToggleLag.key, str); - keyname = str; - keyname.insert(0,GetModifierString(CustomKeys.ToggleLag.modifiers)); - text.append("\t" + keyname); - ChangeMenuItemText(ID_VIEW_DISPLAYLAG, text); -*/ + UpdateHotkeyAssignment(CustomKeys.OpenROM, IDM_OPEN); + UpdateHotkeyAssignment(CustomKeys.PrintScreen, IDM_PRINTSCREEN); + UpdateHotkeyAssignment(CustomKeys.RecordAVI, IDM_FILE_RECORDAVI); + UpdateHotkeyAssignment(CustomKeys.Pause, IDM_PAUSE); + UpdateHotkeyAssignment(CustomKeys.Reset, IDM_RESET); + UpdateHotkeyAssignment(CustomKeys.ToggleFrameCounter, ID_VIEW_FRAMECOUNTER); + UpdateHotkeyAssignment(CustomKeys.ToggleFPS, ID_VIEW_DISPLAYFPS); + UpdateHotkeyAssignment(CustomKeys.ToggleInput, ID_VIEW_DISPLAYINPUT); + UpdateHotkeyAssignment(CustomKeys.ToggleLag, ID_VIEW_DISPLAYLAG); + UpdateHotkeyAssignment(CustomKeys.PlayMovie, IDM_PLAY_MOVIE); + UpdateHotkeyAssignment(CustomKeys.RecordMovie, IDM_RECORD_MOVIE); + UpdateHotkeyAssignment(CustomKeys.StopMovie, IDM_STOPMOVIE); + UpdateHotkeyAssignment(CustomKeys.RecordWAV, IDM_FILE_RECORDWAV); + UpdateHotkeyAssignment(CustomKeys.NewLuaScript, IDC_NEW_LUA_SCRIPT); + UpdateHotkeyAssignment(CustomKeys.MostRecentLuaScript, IDD_LUARECENT_RESERVE_START); + UpdateHotkeyAssignment(CustomKeys.CloseLuaScripts, IDC_CLOSE_LUA_SCRIPTS); + for(int i = 0; i < 10; i++) + UpdateHotkeyAssignment(CustomKeys.Save[(i+1)%10], IDM_STATE_SAVE_F1 + i); + for(int i = 0; i < 10; i++) + UpdateHotkeyAssignment(CustomKeys.Load[(i+1)%10], IDM_STATE_LOAD_F1 + i); } diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index efbe60e2dbebd759c65469c19e870c3fd8d6081b..0ab90cb8f12a49406bbae61f33f26fe0dc3bc135 100644 GIT binary patch delta 7891 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 delta 6872 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