Jump to content
  • Advertisement
Sign in to follow this  
Mike Kent

WM_Input troubles

This topic is 2071 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am a novice programmer trying to create the following application: 

 

1. Can just be a simple command line program. 

 

2. Gets mouse input from WM_Input, not for buttons just whatever the mouse sends for left/right/up/down.

 

3. When a mouse event is received a timer starts.

 

4. If there has not been a mouse event for x amount of milliseconds, stop the timer, report the time elapsed with the idle time subtracted along with the counts that were received during the time interval.

 

5. Program then idles and waits for another mouse event. Perhaps it can wait on some key to quit (although I could just ctrl+c).

 

At first I thought I could frankenstein code from the source for ioquake3 raw. This was a bad idea due to numerous dependencies, and due to it being written in C which I am even less familiar with. I fixed much of the C code to work with C++, but I quickly became overwhelmed.

 

I tried writing it from scratch with examples from the MS raw input page. However MS quite reasonably assumes knowledge that I do not have and I didn't get very far.

 

I tried modifying a few sources from the gamdev forums from people posting about issues or demonstrating their solutions. What would usually happen is that they would only write the key ideas, and not provide a fully working source. Nothing wrong with that as the person asking the questions is usually nowhere near as clueless as I am.

 

Anyways here's a rather embarrassing example. I tried using "darkelf2k5"'s code I found here.

 

I removed most of it because I only want the mouse motion input, nothing from keyboard/mouse buttons.

 

Here's the code: 

#include <cstdint>
#include <iostream>
#include <Windows.h>

void riPoll();

int32_t riMouseX();

int32_t riMouseY();

int32_t riMouseXBal();

int32_t riMouseYBal();

uint8_t riMouseState( uint8_t Button );

static BOOL init_done = false;

static int32_t mxr = 0;

static int32_t myr = 0;

static POINT Cursor;

static uint8_t MouseState0[5] = {0};

static uint8_t MouseState1[5] = {0};

static DWORD MouseTime0[5] = { 0, 0, 0, 0, 0 };

static DWORD MouseTime1[5] = { 1000, 1000, 1000, 1000, 1000 };

void riProcessMouseMessage( const RAWMOUSE* rmouse, DWORD Time )

{

	GetCursorPos( &Cursor );	

	if ( MOUSE_MOVE_ABSOLUTE ^ rmouse->usFlags )

	{

		mxr += rmouse->lLastX;

		myr += rmouse->lLastY;

	}

	else

	{

		mxr = rmouse->lLastX;

		myr = rmouse->lLastY;

	}

	for ( int i = 0; i < 5; i++ )

	{

		const uint16_t MASK_DOWN = (1<<(2*i));

		const uint16_t MASK_UP = MASK_DOWN << 1;
				
		MouseState1[i] = MouseState0[i];

		if ( MASK_DOWN & rmouse->usButtonFlags )

		{

			MouseState1[i] = 1;
			
			MouseTime0[i] = MouseTime1[i];

			MouseTime1[i] = Time;

		}

		else if ( MASK_UP & rmouse->usButtonFlags )

		{

			MouseState1[i] = 0;

		}

	}	

}


int32_t riMouseX() { return mxr; } 

int32_t riMouseY() { return myr; }

int32_t riMouseXBal() { return Cursor.x; } 

int32_t riMouseYBal() { return Cursor.y; }

void riPoll()

