Thread: Windows Form App as parent, Directx as child??

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    1

    Windows Form App as parent, Directx as child??

    I'm trying to write a windows Form Application in VS 2003 using c++. The Form should launch then a child to the form will execute using directX. My main problem is finding a HWND from the form that can be passed to the CreateWindowEx function as the parent handle.

    I get as far as excuting the CreateDevice function and it returns D3DERR_INVALIDCALL. If anyone could point me in a good direction for finding out how to make this work, or what i'm doing wrong in my code it would be much appreciated. =)

    here is the form.h file
    Code:
    #pragma once
    
    
    namespace dformapp
    {
    	using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    
    	/// <summary> 
    	/// Summary for Form1
    	///
    	/// WARNING: If you change the name of this class, you will need to change the 
    	///          'Resource File Name' property for the managed resource compiler tool 
    	///          associated with all .resx files this class depends on.  Otherwise,
    	///          the designers will not be able to interact properly with localized
    	///          resources associated with this form.
    	/// </summary>
    	
    	public __gc class Form1 : public System::Windows::Forms::Form
    	{	
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
    		}
    		Form1(HINSTANCE &hInstance)
    		{
    			//SubScreen = new CD3DSetup(hInstance);
    			InitializeComponent(hInstance);
    		}
    		CD3DSetup *SubScreen;
    	private: 
    		System::Windows::Forms::Timer *  timer1;
    	protected:
    		void Dispose(Boolean disposing)
    		{
    			if (disposing && components)
    			{
    				components->Dispose();
    			}
    			__super::Dispose(disposing);
    		}
    	private: System::ComponentModel::IContainer *  components;
    
    	private:
    		/// <summary>
    		/// Required designer variable.
    		/// </summary>
    
    
    		/// <summary>
    		/// Required method for Designer support - do not modify
    		/// the contents of this method with the code editor.
    		/// </summary>
    		void InitializeComponent(void)
    		{
    			this->components = new System::ComponentModel::Container();
    			this->timer1 = new System::Windows::Forms::Timer(this->components);
    			// 
    			// timer1
    			// 
    			this->timer1->Enabled = true;
    			this->timer1->Tick += new System::EventHandler(this, timer1_Tick);
    			// 
    			// Form1
    			// 
    			this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
    			this->ClientSize = System::Drawing::Size(292, 273);
    			this->Name = S"Form1";
    			this->Text = S"Form1";
    		}
    		void InitializeComponent(HINSTANCE &hInstance)
    		{
    			this->components = new System::ComponentModel::Container();
    			this->timer1 = new System::Windows::Forms::Timer(this->components);
    			// 
    			// timer1
    			// 
    			this->timer1->Enabled = true;
    			this->timer1->Tick += new System::EventHandler(this, timer1_Tick);
    			// 
    			// Form1
    			// 
    			this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
    			this->ClientSize = System::Drawing::Size(292, 273);
    			this->Name = S"Form1";
    			this->Text = S"Form1";
    			this->Parent = this;
    
    			HWND hwnd = FindWindow(NULL,"3dformapp");
    			SubScreen = new CD3DSetup(hInstance,hwnd);
    
    		}	
    
    	private: System::Void timer1_Tick(System::Object *  sender, System::EventArgs *  e)
    			 {
    				if( NULL == SubScreen->g_pd3dDevice )
    				{
                        return;
    				}
    
    				// Clear the backbuffer to a blue color
    				SubScreen->g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
    			    
    				// Begin the scene
    				if( SUCCEEDED( SubScreen->g_pd3dDevice->BeginScene() ) )
    				{
    					// Rendering of scene objects can happen here
    			    
    					// End the scene
    					SubScreen->g_pd3dDevice->EndScene();
    				}
    
    				// Present the backbuffer contents to the display
    				SubScreen->g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
    				
    			 }
    
    	};
    }
    the Form.cpp file
    Code:
    #include "stdafx.h"
    #include "Form1.h"
    #include <windows.h>
    
    using namespace dformapp;
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA;
    	Application::Run(new Form1(hInstance));
    	return 0;
    }
    And here is header that contains my Direct 3d execution info

    Code:
    #include "stdafx.h"
    
    #ifndef D3DSETUP_H
    #define D3DSETUP_H
    
    #include <d3d9.h>
    
    class CD3DSetup
    {
    public:
    	LPDIRECT3D9             g_pD3D;
    	LPDIRECT3DDEVICE9       g_pd3dDevice;
    	D3DPRESENT_PARAMETERS   d3dpp; 
    	CD3DSetup( HINSTANCE &hInstance,HWND parent)
    	{
    		g_pD3D = NULL;
    		g_pd3dDevice = NULL;
    		WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, NULL, 0L, 0L, 
                          GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                          "D3D Tutorial", NULL };
    		RegisterClassEx( &wc );
    
    		// Create the application's window
    		HWND hWnd = CreateWindowEx(WS_EX_MDICHILD, NULL,NULL, 
    									WS_CHILDWINDOW, 100, 100, 300, 300,
    									parent, NULL, wc.hInstance, NULL );
    		
    		// Initialize Direct3D
    		if( SUCCEEDED( InitD3D(hWnd,parent) ) )
    		{
    			// Show the window
    			ShowWindow(hWnd , SW_SHOWDEFAULT );
    			UpdateWindow( hWnd );
    		}
    	}
    	HRESULT InitD3D( HWND hWnd ,HWND Hwnd)
    	{
    		// Create the D3D object, which is needed to create the D3DDevice.
    		if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
    			return E_FAIL;
    
    		ZeroMemory( &d3dpp, sizeof(d3dpp) );
    		d3dpp.Windowed = TRUE;
    		d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    		d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    
    		HRESULT TEST;
    		TEST = g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
    										D3DCREATE_SOFTWARE_VERTEXPROCESSING,
    										&d3dpp, &g_pd3dDevice );
    		
    		if(D3DERR_DEVICELOST == TEST)
    		{
    			MessageBox(0,"Device Lost",0,0);
    			return E_FAIL;
    		}
    		if(D3DERR_INVALIDCALL == TEST)
    		{
    			MessageBox(0,"Invalid Call",0,0);
    			return E_FAIL;
    		}
    		if(D3DERR_NOTAVAILABLE == TEST)
    		{
    			MessageBox(0,"Not Available",0,0);
    			return E_FAIL;
    		}
    		if(D3DERR_OUTOFVIDEOMEMORY == TEST)
    		{
    			MessageBox(0,"Out of Video Memory",0,0);
    			return E_FAIL;
    		}
    
    		return S_OK;
    	}
    };
    
    #endif

  2. #2
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    D3DERR_INVALIDCALL means you're passing a bad argument somewhere, possibly among the presentation parameters. You're using so many default values (0) so I can't suggest any changes though.

    EDIT:
    This piece of code is mighty suspicious. You're adding to the tick variable a (theoretically) random address?
    Code:
    this->timer1->Tick += new System::EventHandler(this, timer1_Tick);
    Last edited by Magos; 05-27-2006 at 08:00 AM.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  3. #3
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,130
    The Timer code is fine, += is overloaded to add another callback function for the timer to call on each tick.

    You can get a native window handle by accessing the Handle property of a form. In managed C++ that would be the get_Handle() method.

    Managed C++ is very useful for interfacing between C++ and managed Code. Using it for something else is just calling for more trouble than any program could be worth. If you want a managed application, use C# and managed DirectX. If you want a native application, use C++ and native classes. Mixing them will just give you the worst from both worlds, all the limits and bloat of the .NET Framework plus the cryptic obscurity of C++. If you don't have a benefit, and I don't see any in your case, don't go that way. Decide on one good side and stick with it. Safety and ease of C# or speed and control of C++. You can have only one, or none. Don't throw away both advantages. Pick one.
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    C++, MFC, and DirectX all play together nicely.

    I'm sure C++, Win32, and DirectX would do much the same if you feel like coding all the windows stuff yourself.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Script errors - bool unrecognized and struct issues
    By ulillillia in forum Windows Programming
    Replies: 10
    Last Post: 12-18-2006, 04:44 AM
  2. child classes calling parent constructors (with arguments)
    By reanimated in forum C++ Programming
    Replies: 3
    Last Post: 05-01-2006, 10:52 AM
  3. pipe
    By smart girl in forum C Programming
    Replies: 4
    Last Post: 04-30-2006, 09:17 AM
  4. Virtual keys
    By Arkanos in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2005, 10:00 AM
  5. Scale MDI child to parent
    By bludstayne in forum C# Programming
    Replies: 0
    Last Post: 07-10-2004, 02:26 PM