2

Windows 7 より前は、ソリューションは簡単でした。独自のメニューを追加して、独自の「元に戻す、やり直し、切り取り、コピー、貼り付け、削除、すべて選択」メニュー項目を作成するだけです。しかし、メニューが Unicode と入力メッセージで非常に複雑になったため、これはもはや不可能です。

4

2 に答える 2

3

エディット コントロールをサブクラス化してからフックを使用する必要があります。コード例を次に示します。

まず、編集コントロールをサブクラス化します。通常は次のようになりWndProcます。

LRESULT CALLBACK WndProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
    case WM_CREATE:
    {
        HANDLE m_editControl; /* Supposing it is created */
        SetWindowSubclass(m_editControl, EditSubclassProc, 0, NULL);
    }
    break;
    default:
        /* default message handling */
    }
}

次に、サブクラス関数で:

LRESULT CALLBACK EditSubclassProc(HWND hWndEdit, UINT Msg, WPARAM wParam, LPARAM lParam, UINT_PTR uIDSubclass, DWORD_PTR dwRefData)
{
    LRESULT ret{};

    switch (Msg)
    {
    case WM_CONTEXTMENU:        
    {
        HWINEVENTHOOK hWinEventHook{ SetWinEventHook(EVENT_SYSTEM_MENUPOPUPSTART, EVENT_SYSTEM_MENUPOPUPSTART, NULL,
            [](HWINEVENTHOOK hWinEventHook, DWORD Event, HWND hWnd, LONG idObject, LONG idChild, DWORD idEventThread, DWORD dwmsEventTime)
            {
                if (idObject == OBJID_CLIENT && idChild == CHILDID_SELF)
                {
                    HMENU hMenuContextEdit{ (HMENU)SendMessage(hWnd, MN_GETHMENU, NULL, NULL) };

                    // Do what you want to do
                }
            },
            GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_OUTOFCONTEXT) };

        ret = DefSubclassProc(hWndEditMessage, Msg, wParam, lParam);

        UnhookWinEvent(hWinEventHook);
    }
    break;
    default:
        {
            ret = DefSubclassProc(hWndEdit, Msg, wParam, lParam);
        }
        break;
    }

    return ret;
}
于 2019-04-18T16:53:23.230 に答える
1

Okay i found how to do it

static bool is_first_time;

case WM_CONTEXTMENU: {
   is_first_time = true;
   original_window_proc(message,wparam,lparam);
   break;

case WM_ENTERIDLE:
    if (wparam == MSGF_MENU) {
        if (is_first_time) {
            is_first_time = false; 
            MENUBARINFO mbi;
            memset(&mbi, 0, sizeof(MENUBARINFO));
            mbi.cbSize = sizeof(MENUBARINFO);
            GetMenuBarInfo((HWND)lparam, OBJID_CLIENT, 0, &mbi);
            if (::IsMenu((HMENU)mbi.hMenu)) {
               .... add your menu items here
            }
        }
    }

Unfortunately this does not work because the code uses TrackPopupMenu with the TPM_RETURNCMD and TPM_NONOTIFY flags. So you can add new menu items but there is no way to handle the commands. Bad Microsoft, very bad design.

于 2011-06-09T14:08:42.833 に答える