Легко получить системное меню в консольном приложении (GetSystemMenu) и добавить несколько собственных записей (AppendMenu). Но тогда эти пункты меню бесполезны для приложения. Есть ли способ попасть в поток сообщений, который бы определял, по какому пункту меню щелкнули?
Я пытался подключиться к окну консоли, но безрезультатно, я имею в виду WH_SYSMSGFILTER, все компилируется нормально, но нет сообщений, показывающих, что функция подключения не запускается системой.
Следующая вещь была ReadConsoleInput
и это работает частично, то есть показывает события мыши в системном меню, но нет информации в MENU_EVENT_RECORD
структура о том, какой пункт меню был нажат.
Это все мои попытки в одном фрагменте, здесь консоль должна быть залита сообщениями, но появляются только те из ReadConsoleInput, но они не содержат никакой полезной информации. Независимо от того, щелкает ли пользователь по первому или второму добавленному пункту меню, отображаются только два кода: 278 (0x116) WM_INITMENU и 287 (0x11F) WM_MENUSELECT, но я не знаю, как получить сообщение wParam сообщения WM_MENUSELECT.
#include <windows.h>
#include <stdio.h>
HHOOK sysMsgFilterHook;
LRESULT CALLBACK SysMsgFilterCallback(int nCode, WPARAM wParam, LPARAM lParam) {
printf("%i\n", nCode);
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
static LRESULT CALLBACK consoleWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
printf("%u\n", uMsg);
WNDPROC origProc = (WNDPROC) GetProp(hWnd, "origProc");
return CallWindowProc(origProc, hWnd, uMsg, wParam, lParam );
}int main() {
SetLastError(0);
HWND console_hwnd = GetConsoleWindow();
HMENU console_hMenu = GetSystemMenu(console_hwnd, FALSE);
HINSTANCE console_hinstance = (HINSTANCE)GetWindowLong(console_hwnd, GWL_HINSTANCE);
DWORD console_processid = GetWindowThreadProcessId(console_hwnd, NULL);
HANDLE console_input_handle = GetStdHandle(STD_INPUT_HANDLE);
AppendMenu(console_hMenu, MF_STRING | MF_CHECKED, NULL, "test menu item");
AppendMenu(console_hMenu, MF_STRING | MF_CHECKED, NULL, "yet another menu item");
WNDPROC origProc = (WNDPROC)SetWindowLongPtr(console_hwnd, GWL_WNDPROC, (LONG_PTR)&consoleWndProc);
SetProp(console_hwnd, "origProc", (HANDLE)origProc);
sysMsgFilterHook = SetWindowsHookEx(
WH_SYSMSGFILTER,
(HOOKPROC)SysMsgFilterCallback,
console_hinstance,
console_processid
);
DWORD numEvents = 0;
INPUT_RECORD input;
while(ReadConsoleInput(console_input_handle, &input, 1, &numEvents)) {
//printf("input.EventType: %i\n", input.EventType);
if (input.EventType == MENU_EVENT) {
printf("input.Event.MenuEvent.dwCommandId %i\n", input.Event.MenuEvent.dwCommandId);
}
}
//printf("GetLastError: %lu\n", GetLastError());
UnhookWindowsHookEx(sysMsgFilterHook);
system("pause");
return 0;
}
Мне удалось создать ловушку для событий мыши, то есть WH_MOUSE_LL. Но все остальные крючки не работают.
То, что я намерен сделать, это получить какое-то сообщение WM_MENUCOMMAND, а затем отдохнуть с GetMenuItemInfo.
Я слышал, что процедура подключения должна быть в другой DLL, но как это сделать? есть ли рабочие фрагменты?
Задача ещё не решена.
Других решений пока нет …