How do you create a window that is attached to the side of parent window opens like a drawer?
In such a way that you don't lose focus of parent window.
What you basically need to do is create yourself a custom control representing your drawer. I'm not sure if that's something you're familiar with or not, but if not there are plenty of tutorials about, such as this one.
I imagine what you'd do is designate part of your control to be the "handle", which if clicked upon "opens" the drawer. You would achieve this by handling the WM_LBUTTONDOWN/WM_LBUTTONUP messages in your control's window procedure, and changing its size from its closed size to its open size when clicks are detected. I haven't used it before, but you might be able to simply achieve animation using AnimateWindow.
You'd probably also want to have your control send it's parent window a notification whenever it is opened or closed, so that your parent window can re-size or move other controls if necessary. You can achieve this by sending a WM_NOTIFY message to the parent window with your own notification code, or using your own custom message. Your parent window would then have to respond to such messages in its window procedure.
As far as I'm aware there's no specific examples to be found addressing your exact requirements, so I probably can't supply much more info at the moment. If there's anything else in particular you need to know to get this running, don't hesitate to ask.
Related
I was wondering how Windows applications typically keep track of dirty controls in a dialog, so that when the user clicks a button like "Apply" or "Save," the application knows which controls' values to commit.
I see that edit controls have an EM_GETMODIFY message, which will tell you whether the contents of the edit control have been modified, but I don't think that type of message is available for other controls like date-time pickers or combo boxes.
So I suspect that this would be done by monitoring change notifications sent from the controls to the parent dialog. But if that's the case, how might the change events be flagged or stored? I thought that perhaps that whenever a change occurs, the application could store the control's ID or hwnd in a std::unordered_set, and then iterate through the set when it's time to commit. Or is there another, more accepted and efficient way? Thank you for any guidance.
I am trying to make a xlib traybar for X11 where it embeds the tray icons using XEMBED as described in the tray specs. However when I close the application with the tray icon it just removes it from the container window but the black container window rectangle and the entry in my code still exists.
In the XEMBED documentation it says
It is the responsibility of the embedder to keep track of all forwarded
accelerators and to remove them when the client window dies.
However my application does not get any events or indication when a embedded window dies.
I basically only receive a dock request event and nothing else afterwards. When a dock request event comes in I create a child window for my panel which contains the tray window and reparent it like this:
enum trayIconSize = 24; // dimensions of icon
icon.trayWindow = XCreateWindow(x.display, panel.window, 0, 0, ...);
icon.ownerHandle = event.data.l[2]; // window id of icon which wants to dock
XReparentWindow(x.display, icon.ownerHandle, icon.trayWindow, 0, 0);
XMoveResizeWindow(x.display, icon.ownerHandle, 0, 0, trayIconSize, trayIconSize);
Adding it to the panel works without any problems but I don't know how to check when to remove it again.
How do I make my application receive close events for those tray icons or how do I check if the reparented window still exists?
I have actually done this before myself: https://github.com/adamdruppe/taskbar it has hacks for my specific setup in the width thing, but most of it should be reasonably usable and the code might help guide you.
But what you want to do is ask for events on the icon window. It has been a while, so I'm kinda using my own code as a guide here, but when I got the dock request, I called XSelectInput(dd, id, EventMask.StructureNotifyMask);
StructureNotifyMask subscribes to events including MapNotify, DestroyNotify, you prolly see where this is going :)
Once you have selected the input on the icon window, you regular event loop can check for the DestroyNotify and UnmapNotify events (my code checks both, tbh, I'm not sure which one actually triggers when the icon is removed) and compare the .window member of the event to your icon's window ID. If it matches, go ahead and remove it from your list because it is gone now.
My taskbar does seem to have a bug if the application crashes as opposed to being closed normally, so I might still be missing something, but checking the event works in most cases.
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.
Scenario: I would like a window control which is a sub-window in my dialog (a subwindow of a subwindow) to propagate its notification messages out to the dialog window.
e.g. A COMBOBOX contains an EDIT control. I have a circumstance where I would really like to know when the EDIT field gains and loses focus (mainly because the stupid COMBOBOX doesn't claim focus or give me notifications if it happens to its embedded EDIT).
But I can see how this could be a general issue: a Control issues a message to its parent WM_NOTIFY... which the direct parent doesn't care about, but maybe its parent does.
Is there a generic way to ask a windows window to propagate notification messages from its subwindows?
e.g. if dialog D has a control C which has a sub-control C', then is there a way to ensure that D receives WM_NOTIFY messages from C'?
I believe you need to subclass the window, see http://msdn.microsoft.com/en-us/library/ms997565.aspx (Content has been removed!) .
I want to make a C++ button on Start>Run i.e but when I do it will not do signalled event?
Im sorry I have seen that you do not get the question.
Ok basically when you create a button with CreateWindowEx(); I want to do that but put on a different window with SetPArent which I have already done now the button does not work so I need my program to someone get when it is clicked from the Run window as example!
And yes you have it, but it's not making the button is the problem it's getting when it's clicked with my program since it does not belong to it anymore!
You need to apply the ancient but still-supported technique known in Windows as subclassing; it is well explained here (15-years-old article, but still quite valid;-). As this article puts it,
Subclassing is a technique that allows
an application to intercept messages
destined for another window. An
application can augment, monitor, or
modify the default behavior of a
window by intercepting messages meant
for another window.
You'll want "instance subclassing", since you're interested only in a single window (either your new button, or, the one you've SetParented your new button to); if you decide to subclass a window belonging to another process, you'll also need to use the injection techniques explained in the article, such as, injecting your DLL into system processes and watching over events with a WH_CBT hook, and the like. But I think you could keep the button in your own process even though you're SetParenting it to a window belonging to a different process, in which case you can do your instance subclassing entirely within your own process, which is much simpler if feasible.
"Superclassing" is an alternative to "subclassing", also explained in the article, but doesn't seem to offer that many advantages when compared to instance subclassing (though it may compared with global subclassing... but, that's not what you need here anyway).
You'll find other interesting articles on such topics here, here, and here (developing a big, rich C++ library for subclassing -- but, also showing a simpler approach based on hooks which you might prefer). Each article has a pretty difference stance and code examples, so I think that having many to look at may help you find the right mindset and code for your specific needs!
OK, I'll do my very best - as I understand you, you're trying to inject a button into some existing window. That meaning: Your tool creates a button in some window that does not belong to your application. Now, you want to be notified when that button is pressed. Am I correct so far?
To be notified about the button being pressed, you need to get the respective window message, which will only work if you also "inject" a different WndProc into the window. Actually I have no idea how that should work, but I faintly remember functions like GetWindowLong and SetWindowLong. Maybe they will help?
EDIT
I've searched MSDN a little: While you can get the address of a window's WndProc using GetWindowLong, you can not set the WndProc using SetWindowLong on Windows NT/2000/XP (and up I suppose). See here (MSDN).
So what you could do is install a global message hook that intercepts all window messages, filter those for the window you've injected the button into and then find your message. If you have trouble with this, however, I'm the wrong person to ask, because it's been years ago since I've done anything like that, but it would be stuff for a new question.
EDIT 2
Please see Alex Martinellis answer for how to define the hook. I think he's describing the technique I was referring to when I talked about defining global message hooks to intercept the window messages for the window you injected your button into.