Мне нужно перечислить все запущенные приложения. В частности, все верхние окна. И для каждого окна мне нужно добавить свой настраиваемый элемент в системное меню этого окна.
Как я могу сделать это на C++?
Обновлять.
Я был бы более чем счастлив иметь решение для Windows, MacOS и Ubuntu (хотя я не уверен, есть ли в MacOS и Ubuntu такое понятие, как «системное меню»).





Если у вас есть дескриптор верхнего уровня другого окна, вы можете вызвать GetMenu (), чтобы получить системное меню окна, а затем изменить его, например:
HMENU hMenu = GetMenu(hwndNext);
Я думаю, вы имели в виду GetSystemMenu, а не GetMenu; см. мой ответ.
Вы можете использовать EnumWindows () для перечисления окон верхнего уровня.
У меня нет конкретного ответа на вторую часть вашего вопроса, но если вы подклассифицируете окно, я полагаю, вы можете изменить системное меню.
Обновлено: или сделайте то, что сказал Крис: вызовите GetMenu ()
Re: обновление - обратите внимание, что даже Microsoft Windows не требует наличия системного меню в Windows. GetMenu () может вернуть 0. Вам также нужно будет перехватить создание окна, потому что оно, вероятно, тоже нужно каждому новому верхнему окну.
Кроме того, то, что вы предлагаете, довольно мешает другим приложениям. Как вы собираетесь гарантировать, что они не сломаются, когда вы измените их меню? И как вы собираетесь подавить сообщения? В частности, как вы обеспечите перехват их до того, как их заметят другие? Процитируя Раймонда Чена, представьте, что произойдет, если две программы попытаются это сделать.
Для Windows другой способ получить окна верхнего уровня (помимо EnumWindows, который использует обратный вызов) - это получить первый дочерний элемент рабочего стола, а затем получить всех его братьев и сестер:
HWND wnd = GetWindow(GetDesktopWindow(), GW_CHILD);
while (wnd) {
// handle 'wnd' here
// ...
wnd = GetNextWindow(wnd, GW_HWNDNEXT);
}
Что касается получения меню система, используйте функцию GetSystemMenu со вторым аргументом FALSE. GetMenu, упомянутый в других ответах, возвращает меню окна обычный.
Обратите внимание, однако, что, хотя добавить настраиваемый пункт меню в окно стороннего процесса легко, ответить на выбор этого элемента немного сложно. Вам придется либо ввести некоторый код в процесс, чтобы иметь возможность создать подкласс окна, либо установить глобальную ловушку (возможно, типа WH_GETMESSAGE или WH_CBT) для отслеживания сообщений WM_SYSCOMMAND.
Ваш ответ только что сделал мой день (на самом деле ночь)! Я никогда не читал о WH_CBT, и, увидев ваш пост, я теперь могу успешно перехватить (с помощью внедренного кода) WM_SYSCOMMAND из другого процесса.
Какая целевая ОС - Windows?