How to add custom item to system menu in C++? - c++

I need to enumerate all running applications. In particular, all top windows. And for every window I need to add my custom item to the system menu of that window.
How can I accomplish that in C++?
Update.
I would be more than happy to have a solution for Windows, MacOS, and Ubuntu (though, I'm not sure if MacOS and Ubuntu have such thing as 'system menu').

For Windows, another way to get the top-level windows (besides EnumWindows, which uses a callback) is to get the first child of the desktop and then retrieve all its siblings:
HWND wnd = GetWindow(GetDesktopWindow(), GW_CHILD);
while (wnd) {
// handle 'wnd' here
// ...
wnd = GetNextWindow(wnd, GW_HWNDNEXT);
}
As for getting the system menu, use the GetSystemMenu function, with FALSE as the second argument. The GetMenu mentioned in the other answers returns the normal window menu.
Note, however, that while adding a custom menu item to a foreign process's window is easy, responding to the selection of that item is a bit tricky. You'll either have to inject some code to the process in order to be able to subclass the window, or install a global hook (probably a WH_GETMESSAGE or WH_CBT type) to monitor WM_SYSCOMMAND messages.

Once you have another window's top level handle, you may be able to call GetMenu() to retrieve the Window's system menu and then modify it, eg:
HMENU hMenu = GetMenu(hwndNext);

You can use EnumWindows() to enumerate top level Windows.
I don't have a specific answer for the second part of your question, but if you subclass the window, I imagine you can modify the system menu.
EDIT: or do what Chris said: call GetMenu()

Re: the update - please note that not even Microsoft Windows requires windows to have a sytem menu. GetMenu( ) may return 0. You'll need to intercept window creation as well, because each new top window presumably needs it too.
Also, what you propose is rather intrusive to other applications. How are you going to ensure they don't break when you modify their menus? And how are you going to ensure you suppress the messages? In particular, how will you ensure you intercept them before anyone else sees them? To quote Raymond Chen, imagine what happens if two programs would try that.

Related

which window is on top on the other

I have 2 windows and I want to know which window is on the top of the other?
I tried to test using GetWindowLong and comparing the results but no chance.
LONG wndState1 = ::GetWindowLong(handler1, GWL_EXSTYLE);
LONG wndState2 = ::GetWindowLong(handler2, GWL_EXSTYLE);
both results is equal to 256.
Edited: In the picture below I have the dialog of notepad++ is on top of the FileZilla, How do I Get That by Code.
Is there a trick for that ?
THank you
GetWindowLong is used to retrieve style information for a particular window.
In order to get the top-most window, use
HWND WINAPI GetForegroundWindow(void);
You will still need to know the window handles (HWND) for the processes you're interested in so that you can find out which process owns the foreground window.
Note that this API can only return the window that the user is interacting with (or has interacted with most recently).
UPDATE:
I agree with Remy that there isn't any API to do that. The only way I can think of to actually do that is to install a global hook and intercept certain messages (e.g. WM_ACTIVATE, WM_SETFOCUS and so on). Since you will also retrieve the timestamps for the messages, it should be simple to infer which window is on top of any other window. This will require you to write a dll but this is relatively simple to do. I can't guarantee this will work either though I think it will (I've written a global hook but never used it to find out the z-order of windows)

Windows.h - Notification when focus enters a text input

I'm trying to come up with a solution for setting up a notification when focus enters a text field. The end goal in mind is to recreate the type of functionality you see on mobile devices with on screen keyboards.
So far I've been exploring SetWinEventHook with EVENT_OBJECT_FOCUS and GetGUIThreadInfo with GUI_CARETBLINKING.
From the docs:
EVENT_OBJECT_FOCUS
An object has received the keyboard focus. The system sends this event
for the following user interface elements: list-view control, menu
bar, pop-up menu, switch window, tab control, tree view control, and
window object.
GUI_CARETBLINKING The caret's blink state. This bit is set if the
caret is visible.
Using these methods I've come up with this solution:
void TextInputHelper::setupEventHook(FREContext iCtx)
{
ctx = iCtx;
CoInitialize(NULL);
evHook = SetWinEventHook(EVENT_OBJECT_FOCUS, EVENT_OBJECT_END, NULL,
handleEventObjectFocus, 0, 0,
WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS);
}
void CALLBACK handleEventObjectFocus(HWINEVENTHOOK hook, DWORD evt, HWND hwnd,
LONG idObj, LONG idChild, DWORD thread, DWORD time)
{
GUITHREADINFO threadInfo;
threadInfo.cbSize = sizeof(GUITHREADINFO);
BOOL result = GetGUIThreadInfo(thread, &threadInfo);
if(threadInfo.flags & GUI_CARETBLINKING)
{
//text field focus
}
}
This does seem to work in some cases but its definitely not reliable. Programs like Notepad an IE seem to work fine but others like Firefox do not. This also will not work for things like text fields on websites because it doesn't look like handleEventObjectFocus will get called.
Does anyone know of another way to approach this problem? I've been searching around and it seems like I might be looking for something in the Accessibility APIs but I haven't been able to dig up to much on it.
Thanks!
edit
To clarify, I'm looking to receive a notification when focus enters any text field. This application is a win32 dll and will never have focus its self.
If you're using standard Windows controls WM_SETFOCUS should do the trick. No need to get fancy with hooking etc.
EDIT: For system wide behavior you can check out SetWindowsHookEx. To catch events system-wide you need to use it from within a DLL. You can use a combination of hooks including one that catches WM_SETFOCUS.
If you're trying to supply an alternative text input method, you should look into "IME" - "Input Method Editor". These are directly supported by the OS.
You can catch the entrance into a text field using the EN_SETFOCUS notification.
WM_FOCUS is for the window itself, not for controls that are in it. Otherwise said, if you want to use WM_FOCUS, you'll have to subclass your EDIT field. It's not necessary here.
EDIT: it wasn't completely clear that you wanted a system-wide behavior. IN that case you have to use an hook (cf. SetWindowsHookEx) as explained in the answer above. Sorry.

How to move the cursor to the last opened window (possibly popup) in c++

I need to move the mouse to the last opened window. This last window will be a popup created by whatever website.
I guess all I need is to get the position of the last opened window and use SetMousePos, right?
I'm not really familiar with the windows API and any help is welcome - Thanks!
Edit:
To answer the questions, we are writing a program that gets malware data. Unfortunately some malware only start working after the mouse moves to a popup they opened. Its a research-based application
I haven't tested this but I believe you could try the following:
Enumerate running processes and order by PID.
The highest number PID should be the "newest" process.
For the newest process enumerate its windows (use GetWindowThreadProcessId)
At this point I guess you'd have to pick which window you think is the "main" window, for example if the malware opens two windows I don't know how you're going to choose which one to give focus to?
Of your picked HWND get its position on the desktop.
Use SetMousePos to move the mouse to the position of the window.
I haven't included all the API's you'll need for these tasks as its generally quite easy to find on here :)
One way to track recently opened windows is to use SetWinEventHook to listen to the EVENT_OBJECT_CREATE and EVENT_OBJECT_SHOW events. In the callback, filter:
just events with a non-null HWND where idObject==OBJID_WINDOW to get just window creation events (vs other creation events such as for items within a listbox)
for top-level only windows, also filter by checking GetAncestor(hwnd, GA_PARENT) is GetDesktopWindow()
And check that the window is indeed currently visible (WS_VISIBLE style is set in GetWindowLong(GWL_STYLE)).
Also filter by GetWindowThreadProcessId() and via the thread/process you pass into SetWinEventHook if you only care about HWNDs from a specific app.
The reason for checking both of these events is that some windows are created hidden and then shown, others are created fully visible, while others are created once, then shown/hidden many times over their lifetime.
You can then cache this 'last known created hwnd' in a global and check it as needed, using GetWindowRect() to get its location, and SetCursorPos() to move the mouse to that location.
--
If the most recent popup is an active window which takes focus - as is the case with dialogs, but not usually the case with 'pop-under' windows - you can use GetGUIThreadInfo(NULL, ...) to determine the currently active HWND, which might be the one you are looking for, returned in the GUITHREADINFO.hwndActive member of the struct you pass it.

How do I write a console application in Windows that would minimize to the system tray?

I have a written a Visual C++ console application (i.e. subsystem:console) that prints useful diagnositic messages to the console.
However, I would like to keep the application minimized most of the time, and instead of minimizing to the taskbar, appear as a nice icon on the system tray. I would also like to restore the console when the system tray icon is clicked.
How should I change my program to do this?
This is going to be an ugly hack.
First, you have to retrieve the hWnd / hInstance of you console application. Right now, I can only come up with one way:
Create a Guid with CoCreateGuid()
Convert it to a string
Set the title of the console window to this guid with SetConsoleTitle()
Find the hWnd of the your window with the Guid as the tile with FindWindow()
And you can do it from the usual way from this point. See http://www.gidforums.com/t-9218.html for more info.
Don't forget the rename your console window to the original title once you're done.
As you can see, even though this is possible to do, it's a horrible and painful solution. Please don't do it. Please do not minimize console applications to the system tray. It is not something you are supposed to be able to do in the Windows API.
You might want to write a separate gui to function as a log reader. You will then find it much easier to make this minimize to the tray. It would also let you do some other stuff you might find useful, such as changing which level of logging messages are visible on the fly.
To learn the console's hWnd you have two choices:
On Windows 2000 or later you can use the GetConsoleWindow() function. Don't forget to define _WIN32_WINNT as 0x0500 or greater before including windows.h to have access to this function.
If you want to run your program on earlier Windows versions as well then you must use something like the GUID trick described above.
Probably your best bet is to create a "Message-only window" (a message queue without a visible window) to receive the Notification Area messages.
The answer with a GUID is completely ridiculous (no sense at all)
The Console hWnd is of course given by GetConsoleWindow() (!)

DLL plugin that creates a parented window doesn't handle messages correctly

I'm creating a plugin framework, where my application loads a series of plugin DLL's, then creates a new window and pass this new window's handle to the plugin. The plugin can, then, use this handle to create their own GUI.
Everything seems to be working very well. The only problem is that when I press TAB on a plugin widget (An editbox, for example), it doen't jump to another widget. I figured out that some Windows messages are passed, and some others aren't. The WM_KEYDOWN is passed for other keys, because I can type on the editbox, but this message doesn't handle TAB key.
Hope somebody has a hint.
I'm using Borland VCL with CBuilder, but I think I could use any framework under WIN32 to create these plugins, since they never know how their parent windows were created.
It's very complex matter indeed.
When you hit TAB focus jumps to another control only when these controls belong to a Modal Dialog Box. In fact there are some buttons like ESC, LEFT, RIGHT, DOWN, UP, TAB which modal dialog message function treats in a special way. If you want these keys to behave in similar way with modeless dialog box or any other window you should change you message processing function and use IsDialogMessage inside. You'll find more information about IsDialogMessage function in MSDN also to better understand this stuff you may check as well Dialog Boxes section.
And, as was mentioned before, you should set WS_TABSTOP and WS_GROUP styles when needed.
Good luck!
I believe you'll have to take the following steps:
Subclass your edit controls (and other controls as needed).
Capture the WM_KEYDOWN message in your edit control's WndProc.
Check to see if the shift key is currently held down (using GetKeyState or similar).
Call GetWindow, passing in a handle to your edit control and either GW_HWNDPREV or GW_HWNDNEXT depending on whether shift is held down. This will give you the handle to the window that should receive focus.
Call SetFocus and pass in the window handle you got in step 4.
Make sure you handle the case where your edit controls are multiline, as you might want to have a real tab character appear instead of moving to the next control.
Hope that helps!
I believe you suffer from having a different instance of the VCL in each of your dlls and exes. Classes from the dll are not the same as the ones from your exe, even if they are called the same. Also global variables (Application, Screen) are not shared between them. Neither is the memory since they both have their own memory manager.
The solution is to have the dlls and the exe share the VCL library and the memory manager. I am not a BCB developer, but a Delphi developer. In Delphi we would just use the rtl and the vcl as runtime packages. Maybe you could do the BCB equivalent.
A DLL has its own TApplication object.
to provide uniform key handling. when the DLL Loads.
assign the DLL::TApplication to the EXE::TApplication
Be sure to do the reverse on exit.
--
Michael