{

	if ( !init_done )

	{

		RAWINPUTDEVICE Rid[2] = {0};



		Rid[0].usUsagePage = 0x01; 

		Rid[0].usUsage = 0x02; 

		Rid[0].dwFlags = RIDEV_DEVNOTIFY;

		Rid[0].hwndTarget = 0;



		Rid[1].usUsagePage = 0x01; 

		Rid[1].usUsage = 0x06; 

		Rid[1].dwFlags = 0;

		Rid[1].hwndTarget = 0;


		if (RegisterRawInputDevices(Rid, 2, sizeof(Rid[0])) == FALSE) {
		    
			return;

		}

		init_done = true;



		return;

	}

	CopyMemory( MouseState0, MouseState1, sizeof(MouseState0) );
	
	for ( int i = 0; i < 5; i++ )

	{

		if ( (MouseTime1[i] - MouseTime0[i]) < 500 )

		{

			MouseTime1[i] = 500;

			MouseTime0[i] = 0;

		}

	}

	MSG msg = {0};
	
	while ( PeekMessage( &msg, 0, WM_INPUT_DEVICE_CHANGE, WM_INPUT, PM_REMOVE | PM_QS_INPUT ) )

	{

		if ( WM_INPUT_DEVICE_CHANGE == msg.message )

		{

			DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);

		}

		if ( RIM_INPUT == GET_RAWINPUT_CODE_WPARAM( msg.wParam ) )

		{

			UINT dwSize = sizeof(RAWINPUT);

			RAWINPUT raw = {0};



			GetRawInputData((HRAWINPUT)msg.lParam, RID_INPUT, &raw, &dwSize, sizeof(RAWINPUTHEADER));



			if ( RIM_TYPEMOUSE == raw.header.dwType ) 

			{

				riProcessMouseMessage( &raw.data.mouse, msg.time );

			}			

		}

		DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);	

	}

}

MSG msg = {0};

while (PeekMessage(&msg, 0, 0, WM_INPUT_DEVICE_CHANGE - 1, PM_REMOVE))

	{

		TranslateMessage( &msg );

		DispatchMessage( &msg );

	}

while ( PeekMessage( &msg, 0, WM_INPUT + 1, 0xffffffff, PM_REMOVE ) )

	{

		TranslateMessage( &msg );

		DispatchMessage( &msg ); 

	}


	int main()
{
	riPoll();

	std::cout<< "bleh   " << mxr << ".\n";
	std::cout<< "bleh2  " << myr << ".\n";

	return 0;
}

The errors I am getting: 

 

(215)error C2059: syntax error : 'while'
(217)error C2143: syntax error : missing ';' before '{'
(217)error C2447: '{' : missing function header (old-style formal list?)
 
(225)error C2059: syntax error : 'while'
(227)error C2143: syntax error : missing ';' before '{'
(227)error C2447: '{' : missing function header (old-style formal list?)
 
These pertain to the last two "peekmessage" whiles, but they look fine to me syntax wise.
 
Any help is greatly appreciated. Thank you for your time.

 

Share this post


Link to post
Share on other sites
Advertisement

I think you put an extra bracket "}" after the code bellow:


void riPoll()

{

    if ( !init_done )

    {

        RAWINPUTDEVICE Rid[2] = {0};



        Rid[0].usUsagePage = 0x01;

        Rid[0].usUsage = 0x02;

        Rid[0].dwFlags = RIDEV_DEVNOTIFY;

        Rid[0].hwndTarget = 0;



        Rid[1].usUsagePage = 0x01;

        Rid[1].usUsage = 0x06;

        Rid[1].dwFlags = 0;

        Rid[1].hwndTarget = 0;


        if (RegisterRawInputDevices(Rid, 2, sizeof(Rid[0])) == FALSE) {
        
            return;

        }

        init_done = true;



        return;

    }

    CopyMemory( MouseState0, MouseState1, sizeof(MouseState0) );
    
    for ( int i = 0; i < 5; i++ )

    {

        if ( (MouseTime1[i] - MouseTime0[i]) < 500 )

        {

            MouseTime1[i] = 500;

            MouseTime0[i] = 0;

        }

    }

    MSG msg = {0};
    
    while ( PeekMessage( &msg, 0, WM_INPUT_DEVICE_CHANGE, WM_INPUT, PM_REMOVE | PM_QS_INPUT ) )

    {

        if ( WM_INPUT_DEVICE_CHANGE == msg.message )

        {

            DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);

        }

        if ( RIM_INPUT == GET_RAWINPUT_CODE_WPARAM( msg.wParam ) )

        {

            UINT dwSize = sizeof(RAWINPUT);

            RAWINPUT raw = {0};



            GetRawInputData((HRAWINPUT)msg.lParam, RID_INPUT, &raw, &dwSize, sizeof(RAWINPUTHEADER));



            if ( RIM_TYPEMOUSE == raw.header.dwType )

            {

                riProcessMouseMessage( &raw.data.mouse, msg.time );

            }            

        }

        DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);    

    }

} <--------------- THIS IS EXTRA IT WILL CLOSE DE FUNCTION BODY DECLARATION



