Can I call TranslateMessage inside the message callback? - winapi

I don't have the canonical message loop running, so is there a way I can call TranslateMessage (or its equivalent) inside my message proc handler?
Basically I need WM_CHAR messages and unless I can call TranslateMessage I'm not going to get those. Currently I have the message proc setup, but no message loop.
// Static window function called by Windows for message processing. Implementation
// delegates message processing to MemberWndProc.
LRESULT CALLBACK FxPlayerTiny::WindowsMsgStatic(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
msg = PeekMessage(&msg, HWnd, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE);
if (msg type is key down){
TranslateMessage(&msg);
//DispatchMessage(&msg); -- needed?
}
else process msg normally
}
My message proc handler is the first point of entry of messages, being setup in the following manner:
WNDCLASSEX wc;
wc.lpfnWndProc = WindowsMsgStatic;
....
RegisterClassEx(&wc);

At some point, in order to get a queued message, you must call a function like GetMessage or PeekMessage. Those functions yield MSG objects and it is those MSG objects that you must pass to TranslateMessage and DispatchMessage.
In the code in the original version of the question, you are trying to call TranslateMessage and DispatchMessage too late. You call them inside your window proc. You should call them at the point where you first receive the MSG object. In other words, call TranslateMessage and DispatchMessage straight after the call to PeekMessage or GetMessage.

Related

Trouble catching WM_INPUT message for lParam, to collect Raw Mouse Input

For my college project I am developing a solution to distinguish between mouse user data from a person with Parkinson's compared to a healthy person. For which I need mouse data, ideally raw.
I presume I have misunderstood how to collect raw mouse input from the WM_INPUT message but I cannot figure it out.
I have been looking at the following thread: How to accurately measure mouse movement in inches or centimetres for a mouse with a known DPI
and Mouse input libraries on github all of which seem to easily catch a WM_INPUT message whose lParam is a handle to some RawInputData with something like this:
GetMessage(&msg, GetActiveWindow(), WM_INPUT, 0);
if (msg.message == WM_INPUT){ .....
And then retreiving the lParam from the message and collecting the data associated with that handle with:
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));
However when I call GetMessage in my main loop, the function never exits!
Consequently there is no way (that i know of) for me to get a handle to the RawInputData. Especially since the MSDN page just assumes you have the lParam already.
In summary I need a method of getting an lParam to pass to the GetRawInputData function which will remain active whether the program is running in the active window of not.
I'm running this code in a blank C++ CLR project in Visual Studio with the "winuser.h" library.
#include "stdafx.h"
#include "Windows.h"
#include "winuser.h"
#ifndef HID_USAGE_PAGE_GENERIC
#define HID_USAGE_PAGE_GENERIC ((USHORT) 0x01)
#endif
#ifndef HID_USAGE_GENERIC_MOUSE
#define HID_USAGE_GENERIC_MOUSE ((USHORT) 0x02)
#endif
int main(array<System::String ^> ^args)
{
RAWINPUTDEVICE Rid[1];
Rid[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
Rid[0].usUsage = HID_USAGE_GENERIC_MOUSE;
Rid[0].dwFlags = 0; //ideally RIDEV_INPUTSINK but that prevents registration
Rid[0].hwndTarget = GetActiveWindow(); //ideally this would be Null to be independent of the active window
if (RegisterRawInputDevices(Rid, 1, sizeof(Rid[0])) == FALSE) {
//registration failed. Call GetLastError for the cause of the error
Console::WriteLine("Registration Error");
}
MSG msg;
while (true) {
while (GetMessage(&msg, GetActiveWindow(), WM_INPUT, 0) != 0) { //this command is never completed
DispatchMessage(&msg); //this line is never ran
}
if (msg.message == WM_INPUT) {
Console::WriteLine("caught a message!!!");
}
}
}
Issue solved after much more research I found the winAPI walk through which I followed fixing the issue above by adding an:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE unused, PSTR cmd, int show) {.....}
Function to register devices and create a window then call GetMessage which calls LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {....} with the parameters occupied by the message ID,WParam and LParam corresponding the message event.
For anyone stuck with a similar issue follow this MSDN guide: https://msdn.microsoft.com/en-us/library/bb384843.aspx

Subclassing an Edit control with SHAutoComplete applied

