Date: 16.12.2019 10:02:10
Какой элемент управления вы используете, чтобы отображать текст? В общем случае, вам нужно установить с помощью SetWinEventHook хук на событие появления меню EVENT_SYSTEM_MENUPOPUPSTART и в обработчике этого события добавить в меню элемент через AppendMenu. Вот так будет выглядеть код для стандартного Edit Control:
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
bool Enabled = false;
UINT CurrentItemID;
HWND GetMenuOwner(DWORD thid) { //получает владельца активного меню UI-потока
GUITHREADINFO info;
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
GetGUIThreadInfo(thid, &info);
if ((info.flags & GUI_POPUPMENUMODE) != 0) {
return info.hwndMenuOwner;
}
else {
return NULL;
}
}
//Обработка появления меню
void CALLBACK HandleMenuPopup(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
LONG idObject, LONG idChild,
DWORD dwEventThread, DWORD dwmsEventTime)
{
HWND hOwner = GetMenuOwner(dwEventThread);
//получаем имя класса окна
WCHAR buf[100] = L"";
GetClassNameW(hOwner, buf, 100);
if (wcscmp(buf, L"Edit") == 0) {
//если это Edit Control, получаем меню
HMENU hMenu = (HMENU)SendMessage(hwnd, MN_GETHMENU, 0, 0);
int c = GetMenuItemCount(hMenu);
UINT id_max = 0;
//найдем максимальный ID элемента...
for (int i = 0; i < c; i++) {
UINT id = GetMenuItemID(hMenu, i);
//Значения больше 10000, видимо, зарезервированы для особых целей - с ними не работает
if (id >= 10000) continue;
if (id > id_max) id_max = id;
}
CurrentItemID = id_max + 1; //получаем уникальный ID для нового элемента
//добавляем новый элемент Test
BOOL res = AppendMenu(hMenu, MF_STRING | MF_POPUP, CurrentItemID, L"Test");
if (res == FALSE) {
printf("AppendMenu error %d", GetLastError());
Enabled = false;
return;
}
Enabled = true;
}
else Enabled = false;
}
//обработка нажатия элемента
void CALLBACK HandleMenuClick(HWINEVENTHOOK hook, DWORD event, HWND hwnd,
LONG idObject, LONG idChild,
DWORD dwEventThread, DWORD dwmsEventTime)
{
if (Enabled && idChild == CurrentItemID) {
HWND hOwner = GetMenuOwner(dwEventThread);
//выполнить необходимые действия...
}
}
void InitializeHook()
{
CoInitialize(NULL);
HWINEVENTHOOK hook = SetWinEventHook(
EVENT_SYSTEM_MENUPOPUPSTART, EVENT_SYSTEM_MENUPOPUPSTART, // Range of events
NULL, // Handle to DLL.
HandleMenuPopup, // The callback.
GetCurrentProcessId(), 0, // Process and thread IDs of interest (0 = all)
WINEVENT_OUTOFCONTEXT); // Flags.
if (hook == 0) printf("SetWinEventHook HandleMenuPopup error %d", GetLastError());
hook = SetWinEventHook(
EVENT_OBJECT_INVOKED, EVENT_OBJECT_INVOKED, // Range of events
NULL, // Handle to DLL.
HandleMenuClick, // The callback.
GetCurrentProcessId(), 0, // Process and thread IDs of interest (0 = all)
WINEVENT_OUTOFCONTEXT); // Flags.
if (hook == 0) printf("SetWinEventHook HandleMenuClick error %d", GetLastError());
}
Основано на ответе https://stackoverflow.com/a/32998022/8674428
Date: 17.12.2019 3:19:02
Текст через сообщение WM_GETTEXT, выделение - через EM_GETSEL.
WCHAR buf[256]=L""; SendMessage(hOwner, WM_GETTEXT, sizeof(buf)/sizeof(WCHAR), (LPARAM)buf); DWORD start, end; SendMessage(hOwner, EM_GETSEL, (WPARAM)&start, (LPARAM)&end); WCHAR selection[256] = L""; wcsncpy_s(selection, sizeof(selection) / sizeof(WCHAR), &(buf[start]), end - start);
Автор: VadimTagil