• Advertisement
Sign in to follow this  

Directx 11 Wpf Message pump

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Now

  • Advertisement
  • Similar Content

    • By Snaked
      Im working in this project for 1 year .... mostly i develop a tool and databases for make the different maps and now i'm doing the client for play the game
      Tell me if you like it......
      this is a capture of how is viewing atm

       
       
      https://youtu.be/9251v4wDTQ0
    • By Dave Haylett
      I'm using WriteableBitmaps in my project, and the tiffbitmapencoder and tiffbitmapdecoder classes to save off and restore a certain large graphic file from a WriteableBitmap to hard disc (the image is too big for the PNGbitmapencoder/decoder).
      This is working ok, but I'd like to encode to and decode from memory if possible, instead of having to save to disc. This is because, as part of the user experience this massive image can get wiped/cut down, and it takes a few precious seconds to reconstruct it again from scratch (which is also part of the user experience), but I can't afford the memory to just clone the whole image into another bitmap and clone it back again when needed, instead of rebuilding.
      Compressing it to TIF and holding in memory until it's needed again seems a viable option, but currently I can only compress/decompress to/from a file on disc.
      I've tried using MemoryStream instead of FileStream, and even though the encoder seems to like it, the decoder doesn't.
      Is it possible for me to achieve this?
    • By Dave Haylett
      Hi everyone. I need some help with my project. It's a 2D-graphics-heavy WPF front-end app written in C#, which talks to two Access 2000 databases (yes I know, it's all I've got). It will be distributed freely on the internet, and so will be being used by Windows users of various installations/versions of Windows, Office, etc.
      One of the two databases (let's call it A), is intended to be read-only, and will be distributed with the app. It has half a dozen relational tables which I as the developer have populated, and is connected to in the app via OleDB Jet 4 with SQL querying the data now and then as the user uses the front-end. The database will be replaced whenever I release an update to the app.
      Database B is read/write, and contains end-user preferences, for example when they favourite something in my front-end, a Favourites table in here gets appended to. This database is not distributed with my app, and should not be overwritten, as it will lose user prefs, etc. and annoy my users.
      Whenever my app is run by a user, during initialisation database A will suck in the user data from database B (using simple SQL SELECT * INTO...), so that all the tables can be joined together by the SQL in database A (to include user prefs/favourites in SQL queries), and whenever the user favourites something, a record is created both in A (for the short-term session) and B (permanently). Database B isn't just about holding favourites, there is other user data in here as well, so there are 3 or 4 tables in B.
      So far, this is all working fine and I'm happy...
      Unfortunately my app is currently 32-bit, and it now needs to break the 32-bit memory barrier what with the size and volume of the graphics I'm pulling in (using the HDD is not really an option, as different graphics are needed kind of instantly and the hard disc would be being hosed and the app dog-slow otherwise, I suspect even off an SSD).
      I'm using VS2015, and switching to 64-bit will probably fix the memory problem, but it breaks Jet 4.0. I'm sure this is old news to most of you.
      To try to keep with 32-bit (and Jet4) but get the memory I need I've tried the -largeaddressaware toggle, and I've tried the editbin suggestion, but I just can't get these solutions to work in VS2015 no matter how hard I try. Are these definitely 100% solutions to 2gb memory limit in 32-bit applications? Should they always work? Am I dumb in being unable to get this to work?
      So otherwise I'm resigned to migrating to 64-bit, and having to get around the database issue, not the memory issue.
      My users will be using a variety of Windows versions (probably 7 and 10), and I'm sure various versions of Office, and so my solution for querying my two Access databases needs to be pretty open if possible.
      Googling has suggested I switch from JET4 to ACE12, but this is apparently requiring me to uninstall Office 2000 and install a 64-bit version (which I don't have), so I can't use it, and I suspect any users who also have an old version of Office installed won't be able to use it either?
      Googling has also suggested I use MS SQL Server. This sounds fine if there's such a thing as a "lite" local version which can manage database access, but I still need to somehow get the data from the databases (A.mdb and B.mdb) into the SQL Server each time the users fire up my app.
      The only solution I can think of at the minute, is to export all the tables from database A into CSVs every time I update the data in there, and have the app import them in a lame way, and also convert database B into some crappy text file which gets written to whenever the user changes a preference. I'd much rather use SQL to do all this if possible, as when the user browses around the app, queries involving joining several tables in A are regularly created and executed to adjust the user's experience/return search results/etc.
      So to summarise my misery, is there either an easy reliable way for me to keep with 32-bit/Jet4 and be able to address >2gb. Or is there instead an easy reliable way for me to switch to 64-bit and successfully query two Access databases without requiring all my users to have 64-bit Office installed?
      Thanks for reading and I hope someone can help.
    • By eldwin11929
      We're looking for programmers for our project.
      Our project is being made in Unity
      Requirements:
      -Skills in Unity
      -C#
      -Javascript
      -Node.js
      We're looking for programmers who can perform a variety of functions on our project.
      Project is a top-down hack-and-slash pvp dungeon-crawler like game. Game is entirely multiplayer based, using randomized dungeons, and a unique combat system with emphasis on gameplay.
      We have a GDD to work off of, and a Lead Programmer you would work under.
      Assignments may include:
      -Creating new scripts of varying degrees specific to the project (mostly server-side, but sometimes client-side)
      -Assembling already created monsters/characters with existing or non-existing code.
      -Creating VFX
      -Assembling already created environment models
      If interested, please contact: eldwin11929@yahoo.com
      This project is unpaid, but with royalties.
       
      ---
      Additional Project Info:
      Summary:
      Bassetune Reapers is a Player-verus-Player, competitive dungeon crawler. This basically takes on aspects of dungeon crawling, but with a more aggressive setting. Players will have the option to play as the "dungeon-crawlers" (called the 'Knights', or "Knight Class", in-game) or as the "dungeon" itself (literally called the 'Bosses', or "Boss Class", in-game). What this means is that players can choose to play as the people invading the dungeon, or as the dungeon-holders themselves.
      Key Features:
      -Intense, fast-paced combat
      -Multiple skills, weapons, and ways to play the game
      -Tons of different Bosses, Minibosses, creatures and traps to utilize throughout the dungeon
      -Multiple unique environments
      -Interesting, detailed lore behind both the game and world
      -Intricate RPG system
      -Ladder and ranking system
      -Lots of customization for both classes s of customization for both classes
    • By reenigne
      For those that don't know me. I am the individual who's two videos are listed here under setup for https://wiki.libsdl.org/Tutorials
      I also run grhmedia.com where I host the projects and code for the tutorials I have online.
      Recently, I received a notice from youtube they will be implementing their new policy in protecting video content as of which I won't be monetized till I meat there required number of viewers and views each month.

      Frankly, I'm pretty sick of youtube. I put up a video and someone else learns from it and puts up another video and because of the way youtube does their placement they end up with more views.
      Even guys that clearly post false information such as one individual who said GLEW 2.0 was broken because he didn't know how to compile it. He in short didn't know how to modify the script he used because he didn't understand make files and how the requirements of the compiler and library changes needed some different flags.

      At the end of the month when they implement this I will take down the content and host on my own server purely and it will be a paid system and or patreon. 

      I get my videos may be a bit dry, I generally figure people are there to learn how to do something and I rather not waste their time. 
      I used to also help people for free even those coming from the other videos. That won't be the case any more. I used to just take anyone emails and work with them my email is posted on the site.

      I don't expect to get the required number of subscribers in that time or increased views. Even if I did well it wouldn't take care of each reoccurring month.
      I figure this is simpler and I don't plan on putting some sort of exorbitant fee for a monthly subscription or the like.
      I was thinking on the lines of a few dollars 1,2, and 3 and the larger subscription gets you assistance with the content in the tutorials if needed that month.
      Maybe another fee if it is related but not directly in the content. 
      The fees would serve to cut down on the number of people who ask for help and maybe encourage some of the people to actually pay attention to what is said rather than do their own thing. That actually turns out to be 90% of the issues. I spent 6 hours helping one individual last week I must have asked him 20 times did you do exactly like I said in the video even pointed directly to the section. When he finally sent me a copy of the what he entered I knew then and there he had not. I circled it and I pointed out that wasn't what I said to do in the video. I didn't tell him what was wrong and how I knew that way he would go back and actually follow what it said to do. He then reported it worked. Yea, no kidding following directions works. But hey isn't alone and well its part of the learning process.

      So the point of this isn't to be a gripe session. I'm just looking for a bit of feed back. Do you think the fees are unreasonable?
      Should I keep the youtube channel and do just the fees with patreon or do you think locking the content to my site and require a subscription is an idea.

      I'm just looking at the fact it is unrealistic to think youtube/google will actually get stuff right or that youtube viewers will actually bother to start looking for more accurate videos. 
  • Advertisement