I'm new, so sorry if the question isn't posed exactly as you're get used to.
I inevitably need to subclass an Edit control for which SHAutoComplete() has been called like this:
// initialization
if FAILED( CoInitialize(NULL) ) exit(1);
// creation of an Edit control
HWND hEdit=CreateWindow( WC_EDIT, ... );
// calling SHAutoComplete - I essentially understand this as a subclassing behind the scenes
SHAutoComplete( hEdit , SHACF_AUTOSUGGEST_FORCE_ON|SHACF_FILESYSTEM );
// subclassing an Edit box for which SHAutoComplete has been called
WNDPROC autoCompleteWndProc=SubclassWindow( hEdit , __myNewWndProc__ ); // using macro
Suppose the __myNewWndProc__ function looks like a classic window procedure:
LRESULT CALLBACK __myNewWndProc__(HWND hEdit, UINT msg, WPARAM wParam, LPARAM lParam){
// handle subclass-specific messages
switch (msg){ ... }
// handle SHAutoComplete-specific messages
return autoCompleteWndProc(hEdit,msg,wParam,lParam); // <-- here's the problem (read further)
}
The problem is, it doesn't work. The application crashes with error:
Process returned -1073741819 (0xC0000005)" (access violation)
pointing the problem at line marked in the above listing.
The question is what am I doing wrong?
(I've experienced the same problem when subclassing from ComboBoxEx, but I managed to work around it, but can't find any trick with the SHAutoComplete() problem.)
SubclassWindow() is a wrapper for SetWindowLongPtr():
#define SubclassWindow(hwnd, lpfn) \
((WNDPROC)SetWindowLongPtr((hwnd), GWLP_WNDPROC, (LPARAM)(WNDPROC)(lpfn)))
When you use that type of subclassing, you MUST use CallWindowProc() to call the previous window procedure when needed, DO NOT call the procedure directly:
LRESULT CALLBACK __myNewWndProc__(HWND hEdit, UINT msg, WPARAM wParam, LPARAM lParam)
{
//...
// handle SHAutoComplete-specific messages
return CallWindowProc(autoCompleteWndProc,hEdit,msg,wParam,lParam);
}
The reason for that is stated in the documentation:
SetWindowLongPtr function
Calling SetWindowLongPtr with the GWLP_WNDPROC index creates a subclass of the window class used to create the window. An application can subclass a system class, but should not subclass a window class created by another process. The SetWindowLongPtr function creates the window subclass by changing the window procedure associated with a particular window class, causing the system to call the new window procedure instead of the previous one. An application must pass any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc. This allows the application to create a chain of window procedures.
CallWindowProc function:
lpPrevWndFunc [in]
Type: WNDPROC
The previous window procedure. If this value is obtained by calling the GetWindowLong function with the nIndex parameter set to GWL_WNDPROC or DWL_DLGPROC, it is actually either the address of a window or dialog box procedure, or a special internal value meaningful only to CallWindowProc.
You are probably running into the latter case, which will crash trying to call something that is not directly callable.
With that said, you should not be using SetWindowLongPtr() to subclass. Use SetWindowSubClass() instead. Read the following articles for more details:
Subclassing Controls
Safer subclassing

winapi global hook WM_TIMER trace message sender

I'm trying to monitor a message sent by another window handle (particularly WM_TIMER) using WH_GETMESSAGE hook but it seems that I can only get the receiver handle, not the sender. Here's my code:
LRESULT WINAPI GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam){
if (nCode < 0){
return CallNextHookEx(hGetMsgHook, nCode, wParam, lParam);
}
else{
MSG* msg = (MSG*)lParam;
HWND window = msg->hwnd;
unsigned int msgCode=LOWORD(msg->message);
char* className = new char[50];
if (msgCode == WM_TIMER){
GetClassNameA(window, className, 50);
//className of the receiver handle
}
}
return CallNextHookEx(hGetMsgHook, nCode, wParam, lParam);
}
How do I get the sender hwnd?
You are asking to find information that has no meaning. The WM_TIMER message is not sent from one window to another. It is a pseudo-message that is synthesised by the system.
Certain low priority messages are implemented this way. The other common example is WM_PAINT. Your program has a message loop that repeatedly calls GetMessage which pulls messages off the queue. When the queue of real messages is empty, pseudo-messages are generated if needed. At this point the system will synthesise WM_TIMER or WM_PAINT messages.
So, these messages are never actually sent. They are just synthesised on demand.
On top of that, messages are not sent by windows. Messages are sent by calls to SendMessage, PostMessage etc. These functions do not ask the caller to supply a window handle for the sender. And they can be called from anywhere and have no clear affinity with any sender window. So even for tradition true messages, the concept of sender window has no meaning.

