55using static Npp . DotNet . Plugin . Winforms . WinGDI ;
66using static Npp . DotNet . Plugin . Winforms . WinUser ;
77using static System . Diagnostics . FileVersionInfo ;
8+ using System . Runtime . InteropServices ;
89
910namespace WebEdit {
1011 partial class Main : IDotNetPlugin {
@@ -15,6 +16,8 @@ partial class Main : IDotNetPlugin {
1516 private const string IniFileName = PluginName + ".ini" ;
1617 private const string Version = "2.8" ;
1718 private static string MsgBoxCaption = $ "{ PluginName } { Version } ";
19+ private static string [ ] currentCommandKeys = null ; // Temporary storage of the current [Commands] keys to detect changes on reload
20+ private static bool currentCommandKeysAlerted = false ; // Whether the user has been alerted about changes in [Commands] section
1821 private const string AboutMsg =
1922 "This small freeware plugin allows you to wrap the selected text in "
2023 + "tag pairs and expand abbreviations using a hotkey.\n "
@@ -29,8 +32,6 @@ partial class Main : IDotNetPlugin {
2932
3033 static IniFile ini = null ;
3134 static bool isConfigDirty = false ;
32- private static string [ ] currentCommandKeys = null ;
33- private static bool currentCommandKeysAlerted = false ;
3435 internal static string iniDirectory , iniFilePath = null ;
3536
3637 public void OnBeNotified ( ScNotification notification )
@@ -52,7 +53,7 @@ public void OnBeNotified(ScNotification notification)
5253 LoadConfig ( ) ;
5354 isConfigDirty = false ;
5455 }
55- SetMenuItemNames ( ) ;
56+ SetMenuItemNames ( true ) ;
5657 break ;
5758 case NppMsg . NPPN_TBMODIFICATION :
5859 PluginData . FuncItems . RefreshItems ( ) ;
@@ -407,35 +408,68 @@ private static string GetIconPath(string icon)
407408 }
408409
409410 /// <summary>
410- /// Set the text of each menu item, i.e., remove the "WebEdit - " prefix.
411+ /// (Re-)add menu items
411412 /// </summary>
412413 /// <remarks>
413414 /// Adapted from <see href="https://github.com/alex-ilin/WebEdit/blob/7bb4243/Legacy-v2.1/Src/NotepadPPU.ob2#L184"/>
414415 /// </remarks>
415- private static unsafe void SetMenuItemNames ( )
416+ private static unsafe void SetMenuItemNames ( bool isReload = false )
416417 {
417418 var actions = new Actions ( ini ) ;
418419
419- // Alert if the [Commands] section has changed
420- if ( currentCommandKeys != null && ! currentCommandKeys . SequenceEqual ( actions . iniKeys ) )
420+ // Remove previously added plugin menu items so we can re-add them (NOT WORKING AS EXPECTED)
421+ // if (isReload )
421422 {
422- if ( ! currentCommandKeysAlerted )
423+
424+ // Alert if the [Commands] section has changed (TEMPORARY, may be removed in future versions)
425+ if ( currentCommandKeys != null && ! currentCommandKeys . SequenceEqual ( actions . iniKeys ) )
423426 {
424- MsgBoxDialog (
427+ if ( ! currentCommandKeysAlerted )
428+ {
429+ MsgBoxDialog (
425430 PluginData . NppData . NppHandle ,
426431 "The [Commands] configuration has changed. Please restart Notepad++ for all changes to take effect" ,
427432 MsgBoxCaption ,
428433 ( uint ) ( MsgBox . ICONWARNING | MsgBox . OK ) ) ;
434+ }
435+ currentCommandKeysAlerted = true ;
436+ return ;
429437 }
430- currentCommandKeysAlerted = true ;
431- return ;
438+ currentCommandKeys = actions . iniKeys ;
439+
440+ /*
441+ // Remove all previously added menu items (NOT WORKING AS EXPECTED)
442+ try
443+ {
444+ IntPtr hMenu = SendMessage(PluginData.NppData.NppHandle, (uint)NppMsg.NPPM_GETMENUHANDLE, (uint)NppMsg.NPPPLUGINMENU);
445+ if (hMenu != IntPtr.Zero)
446+ {
447+ // Iterate the registered function items and delete them by command id.
448+ // Iterate backwards to avoid any issues with indices when removing.
449+ for (int idx = PluginData.FuncItems.Items.Count - 1; idx >= 0; --idx)
450+ {
451+ try
452+ {
453+ int cmdId = PluginData.FuncItems.Items[idx].CmdID;
454+ if (PluginData.FuncItems.Items[idx].PFunc != null && PluginData.FuncItems.Items[idx].ItemName != "-")
455+ _ = NativeMethods.DeleteMenu(hMenu, (uint)cmdId, MF_BYCOMMAND); // Delete the menu item by command identifier
456+ else
457+ _ = NativeMethods.DeleteMenu(hMenu, (uint)idx, MF_BYPOSITION); // Delete the menu item separator by position
458+ }
459+ catch { }
460+ }
461+ }
462+ } catch { }
463+
464+ // Clear the registered function items so Utils.SetCommand can add them again
465+ try { PluginData.FuncItems.Items.Clear(); } catch { }
466+ */
432467 }
433- currentCommandKeys = actions . iniKeys ;
434468
435469 // Add menu items for each command in the [Commands] section of the ini-file
436- int i = 0 ;
437470 bool foundItem = false ;
438- foreach ( string key in currentCommandKeys )
471+ int i = 0 ;
472+ foreach ( string key in actions . iniKeys )
439473 {
440474 var methodInfo = actions . GetCommand ( i ++ ) ;
441475 if ( methodInfo == null )
@@ -463,6 +497,17 @@ private static unsafe void SetMenuItemNames()
463497 Utils . SetCommand ( "Edit Config" , EditConfig ) ;
464498 Utils . SetCommand ( "Load Config" , LoadConfig ) ;
465499 Utils . SetCommand ( "About..." , About ) ;
500+
501+ /* // Refresh the menu items if this is a reload request (NOT WORKING AS EXPECTED, SEE ABOVE)
502+ if (isReload)
503+ {
504+ PluginData.FuncItems.RefreshItems();
505+ _ = NativeMethods.DrawMenuBar(PluginData.NppData.NppHandle);
506+ }
507+ // */
508+
509+
510+
466511
467512 /* DEPRECATED (may cause non-expected behavior)
468513 // PluginData.FuncItems.Items.Clear();
@@ -526,5 +571,15 @@ public static int calculateLevenshtein(string source1, string source2) //O(n*m)
526571 // Return result
527572 return matrix [ source1Length , source2Length ] ;
528573 }
574+
575+ // P/Invoke helpers not present in Win32 wrapper
576+ private static class NativeMethods
577+ {
578+ [ DllImport ( "user32" , SetLastError = true ) ]
579+ public static extern bool DeleteMenu ( IntPtr hMenu , uint uPosition , uint uFlags ) ;
580+
581+ [ DllImport ( "user32" ) ]
582+ public static extern bool DrawMenuBar ( IntPtr hWnd ) ;
583+ }
529584 }
530585}
0 commit comments