// YOU MUST DECLARE A NEW FUNCTION OR REMOVE THE BRACKET

MSG msg = {0};

while (PeekMessage(&msg, 0, 0, WM_INPUT_DEVICE_CHANGE - 1, PM_REMOVE))

    {

        TranslateMessage( &msg );

        DispatchMessage( &msg );

    }

while ( PeekMessage( &msg, 0, WM_INPUT + 1, 0xffffffff, PM_REMOVE ) )


Share this post


Link to post
Share on other sites

Ok thanks for your help. I got it to compile, but I still had to comment out msg MSG = {0} due to duplicate declaration error. Hopefully I don't need it later.

 

Anyways now I can't get it to like, initialize. I think I am missing some other initialization type code. I put couts throughout the code to see what it was doing and it seems like RegisterRawInputDevices isn't able to grab the appropriate values.

#include <cstdint>
#include <iostream>
#include <Windows.h>

int32_t riMouseX();

int32_t riMouseY();

int32_t riMouseXBal();

int32_t riMouseYBal();

uint8_t riMouseState( uint8_t Button );

static BOOL init_done = false;

static int32_t mxr = 0;

static int32_t myr = 0;

static POINT Cursor;

static uint8_t MouseState0[5] = {0};

static uint8_t MouseState1[5] = {0};

static DWORD MouseTime0[5] = { 0, 0, 0, 0, 0 };

static DWORD MouseTime1[5] = { 1000, 1000, 1000, 1000, 1000 };

void riProcessMouseMessage( const RAWMOUSE* rmouse, DWORD Time )

{

	GetCursorPos( &Cursor );	

	if ( MOUSE_MOVE_ABSOLUTE ^ rmouse->usFlags )

	{

		mxr += rmouse->lLastX;

		myr += rmouse->lLastY;

		std::cout<< "MOUSE_MOVE_ABSOLUTE ^ rmouse->usFlags  " << ".\n";

	}

	else

	{

		mxr = rmouse->lLastX;

		myr = rmouse->lLastY;

		std::cout<< "NOT MOUSE_MOVE_ABSOLUTE ^ rmouse->usFlags  " << ".\n";

	}

	for ( int i = 0; i < 5; i++ )

	{

		const uint16_t MASK_DOWN = (1<<(2*i));

		const uint16_t MASK_UP = MASK_DOWN << 1;
				
		MouseState1[i] = MouseState0[i];

		std::cout<< "For loop riProcessMouseMessage  " << ".\n";

		if ( MASK_DOWN & rmouse->usButtonFlags )

		{

			MouseState1[i] = 1;
			
			MouseTime0[i] = MouseTime1[i];

			MouseTime1[i] = Time;

			std::cout<< "MASK_DOWN & rmouse->usButtonFlags  " << ".\n";

		}

		else if ( MASK_UP & rmouse->usButtonFlags )

		{

			MouseState1[i] = 0;

			std::cout<< "NOT MASK_DOWN & rmouse->usButtonFlags  " << ".\n";

		}

	}	

}

int32_t riMouseX() { return mxr; } 

int32_t riMouseY() { return myr; }

int32_t riMouseXBal() { return Cursor.x; } 

int32_t riMouseYBal() { return Cursor.y; }

void riPoll()

