notepad-plus-plus / npp-usermanual

Notepad++ User Manual
https://npp-user-manual.org/
Other
215 stars 98 forks source link

Add documentation on new notification and message related to native language preference #695

Closed molsonkiko closed 2 weeks ago

molsonkiko commented 2 weeks ago

In this commit to notepad-plus-plus, the NPPN_NATIVELANGCHANGED notification and NPPM_GETNATIVELANGFILENAME message were added, allowing plugins to determine the Notepad++ native language and be notified when the native language changes.

In addition to adding documentation of that notification and message in this part of the documentation, I might also add a subsection to the binary translation section of the manual explaining how to translate plugins. This subsection might include pseudocode along these lines:

char[] getNativeLangName()
{
    int lenFilename = SendMessage(hwndNpp, NPPM_GETNATIVELANGFILENAME, 0, 0) + 1;
    if (lenFilename == 1)
        return NULL; // the most likely reason this happened is that you sent the message to an old version of Npp that hasn't implemented it
    char filename[lenFilename];
    SendMessage(hwndNpp, NPPM_GETNATIVELANGFILENAME, lenFilename, filename); // fill the buffer
    if (!filename.Endswith(".xml"))
        return NULL;
    char[] langName = filename.Substring(0, lenFilename - 4); // to remove the ".xml" at the end
    return langName;
}

HMENU getMyPluginMenuHandle()
{
    const int NPPPLUGINMENU = 0;
    HMENU allPluginsMenuHandle = SendMessage(hwndNpp, NPPM_GETMENUHANDLE, NPPPLUGINMENU, 0);
    if (allPluginsMenuHandle == NULL)
        return NULL;
    // below code references the following from Win32:
    // * GetMenuItemCount (method): https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmenuitemcount
    // * GetMenuItemInfo (method): https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmenuiteminfow
    // * MENUITEMINFO (struct): https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-menuiteminfow 
    // * GetSubMenu (method): https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsubmenu
    int numPluginsInstalled = GetMenuItemCount(allPluginsMenuHandle);
    if (numPluginsInstalled <= 0)
        return NULL;
    for (int ii = 0; ii < numPluginsInstalled; ii++)
    {
         // GetMenuItemTextAtIndex is shorthand for some stuff involving a MENUITEMINFO struct and two calls to GetMenuItemInfo that fill the pluginName char buffer. See the docs above.
        char[] pluginName = GetMenuItemTextAtIndex(allPluginsMenuHandle, ii);
        if (pluginName == myPluginName)
        {
            return GetSubMenu(allPluginsMenuHandle, ii);
        }
    }
    return NULL;
}

void translateMyPlugin()
{
    HMENU myPluginMenuHandle = getMyPluginMenuHandle();
    char[] langName = getNativeLangName();
    // determine if your plugin can translate to the new language
    bool myPluginCanTranslate = someFunction(langName);
    if (langName == NULL || myPluginMenuHandle == NULL || !myPluginCanTranslate)
        return;
    int numCommandsMyPlugin = GetMenuItemCount(myPluginMenuHandle);
    for (int ii = 0; ii < numCommandsMyPlugin; ii++)
    {
        // use SetMenuItemInfo (https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setmenuiteminfow) to translate all your menu items to the new language
    }
    // do any other translation you want (for example, change the text on any forms you have open)
}

// this is the standard method that all plugins use to listen to NPPN notifications
void beNotified(scNotification * notif)
{
    switch (notif->nmhdr.code)
    {
        // do other plugin stuff in response to notifications
        case NPPN_READY: // at Notepad++ startup, after everything else is initialized
        case NPPN_NATIVELANGCHANGED: // when the user changes their native language preference
            translateMyPlugin();
            break;
    }
}
donho commented 2 weeks ago

In addition to adding documentation of that notification and message in this part of the documentation, I might also add a subsection to the binary translation section of the manual explaining how to translate plugins. This subsection might include pseudocode along these lines:

It won't be necessary IMO. Such information will be in Plugins Communication so no need to put these info everywhere to pollute User Manual. Let's keep User Manual short, clean and concise.