   Game Engine trouble
  Basically, I want to make and engine in C++. However, I also wanted to use windows forms, and the clr as well. This left me tring to use managed direct X, which I got working, but is completely different to normal direct X. Seeing as there aren't many resources on MDX, I then decided to put my engine into a DLL. I need the DLL to either (do both):- Put Direct X in a panel on the forum (I know in the Crysis Sandbox editor they magically do that somehow)- Put Direct X in a new window, using the ancient windows API.I have no idea how to do this. I cant seem to make the DLL popup a window, let alone in a panel on a form. Any help would be much appreciated as I cant continue without fixing this. Thankyou in advance.   
  Maybe this GameDev article will helphttp://www.gamedev.net/reference/programming/features/D3DCsharpWinform/;  Thanks, that helps a bit, but I need to know how to get the DLL to actually open a window aswell. Also, some of that seems to be in C#, and may use some fancy feature of that I dont know about. Help would be much appreciated.   ;Quote:- Put Direct X in a panel on the forum (I know in the Crysis Sandbox editor they magically do that somehow)- Put Direct X in a new window, using the ancient windows API.I won't have specific code for DirectX, but generally speaking, you simply pass the HWND of the form to your DLL to use as the base window or alternatively call another function to create a window. You will need to make a C interfaced DLL that can be run-time loaded as well. You can still use C++ inside the DLL, but the external interface needs to be C.For example, this is what your DLL code could look like:#include <windows.h>#define EXPORT extern "C" __declspec(dllexport)#define CONVENTION __stdcallHWND g_hGlobalWnd = 0;const char g_szClassName[] = "myWindowClass";LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){    switch(msg)    {   case WM_LBUTTONDOWN:   {  char szFileName[MAX_PATH];  HINSTANCE hInstance = GetModuleHandle(NULL);  GetModuleFileNameA(hInstance, szFileName, MAX_PATH);  MessageBoxA(hwnd, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION);   }   break;   case WM_CLOSE:  DestroyWindow(hwnd);   break;   case WM_DESTROY:  PostQuitMessage(0);   break;   default:  return DefWindowProc(hwnd, msg, wParam, lParam);    }    return 0;}int SetupDirectX(){// Use g_hGlobalWnd, etc...return 1;}EXPORT HWND CONVENTION CreateEngine(int width, int height, const char * title){WNDCLASSEXA wc;HINSTANCE hInstance = GetModuleHandleA(0);    wc.cbSize   = sizeof(WNDCLASSEX);    wc.style    = 0;    wc.lpfnWndProc   = WndProc;    wc.cbClsExtra    = 0;    wc.cbWndExtra    = 0;wc.hInstance= hInstance;    wc.hIcon    = LoadIcon(NULL, IDI_APPLICATION);    wc.hCursor  = LoadCursor(NULL, IDC_ARROW);    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);    wc.lpszMenuName  = NULL;    wc.lpszClassName = g_szClassName;    wc.hIconSm  = LoadIcon(NULL, IDI_APPLICATION);    if(!RegisterClassExA(&wc))    {   MessageBoxA(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);   return 0;    }    g_hGlobalWnd = CreateWindowExA(WS_EX_CLIENTEDGE, g_szClassName, title, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL);    if(g_hGlobalWnd == NULL)    {   MessageBoxA(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);   return 0;    }    ShowWindow(g_hGlobalWnd, SW_SHOW);    UpdateWindow(g_hGlobalWnd);if(SetupDirectX() == 0){DestroyWindow(g_hGlobalWnd);g_hGlobalWnd = 0;return 0;}return g_hGlobalWnd;}EXPORT int CONVENTION CreateEngineFrom(HWND hWnd){g_hGlobalWnd = hWnd;if(SetupDirectX() == 0){g_hGlobalWnd = 0;return 0;}return 1;}Since you really should use the __stdcall calling convention, you will need to create your own .def for the DLL so your functions are exported without any __stdcall name mangling (@ followed by the parameter list size). An example of the def file for the above code would be:LIBRARY endlessDemo.dllEXPORTSCreateEngineCreateEngineFromWhen you added in the .def file to the project settings and build the DLL, you will get a clean API to load in your host program. Functions will look like this in Dependency Walker:1 (0x0001) 0 (0x0000) CreateEngine  0x0001110E2 (0x0002) 1 (0x0001) CreateEngineFrom 0x00011082Rather than this:1 (0x0001) 0 (0x0000) CreateEngine@12  0x000010D02 (0x0002) 1 (0x0001) CreateEngineFrom@4 0x000011F0This is important since it cuts down on the work you have to do in creating your own API. Once you have that done, you just need to create the API to use the DLL functions. I would suggest using macros to help make the work more automated and easier to maintain.Here's some code from my project that makes life a lot easier when doing this stuff. I went ahead and put everything into one file, but the way I have it setup the API goes into one header file that you include where needed and define a special define to implement the function pointers in one particular file.#include <windows.h>#include <stdio.h>// These were the two functions we exported from the DLL for reference//EXPORT HWND CONVENTION CreateEngine(int width, int height, const char * title)//EXPORT int CONVENTION CreateEngineFrom(HWND hWnd)//-----------------------------------------------------------------------------#define EXPORT#define CONVENTION __stdcall// These are my API loading macros that make life easier#define API_DECLARATION(ret, name, ...) extern ret (CONVENTION * name)(__VA_ARGS__ );#define API_DEFINITION(ret, name, ...) ret (CONVENTION * name)(__VA_ARGS__ ) = 0;#define API_LOAD(var, name) \ func = GetProcAddress(hDLL, #name); \ if(func == 0) \ { \ _snprintf_s(failedFunction, sizeof(failedFunction), sizeof(failedFunction) - 1, "%s", #name); \ break; \ } \ __asm { push eax } \ __asm { mov eax, func } \ __asm { mov var, eax } \ __asm { pop eax } //-----------------------------------------------------------------------------#define DEFINE_APIAPI_DECLARATION(HWND, CreateEngine, int width, int height, const char * title)API_DECLARATION(int, CreateEngineFrom, HWND hWnd)// This part is so we can have the API in on header file only and define DEFINE_API once to have it // compiled into the project. If we didn't we would have multiple linker errors or unresolved linker errors// if we forget to define it.#ifdef DEFINE_APIAPI_DEFINITION(HWND, CreateEngine, int width, int height, const char * title)API_DEFINITION(int, CreateEngineFrom, HWND hWnd)#endif//-----------------------------------------------------------------------------HMODULE hDLL = 0;char failedFunction[1024] = {0};//-----------------------------------------------------------------------------int LoadAPI(){if(hDLL) return 0;#ifndef _DEBUGhDLL = LoadLibraryA("endlessDemo.dll");#elsehDLL = LoadLibraryA("endlessDemo_d.dll");#endifif(hDLL == 0) return 0;FARPROC func = 0;do{API_LOAD(CreateEngine, CreateEngine)API_LOAD(CreateEngineFrom, CreateEngineFrom)return 1;} while(false);FreeLibrary(hDLL);hDLL = 0;return 0;}//-----------------------------------------------------------------------------int UnloadAPI(){if(hDLL == 0) return 0;FreeLibrary(hDLL);hDLL = 0;return 1;}int main(int argc, char * argv[]){if(LoadAPI() == 0){if(strlen(failedFunction))printf("Error: the function %s was not loaded\n", failedFunction);elseprintf("Error: the DLL was not loaded\n");return 0;}HWND h = CreateEngine(640, 480, "My Test Engine");Sleep(5000);UnloadAPI();return 0;}//-----------------------------------------------------------------------------A setup like that works out really well for using your DLL in any language that supports C strings, DLL loading, as well as pointers. You should be able to easily interface into your other code with it. However, you do have to be careful of miscellaneous issues when mixing code. For example, if you want to use your own handle from .Net, you might have issues based on the message handling and would need to resolve that issue. Most of the time the problems to solve are not that hard, but if you are new at this stuff, it will be a little tricky at first.I'm sure you might have some questions on specifics, so feel free to ask. Hope that helps some. [smile]   ;  Wow. Thanks loads. I got it working. Thanks again.   