ive recently started to work with the win32 api and im trying to do a couple of things.
I have a project that is gonna use about 4-5 windows. I want to seperate each of these into a different cpp file where each has its own message Loop. How do i pass information from window to window?(is there some sort of entry point?) at the moment im creating all windows during case WM_CREATE: and I am showing them as required.
I am trying to have a nice OOP design but having trouble with that, my main issue is the communication between windows. I have a fair amount of experience in C# and C++ and other than this the win32 api is not being a problem.
Thanks for your help!
I don't think you want a per-window message loop, unless you want each window in its own thread. You probably need a window procedure instead.
Each window class has its own window procedure, which you register by setting lpfnWndProc field of WNDCLASS structure before passing it to the RegisterClass. Once you've done that, you can use that class when creating a new window with CreateWindow.
In your case, you'll probably want to implement the window procedure so it accepts custom messages (WM_APP + x), and then pass custom messages between windows using PostMessage (for asynchronous communication) or SendMessage (for synchronous communication). If necessary, you can create separate window classes and window procedures for your different windows. A single message loop is capable of pumping messages to all these procedures.
The classic way of inter-window communication is sending / posting messages:
SendMessage
PostMessage
Related
I have recently migrated a project of mine to WebView2 and the last part I can't figure out is how to intercept the Windows Messages for the webview. My code is very similar to webview/webview but I was unable to find help on their GitHub.
Previously, I was able to find the hWnd for the webview and use SetWindowSubclass to add my own wndproc to the webview. However, I've used Spy++ and tried SetWindowSubclass on all the windows that showed up there (see below) but none of them had any windows messages in my wndproc other than some window management ones I did not think were useful - The best I got was WM_PARENTYNOTIFY, but I am interested in WM_MOUSEMOVE and WM_NCHITTEST - neither of which I could find.
My goal is to create a borderless, draggable, resizeable WebView2 based app.
The problem is, that the real window that controls and gets all this input is in another process. You just see a window that shows the output in your process.
Look into Spy++. Everything below Chrome_WidgetWin_0 belongs to a new process (MSEDGEWEBVIEW2) and is not part of your process. So you can't subclass such a window with the normal techniques.
So if you want to subclass this window. You need to inject a new DLL into this new process. This DLL might subclass the real window. And this DLL might communicate with you hosting program via any IPC.
everyone.
Now, I'm developing desktop window apps with c++ mfc.
I wanna get the mouse move and down event on the desktop background.
Why I want these, this app requires all windows move and resize event, and also mouse position.
After so many googling, I don't search things as a right solution.
Someone suggests that global mouse hooks is helpful, but I don't really know how to use this.
What is your idea about this?
Please help me to find a right solution.
Best Regards
Falcon
You're looking for the windows low level global input hook api SetWindowsHookEx
You can find more information here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
Specifically, you're looking to use the "low level" mouse hook like so:
HHOOK mousehook = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
You'll need to use this with a windows message queue per this link:
Why must SetWindowsHookEx be used with a windows message queue
The low-level hooks, WH_KEYBOARD_LL and WH_MOUSE_LL are different from all the other hooks. They don't require a DLL to be injected into the target process. Instead, Windows calls your hook callback directly, inside your own process. To make that work, a message loop is required. There is no other mechanism for Windows to make callbacks on your main thread, the callback can only occur when you've called Get/PeekMessage() so that Windows is in control.
A global hook like WH_KEYBOARD is very different. It requires a DLL and the callback occurs within the process that processes the keyboard message. You need some kind of inter-process communication to let your own program be aware of this. Named pipes are the usual choice. Which otherwise of course requires that this injected process pumps a message loop. It wouldn't get keyboard messages otherwise.
Favor a low-level hook, they are much easier to get going. But do pump or it won't work. And beware of timeouts, if you're not responsive enough then Windows will kill your hook without notice.
I have a large code base where there are lots of calls to AfxMessageBox(...). What I need to do is while these messageboxes are modal service some external IO (i.e. a network communication).
I've considered writing a custom CDialog and my own message pump - but I'm unsure of how to make the CDialog generic enough that I can reliably create all the messageboxes without having to test them all.
Alternatively I've been looking at hooking into the messageboxes' windproc function through SetWindowsHookEx but this has the limitation that it happens after the messagepump and will not fire if there are no messages for that dialog.
Does anyone have any suggestions on how to acheive this or if either of my two approaches above are worth pursuing. ?
When I use Spy++, I notice that mouse entering a button triggers a series of WM_TIMER .
How is Windows doing this? Is it requesting that the OS notify it or call a function pointer after X milliseconds, or does the widget register its own timer proc?
The reason I want to know this is because I'm building a game gui api in C++ and want to incorporate this sort of mechanism.
Thanks
I believe that the button's window procedure is using the SetTimer function to register the window for notification via a WM_TIMER message. You can use SetTimer either to call a specific function after time elapses, or to trigger a WM_TIMER message with the specified information.
MS Windows's GUI animation capability is very limited. You can say nothing if you had known real animation capable OS like Mac OS X.
Windows GUI is a composition of various child windows which has own event handler routine and drawing code. Very clumsy and performance inefficient of course, only provide easy access to ordinary developers.
In short, I want to say that MS Windows is the least recommendable reference for developing a game GUI framework. If I have a opportunity to develop new GUI framework, first thing I would devise is a mechanism to separate input event handling and graphic drawing for consolidated screen drawing, like game programs do.
Have a look at this:
http://www.rawmaterialsoftware.com/juce.php
(source: rawmaterialsoftware.com)
Game API's normally do their timing in the actual message loop of the application as most games draw sprites directly on the surface of the window, rather than using individual child windows.
Self animating controls that are build as child windows can schedule WM_TIMER messages to themselves via SetTimer, normally to process short term states - in your case the Button has probably used the TrackMouseEvent API to be notified via WM_MOUSELEAVE when the mouse leaves the button.
To allow more advanced animations in form based applications, Microsoft has introduced the Windows Animation Manager.
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