Listen to WM_SYSCOMMAND Events - c++

I am writing a small c++ program that should react to the sc_screensaver and sc_monitorpower event.
this should run in background hence no gui is intended.
Since i have no experience with the windows api yet, i am struggling a lot with this.
A already googled a lot and found many approaches which either i dont understand or dont work.
Can anyone of you give me a hint?
I read its about catching the wm_syscommand but that seems to be difficult because i dont have a window.

The only way to get messages is by a message loop and a window procedure.
If your program does not have a visible gui, you have to create a message-only window for that purpose, and your main must have the code to create it and to listen windows messages (note: "windows" here, refers to the system, not the gui).

Related

Simulate mouse click in background window

I'm trying to use SendMessage to post mouse clicks to a background window (Chrome), which works fine, but brings the window to front after every click. Is there any way to avoid that?
Before anyone says this is a duplicate question, please make sure that the other topic actually mentions not activating the target window, because I couldn't find any.
Update: aha, hiding the window does the trick, almost. It receives simulated mouse/keyboard events as intended, and doesn't show up on screen. However, I can just barely use my own mouse to navigate around the computer, and keyboard input is completely disrupted.
So my question is, how does sending messages to a window affect other applications? Since I'm not actually simulating mouse/keyboard events, shouldn't the other windows be completely oblivious to this?
Is it possibly related to the window calling SetCapture when it receives WM_LBUTTONDOWN? And how would I avoid that, other than hooking the API call (which would be very, very ugly for such a small task)?
The default handling provided by the system (via DefWindowProc) causes windows to come to the front (when clicked on) as a response to the WM_MOUSEACTIVATE message, not WM_LBUTTONDOWN.
The fact that Chrome comes to the front in response to WM_LBUTTONDOWN suggests that it's something Chrome is specifically doing, rather than default system behaviour that you might be able to prevent in some way.
The source code to Chrome is available; I suggest you have a look at it and see if it is indeed something Chrome is doing itself. If so, the only practical way you would be able to prevent it (short of compiling your own version of Chrome) is to inject code into Chrome's process and sub-class its main window procedure.

c++ get other windows messages

im learning to make things to other windows like resize the ie or any type of window. the only problem i don't know how i can get or give messages to other windows.
so like i pressed a key in ie i would like to get that message to my program too!
any idea
To get the messages that are sent to windows programs you have to install a hook in order to listen to the messages you want. You do this via the SetWindowsHookEx function.
However, I believe that you should read a book about this kind of behaviour, since there are certain rules you have to apply. For instance, before returning from your callback function, you have to call CallNextHookEx in order to let the other hooks handle the message. This is the first hit in books.google.com when searching for setwindowshookex.
Normally your application won't receive Windows messages for other applications (this can be a security problem, for example with keylogger spyware). However, the CBT Hook method can be used to install a hook that receives other window message inputs.
However, note that a Windows feature called UIPI can cause problems with CBT hooks.

Closing a MessageBox automatically

I have a third party encryption library, which may create a MessageBox if key creation fails. The failure can be caused by bad random number generation or other rarities, and in most cases, trying again will result in success. My code will attempt key creation up to three times before deciding it failed.
Now, the issue is that the program may be used with automation. If a MessageBox is created during automation, it will block the process forever, because there's nobody to click the 'OK' button.
Does anyone know of a way to catch when this message box is created and automatically close it?
Anything is fair game, as long as it's not something that will make security suites angry. This means no hooking or code tunneling.
In summary, I need to catch when a MessageBox is created and close it. The MessageBox's creation is outside of my control. Modifying the code at runtime is not acceptable.
Also, I've noticed there are some other similar questions, but they don't have the same requirements.
EDIT: Additional note, I can find the message box via searching through all windows until I find one with a matching title and then send it a WM_CLOSE message, but I don't think this is a great solution. I also have no guarantee that the message box has been/will be displayed, or how long after my call it will be displayed. It could display instantly, it could display 1200 ms later, or it could not display at all.
Just before you begin the encryption process, install a WH_CBT hook, and in its callback watch for an nCode of HCBT_CREATEWND. If you get a matching class name ('#32770 (Dialog)' ?) and a matching title either return a nonzero value from the callback, or if that doesn't work post a WM_CLOSE (or a BM_CLICK to a relevant button if selecting an option is necessary). Uninstall the hook after the process for not messing with every possible dialog your application pops up.
That sounds like bad design on the part of that library. Generally any sort of utility library (like encryption) has no business invoking any kind of GUI (unless you explicitly ask it to).
Is there possibly some configuration or setting in this library that could disable its use of message boxes?
If not, I'd suggest that you might want to investigate using a different library. After all, if the designers of this library have already made this kind of poor design decision once, then there may be other unfortunate surprises lurking in there.
You can hope that it will be found by GetForegroundWindow, but this may catch other applications. The more brute force way is to iterate over all windows with EnumWindows looking for something that has a caption or text equal to this shown by the library.
I have once "remote controlled" an application by sending mouse click events to some controls. I guess you would have to do this in a separate thread that is watching for Events if a window is opened. Pretty ugly but working...
Create a new thread. If your function fails and a Message Box is opened, obtain a handle to the message box by looping through the windows (GetTopWindow, GetNextWindow) and comparing the window's process id to the one returned from GetCurrentProcessId().
Or, you can avoid all the hard work and just hook the MessageBox API with detours. It's not very hard, and if you don't want to pay for detours, you can do it manually.
Call VirtualProtect and set the memory protection at MessageBox at PAGE_EXECUTE_READWRITE
Create a naked function, and use it as a trampoline.
Create a function identical in parameters to MessageBox (this will be your hook)
Create a jump from MessageBox to your hook function.

Handling Messages in Console Apps/DLLs in C++ Win32

I would like to have the ability to process Win32 messages in a console app and/or inside a standalone DLL.
I have been able to do it in .NET with the following article and it works great in C# inside a console app and standalone DLL
http://msdn.microsoft.com/en-us/magazine/cc163417.aspx
Is there a way to do the equivalent with C/C++ Win32 APIs? I have tried doing RegisterClassEx(...) and CreateWindow(...) even passing in HWND_MESSAGE to hWndParent but the trouble is that after the "invisible" window is created messages are not being processed probably due to the lack of a message pump.
Where would the message pump go if you had a DLL entry point? I have tried creating another thread in a DLL and put while(GetMesage(..)) there but that did not work either.
Any ideas?
You need a message pump yes. The window also has thread affinity so it needs to be created on the same thread that you're running the message pump on. The basic approach is sound, if you include more code it may become clear what the problem is.
In addition to what Logan Capaldo said, you also have the problem that, as a DLL, you don't know at compile time what kind of process is going to be loading you at runtime.
If you are being loaded by a console application (/SUBSYSTEM:CONSOLE), then creating a hidden window of your own and setting up a message pump on that same thread will work fine (as long as you are the first window created).
If you are being loaded by a windows app (/SUBSYSTEM:WINDOWS) then you might run into problems getting messages. They will be sent to the top-level window in the hierarchy, which you didn't create. You'll need to get the hWnd of the main process and subclass it (if you aren't already).
If you are being loaded by a service, then you aren't going to get window messages at all. You instead need to use the RegisterServiceCtrlHandlerEx Function

How to mix C++ and external buttons on seperate window?

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.