I am trying to exit a window i've third DestroyWindow() and SendMessage() with WM_CLOSE and CloseWindow() the first two don't work and CloseWindow(); only minimizes it!
Example code of what i'm trying to do:
int main()
{
HWND curwind;
char ccurwind[256];
HWND newwind;
HWND wind2;
Sleep(1000);
printf("Destroying in 5...\n");
Sleep(1000);
printf("Destroying in 4...\n");
Sleep(1000);
printf("Destroying in 3...\n");
Sleep(1000);
printf("Destroying in 2...\n");
Sleep(1000);
printf("Destroying in 1...\n");
curwind = GetForegroundWindow();
GetWindowTextA(curwind, ccurwind, 256);
//DestroyWindow(curwind);
if (DestroyWindow(curwind) == 0) {
printf("Failed with error: %s", GetLastError());
}
else {
printf("\nDestroyed %s", ccurwind);
}
getch();
return 0;
}
So basically close the window but not the process
example scenario:
I open a new tab on google in a new window this program will close that window but not the whole process. Is this possible and if so what function would i use?
Only the thread that owns the window is allowed to call DestroyWindow. SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0) is the same as closing the window with the system menu but it ultimately just sends WM_CLOSE.
A window can ignore WM_CLOSE and there is not much you can do about that.
If the window is in a process with a higher integrity level than you then UIPI will block your message.
the function: DestroyWindow() should do the job.
From: 'https://msdn.microsoft.com/en-us/library/windows/desktop/ms632682(v=vs.85).aspx'
Destroys the specified window. The function sends WM_DESTROY and WM_NCDESTROY messages to the window to deactivate it and remove the keyboard focus from it. The function also destroys the window's menu, flushes the thread message queue, destroys timers, removes clipboard ownership, and breaks the clipboard viewer chain (if the window is at the top of the viewer chain).
If the specified window is a parent or owner window, DestroyWindow automatically destroys the associated child or owned windows when it destroys the parent or owner window. The function first destroys child or owned windows, and then it destroys the parent or owner window.
DestroyWindow also destroys modeless dialog boxes created by the CreateDialog function.
Related
I try to get some messages from other windows. I need to find window by name, I used FindWindowW(). How can I get active window and get message from its?
When I add hwnd in GetMessage(), it doesn't work.
//WndProc
case WM_KEYDOWN:
OutputDebugStringW(L"Key down");
break;
//main.c
//WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
hwnd = FindWindowW(NULL, L"Sublime Text");
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
Only the thread that creates a window can directly receive and dispatch messages for that window. GetMessage() retrieves messages from the calling thread's message queue, so it can only be used with windows that are owned by the calling thread.
Since you are trying to catch messages for a window that is not yours, you will have to use SetWindowsHookEx() or SetWinEventHook() to install a hook callback into that window's owning thread, and then that callback can intercept the desired messages/events for that window. You can use GetWindowThreadProcessId() to get the IDs of the Process and Thread that own the window.
If you use SetWindowsHookEx() and are trying to hook a window in another process, your callback must reside in a DLL so it can be injected into that process. You do not need to do that with SetWinEventHook().
I wrote the following code to detect when a window is created on the screen by another application (not by my code):
Display* display = XOpenDisplay(":0");
XSetWindowAttributes attributes;
attributes.event_mask = SubstructureNotifyMask | StructureNotifyMask;
Window win = XDefaultRootWindow(display);
XChangeWindowAttributes(display, win, CWEventMask, &attributes);
while (1) {
XEvent event;
XNextEvent(display, &event);
if (event.type == CreateNotify)
puts("create Notify event occured\n");
}
The code basically works, however, I noticed that, when I start an application (e.g. terminal) the CreateNotify event seems to be fired multiple times. Can anybody explain why? I would have expected that CreateNotify will only be fired once for every started application/window. How do I have to modify the code to achieve this?
The events are for child windows. Per the Xlib Programming Manual, "Creating any children ... generates an event." A typical X application includes numerous child windows, and you're seeing each of them.
When you get the event, check event.xcreatewindow.parent (XEvent is a union per the reference). If that is win, the root window, you have a top-level window. Otherwise, you have a child window. Try:
if ( (event.type == CreateNotify) && (event.xcreatewindow.parent == win) )
puts("top-level create Notify event occured\n");
What is the proper way to wait until an X11 window is mapped and viewable? Precisely, I want to wait until I can safely call XSetInputFocus() without running into any risks of the X server backfiring with the following error:
// X Error of failed request: BadMatch (invalid parameter attributes)
// Major opcode of failed request: 42 (X_SetInputFocus)
Currently this error happens quite often, especially on slow X servers or when trying to open a new window right after having changed the monitor resolution using libXrandr.
I already have a solution for this problem but it is pretty hacky because it polls the window attribute so I'd like to know whether or not there is a cleaner version.
Here is my current approach:
static Bool predicate(Display *display, XEvent *ev, XPointer arg)
{
return(ev->type == MapNotify);
}
static void waitmapnotify(struct osdisplayinfo *osd)
{
XEvent ev;
XWindowAttributes xwa;
XPeekIfEvent(osd->display, &ev, predicate, NULL);
do {
XGetWindowAttributes(osd->display, osd->window, &xwa);
usleep(1);
} while(xwa.map_state != IsViewable);
}
This code works fine but it is hacky so I'm putting it up for debate here - just in case there is a cleaner way of doing this.
Select SubstructureNotifyMask on the root window. You should get an event each time a top-level window is mapped, unmapped, moved, raised, resized etc. These are the events that potentially change visibility of top-level windows. This program prints a message whenever such an event happens:
#include <X11/Xlib.h>
#include <stdio.h>
int main ()
{
Display* d = XOpenDisplay(0);
int cnt = 0;
XEvent ev;
XSelectInput (d, RootWindow(d, DefaultScreen(d)), SubstructureNotifyMask);
while (1)
{
XNextEvent(d, &ev);
printf ("Got an event %d!\n", cnt++);
// <----- do your XGetWindowAttributes(...) check here
}
}
Note that you may not get events about your own windows getting mapped. This is because the WM is likely to reparent top-level windows to be children not of the root, but of intermediate decoration windows.
There are two ways to cope with the situation:
Check if your window parent, the parent of the parent, ... etc is the mapped window of the event.
Add XSelectInput (d, yourwindow, StructureNotifyMask); to the mix.
Note the first select has SubstructureNotifyMask and the second one StructureNotifyMask, a different mask.
As far as I know X11 lib does not expose any callback mechanics for the X11 Event handling. (you can easily build your own once you understand the event filtering model)
You might want to loop on the X11 event queue as I guest this should be more efficient being designed for that purpose. Moreover you can configure the events filter, so that you get only the events that are of interest for your specific window.
A useful (though dated) link might be:
Linux Journal X11 Tutorial Check page two for an example on installing filters and getting events from the X11 queue.
I'm new to WinAPI and I already created an empty window. Now I want to make a little hack for the tutorial program of Cheat Engine. I already know, how to change values in the memory of other processes. But as soon as I changed a value in the tutorial program, I'm forced to click a "next" button. So my question is: Is it possible to send a click command to a window of another process? I have a handle of the window, a handle of the process and the process id (if it is not the same).
The only thing I know about the buttons is, that their text is always "next".
Here is a shortened version of my code:
HWND hWnd = FindWindow (NULL, L"Window's title"); // Search startup window
DWORD pid; // Get process id
GetWindowThreadProcessId (hWnd, &pid);
HANDLE hProc = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); // Get access to process
DWORD base = 0x789ABCDE; // Get value of static pointer
ReadProcessMemory (hProc, &base, &base, 4, NULL);
WORD offset = 0xBCDE; // Write to memory
WriteProcessMemory (hProc, (void *)(base + offset), (void *)5000, 4, NULL);
// Send click command (???)
Sorry, if my english and/or some technical terms aren't correct, but I'm new to Win32.
EDIT:
I discovered, that the tutorial forbits every memory access, so my project will never work. In addition, GetLastError(); always returns ERROR_INVALID_PARAMETER when I try to install a second windows procedure for the tutorial program. Do I have to use hProc instead of pid in SetWindowsHookEx (WH_CALLWNDPROC, &fnHook, NULL, pid);?
The simplest way to do this is to use SendMessage() to send an WM_LBUTTONDOWN and then a WM_LBUTTONUP message to the given window, something like
// x, y are the coords
SendMessage(hWnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
SendMessage(hWnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(x, y));
This may or may not work in your particular case; if the spot that you're trying to click is actually in a child window or a popup you've just "clicked" the wrong window, and a lot of apps rely on other messages.
The more reliable way to do it is to call SetWindowsHookEx(WH_MOUSE, ...), and "play" the mouse messages through the given hook procedure. I haven't done that in a couple of decades so can't really talk about it in detail.
In my application the main window spawns several dialogs, often multiple dialogs are opened at the same time. On Ubuntu if I minimize the main window each of the child dialogs are also minimized. On Windows XP/Vista/7 the dialogs don't minimize with the main window.
On Windows, is there a way to get all top level windows to minimize when the main application gets minimized.
EDIT:
Solved by setting a signal for a "window-state-event" and manually using gtk_window_iconify.
Setting the signal:
g_signal_connect(G_OBJECT(Main_Application), "window-state-event", G_CALLBACK(minimize_windows), NULL);
Here is the minimize_windows function.
gboolean minimize_windows( GtkWidget *widget, GdkEventWindowState *event, gpointer user_data)
{
GList *glist;
/*Returns a GList of each toplevel window*/
glist = gtk_window_list_toplevels();
/*Iconify check*/
if(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED)
g_list_foreach(glist, (GFunc)gtk_window_iconify,NULL);
/* If not make sure all the windows are deiconified */
else
g_list_foreach(glist, (GFunc)gtk_window_deiconify, NULL);
g_list_free(glist);
return TRUE;
}
Try making the parent form the owner of the child forms:
Form2 f2 = new Form2();
f2.Show(this);