win32 / opengl and callback functions.. how are they structured?

I'm working on a win32 c/cpp project involving openGL. I'm just starting and had a few basic questions regarding how a standard win32 program works. Following a tutorial, I made the winmain create a new window, enable openGL for the window, and then enter the main loop where if there are messages, the program handles them, and otherwise, the program moves onto drawing openGL animations. Following that, I simply shut down openGL and destroy the window. I'm not too confused about what's happening in here, but this is where I get lost:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch (message)
{
case WM_CREATE:
return 0;
case WM_CLOSE:
PostQuitMessage( 0 );
return 0;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
switch ( wParam )
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
though I do see in the winmain that I register this function to my window class via
wc.lpfnWndProc = WndProc;
How exactly does this process work? Can someone explain the pipeline to me - as the winmain method runs, it goes onto drawing the opengl animation, but as soon as a key is pressed, it enters message handling... and then what? How does my winmain method communicate with the WndProc method? What's actually happening from the machine's point of view?
In your WinMain there should be a pair of TranslateMessage / DispatchMessage calls. TranslateMessage is responsible for getting keystrokes being delivered correctly and DispatchMessage traverses the window hierachy to deliver the messages to the window that has the input focus, effectively calling the function which pointer was registered as default window message handler (Window Procedure) with the message as parameters.

Create a native Windows window in JNA and some GetWindowLong with GWL_WNDPROC

Good day,
I have been using JNA for a while to interact with the Windows API and now I am stuck when creating a window. As far as I have done the following:
1. Have created a child window of an existing window and obtained a valid handler to it.
2. Understood that every window in Windows has a non-stop message-dispatch loop.
3. Understood that the best way to include my window in the message-dispatch loop is to use something like the following code (not mine, but that is what I would do as well):
final LONG_PTR prevWndProc = new LONG_PTR(User32.INSTANCE.GetWindowLong(hwnd, User32.GWL_WNDPROC)); //this is to obtain a pointer to the WNDPROC of the parent window, which we are going to need later
wndProcCallbackListener = new WndProcCallbackListener()
{
public LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam)
{
if (uMsg == WTSAPI.WM_POWERBROADCAST)
{
System.out.println("WM_POWERBROADCAST Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam);
}
else if (uMsg == WTSAPI.WTS_SESSION_CHANGE)
{
System.out.println("WTS_SESSION_CHANGE Event: hWnd="+hwnd+", uMsg="+uMsg+", uParam="+uParam+", lParam="+lParam);
}
//Call the window's actual WndProc so the events get processed.
return User32.INSTANCE.CallWindowProc(prevWndProc, hWnd, uMsg, uParam, lParam);
}
};
//Set the WndProc function to use our callback listener instead of the window's one.
int result = User32.INSTANCE.SetWindowLong(hwnd, User32.GWL_WNDPROC, wndProcCallbackListener);
However, my problem is when I call the GetWindowLong() for the parent window (my first line of code) I get a 0 for the pointer which indicated the function did not complete successfully. A subsequent call to GetLastError() and a quick check in the error codes give me an 'Access is denied' error. This, of course, is logical, since I am trying from my own thread to access the address of the WNDPROC of another, but I was wondering if there is any way (there should be, of course) to circumvent that.
Any pointers? (pun intended)
Do not use GetLastError() after a JNA call. JNA & JNI may call other APIs that may change the last error. Declare SetWindowLong with the clause throws LastErrorException, like this:
int SetWindowLongA(int hWnd, int nIndex, WndProcCallbackListener dwNewLong)
throws LastErrorException;
Notice the 'A' after the name. It makes explicit use of ANSI version. You could use SetWindowLongW as well.
Make sure your callback implements both Callback and StdCall. I prefer using primitive types as much as possible, because this makes mapping fast and obvious to JNA:
public interface WndProcCallbackListener extends Callback, StdCall {
int callback(int hWnd, int Msg, int wParam, int lParam);
}

Resources