   DirectX 9 and multiple windows
  Hello everyone, I am new to these forums and fairly new to DirectX programming. Moreover, the integration of more complex Windows programming is starting to cause me some real trouble.I am trying to put together a little piece of game world editor and would very much like to use a dialog window with a TreeView for browsing game objects. With the dialog window working in otherwise, it seems DirectX is rendering over it, and I just can't figure out how to prevent this (If I comment away the rendering call, it shows up clearly).I have assembled a pretty light version which suffers the same problem as my real project, hopefully not too painful to read through if anyone is up to the challenge. (I realize while writing this that any dialog window procedure might have sufficed so I probably could have cut you an even shorter version).If I may in any other way supply more information I will be eager to do so, the whole project is kind of on hold because of this problem.Many thanks in advance !- Dave#include <windows.h>#include <windowsx.h>#include <d3d9.h>#pragma comment (lib, "d3d9.lib")#pragma comment(lib, "comctl32.lib")#include "commctrl.h"#include "resource.h"LPDIRECT3D9 d3d;LPDIRECT3DDEVICE9 d3ddev;HWND HTrCtrl;void initD3D(HWND hWnd);void render_frame(void);void cleanD3D(void);BOOL InitTreeViewItems( HWND hwndTV );HWND CreateATreeView( HINSTANCE hInstance, HWND hwndParent );LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){    HWND hWnd;    WNDCLASSEX wc;    ZeroMemory(&wc, sizeof(WNDCLASSEX));    wc.cbSize = sizeof(WNDCLASSEX);    wc.style = CS_HREDRAW | CS_VREDRAW;    wc.lpfnWndProc = WindowProc;    wc.hInstance = hInstance;    wc.hCursor = LoadCursor(NULL, IDC_ARROW);    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;    wc.lpszClassName = "WindowClass";    RegisterClassEx(&wc);    hWnd = CreateWindowEx(NULL, "WindowClass", "Test Application", WS_OVERLAPPEDWINDOW, 300, 300, 800, 600, NULL, NULL, hInstance, NULL);HTrCtrl = CreateATreeView( hInstance, hWnd );    ShowWindow( hWnd, nCmdShow );    initD3D(hWnd);    MSG msg;    while(TRUE)    {   while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )   {  TranslateMessage(&msg);  DispatchMessage(&msg);   }   if( msg.message == WM_QUIT )  break;   render_frame();    }    cleanD3D();    return msg.wParam;}LRESULT CALLBACK WindowProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){    switch( message )    {   case WM_DESTROY:  { PostQuitMessage(0); return 0;  } break;    }    return DefWindowProc ( hWnd, message, wParam, lParam );}void initD3D( HWND hWnd ){    d3d = Direct3DCreate9( D3D_SDK_VERSION );    D3DPRESENT_PARAMETERS d3dpp;    ZeroMemory( &d3dpp, sizeof(d3dpp) );    d3dpp.Windowed = TRUE;    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    d3dpp.hDeviceWindow = hWnd;    d3d->CreateDevice(D3DADAPTER_DEFAULT,  D3DDEVTYPE_HAL,  hWnd,  D3DCREATE_SOFTWARE_VERTEXPROCESSING,  &d3dpp,  &d3ddev);}void render_frame(void){    d3ddev->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0 );    d3ddev->BeginScene();    d3ddev->EndScene();    d3ddev->Present( NULL, NULL, NULL, NULL );}void cleanD3D(void){    d3ddev->Release();    d3d->Release();}HTREEITEM AddItemToTree( HWND hwndTV, LPTSTR lpszItem, int nLevel ){TVITEM tvi;    TVINSERTSTRUCT tvins;    static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;    static HTREEITEM hPrevRootItem = NULL;static HTREEITEM hPrevLev2Item = NULL;HTREEITEM hti;tvi.mask = TVIF_TEXT | TVIF_PARAM;    // Set the text of the item.tvi.pszText = lpszItem;tvi.cchTextMax = sizeof(tvi.pszText)/sizeof(tvi.pszText[0]);// Save the heading level in the item's application-defined// data area    tvi.lParam = (LPARAM)nLevel;tvins.item = tvi;tvins.hInsertAfter = hPrev;// Set the parent item based on the specified level    if ( nLevel == 1 )   tvins.hParent = TVI_ROOT;else if ( nLevel == 2 )   tvins.hParent = hPrevRootItem;else    tvins.hParent = hPrevLev2Item;// Add the item to the tree-view control    hPrev = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM, 0,(LPARAM)(LPTVINSERTSTRUCT)&tvins);// Save the handle to the item    if( nLevel == 1 )    hPrevRootItem = hPrev;else if( nLevel == 2 )    hPrevLev2Item = hPrev;return hPrev; }BOOL InitTreeViewItems( HWND hwndTV ) { AddItemToTree( hwndTV, "1. Why", 0 );AddItemToTree( hwndTV, "2. won't", 0 );AddItemToTree( hwndTV, "3. this", 2 );AddItemToTree( hwndTV, "4. crap", 0 );AddItemToTree( hwndTV, "5. work?!", 0 );    return TRUE;}HWND CreateATreeView( HINSTANCE hInstance, HWND hwndParent ) {RECT rcClient;    HWND hwndTV;    // Ensure that the common control DLL is loaded.InitCommonControls();    GetClientRect( hwndParent, &rcClient );    hwndTV = CreateWindowEx(0,   WC_TREEVIEW,   TEXT( "File List" ),WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | WS_EX_APPWINDOW | WS_DLGFRAME | WS_EX_RIGHTSCROLLBAR,    0,    0,    200,    rcClient.bottom,   hwndParent,    (HMENU)IDC_TREE1,hInstance,    NULL);SetWindowPos( HTrCtrl, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE );    if ( !InitTreeViewItems( hwndTV ) )    {   DestroyWindow(hwndTV);   return FALSE;    }    return hwndTV;}[Edited by - Vanderry on August 3, 2009 5:00:02 PM]
  Disclaimer... I didn't look very hard at your code before replying.That being said, try creating a "CreateRenderWindow" method like you have for tree views, and put the HWND returned onto your window as a child window, just like you are with your tree view.  If you're giving it the hwnd of the main window right now, it's just going to draw over top of everything else.  If you do that, and it's still drawing over top, try reversing your calls to CreateRenderWindow and CreateATreeView, as creation order may affect zorder.Additionally, if you're trying to render to the full size of the window, and you want win32 controls "hovering" over what you render, you're cutting your FPS in half.  Win32 controls are rendered with GDI/GDI+, and you're rendering with DirectX.  These tend to fight it out for proper z-order and the result of that fight, from my experience, is about a 50% drop in fps.  It's much better to not overlap controls.And finally, in d3d, if you want multiple d3d render windows (and it's useful for tools, especially if you want an asset browser) you'll probably want to use a D3D swap chain.;  It looks to me like you are passing the main hWnd to your initD3D function.  What you probably want to do is to have two sub-windows: 1) the tree/list view control and 2) your D3D render window.  Since D3D can render to anything that has an HWND available, you can either create another complete window and pass that window's handle to your initD3D function, or you can create another sub-window within the main window.  Think of something like a split screen where the left hand side is the tree view, and the right hand side is your rendering area.With that said, you may want to consider using something a bit more heavy weight for the GUI if you are going to do a bunch of interface work.  Something like MFC, wxWidgets, or Qt are all commonly used with D3D and would follow a similar concept as described above - you find an hWnd and render to it when that object should be 'drawing' its own surface.   ;  Thanks for the quick response, guys. Using sub-windows within the main one solved the problem in the sense that I no longer need to have them overlapping one another. I can't prevent the DirectX rendering to override anything else in the window but then like mentioned, it would just be a waste of efficiency to hide part of the rendered window.I hope this post can come to use to anyone else running into the same problem, as I have come to base most of my own programming knowledge on posts like these.- Dave   