Jump to content
  • Advertisement
Sign in to follow this  
Jemme

Directx 11 Wpf Message pump

This topic is 460 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

Howdy

Ive got a WPF level editor  and a C++ Directx DLL.

Here are the main functions:

 public static class Engine
    {
        //DX dll
        //Init
        [DllImport("Win32Engine.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void Initialize(IntPtr hwnd, int Width, int Height);

        //Messages / Input
        [DllImport("Win32Engine.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void HandleMessage(IntPtr hwnd, int msg, int wParam, int lParam);

        //Load
        [DllImport("Win32Engine.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void Load();

        //Update
        [DllImport("Win32Engine.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void Update();

        //Draw
        [DllImport("Win32Engine.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void Draw();

        //Shutdown
        [DllImport("Win32Engine.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern void ShutDown();

    }

Okay so what is the proper way to get the window hosted inside a control and the pump the engine?

At the moment i have it inside a (winfom) panel and use:
 

 protected override void OnSourceInitialized(EventArgs e)
        {
            base.OnSourceInitialized(e);

            HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
            source.AddHook(WndProc);
        }

        private static IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            Engine.HandleMessage(hwnd, msg, (int)wParam, (int)lParam);

            Engine.Update();
            Engine.Draw();

            return IntPtr.Zero;
        }

But there's just a few problems:

  • Messages come from everywhere not just the panel (due to using the main window)
  • The input doesn't actually work
  • It's super duper ugly code wise

In terms of c++ side the normal enigne (non-editor ) uses this pump:

	while (msg.message != WM_QUIT)
	{
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);


			//Input
			if (msg.message == WM_INPUT)
			{

				//Buffer size
				UINT size = 512;
				BYTE buffer[512];
				GetRawInputData((HRAWINPUT)msg.lParam, RID_INPUT, (LPVOID)buffer, &size, sizeof(RAWINPUTHEADER));

				RAWINPUT *raw = (RAWINPUT*)buffer;

				if (raw->header.dwType == RIM_TYPEKEYBOARD)
				{
					bool keyUp = raw->data.keyboard.Flags & RI_KEY_BREAK;
					USHORT keyCode = raw->data.keyboard.VKey;

					if (!keyUp)
					{
						Keyboard::SetKeyState(keyCode, true);
					}
					else
					{
						Keyboard::SetKeyState(keyCode, false);
					}
				}
			}
		}

		time->Update();
		engine->Update(time->DeltaTime());
		engine->Draw();
	}

Not the nicest loop but works for now for testing and things.

Now the Editor versions code is:
 

//Initalize enigne and all sub systems
extern "C"
{
	//Hwnd is a panel usually
	DLLExport void Initialize(int* hwnd, int Width, int Height)
	{
		engine = new Engine();
		time = new Timer();
		time->Update();

		if (engine->Initialize(Width, Height,(WINHANDLE)hwnd))
		{
			//WindowMessagePump();
		}
		else
		{
			//return a fail?
		}
	}
}

extern "C"
{
	DLLExport void HandleMessage(int* hwnd, int msg, int wParam, int lParam)
	{
			//Input
			if (msg == WM_INPUT)
			{

				//Buffer size
				UINT size = 512;
				BYTE buffer[512];
				GetRawInputData((HRAWINPUT)lParam, RID_INPUT, (LPVOID)buffer, &size, sizeof(RAWINPUTHEADER));

				RAWINPUT *raw = (RAWINPUT*)buffer;

				if (raw->header.dwType == RIM_TYPEKEYBOARD)
				{
					bool keyUp = raw->data.keyboard.Flags & RI_KEY_BREAK;
					USHORT keyCode = raw->data.keyboard.VKey;

					if (!keyUp)
					{
						Keyboard::SetKeyState(keyCode, true);
					}
					else
					{
						Keyboard::SetKeyState(keyCode, false);
					}
				}
		}
	}
}

//Load
extern "C"
{
	DLLExport void Load()
	{
		engine->Load();
	}
}

//Update
extern "C"
{
	DLLExport void Update()
	{
		time->Update();
		engine->Update(time->DeltaTime());
	}
}

//Draw
extern "C"
{
	DLLExport void Draw()
	{
		engine->Draw();
	}
}

//ShutDown Engine
extern "C"
{
	DLLExport void ShutDown()
	{
		engine->ShutDown();
		delete time;
		delete engine;
	}
}

 

Any advice of how to do this properly would be much apprcieated.

p.s in my opinion the loop should kind of stay the same? but allow the wpf to psuh the message through some how and the loop within c++ calls the update and draw still so :
 

//Gets message from C# somehow
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
  TranslateMessage(&msg);
  DispatchMessage(&msg);
  //Input
}

time->Update();
engine->Update(time->DeltaTime());
engine->Draw();
//returns back to c#

^ some how have that in c++ as the message pump called from wpf 

Thanks :D

Share this post


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

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!