{

	if ( !init_done )

	{

		RAWINPUTDEVICE Rid[2] = {0};



		Rid[0].usUsagePage = 0x01; 

		Rid[0].usUsage = 0x02; 

		Rid[0].dwFlags = RIDEV_DEVNOTIFY;

		Rid[0].hwndTarget = 0;



		Rid[1].usUsagePage = 0x01; 

		Rid[1].usUsage = 0x06; 

		Rid[1].dwFlags = 0;

		Rid[1].hwndTarget = 0;

		std::cout<< "NOT !init_done  " << ".\n";


		if (RegisterRawInputDevices(Rid, 2, sizeof(Rid[0])) == FALSE) {

			std::cout<< "sizeof rid 0 == false  " << ".\n";
		    
			return;

		}

		init_done = true;

		std::cout<< "init_done = true  " << ".\n";

		return;

	}

	CopyMemory( MouseState0, MouseState1, sizeof(MouseState0) );
	
	for ( int i = 0; i < 5; i++ )

	{
		std::cout<< "for loop in RiPoll() " << ".\n";

		if ( (MouseTime1[i] - MouseTime0[i]) < 500 )

		{

			MouseTime1[i] = 500;

			MouseTime0[i] = 0;

			std::cout<< "Mouse time[i] - MouseTime0[i] < 500  " << ".\n";

		}

	}

	MSG msg = {0};
	
	while ( PeekMessage( &msg, 0, WM_INPUT_DEVICE_CHANGE, WM_INPUT, PM_REMOVE | PM_QS_INPUT ) )

	{

		std::cout<< "while in riPoll()  " << ".\n";

		if ( WM_INPUT_DEVICE_CHANGE == msg.message )

		{

			DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);

			std::cout<< "WM_INPUT_DEVICE_CHANGE == msg.message  " << ".\n";

		}

		if ( RIM_INPUT == GET_RAWINPUT_CODE_WPARAM( msg.wParam ) )

		{

			UINT dwSize = sizeof(RAWINPUT);

			RAWINPUT raw = {0};

			GetRawInputData((HRAWINPUT)msg.lParam, RID_INPUT, &raw, &dwSize, sizeof(RAWINPUTHEADER));

			std::cout<< "GET_RAWINPUT_CODE_WPARAM( msg.wParam)  " << ".\n";

			if ( RIM_TYPEMOUSE == raw.header.dwType ) 

			{

				riProcessMouseMessage( &raw.data.mouse, msg.time );
				std::cout<< "RIM_TYPEMOUSE == raw.header.dwType " << ".\n";
			}			

		}

		DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);	

		std::cout<< "defwindowproc msg hwnd msg.message msg.wparam.msg.lparam  " << ".\n";
	}



//MSG msg = {0};

while (PeekMessage(&msg, 0, 0, WM_INPUT_DEVICE_CHANGE - 1, PM_REMOVE))

	{

		TranslateMessage( &msg );

		DispatchMessage( &msg );

		std::cout<< "peekmessage 1  " << ".\n";

	}

while ( PeekMessage( &msg, 0, WM_INPUT + 1, 0xffffffff, PM_REMOVE ) )

	{

		TranslateMessage( &msg );

		DispatchMessage( &msg ); 

		std::cout<< "peekmessage 2  " << ".\n";
	}

}


	int main()
{
	riPoll();

	std::cout<< "bleh   " << mxr << ".\n";
	std::cout<< "bleh2  " << myr << ".\n";
		
	return 0;
}
My output is this: 
 
NOT !init_done  .
sizeof rid 0 == false  .
bleh   0.
bleh2  0.

Share this post


Link to post
Share on other sites

Ok I called GetLastError to see what it said. It was a 1004, ERROR_INVALID_FLAGS.

 

I changed Rid[0].dwFlags = RIDEV_DEVNOTIFY to Rid[0].dwFlags = RIDEV_NOLEGACY

 

Now I get: 

 

NOT !init_done  .
init_done = true  .
bleh   0.
bleh2  0.
 
So yeah that's at least some progress.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!