DXUTgui.cpp
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:284k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. //--------------------------------------------------------------------------------------
  2. // File: DXUTgui.cpp
  3. //
  4. // Desc: 
  5. //
  6. // Copyright (c) Microsoft Corporation. All rights reserved.
  7. //--------------------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9. #include "DXUTgui.h"
  10. #include "DXUTsettingsDlg.h"
  11. #undef min // use __min instead
  12. #undef max // use __max instead
  13. #ifndef WM_XBUTTONDOWN
  14. #define WM_XBUTTONDOWN 0x020B // (not always defined)
  15. #endif
  16. #ifndef WM_XBUTTONUP
  17. #define WM_XBUTTONUP 0x020C // (not always defined)
  18. #endif
  19. #ifndef WM_MOUSEWHEEL
  20. #define WM_MOUSEWHEEL 0x020A // (not always defined)
  21. #endif
  22. #ifndef WHEEL_DELTA
  23. #define WHEEL_DELTA 120 // (not always defined)
  24. #endif
  25. // Minimum scroll bar thumb size
  26. #define SCROLLBAR_MINTHUMBSIZE 8
  27. // Delay and repeat period when clicking on the scroll bar arrows
  28. #define SCROLLBAR_ARROWCLICK_DELAY  0.33
  29. #define SCROLLBAR_ARROWCLICK_REPEAT 0.05
  30. #define UNISCRIBE_DLLNAME L"\usp10.dll"
  31. #define GETPROCADDRESS( Module, APIName, Temp ) 
  32.     Temp = GetProcAddress( Module, #APIName ); 
  33.     if( Temp ) 
  34.         *(FARPROC*)&_##APIName = Temp
  35. #define PLACEHOLDERPROC( APIName ) 
  36.     _##APIName = Dummy_##APIName
  37. #define IMM32_DLLNAME L"\imm32.dll"
  38. #define VER_DLLNAME L"\version.dll"
  39. // DXUT_MAX_EDITBOXLENGTH is the maximum string length allowed in edit boxes,
  40. // including the NULL terminator.
  41. // 
  42. // Uniscribe does not support strings having bigger-than-16-bits length.
  43. // This means that the string must be less than 65536 characters long,
  44. // including the NULL terminator.
  45. #define DXUT_MAX_EDITBOXLENGTH 0xFFFF
  46. double        CDXUTDialog::s_fTimeRefresh = 0.0f;
  47. CDXUTControl* CDXUTDialog::s_pControlFocus = NULL;        // The control which has focus
  48. CDXUTControl* CDXUTDialog::s_pControlPressed = NULL;      // The control currently pressed
  49. struct DXUT_SCREEN_VERTEX
  50. {
  51.     float x, y, z, h;
  52.     D3DCOLOR color;
  53.     float tu, tv;
  54.     static DWORD FVF;
  55. };
  56. DWORD DXUT_SCREEN_VERTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;
  57. struct DXUT_SCREEN_VERTEX_UNTEX
  58. {
  59.     float x, y, z, h;
  60.     D3DCOLOR color;
  61.     static DWORD FVF;
  62. };
  63. DWORD DXUT_SCREEN_VERTEX_UNTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE;
  64. inline int RectWidth( RECT &rc ) { return ( (rc).right - (rc).left ); }
  65. inline int RectHeight( RECT &rc ) { return ( (rc).bottom - (rc).top ); }
  66. //--------------------------------------------------------------------------------------
  67. // CDXUTDialog class
  68. //--------------------------------------------------------------------------------------
  69. //--------------------------------------------------------------------------------------
  70. CDXUTDialog::CDXUTDialog()
  71. {
  72.     m_x = 0;
  73.     m_y = 0;
  74.     m_width = 0;
  75.     m_height = 0;
  76.     m_pManager = NULL;
  77.     m_bVisible = true;
  78.     m_bCaption = false;
  79.     m_bMinimized = false;
  80.     m_bDrag = false;
  81.     m_wszCaption[0] = L'';
  82.     m_nCaptionHeight = 18;
  83.     m_colorTopLeft = 0;
  84.     m_colorTopRight = 0;
  85.     m_colorBottomLeft = 0;
  86.     m_colorBottomRight = 0;
  87.     m_pCallbackEvent = NULL;
  88.     m_pCallbackEventUserContext = NULL;
  89.     m_fTimeLastRefresh = 0;
  90.     m_pControlMouseOver = NULL;
  91.     m_pNextDialog = this;
  92.     m_pPrevDialog = this;
  93.     m_nDefaultControlID = 0xffff;
  94.     m_bNonUserEvents = false;
  95.     m_bKeyboardInput = false;
  96.     m_bMouseInput = true;
  97. }
  98. //--------------------------------------------------------------------------------------
  99. CDXUTDialog::~CDXUTDialog()
  100. {
  101.     int i=0;
  102.     RemoveAllControls();
  103.     m_Fonts.RemoveAll();
  104.     m_Textures.RemoveAll();
  105.     for( i=0; i < m_DefaultElements.GetSize(); i++ )
  106.     {
  107.         DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
  108.         SAFE_DELETE( pElementHolder );
  109.     }
  110.     m_DefaultElements.RemoveAll();
  111. }
  112. //--------------------------------------------------------------------------------------
  113. void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog )
  114. {
  115.     m_pManager = pManager;
  116.     if( bRegisterDialog )
  117.         pManager->RegisterDialog( this );
  118.     SetTexture( 0, MAKEINTRESOURCE(0xFFFF), (HMODULE)0xFFFF );
  119.     InitDefaultElements();
  120. }
  121. //--------------------------------------------------------------------------------------
  122. void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog, LPCWSTR pszControlTextureFilename )
  123. {
  124.     m_pManager = pManager;
  125.     if( bRegisterDialog )
  126.         pManager->RegisterDialog( this );
  127.     SetTexture( 0, pszControlTextureFilename );
  128.     InitDefaultElements();
  129. }
  130. //--------------------------------------------------------------------------------------
  131. void CDXUTDialog::Init( CDXUTDialogResourceManager* pManager, bool bRegisterDialog, LPCWSTR szControlTextureResourceName, HMODULE hControlTextureResourceModule )
  132. {
  133.     m_pManager = pManager;
  134.     if( bRegisterDialog )
  135.         pManager->RegisterDialog( this );
  136.     
  137.     SetTexture( 0, szControlTextureResourceName, hControlTextureResourceModule );
  138.     InitDefaultElements();
  139. }
  140. //--------------------------------------------------------------------------------------
  141. void CDXUTDialog::SetCallback( PCALLBACKDXUTGUIEVENT pCallback, void* pUserContext )
  142. {
  143.     // If this assert triggers, you need to call CDXUTDialog::Init() first.  This change
  144.     // was made so that the DXUT's GUI could become seperate and optional from DXUT's core.  The 
  145.     // creation and interfacing with CDXUTDialogResourceManager is now the responsibility 
  146.     // of the application if it wishes to use DXUT's GUI.
  147.     assert( m_pManager != NULL && L"To fix call CDXUTDialog::Init() first.  See comments for details." ); 
  148.     m_pCallbackEvent = pCallback; 
  149.     m_pCallbackEventUserContext = pUserContext; 
  150. }
  151. //--------------------------------------------------------------------------------------
  152. void CDXUTDialog::RemoveControl( int ID )
  153. {
  154.     for( int i=0; i < m_Controls.GetSize(); i++ )
  155.     {
  156.         CDXUTControl* pControl = m_Controls.GetAt( i );
  157.         if( pControl->GetID() == ID )
  158.         {
  159.             // Clean focus first
  160.             ClearFocus();
  161.             // Clear references to this control
  162.             if( s_pControlFocus == pControl )
  163.                 s_pControlFocus = NULL;
  164.             if( s_pControlPressed == pControl )
  165.                 s_pControlPressed = NULL;
  166.             if( m_pControlMouseOver == pControl )
  167.                 m_pControlMouseOver = NULL;
  168.             SAFE_DELETE( pControl );
  169.             m_Controls.Remove( i );
  170.             return;
  171.         }
  172.     }
  173. }
  174. //--------------------------------------------------------------------------------------
  175. void CDXUTDialog::RemoveAllControls()
  176. {
  177.     if( s_pControlFocus && s_pControlFocus->m_pDialog == this )
  178.         s_pControlFocus = NULL;
  179.     if( s_pControlPressed && s_pControlPressed->m_pDialog == this )
  180.         s_pControlPressed = NULL;
  181.     m_pControlMouseOver = NULL;
  182.     for( int i=0; i < m_Controls.GetSize(); i++ )
  183.     {
  184.         CDXUTControl* pControl = m_Controls.GetAt( i );
  185.         SAFE_DELETE( pControl );
  186.     }
  187.     m_Controls.RemoveAll();
  188. }
  189. //--------------------------------------------------------------------------------------
  190. CDXUTDialogResourceManager::CDXUTDialogResourceManager()
  191. {
  192.     m_pd3dDevice = NULL;
  193.     m_pStateBlock = NULL;
  194.     m_pSprite = NULL;
  195. }
  196. //--------------------------------------------------------------------------------------
  197. CDXUTDialogResourceManager::~CDXUTDialogResourceManager()
  198. {
  199.     int i;
  200.     for( i=0; i < m_FontCache.GetSize(); i++ )
  201.     {
  202.         DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
  203.         SAFE_DELETE( pFontNode );
  204.     }
  205.     m_FontCache.RemoveAll();   
  206.     for( i=0; i < m_TextureCache.GetSize(); i++ )
  207.     {
  208.         DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
  209.         SAFE_DELETE( pTextureNode );
  210.     }
  211.     m_TextureCache.RemoveAll();   
  212.     CUniBuffer::Uninitialize();
  213.     CDXUTIMEEditBox::Uninitialize();
  214. }
  215. //--------------------------------------------------------------------------------------
  216. HRESULT CDXUTDialogResourceManager::OnCreateDevice( LPDIRECT3DDEVICE9 pd3dDevice )
  217. {
  218.     HRESULT hr = S_OK;
  219.     int i=0;
  220.     m_pd3dDevice = pd3dDevice;
  221.     
  222.     for( i=0; i < m_FontCache.GetSize(); i++ )
  223.     {
  224.         hr = CreateFont( i );
  225.         if( FAILED(hr) )
  226.             return hr;
  227.     }
  228.     
  229.     for( i=0; i < m_TextureCache.GetSize(); i++ )
  230.     {
  231.         hr = CreateTexture( i );
  232.         if( FAILED(hr) )
  233.             return hr;
  234.     }
  235.     hr = D3DXCreateSprite( pd3dDevice, &m_pSprite );
  236.     if( FAILED(hr) )
  237.         return DXUT_ERR( L"D3DXCreateSprite", hr );
  238.     // Call CDXUTIMEEditBox's StaticOnCreateDevice()
  239.     // to initialize certain window-dependent data.
  240.     CDXUTIMEEditBox::StaticOnCreateDevice();
  241.     return S_OK;
  242. }
  243. //--------------------------------------------------------------------------------------
  244. HRESULT CDXUTDialogResourceManager::OnResetDevice()
  245. {
  246.     HRESULT hr = S_OK;
  247.     for( int i=0; i < m_FontCache.GetSize(); i++ )
  248.     {
  249.         DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
  250.         if( pFontNode->pFont )
  251.             pFontNode->pFont->OnResetDevice();
  252.     }
  253.     if( m_pSprite )
  254.         m_pSprite->OnResetDevice();
  255.     IDirect3DDevice9* pd3dDevice = DXUTGetD3DDevice();
  256.     V_RETURN( pd3dDevice->CreateStateBlock( D3DSBT_ALL, &m_pStateBlock ) );
  257.     return S_OK;
  258. }
  259. //--------------------------------------------------------------------------------------
  260. bool CDXUTDialogResourceManager::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  261. {
  262.     // Let the CDXUTIMEEditBox's static message proc handle the msg.
  263.     // This is because some IME messages must be handled to ensure
  264.     // proper functionalities and the static msg proc ensures that
  265.     // this happens even if no control has the input focus.
  266.     if( CDXUTIMEEditBox::StaticMsgProc( uMsg, wParam, lParam ) )
  267.         return true;
  268.     return false;
  269. }
  270. //--------------------------------------------------------------------------------------
  271. void CDXUTDialogResourceManager::OnLostDevice()
  272. {
  273.     for( int i=0; i < m_FontCache.GetSize(); i++ )
  274.     {
  275.         DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
  276.         if( pFontNode->pFont )
  277.             pFontNode->pFont->OnLostDevice();
  278.     }
  279.     if( m_pSprite )
  280.         m_pSprite->OnLostDevice();
  281.     SAFE_RELEASE( m_pStateBlock  );
  282. }
  283.     
  284. //--------------------------------------------------------------------------------------
  285. void CDXUTDialogResourceManager::OnDestroyDevice()
  286. {
  287.     int i=0; 
  288.     m_pd3dDevice = NULL;
  289.     // Release the resources but don't clear the cache, as these will need to be
  290.     // recreated if the device is recreated
  291.     for( i=0; i < m_FontCache.GetSize(); i++ )
  292.     {
  293.         DXUTFontNode* pFontNode = m_FontCache.GetAt( i );
  294.         SAFE_RELEASE( pFontNode->pFont );
  295.     }
  296.     
  297.     for( i=0; i < m_TextureCache.GetSize(); i++ )
  298.     {
  299.         DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( i );
  300.         SAFE_RELEASE( pTextureNode->pTexture );
  301.     }
  302.     SAFE_RELEASE( m_pSprite );
  303. }
  304. //--------------------------------------------------------------------------------------
  305. bool CDXUTDialogResourceManager::RegisterDialog( CDXUTDialog *pDialog )
  306. {
  307.     // Check that the dialog isn't already registered.
  308.     for( int i = 0; i < m_Dialogs.GetSize(); ++i )
  309.         if( m_Dialogs.GetAt( i ) == pDialog )
  310.             return true;
  311.     // Add to the list.
  312.     if( FAILED( m_Dialogs.Add( pDialog ) ) )
  313.         return false;
  314.     // Set up next and prev pointers.
  315.     if( m_Dialogs.GetSize() > 1 )
  316.         m_Dialogs[m_Dialogs.GetSize() - 2]->SetNextDialog( pDialog );
  317.     m_Dialogs[m_Dialogs.GetSize() - 1]->SetNextDialog( m_Dialogs[0] );
  318.     return true;
  319. }
  320. //--------------------------------------------------------------------------------------
  321. void CDXUTDialogResourceManager::UnregisterDialog( CDXUTDialog *pDialog )
  322. {
  323.     // Search for the dialog in the list.
  324.     for( int i = 0; i < m_Dialogs.GetSize(); ++i )
  325.         if( m_Dialogs.GetAt( i ) == pDialog )
  326.         {
  327.             m_Dialogs.Remove( i );
  328.             if( m_Dialogs.GetSize() > 0 )
  329.             {
  330.                 int l, r;
  331.                 if( 0 == i )
  332.                     l = m_Dialogs.GetSize() - 1;
  333.                 else
  334.                     l = i - 1;
  335.                 if( m_Dialogs.GetSize() == i )
  336.                     r = 0;
  337.                 else
  338.                     r = i;
  339.                 m_Dialogs[l]->SetNextDialog( m_Dialogs[r] );
  340.             }
  341.             return;
  342.         }
  343. }
  344. //--------------------------------------------------------------------------------------
  345. void CDXUTDialogResourceManager::EnableKeyboardInputForAllDialogs()
  346. {
  347.     // Enable keyboard input for all registered dialogs
  348.     for( int i = 0; i < m_Dialogs.GetSize(); ++i )
  349.         m_Dialogs[i]->EnableKeyboardInput( true );
  350. }
  351. //--------------------------------------------------------------------------------------
  352. void CDXUTDialog::Refresh()
  353. {
  354.     if( s_pControlFocus )
  355.         s_pControlFocus->OnFocusOut();
  356.     if( m_pControlMouseOver )
  357.         m_pControlMouseOver->OnMouseLeave();
  358.     s_pControlFocus = NULL;
  359.     s_pControlPressed = NULL;
  360.     m_pControlMouseOver = NULL;
  361.     for( int i=0; i < m_Controls.GetSize(); i++ )
  362.     {
  363.         CDXUTControl* pControl = m_Controls.GetAt(i);
  364.         pControl->Refresh();
  365.     }
  366.     if( m_bKeyboardInput )
  367.         FocusDefaultControl();
  368. }
  369. //--------------------------------------------------------------------------------------
  370. HRESULT CDXUTDialog::OnRender( float fElapsedTime )
  371. {   
  372.     // If this assert triggers, you need to call CDXUTDialogResourceManager::On*Device() from inside
  373.     // the application's device callbacks.  See the SDK samples for an example of how to do this.
  374.     assert( m_pManager->GetD3DDevice() && m_pManager->m_pStateBlock && L"To fix hook up CDXUTDialogResourceManager to device callbacks.  See comments for details" );
  375.     // See if the dialog needs to be refreshed
  376.     if( m_fTimeLastRefresh < s_fTimeRefresh )
  377.     {
  378.         m_fTimeLastRefresh = DXUTGetTime();
  379.         Refresh();
  380.     }
  381.     // For invisible dialog, out now.
  382.     if( !m_bVisible ||
  383.         ( m_bMinimized && !m_bCaption ) )
  384.         return S_OK;
  385.     IDirect3DDevice9* pd3dDevice = m_pManager->GetD3DDevice();
  386.     // Set up a state block here and restore it when finished drawing all the controls
  387.     m_pManager->m_pStateBlock->Capture();
  388.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
  389.     pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
  390.     pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
  391.     pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
  392.     pd3dDevice->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, FALSE );
  393.     pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );
  394.     pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED );
  395.     pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
  396.     pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
  397.     pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
  398.     pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
  399.     pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
  400.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  401.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  402.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
  403.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
  404.     pd3dDevice->SetTextureStageState( 0, D3DTSS_RESULTARG, D3DTA_CURRENT );
  405.     pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
  406.     pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
  407.     BOOL bBackgroundIsVisible = ( m_colorTopLeft | m_colorTopRight | m_colorBottomRight | m_colorBottomLeft ) & 0xff000000;
  408.     if( !m_bMinimized && bBackgroundIsVisible )
  409.     {
  410.         DXUT_SCREEN_VERTEX_UNTEX vertices[4] =
  411.         {
  412.             (float)m_x,           (float)m_y,            0.5f, 1.0f, m_colorTopLeft,
  413.             (float)m_x + m_width, (float)m_y,            0.5f, 1.0f, m_colorTopRight,
  414.             (float)m_x + m_width, (float)m_y + m_height, 0.5f, 1.0f, m_colorBottomRight,
  415.             (float)m_x,           (float)m_y + m_height, 0.5f, 1.0f, m_colorBottomLeft,
  416.         };
  417.         pd3dDevice->SetVertexShader( NULL );
  418.         pd3dDevice->SetPixelShader( NULL );
  419.         pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
  420.         pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX_UNTEX::FVF );
  421.         pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, vertices, sizeof(DXUT_SCREEN_VERTEX_UNTEX) );
  422.     }
  423.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  424.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  425.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  426.     
  427.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  428.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
  429.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
  430.     pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
  431.     DXUTTextureNode* pTextureNode = GetTexture( 0 );
  432.     pd3dDevice->SetTexture( 0, pTextureNode->pTexture );
  433.     m_pManager->m_pSprite->Begin( D3DXSPRITE_DONOTSAVESTATE );
  434.     // Render the caption if it's enabled.
  435.     if( m_bCaption )
  436.     {
  437.         // DrawSprite will offset the rect down by
  438.         // m_nCaptionHeight, so adjust the rect higher
  439.         // here to negate the effect.
  440.         RECT rc = { 0, -m_nCaptionHeight, m_width, 0 };
  441.         DrawSprite( &m_CapElement, &rc );
  442.         rc.left += 5; // Make a left margin
  443.         WCHAR wszOutput[256];
  444.         StringCchCopy( wszOutput, 256, m_wszCaption );
  445.         if( m_bMinimized )
  446.             StringCchCat( wszOutput, 256, L" (Minimized)" );
  447.         DrawText( wszOutput, &m_CapElement, &rc, true );
  448.     }
  449.     // If the dialog is minimized, skip rendering
  450.     // its controls.
  451.     if( !m_bMinimized )
  452.     {
  453.         for( int i=0; i < m_Controls.GetSize(); i++ )
  454.         {
  455.             CDXUTControl* pControl = m_Controls.GetAt(i);   
  456.             // Focused control is drawn last
  457.             if( pControl == s_pControlFocus )
  458.                 continue;
  459.             pControl->Render( pd3dDevice, fElapsedTime );
  460.         }
  461.         if( s_pControlFocus != NULL && s_pControlFocus->m_pDialog == this )
  462.             s_pControlFocus->Render( pd3dDevice, fElapsedTime );
  463.     }
  464.     m_pManager->m_pSprite->End();
  465.     m_pManager->m_pStateBlock->Apply();
  466.     return S_OK;
  467. }
  468. //--------------------------------------------------------------------------------------
  469. VOID CDXUTDialog::SendEvent( UINT nEvent, bool bTriggeredByUser, CDXUTControl* pControl )
  470. {
  471.     // If no callback has been registered there's nowhere to send the event to
  472.     if( m_pCallbackEvent == NULL )
  473.         return;
  474.     // Discard events triggered programatically if these types of events haven't been
  475.     // enabled
  476.     if( !bTriggeredByUser && !m_bNonUserEvents )
  477.         return;
  478.     m_pCallbackEvent( nEvent, pControl->GetID(), pControl, m_pCallbackEventUserContext );
  479. }
  480. //--------------------------------------------------------------------------------------
  481. int CDXUTDialogResourceManager::AddFont( LPCWSTR strFaceName, LONG height, LONG weight )
  482. {
  483.     // See if this font already exists
  484.     for( int i=0; i < m_FontCache.GetSize(); i++ )
  485.     {
  486.         DXUTFontNode* pFontNode = m_FontCache.GetAt(i);
  487.         size_t nLen = 0;
  488.         StringCchLength( strFaceName, MAX_PATH, &nLen );        
  489.         if( 0 == _wcsnicmp( pFontNode->strFace, strFaceName, nLen ) &&
  490.             pFontNode->nHeight == height &&
  491.             pFontNode->nWeight == weight )
  492.         {
  493.             return i;
  494.         }
  495.     }
  496.     // Add a new font and try to create it
  497.     DXUTFontNode* pNewFontNode = new DXUTFontNode();
  498.     if( pNewFontNode == NULL )
  499.         return -1;
  500.     ZeroMemory( pNewFontNode, sizeof(DXUTFontNode) );
  501.     StringCchCopy( pNewFontNode->strFace, MAX_PATH, strFaceName );
  502.     pNewFontNode->nHeight = height;
  503.     pNewFontNode->nWeight = weight;
  504.     m_FontCache.Add( pNewFontNode );
  505.     
  506.     int iFont = m_FontCache.GetSize()-1;
  507.     // If a device is available, try to create immediately
  508.     if( m_pd3dDevice )
  509.         CreateFont( iFont );
  510.     return iFont;
  511. }
  512. //--------------------------------------------------------------------------------------
  513. HRESULT CDXUTDialog::SetFont( UINT index, LPCWSTR strFaceName, LONG height, LONG weight )
  514. {
  515.     // If this assert triggers, you need to call CDXUTDialog::Init() first.  This change
  516.     // was made so that the DXUT's GUI could become seperate and optional from DXUT's core.  The 
  517.     // creation and interfacing with CDXUTDialogResourceManager is now the responsibility 
  518.     // of the application if it wishes to use DXUT's GUI.
  519.     assert( m_pManager != NULL && L"To fix call CDXUTDialog::Init() first.  See comments for details." ); 
  520.     // Make sure the list is at least as large as the index being set
  521.     UINT i;
  522.     for( i=m_Fonts.GetSize(); i <= index; i++ )
  523.     {
  524.         m_Fonts.Add( -1 );
  525.     }
  526.     int iFont = m_pManager->AddFont( strFaceName, height, weight );
  527.     m_Fonts.SetAt( index, iFont );
  528.     return S_OK;
  529. }
  530. //--------------------------------------------------------------------------------------
  531. DXUTFontNode* CDXUTDialog::GetFont( UINT index )
  532. {
  533.     if( NULL == m_pManager )
  534.         return NULL;
  535.     return m_pManager->GetFontNode( m_Fonts.GetAt( index ) );
  536. }
  537. //--------------------------------------------------------------------------------------
  538. int CDXUTDialogResourceManager::AddTexture( LPCWSTR strFilename )
  539. {
  540.     // See if this texture already exists
  541.     for( int i=0; i < m_TextureCache.GetSize(); i++ )
  542.     {
  543.         DXUTTextureNode* pTextureNode = m_TextureCache.GetAt(i);
  544.         size_t nLen = 0;
  545.         StringCchLength( strFilename, MAX_PATH, &nLen );        
  546.         if( pTextureNode->bFileSource &&  // Sources must match
  547.             0 == _wcsnicmp( pTextureNode->strFilename, strFilename, nLen ) )
  548.             return i;
  549.     }
  550.     // Add a new texture and try to create it
  551.     DXUTTextureNode* pNewTextureNode = new DXUTTextureNode();
  552.     if( pNewTextureNode == NULL )
  553.         return -1;
  554.     ZeroMemory( pNewTextureNode, sizeof(DXUTTextureNode) );
  555.     pNewTextureNode->bFileSource = true;
  556.     StringCchCopy( pNewTextureNode->strFilename, MAX_PATH, strFilename );
  557.     m_TextureCache.Add( pNewTextureNode );
  558.     
  559.     int iTexture = m_TextureCache.GetSize()-1;
  560.     // If a device is available, try to create immediately
  561.     if( m_pd3dDevice )
  562.         CreateTexture( iTexture );
  563.     return iTexture;
  564. }
  565. //--------------------------------------------------------------------------------------
  566. int CDXUTDialogResourceManager::AddTexture( LPCWSTR strResourceName, HMODULE hResourceModule )
  567. {
  568.     // See if this texture already exists
  569.     for( int i=0; i < m_TextureCache.GetSize(); i++ )
  570.     {
  571.         DXUTTextureNode* pTextureNode = m_TextureCache.GetAt(i);
  572.         if( !pTextureNode->bFileSource &&      // Sources must match
  573.             pTextureNode->hResourceModule == hResourceModule ) // Module handles must match
  574.         {
  575.             if( IS_INTRESOURCE( strResourceName ) )
  576.             {
  577.                 // Integer-based ID
  578.                 if( (INT_PTR)strResourceName == pTextureNode->nResourceID )
  579.                     return i;
  580.             }
  581.             else
  582.             {
  583.                 // String-based ID
  584.                 size_t nLen = 0;
  585.                 StringCchLength( strResourceName, MAX_PATH, &nLen );        
  586.                 if( 0 == _wcsnicmp( pTextureNode->strFilename, strResourceName, nLen ) )
  587.                     return i;
  588.             }
  589.         }
  590.     }
  591.     // Add a new texture and try to create it
  592.     DXUTTextureNode* pNewTextureNode = new DXUTTextureNode();
  593.     if( pNewTextureNode == NULL )
  594.         return -1;
  595.     ZeroMemory( pNewTextureNode, sizeof(DXUTTextureNode) );
  596.     pNewTextureNode->hResourceModule = hResourceModule;
  597.     if( IS_INTRESOURCE( strResourceName ) )
  598.     {
  599.         pNewTextureNode->nResourceID = (int)(size_t)strResourceName;
  600.     }
  601.     else
  602.     {
  603.         pNewTextureNode->nResourceID = 0;
  604.         StringCchCopy( pNewTextureNode->strFilename, MAX_PATH, strResourceName );
  605.     }
  606.     m_TextureCache.Add( pNewTextureNode );
  607.     
  608.     int iTexture = m_TextureCache.GetSize()-1;
  609.     // If a device is available, try to create immediately
  610.     if( m_pd3dDevice )
  611.         CreateTexture( iTexture );
  612.     return iTexture;
  613. }
  614. //--------------------------------------------------------------------------------------
  615. HRESULT CDXUTDialog::SetTexture( UINT index, LPCWSTR strFilename )
  616. {
  617.     // If this assert triggers, you need to call CDXUTDialog::Init() first.  This change
  618.     // was made so that the DXUT's GUI could become seperate and optional from DXUT's core.  The 
  619.     // creation and interfacing with CDXUTDialogResourceManager is now the responsibility 
  620.     // of the application if it wishes to use DXUT's GUI.
  621.     assert( m_pManager != NULL && L"To fix this, call CDXUTDialog::Init() first.  See comments for details." ); 
  622.     // Make sure the list is at least as large as the index being set
  623.     for( UINT i=m_Textures.GetSize(); i <= index; i++ )
  624.     {
  625.         m_Textures.Add( -1 );
  626.     }
  627.     int iTexture = m_pManager->AddTexture( strFilename );
  628.     m_Textures.SetAt( index, iTexture );
  629.     return S_OK;
  630. }
  631. //--------------------------------------------------------------------------------------
  632. HRESULT CDXUTDialog::SetTexture( UINT index, LPCWSTR strResourceName, HMODULE hResourceModule )
  633. {
  634.     // If this assert triggers, you need to call CDXUTDialog::Init() first.  This change
  635.     // was made so that the DXUT's GUI could become seperate and optional from DXUT's core.  The 
  636.     // creation and interfacing with CDXUTDialogResourceManager is now the responsibility 
  637.     // of the application if it wishes to use DXUT's GUI.
  638.     assert( m_pManager != NULL && L"To fix this, call CDXUTDialog::Init() first.  See comments for details." ); 
  639.     // Make sure the list is at least as large as the index being set
  640.     for( UINT i=m_Textures.GetSize(); i <= index; i++ )
  641.     {
  642.         m_Textures.Add( -1 );
  643.     }
  644.     int iTexture = m_pManager->AddTexture( strResourceName, hResourceModule );
  645.     m_Textures.SetAt( index, iTexture );
  646.     return S_OK;
  647. }
  648. //--------------------------------------------------------------------------------------
  649. DXUTTextureNode* CDXUTDialog::GetTexture( UINT index )
  650. {
  651.     if( NULL == m_pManager )
  652.         return NULL;
  653.     return m_pManager->GetTextureNode( m_Textures.GetAt( index ) );
  654. }
  655. //--------------------------------------------------------------------------------------
  656. bool CDXUTDialog::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  657. {
  658.     bool bHandled = false;
  659.     // For invisible dialog, do not handle anything.
  660.     if( !m_bVisible )
  661.         return false;
  662.     // If automation command-line switch is on, enable this dialog's keyboard input
  663.     // upon any key press or mouse click.
  664.     if( DXUTGetAutomation() &&
  665.         ( WM_LBUTTONDOWN == uMsg || WM_LBUTTONDBLCLK == uMsg || WM_KEYDOWN == uMsg ) )
  666.     {
  667.         m_pManager->EnableKeyboardInputForAllDialogs();
  668.     }
  669.     // If caption is enable, check for clicks in the caption area.
  670.     if( m_bCaption )
  671.     {
  672.         if( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK )
  673.         {
  674.             POINT mousePoint = { short(LOWORD(lParam)), short(HIWORD(lParam)) };
  675.             if( mousePoint.x >= m_x && mousePoint.x < m_x + m_width &&
  676.                 mousePoint.y >= m_y && mousePoint.y < m_y + m_nCaptionHeight )
  677.             {
  678.                 m_bDrag = true;
  679.                 SetCapture( DXUTGetHWND() );
  680.                 return true;
  681.             }
  682.         } else
  683.         if( uMsg == WM_LBUTTONUP && m_bDrag )
  684.         {
  685.             POINT mousePoint = { short(LOWORD(lParam)), short(HIWORD(lParam)) };
  686.             if( mousePoint.x >= m_x && mousePoint.x < m_x + m_width &&
  687.                 mousePoint.y >= m_y && mousePoint.y < m_y + m_nCaptionHeight )
  688.             {
  689.                 ReleaseCapture();
  690.                 m_bDrag = false;
  691.                 m_bMinimized = !m_bMinimized;
  692.                 return true;
  693.             }
  694.         }
  695.     }
  696.     // If the dialog is minimized, don't send any messages to controls.
  697.     if( m_bMinimized )
  698.         return false;
  699.     // If a control is in focus, it belongs to this dialog, and it's enabled, then give
  700.     // it the first chance at handling the message.
  701.     if( s_pControlFocus && 
  702.         s_pControlFocus->m_pDialog == this && 
  703.         s_pControlFocus->GetEnabled() )
  704.     {
  705.         // If the control MsgProc handles it, then we don't.
  706.         if( s_pControlFocus->MsgProc( uMsg, wParam, lParam ) )
  707.             return true;
  708.     }
  709.     switch( uMsg )
  710.     {
  711.         case WM_SIZE:
  712.         case WM_MOVE:
  713.         {
  714.             // Handle sizing and moving messages so that in case the mouse cursor is moved out
  715.             // of an UI control because of the window adjustment, we can properly
  716.             // unhighlight the highlighted control.
  717.             POINT pt = { -1, -1 };
  718.             OnMouseMove( pt );
  719.             break;
  720.         }
  721.         case WM_ACTIVATEAPP:
  722.             // Call OnFocusIn()/OnFocusOut() of the control that currently has the focus
  723.             // as the application is activated/deactivated.  This matches the Windows
  724.             // behavior.
  725.             if( s_pControlFocus && 
  726.                 s_pControlFocus->m_pDialog == this && 
  727.                 s_pControlFocus->GetEnabled() )
  728.             {
  729.                 if( wParam )
  730.                     s_pControlFocus->OnFocusIn();
  731.                 else
  732.                     s_pControlFocus->OnFocusOut();
  733.             }
  734.             break;
  735.         // Keyboard messages
  736.         case WM_KEYDOWN:
  737.         case WM_SYSKEYDOWN:
  738.         case WM_KEYUP:
  739.         case WM_SYSKEYUP:
  740.         {
  741.             // If a control is in focus, it belongs to this dialog, and it's enabled, then give
  742.             // it the first chance at handling the message.
  743.             if( s_pControlFocus && 
  744.                 s_pControlFocus->m_pDialog == this && 
  745.                 s_pControlFocus->GetEnabled() )
  746.             {
  747.                 if( s_pControlFocus->HandleKeyboard( uMsg, wParam, lParam ) )
  748.                     return true;
  749.             }
  750.             // Not yet handled, see if this matches a control's hotkey
  751.             // Activate the hotkey if the focus doesn't belong to an
  752.             // edit box.
  753.             if( uMsg == WM_KEYDOWN && ( !s_pControlFocus ||
  754.                                       ( s_pControlFocus->GetType() != DXUT_CONTROL_EDITBOX
  755.                                      && s_pControlFocus->GetType() != DXUT_CONTROL_IMEEDITBOX ) ) )
  756.             {
  757.                 for( int i=0; i < m_Controls.GetSize(); i++ )
  758.                 {
  759.                     CDXUTControl* pControl = m_Controls.GetAt( i );
  760.                     if( pControl->GetHotkey() == wParam )
  761.                     {
  762.                         pControl->OnHotkey();
  763.                         return true;
  764.                     }
  765.                 }
  766.             }
  767.             // Not yet handled, check for focus messages
  768.             if( uMsg == WM_KEYDOWN )
  769.             {
  770.                 // If keyboard input is not enabled, this message should be ignored
  771.                 if( !m_bKeyboardInput )
  772.                     return false;
  773.                 switch( wParam )
  774.                 {
  775.                     case VK_RIGHT:
  776.                     case VK_DOWN:
  777.                         if( s_pControlFocus != NULL )
  778.                         {
  779.                             return OnCycleFocus( true );
  780.                         }
  781.                         break;
  782.                     case VK_LEFT:
  783.                     case VK_UP:
  784.                         if( s_pControlFocus != NULL )
  785.                         {
  786.                             return OnCycleFocus( false );
  787.                         }
  788.                         break;
  789.                     case VK_TAB: 
  790.                     {
  791.                         bool bShiftDown = ((GetKeyState( VK_SHIFT ) & 0x8000) != 0);
  792.                         return OnCycleFocus( !bShiftDown );
  793.                     }
  794.                 }
  795.             }
  796.             break;
  797.         }
  798.         // Mouse messages
  799.         case WM_MOUSEMOVE:
  800.         case WM_LBUTTONDOWN:
  801.         case WM_LBUTTONUP:
  802.         case WM_MBUTTONDOWN:
  803.         case WM_MBUTTONUP:
  804.         case WM_RBUTTONDOWN:
  805.         case WM_RBUTTONUP:
  806.         case WM_XBUTTONDOWN:
  807.         case WM_XBUTTONUP:
  808.         case WM_LBUTTONDBLCLK:
  809.         case WM_MBUTTONDBLCLK:
  810.         case WM_RBUTTONDBLCLK:
  811.         case WM_XBUTTONDBLCLK:
  812.         case WM_MOUSEWHEEL:
  813.         {
  814.             // If not accepting mouse input, return false to indicate the message should still 
  815.             // be handled by the application (usually to move the camera).
  816.             if( !m_bMouseInput )
  817.                 return false;
  818.             POINT mousePoint = { short(LOWORD(lParam)), short(HIWORD(lParam)) };
  819.             mousePoint.x -= m_x;
  820.             mousePoint.y -= m_y;
  821.             // If caption is enabled, offset the Y coordinate by the negative of its height.
  822.             if( m_bCaption )
  823.                 mousePoint.y -= m_nCaptionHeight;
  824.             // If a control is in focus, it belongs to this dialog, and it's enabled, then give
  825.             // it the first chance at handling the message.
  826.             if( s_pControlFocus && 
  827.                 s_pControlFocus->m_pDialog == this && 
  828.                 s_pControlFocus->GetEnabled() )
  829.             {
  830.                 if( s_pControlFocus->HandleMouse( uMsg, mousePoint, wParam, lParam ) )
  831.                     return true;
  832.             }
  833.             // Not yet handled, see if the mouse is over any controls
  834.             CDXUTControl* pControl = GetControlAtPoint( mousePoint );
  835.             if( pControl != NULL && pControl->GetEnabled() )
  836.             {
  837.                 bHandled = pControl->HandleMouse( uMsg, mousePoint, wParam, lParam );
  838.                 if( bHandled )
  839.                     return true;
  840.             }
  841.             else
  842.             {
  843.                 // Mouse not over any controls in this dialog, if there was a control
  844.                 // which had focus it just lost it
  845.                 if( uMsg == WM_LBUTTONDOWN && 
  846.                     s_pControlFocus && 
  847.                     s_pControlFocus->m_pDialog == this )
  848.                 {
  849.                     s_pControlFocus->OnFocusOut();
  850.                     s_pControlFocus = NULL;
  851.                 }
  852.             }
  853.             // Still not handled, hand this off to the dialog. Return false to indicate the
  854.             // message should still be handled by the application (usually to move the camera).
  855.             switch( uMsg )
  856.             {
  857.                 case WM_MOUSEMOVE:
  858.                     OnMouseMove( mousePoint );
  859.                     return false;
  860.             }
  861.             break;
  862.         }
  863.         case WM_CAPTURECHANGED:
  864.         {
  865.             // The application has lost mouse capture.
  866.             // The dialog object may not have received
  867.             // a WM_MOUSEUP when capture changed. Reset
  868.             // m_bDrag so that the dialog does not mistakenly
  869.             // think the mouse button is still held down.
  870.             if( (HWND)lParam != hWnd )
  871.                 m_bDrag = false;
  872.         }
  873.     }
  874.     return false;
  875. }
  876. //--------------------------------------------------------------------------------------
  877. CDXUTControl* CDXUTDialog::GetControlAtPoint( POINT pt )
  878. {
  879.     // Search through all child controls for the first one which
  880.     // contains the mouse point
  881.     for( int i=0; i < m_Controls.GetSize(); i++ )
  882.     {
  883.         CDXUTControl* pControl = m_Controls.GetAt(i);
  884.         if( pControl == NULL )
  885.         {
  886.             continue;
  887.         }
  888.         // We only return the current control if it is visible
  889.         // and enabled.  Because GetControlAtPoint() is used to do mouse
  890.         // hittest, it makes sense to perform this filtering.
  891.         if( pControl->ContainsPoint( pt ) && pControl->GetEnabled() && pControl->GetVisible() )
  892.         {
  893.             return pControl;
  894.         }
  895.     }
  896.     return NULL;
  897. }
  898. //--------------------------------------------------------------------------------------
  899. bool CDXUTDialog::GetControlEnabled( int ID )
  900. {
  901.     CDXUTControl* pControl = GetControl( ID );
  902.     if( pControl == NULL )
  903.         return false;
  904.     return pControl->GetEnabled();
  905. }
  906. //--------------------------------------------------------------------------------------
  907. void CDXUTDialog::SetControlEnabled( int ID, bool bEnabled )
  908. {
  909.     CDXUTControl* pControl = GetControl( ID );
  910.     if( pControl == NULL )
  911.         return;
  912.     pControl->SetEnabled( bEnabled );
  913. }
  914. //--------------------------------------------------------------------------------------
  915. void CDXUTDialog::OnMouseUp( POINT pt )
  916. {
  917.     s_pControlPressed = NULL;
  918.     m_pControlMouseOver = NULL;
  919. }
  920. //--------------------------------------------------------------------------------------
  921. void CDXUTDialog::OnMouseMove( POINT pt )
  922. {
  923.     // Figure out which control the mouse is over now
  924.     CDXUTControl* pControl = GetControlAtPoint( pt );
  925.     // If the mouse is still over the same control, nothing needs to be done
  926.     if( pControl == m_pControlMouseOver )
  927.         return;
  928.     // Handle mouse leaving the old control
  929.     if( m_pControlMouseOver )
  930.         m_pControlMouseOver->OnMouseLeave();
  931.     // Handle mouse entering the new control
  932.     m_pControlMouseOver = pControl;
  933.     if( pControl != NULL )
  934.         m_pControlMouseOver->OnMouseEnter();
  935. }
  936. //--------------------------------------------------------------------------------------
  937. HRESULT CDXUTDialog::SetDefaultElement( UINT nControlType, UINT iElement, CDXUTElement* pElement )
  938. {
  939.     // If this Element type already exist in the list, simply update the stored Element
  940.     for( int i=0; i < m_DefaultElements.GetSize(); i++ )
  941.     {
  942.         DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
  943.         
  944.         if( pElementHolder->nControlType == nControlType &&
  945.             pElementHolder->iElement == iElement )
  946.         {
  947.             pElementHolder->Element = *pElement;
  948.             return S_OK;
  949.         }
  950.     }
  951.     // Otherwise, add a new entry
  952.     DXUTElementHolder* pNewHolder;
  953.     pNewHolder = new DXUTElementHolder;
  954.     if( pNewHolder == NULL )
  955.         return E_OUTOFMEMORY;
  956.     pNewHolder->nControlType = nControlType;
  957.     pNewHolder->iElement = iElement;
  958.     pNewHolder->Element = *pElement;
  959.     m_DefaultElements.Add( pNewHolder );
  960.     return S_OK;
  961. }
  962. //--------------------------------------------------------------------------------------
  963. CDXUTElement* CDXUTDialog::GetDefaultElement( UINT nControlType, UINT iElement )
  964. {
  965.     for( int i=0; i < m_DefaultElements.GetSize(); i++ )
  966.     {
  967.         DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
  968.         
  969.         if( pElementHolder->nControlType == nControlType &&
  970.             pElementHolder->iElement == iElement )
  971.         {
  972.             return &pElementHolder->Element;
  973.         }
  974.     }
  975.     
  976.     return NULL;
  977. }
  978. //--------------------------------------------------------------------------------------
  979. HRESULT CDXUTDialog::AddStatic( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault, CDXUTStatic** ppCreated )
  980. {
  981.     HRESULT hr = S_OK;
  982.     CDXUTStatic* pStatic = new CDXUTStatic( this );
  983.     if( ppCreated != NULL )
  984.         *ppCreated = pStatic;
  985.     if( pStatic == NULL )
  986.         return E_OUTOFMEMORY;
  987.     hr = AddControl( pStatic );
  988.     if( FAILED(hr) )
  989.         return hr;
  990.     // Set the ID and list index
  991.     pStatic->SetID( ID ); 
  992.     pStatic->SetText( strText );
  993.     pStatic->SetLocation( x, y );
  994.     pStatic->SetSize( width, height );
  995.     pStatic->m_bIsDefault = bIsDefault;
  996.     return S_OK;
  997. }
  998. //--------------------------------------------------------------------------------------
  999. HRESULT CDXUTDialog::AddButton( int ID, LPCWSTR strText, int x, int y, int width, int height, UINT nHotkey, bool bIsDefault, CDXUTButton** ppCreated )
  1000. {
  1001.     HRESULT hr = S_OK;
  1002.     CDXUTButton* pButton = new CDXUTButton( this );
  1003.     if( ppCreated != NULL )
  1004.         *ppCreated = pButton;
  1005.     if( pButton == NULL )
  1006.         return E_OUTOFMEMORY;
  1007.     hr = AddControl( pButton );
  1008.     if( FAILED(hr) )
  1009.         return hr;
  1010.     // Set the ID and list index
  1011.     pButton->SetID( ID ); 
  1012.     pButton->SetText( strText );
  1013.     pButton->SetLocation( x, y );
  1014.     pButton->SetSize( width, height );
  1015.     pButton->SetHotkey( nHotkey );
  1016.     pButton->m_bIsDefault = bIsDefault;
  1017.     return S_OK;
  1018. }
  1019. //--------------------------------------------------------------------------------------
  1020. HRESULT CDXUTDialog::AddCheckBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bChecked, UINT nHotkey, bool bIsDefault, CDXUTCheckBox** ppCreated )
  1021. {
  1022.     HRESULT hr = S_OK;
  1023.     CDXUTCheckBox* pCheckBox = new CDXUTCheckBox( this );
  1024.     if( ppCreated != NULL )
  1025.         *ppCreated = pCheckBox;
  1026.     if( pCheckBox == NULL )
  1027.         return E_OUTOFMEMORY;
  1028.     hr = AddControl( pCheckBox );
  1029.     if( FAILED(hr) )
  1030.         return hr;
  1031.     // Set the ID and list index
  1032.     pCheckBox->SetID( ID ); 
  1033.     pCheckBox->SetText( strText );
  1034.     pCheckBox->SetLocation( x, y );
  1035.     pCheckBox->SetSize( width, height );
  1036.     pCheckBox->SetHotkey( nHotkey );
  1037.     pCheckBox->m_bIsDefault = bIsDefault;
  1038.     pCheckBox->SetChecked( bChecked );
  1039.     
  1040.     return S_OK;
  1041. }
  1042. //--------------------------------------------------------------------------------------
  1043. HRESULT CDXUTDialog::AddRadioButton( int ID, UINT nButtonGroup, LPCWSTR strText, int x, int y, int width, int height, bool bChecked, UINT nHotkey, bool bIsDefault, CDXUTRadioButton** ppCreated )
  1044. {
  1045.     HRESULT hr = S_OK;
  1046.     CDXUTRadioButton* pRadioButton = new CDXUTRadioButton( this );
  1047.     if( ppCreated != NULL )
  1048.         *ppCreated = pRadioButton;
  1049.     if( pRadioButton == NULL )
  1050.         return E_OUTOFMEMORY;
  1051.     hr = AddControl( pRadioButton );
  1052.     if( FAILED(hr) )
  1053.         return hr;
  1054.     // Set the ID and list index
  1055.     pRadioButton->SetID( ID ); 
  1056.     pRadioButton->SetText( strText );
  1057.     pRadioButton->SetButtonGroup( nButtonGroup );
  1058.     pRadioButton->SetLocation( x, y );
  1059.     pRadioButton->SetSize( width, height );
  1060.     pRadioButton->SetHotkey( nHotkey );
  1061.     pRadioButton->SetChecked( bChecked );
  1062.     pRadioButton->m_bIsDefault = bIsDefault;
  1063.     pRadioButton->SetChecked( bChecked );
  1064.     return S_OK;
  1065. }
  1066. //--------------------------------------------------------------------------------------
  1067. HRESULT CDXUTDialog::AddComboBox( int ID, int x, int y, int width, int height, UINT nHotkey, bool bIsDefault, CDXUTComboBox** ppCreated )
  1068. {
  1069.     HRESULT hr = S_OK;
  1070.     CDXUTComboBox* pComboBox = new CDXUTComboBox( this );
  1071.     if( ppCreated != NULL )
  1072.         *ppCreated = pComboBox;
  1073.     if( pComboBox == NULL )
  1074.         return E_OUTOFMEMORY;
  1075.     hr = AddControl( pComboBox );
  1076.     if( FAILED(hr) )
  1077.         return hr;
  1078.     // Set the ID and list index
  1079.     pComboBox->SetID( ID ); 
  1080.     pComboBox->SetLocation( x, y );
  1081.     pComboBox->SetSize( width, height );
  1082.     pComboBox->SetHotkey( nHotkey );
  1083.     pComboBox->m_bIsDefault = bIsDefault;
  1084.     return S_OK;
  1085. }
  1086. //--------------------------------------------------------------------------------------
  1087. HRESULT CDXUTDialog::AddSlider( int ID, int x, int y, int width, int height, int min, int max, int value, bool bIsDefault, CDXUTSlider** ppCreated )
  1088. {
  1089.     HRESULT hr = S_OK;
  1090.     CDXUTSlider* pSlider = new CDXUTSlider( this );
  1091.     if( ppCreated != NULL )
  1092.         *ppCreated = pSlider;
  1093.     if( pSlider == NULL )
  1094.         return E_OUTOFMEMORY;
  1095.     hr = AddControl( pSlider );
  1096.     if( FAILED(hr) )
  1097.         return hr;
  1098.     // Set the ID and list index
  1099.     pSlider->SetID( ID ); 
  1100.     pSlider->SetLocation( x, y );
  1101.     pSlider->SetSize( width, height );
  1102.     pSlider->m_bIsDefault = bIsDefault;
  1103.     pSlider->SetRange( min, max );
  1104.     pSlider->SetValue( value );
  1105.     pSlider->UpdateRects();
  1106.     return S_OK;
  1107. }
  1108. //--------------------------------------------------------------------------------------
  1109. HRESULT CDXUTDialog::AddEditBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault, CDXUTEditBox** ppCreated )
  1110. {
  1111.     HRESULT hr = S_OK;
  1112.     CDXUTEditBox *pEditBox = new CDXUTEditBox( this );
  1113.     if( ppCreated != NULL )
  1114.         *ppCreated = pEditBox;
  1115.     if( pEditBox == NULL )
  1116.         return E_OUTOFMEMORY;
  1117.     hr = AddControl( pEditBox );
  1118.     if( FAILED(hr) )
  1119.         return hr;
  1120.     // Set the ID and position
  1121.     pEditBox->SetID( ID ); 
  1122.     pEditBox->SetLocation( x, y );
  1123.     pEditBox->SetSize( width, height );
  1124.     pEditBox->m_bIsDefault = bIsDefault;
  1125.     if( strText )
  1126.         pEditBox->SetText( strText );
  1127.     return S_OK;
  1128. }
  1129. //--------------------------------------------------------------------------------------
  1130. HRESULT CDXUTDialog::AddIMEEditBox( int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault, CDXUTIMEEditBox** ppCreated )
  1131. {
  1132.     HRESULT hr = S_OK;
  1133.     CDXUTIMEEditBox *pEditBox = new CDXUTIMEEditBox( this );
  1134.     if( ppCreated != NULL )
  1135.         *ppCreated = pEditBox;
  1136.     if( pEditBox == NULL )
  1137.         return E_OUTOFMEMORY;
  1138.     hr = AddControl( pEditBox );
  1139.     if( FAILED(hr) )
  1140.         return hr;
  1141.     // Set the ID and position
  1142.     pEditBox->SetID( ID ); 
  1143.     pEditBox->SetLocation( x, y );
  1144.     pEditBox->SetSize( width, height );
  1145.     pEditBox->m_bIsDefault = bIsDefault;
  1146.     if( strText )
  1147.         pEditBox->SetText( strText );
  1148.     return S_OK;
  1149. }
  1150. //--------------------------------------------------------------------------------------
  1151. HRESULT CDXUTDialog::AddListBox( int ID, int x, int y, int width, int height, DWORD dwStyle, CDXUTListBox** ppCreated )
  1152. {
  1153.     HRESULT hr = S_OK;
  1154.     CDXUTListBox *pListBox = new CDXUTListBox( this );
  1155.     if( ppCreated != NULL )
  1156.         *ppCreated = pListBox;
  1157.     if( pListBox == NULL )
  1158.         return E_OUTOFMEMORY;
  1159.     hr = AddControl( pListBox );
  1160.     if( FAILED(hr) )
  1161.         return hr;
  1162.     // Set the ID and position
  1163.     pListBox->SetID( ID );
  1164.     pListBox->SetLocation( x, y );
  1165.     pListBox->SetSize( width, height );
  1166.     pListBox->SetStyle( dwStyle );
  1167.     return S_OK;
  1168. }
  1169. //--------------------------------------------------------------------------------------
  1170. HRESULT CDXUTDialog::InitControl( CDXUTControl* pControl )
  1171. {
  1172.     HRESULT hr;
  1173.     if( pControl == NULL )
  1174.         return E_INVALIDARG;
  1175.     pControl->m_Index = m_Controls.GetSize();
  1176.     
  1177.     // Look for a default Element entries
  1178.     for( int i=0; i < m_DefaultElements.GetSize(); i++ )
  1179.     {
  1180.         DXUTElementHolder* pElementHolder = m_DefaultElements.GetAt( i );
  1181.         if( pElementHolder->nControlType == pControl->GetType() )
  1182.             pControl->SetElement( pElementHolder->iElement, &pElementHolder->Element );
  1183.     }
  1184.     V_RETURN( pControl->OnInit() );
  1185.     return S_OK;
  1186. }
  1187. //--------------------------------------------------------------------------------------
  1188. HRESULT CDXUTDialog::AddControl( CDXUTControl* pControl )
  1189. {
  1190.     HRESULT hr = S_OK;
  1191.     hr = InitControl( pControl );
  1192.     if( FAILED(hr) )
  1193.         return DXTRACE_ERR( L"CDXUTDialog::InitControl", hr );
  1194.     // Add to the list
  1195.     hr = m_Controls.Add( pControl );
  1196.     if( FAILED(hr) )
  1197.     {
  1198.         return DXTRACE_ERR( L"CGrowableArray::Add", hr );
  1199.     }
  1200.     return S_OK;
  1201. }
  1202. //--------------------------------------------------------------------------------------
  1203. CDXUTControl* CDXUTDialog::GetControl( int ID )
  1204. {
  1205.     // Try to find the control with the given ID
  1206.     for( int i=0; i < m_Controls.GetSize(); i++ )
  1207.     {
  1208.         CDXUTControl* pControl = m_Controls.GetAt( i );
  1209.         if( pControl->GetID() == ID )
  1210.         {
  1211.             return pControl;
  1212.         }
  1213.     }
  1214.     // Not found
  1215.     return NULL;
  1216. }
  1217. //--------------------------------------------------------------------------------------
  1218. CDXUTControl* CDXUTDialog::GetControl( int ID, UINT nControlType )
  1219. {
  1220.     // Try to find the control with the given ID
  1221.     for( int i=0; i < m_Controls.GetSize(); i++ )
  1222.     {
  1223.         CDXUTControl* pControl = m_Controls.GetAt( i );
  1224.         if( pControl->GetID() == ID && pControl->GetType() == nControlType )
  1225.         {
  1226.             return pControl;
  1227.         }
  1228.     }
  1229.     // Not found
  1230.     return NULL;
  1231. }
  1232. //--------------------------------------------------------------------------------------
  1233. CDXUTControl* CDXUTDialog::GetNextControl( CDXUTControl* pControl )
  1234. {
  1235.     int index = pControl->m_Index + 1;
  1236.     CDXUTDialog* pDialog = pControl->m_pDialog;
  1237.     // Cycle through dialogs in the loop to find the next control. Note
  1238.     // that if only one control exists in all looped dialogs it will
  1239.     // be the returned 'next' control.
  1240.     while( index >= (int) pDialog->m_Controls.GetSize() )
  1241.     {
  1242.         pDialog = pDialog->m_pNextDialog;
  1243.         index = 0;
  1244.     }
  1245.     return pDialog->m_Controls.GetAt( index );
  1246. }
  1247. //--------------------------------------------------------------------------------------
  1248. CDXUTControl* CDXUTDialog::GetPrevControl( CDXUTControl* pControl )
  1249. {
  1250.     int index = pControl->m_Index - 1;
  1251.     CDXUTDialog* pDialog = pControl->m_pDialog;
  1252.     
  1253.     // Cycle through dialogs in the loop to find the next control. Note
  1254.     // that if only one control exists in all looped dialogs it will
  1255.     // be the returned 'previous' control.
  1256.     while( index < 0 )
  1257.     {
  1258.         pDialog = pDialog->m_pPrevDialog;
  1259.         if( pDialog == NULL )
  1260.             pDialog = pControl->m_pDialog;
  1261.         index = pDialog->m_Controls.GetSize() - 1;
  1262.     }
  1263.     
  1264.     return pDialog->m_Controls.GetAt( index );    
  1265. }
  1266. //--------------------------------------------------------------------------------------
  1267. void CDXUTDialog::ClearRadioButtonGroup( UINT nButtonGroup )
  1268. {
  1269.     // Find all radio buttons with the given group number
  1270.     for( int i=0; i < m_Controls.GetSize(); i++ )
  1271.     {
  1272.         CDXUTControl* pControl = m_Controls.GetAt( i );
  1273.         if( pControl->GetType() == DXUT_CONTROL_RADIOBUTTON )
  1274.         {
  1275.             CDXUTRadioButton* pRadioButton = (CDXUTRadioButton*) pControl;
  1276.             if( pRadioButton->GetButtonGroup() == nButtonGroup )
  1277.                 pRadioButton->SetChecked( false, false );
  1278.         }
  1279.     }
  1280. }
  1281. //--------------------------------------------------------------------------------------
  1282. void CDXUTDialog::ClearComboBox( int ID )
  1283. {
  1284.     CDXUTComboBox* pComboBox = GetComboBox( ID );
  1285.     if( pComboBox == NULL )
  1286.         return;
  1287.     pComboBox->RemoveAllItems();
  1288. }
  1289. //--------------------------------------------------------------------------------------
  1290. void CDXUTDialog::RequestFocus( CDXUTControl* pControl )
  1291. {
  1292.     if( s_pControlFocus == pControl )
  1293.         return;
  1294.     if( !pControl->CanHaveFocus() )
  1295.         return;
  1296.     if( s_pControlFocus )
  1297.         s_pControlFocus->OnFocusOut();
  1298.     pControl->OnFocusIn();
  1299.     s_pControlFocus = pControl;
  1300. }
  1301. //--------------------------------------------------------------------------------------
  1302. HRESULT CDXUTDialog::DrawRect( RECT* pRect, D3DCOLOR color )
  1303. {
  1304.     RECT rcScreen = *pRect;
  1305.     OffsetRect( &rcScreen, m_x, m_y );
  1306.     // If caption is enabled, offset the Y position by its height.
  1307.     if( m_bCaption )
  1308.         OffsetRect( &rcScreen, 0, m_nCaptionHeight );
  1309.     DXUT_SCREEN_VERTEX vertices[4] =
  1310.     {
  1311.         (float) rcScreen.left -0.5f,  (float) rcScreen.top -0.5f,    0.5f, 1.0f, color, 0, 0,
  1312.         (float) rcScreen.right -0.5f, (float) rcScreen.top -0.5f,    0.5f, 1.0f, color, 0, 0, 
  1313.         (float) rcScreen.right -0.5f, (float) rcScreen.bottom -0.5f, 0.5f, 1.0f, color, 0, 0, 
  1314.         (float) rcScreen.left -0.5f,  (float) rcScreen.bottom -0.5f, 0.5f, 1.0f, color, 0, 0,
  1315.     };
  1316.     IDirect3DDevice9* pd3dDevice = m_pManager->GetD3DDevice();
  1317.     // Since we're doing our own drawing here we need to flush the sprites
  1318.     m_pManager->m_pSprite->Flush();
  1319.     IDirect3DVertexDeclaration9 *pDecl = NULL;
  1320.     pd3dDevice->GetVertexDeclaration( &pDecl );  // Preserve the sprite's current vertex decl
  1321.     pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX::FVF );
  1322.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  1323.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
  1324.     pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, vertices, sizeof(DXUT_SCREEN_VERTEX) );
  1325.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  1326.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  1327.     // Restore the vertex decl
  1328.     pd3dDevice->SetVertexDeclaration( pDecl );
  1329.     pDecl->Release();
  1330.     return S_OK;
  1331. }
  1332. //--------------------------------------------------------------------------------------
  1333. HRESULT CDXUTDialog::DrawPolyLine( POINT* apPoints, UINT nNumPoints, D3DCOLOR color )
  1334. {
  1335.     DXUT_SCREEN_VERTEX* vertices = new DXUT_SCREEN_VERTEX[ nNumPoints ];
  1336.     if( vertices == NULL )
  1337.         return E_OUTOFMEMORY;
  1338.     DXUT_SCREEN_VERTEX* pVertex = vertices;
  1339.     POINT* pt = apPoints;
  1340.     for( UINT i=0; i < nNumPoints; i++ )
  1341.     {
  1342.         pVertex->x = m_x + (float) pt->x;
  1343.         pVertex->y = m_y + (float) pt->y;
  1344.         pVertex->z = 0.5f;
  1345.         pVertex->h = 1.0f;
  1346.         pVertex->color = color;
  1347.         pVertex->tu = 0.0f;
  1348.         pVertex->tv = 0.0f;
  1349.         pVertex++;
  1350.         pt++;
  1351.     }
  1352.     IDirect3DDevice9* pd3dDevice = m_pManager->GetD3DDevice();
  1353.     // Since we're doing our own drawing here we need to flush the sprites
  1354.     m_pManager->m_pSprite->Flush();
  1355.     IDirect3DVertexDeclaration9 *pDecl = NULL;
  1356.     pd3dDevice->GetVertexDeclaration( &pDecl );  // Preserve the sprite's current vertex decl
  1357.     pd3dDevice->SetFVF( DXUT_SCREEN_VERTEX::FVF );
  1358.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  1359.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2 );
  1360.     pd3dDevice->DrawPrimitiveUP( D3DPT_LINESTRIP, nNumPoints - 1, vertices, sizeof(DXUT_SCREEN_VERTEX) );
  1361.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
  1362.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
  1363.     // Restore the vertex decl
  1364.     pd3dDevice->SetVertexDeclaration( pDecl );
  1365.     pDecl->Release();
  1366.     SAFE_DELETE_ARRAY( vertices );
  1367.     return S_OK;
  1368. }
  1369.  
  1370. //--------------------------------------------------------------------------------------
  1371. HRESULT CDXUTDialog::DrawSprite( CDXUTElement* pElement, RECT* prcDest )
  1372. {
  1373.     // No need to draw fully transparent layers
  1374.     if( pElement->TextureColor.Current.a == 0 )
  1375.         return S_OK;
  1376.     RECT rcTexture = pElement->rcTexture;
  1377.     
  1378.     RECT rcScreen = *prcDest;
  1379.     OffsetRect( &rcScreen, m_x, m_y );
  1380.     // If caption is enabled, offset the Y position by its height.
  1381.     if( m_bCaption )
  1382.         OffsetRect( &rcScreen, 0, m_nCaptionHeight );
  1383.     DXUTTextureNode* pTextureNode = GetTexture( pElement->iTexture );
  1384.     if( pTextureNode == NULL )
  1385.         return E_FAIL;
  1386.     
  1387.     float fScaleX = (float) RectWidth( rcScreen ) / RectWidth( rcTexture );
  1388.     float fScaleY = (float) RectHeight( rcScreen ) / RectHeight( rcTexture );
  1389.     D3DXMATRIXA16 matTransform;
  1390.     D3DXMatrixScaling( &matTransform, fScaleX, fScaleY, 1.0f );
  1391.     m_pManager->m_pSprite->SetTransform( &matTransform );
  1392.     
  1393.     D3DXVECTOR3 vPos( (float)rcScreen.left, (float)rcScreen.top, 0.0f );
  1394.     vPos.x /= fScaleX;
  1395.     vPos.y /= fScaleY;
  1396.     return m_pManager->m_pSprite->Draw( pTextureNode->pTexture, &rcTexture, NULL, &vPos, pElement->TextureColor.Current );
  1397. }
  1398. //--------------------------------------------------------------------------------------
  1399. HRESULT CDXUTDialog::CalcTextRect( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, int nCount )
  1400. {
  1401.     HRESULT hr = S_OK;
  1402.     DXUTFontNode* pFontNode = GetFont( pElement->iFont );
  1403.     if( pFontNode == NULL )
  1404.         return E_FAIL;
  1405.     DWORD dwTextFormat = pElement->dwTextFormat | DT_CALCRECT;
  1406.     // Since we are only computing the rectangle, we don't need a sprite.
  1407.     hr = pFontNode->pFont->DrawText( NULL, strText, nCount, prcDest, dwTextFormat, pElement->FontColor.Current );
  1408.     if( FAILED(hr) )
  1409.         return hr;
  1410.     return S_OK;
  1411. }
  1412. //--------------------------------------------------------------------------------------
  1413. HRESULT CDXUTDialog::DrawText( LPCWSTR strText, CDXUTElement* pElement, RECT* prcDest, bool bShadow, int nCount )
  1414. {
  1415.     HRESULT hr = S_OK;
  1416.     // No need to draw fully transparent layers
  1417.     if( pElement->FontColor.Current.a == 0 )
  1418.         return S_OK;
  1419.     RECT rcScreen = *prcDest;
  1420.     OffsetRect( &rcScreen, m_x, m_y );
  1421.     // If caption is enabled, offset the Y position by its height.
  1422.     if( m_bCaption )
  1423.         OffsetRect( &rcScreen, 0, m_nCaptionHeight );
  1424.     //debug
  1425.     //DrawRect( &rcScreen, D3DCOLOR_ARGB(100, 255, 0, 0) );
  1426.     D3DXMATRIXA16 matTransform;
  1427.     D3DXMatrixIdentity( &matTransform );
  1428.     m_pManager->m_pSprite->SetTransform( &matTransform );
  1429.     DXUTFontNode* pFontNode = GetFont( pElement->iFont );
  1430.     
  1431.     if( bShadow )
  1432.     {
  1433.         RECT rcShadow = rcScreen;
  1434.         OffsetRect( &rcShadow, 1, 1 );
  1435.         hr = pFontNode->pFont->DrawText( m_pManager->m_pSprite, strText, nCount, &rcShadow, pElement->dwTextFormat, D3DCOLOR_ARGB(DWORD(pElement->FontColor.Current.a * 255), 0, 0, 0) );
  1436.         if( FAILED(hr) )
  1437.             return hr;
  1438.     }
  1439.     hr = pFontNode->pFont->DrawText( m_pManager->m_pSprite, strText, nCount, &rcScreen, pElement->dwTextFormat, pElement->FontColor.Current );
  1440.     if( FAILED(hr) )
  1441.         return hr;
  1442.     return S_OK;
  1443. }
  1444. //--------------------------------------------------------------------------------------
  1445. void CDXUTDialog::SetBackgroundColors( D3DCOLOR colorTopLeft, D3DCOLOR colorTopRight, D3DCOLOR colorBottomLeft, D3DCOLOR colorBottomRight )
  1446. {
  1447.     m_colorTopLeft = colorTopLeft;
  1448.     m_colorTopRight = colorTopRight;
  1449.     m_colorBottomLeft = colorBottomLeft;
  1450.     m_colorBottomRight = colorBottomRight;
  1451. }
  1452. //--------------------------------------------------------------------------------------
  1453. void CDXUTDialog::SetNextDialog( CDXUTDialog* pNextDialog )
  1454.     if( pNextDialog == NULL )
  1455.         pNextDialog = this;
  1456.     
  1457.     m_pNextDialog = pNextDialog;
  1458.     if( pNextDialog )
  1459.         m_pNextDialog->m_pPrevDialog = this;
  1460. }
  1461. //--------------------------------------------------------------------------------------
  1462. void CDXUTDialog::ClearFocus()
  1463. {
  1464.     if( s_pControlFocus )
  1465.     {
  1466.         s_pControlFocus->OnFocusOut();
  1467.         s_pControlFocus = NULL;
  1468.     }
  1469.     ReleaseCapture();
  1470. }
  1471. //--------------------------------------------------------------------------------------
  1472. void CDXUTDialog::FocusDefaultControl()
  1473. {
  1474.     // Check for default control in this dialog
  1475.     for( int i=0; i < m_Controls.GetSize(); i++ )
  1476.     {
  1477.         CDXUTControl* pControl = m_Controls.GetAt( i );
  1478.         if( pControl->m_bIsDefault )
  1479.         {
  1480.             // Remove focus from the current control
  1481.             ClearFocus();
  1482.             // Give focus to the default control
  1483.             s_pControlFocus = pControl;
  1484.             s_pControlFocus->OnFocusIn();
  1485.             return;
  1486.         }
  1487.     }
  1488. }
  1489. //--------------------------------------------------------------------------------------
  1490. bool CDXUTDialog::OnCycleFocus( bool bForward )
  1491. {
  1492.     CDXUTControl *pControl = NULL;
  1493.     CDXUTDialog *pDialog = NULL; // pDialog and pLastDialog are used to track wrapping of
  1494.     CDXUTDialog *pLastDialog;    // focus from first control to last or vice versa.
  1495.     if( s_pControlFocus == NULL )
  1496.     {
  1497.         // If s_pControlFocus is NULL, we focus the first control of first dialog in
  1498.         // the case that bForward is true, and focus the last control of last dialog when
  1499.         // bForward is false.
  1500.         //
  1501.         if( bForward )
  1502.         {
  1503.             // Search for the first control from the start of the dialog
  1504.             // array.
  1505.             for( int d = 0; d < m_pManager->m_Dialogs.GetSize(); ++d )
  1506.             {
  1507.                 pDialog = pLastDialog = m_pManager->m_Dialogs.GetAt(d);
  1508.                 if( pDialog && pDialog->m_Controls.GetSize() > 0 )
  1509.                 {
  1510.                     pControl = pDialog->m_Controls.GetAt(0);
  1511.                     break;
  1512.                 }
  1513.             }
  1514.             if( !pDialog || !pControl )
  1515.             {
  1516.                 // No dialog has been registered yet or no controls have been
  1517.                 // added to the dialogs. Cannot proceed.
  1518.                 return true;
  1519.             }
  1520.         }
  1521.         else
  1522.         {
  1523.             // Search for the first control from the end of the dialog
  1524.             // array.
  1525.             for( int d = m_pManager->m_Dialogs.GetSize() - 1; d >= 0; --d )
  1526.             {
  1527.                 pDialog = pLastDialog = m_pManager->m_Dialogs.GetAt(d);
  1528.                 if( pDialog && pDialog->m_Controls.GetSize() > 0 )
  1529.                 {
  1530.                     pControl = pDialog->m_Controls.GetAt( pDialog->m_Controls.GetSize() - 1 );
  1531.                     break;
  1532.                 }
  1533.             }
  1534.             if( !pDialog || !pControl )
  1535.             {
  1536.                 // No dialog has been registered yet or no controls have been
  1537.                 // added to the dialogs. Cannot proceed.
  1538.                 return true;
  1539.             }
  1540.         }
  1541.     }
  1542.     else
  1543.     if( s_pControlFocus->m_pDialog != this )
  1544.     {
  1545.         // If a control belonging to another dialog has focus, let that other
  1546.         // dialog handle this event by returning false.
  1547.         //
  1548.         return false;
  1549.     }
  1550.     else
  1551.     {
  1552.         // Focused control belongs to this dialog. Cycle to the
  1553.         // next/previous control.
  1554.         pLastDialog = s_pControlFocus->m_pDialog;
  1555.         pControl = (bForward) ? GetNextControl( s_pControlFocus ) : GetPrevControl( s_pControlFocus );
  1556.         pDialog = pControl->m_pDialog;
  1557.     }
  1558.     for( int i=0; i < 0xffff; i++ )
  1559.     {
  1560.         // If we just wrapped from last control to first or vice versa,
  1561.         // set the focused control to NULL. This state, where no control
  1562.         // has focus, allows the camera to work.
  1563.         int nLastDialogIndex = m_pManager->m_Dialogs.IndexOf( pLastDialog );
  1564.         int nDialogIndex = m_pManager->m_Dialogs.IndexOf( pDialog );
  1565.         if( ( !bForward && nLastDialogIndex < nDialogIndex ) ||
  1566.             ( bForward && nDialogIndex < nLastDialogIndex ) )
  1567.         {
  1568.             if( s_pControlFocus )
  1569.                 s_pControlFocus->OnFocusOut();
  1570.             s_pControlFocus = NULL;
  1571.             return true;
  1572.         }
  1573.         // If we've gone in a full circle then focus doesn't change
  1574.         if( pControl == s_pControlFocus )
  1575.             return true;
  1576.         // If the dialog accepts keybord input and the control can have focus then
  1577.         // move focus
  1578.         if( pControl->m_pDialog->m_bKeyboardInput && pControl->CanHaveFocus() )
  1579.         {
  1580.             if( s_pControlFocus )
  1581.                 s_pControlFocus->OnFocusOut();
  1582.             s_pControlFocus = pControl;
  1583.             s_pControlFocus->OnFocusIn();
  1584.             return true;
  1585.         }
  1586.         pLastDialog = pDialog;
  1587.         pControl = (bForward) ? GetNextControl( pControl ) : GetPrevControl( pControl );
  1588.         pDialog = pControl->m_pDialog;
  1589.     }
  1590.     // If we reached this point, the chain of dialogs didn't form a complete loop
  1591.     DXTRACE_ERR( L"CDXUTDialog: Multiple dialogs are improperly chained together", E_FAIL );
  1592.     return false;
  1593. }
  1594. //--------------------------------------------------------------------------------------
  1595. HRESULT CDXUTDialogResourceManager::CreateFont( UINT iFont )
  1596. {
  1597.     HRESULT hr = S_OK;
  1598.     DXUTFontNode* pFontNode = m_FontCache.GetAt( iFont );
  1599.     SAFE_RELEASE( pFontNode->pFont );
  1600.     
  1601.     V_RETURN( D3DXCreateFont( m_pd3dDevice, pFontNode->nHeight, 0, pFontNode->nWeight, 1, FALSE, DEFAULT_CHARSET, 
  1602.                               OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
  1603.                               pFontNode->strFace, &pFontNode->pFont ) );
  1604.     return S_OK;
  1605. }
  1606. //--------------------------------------------------------------------------------------
  1607. HRESULT CDXUTDialogResourceManager::CreateTexture( UINT iTexture )
  1608. {
  1609.     HRESULT hr = S_OK;
  1610.     DXUTTextureNode* pTextureNode = m_TextureCache.GetAt( iTexture );
  1611.     
  1612.     D3DXIMAGE_INFO info;
  1613.     if( !pTextureNode->bFileSource )
  1614.     {
  1615.         if( pTextureNode->nResourceID == 0xFFFF && pTextureNode->hResourceModule == (HMODULE) 0xFFFF )
  1616.         {
  1617.             hr = DXUTCreateGUITextureFromInternalArray( m_pd3dDevice, &pTextureNode->pTexture, &info );
  1618.             if( FAILED(hr) )
  1619.                 return DXTRACE_ERR( L"D3DXCreateTextureFromFileInMemoryEx", hr );
  1620.         }
  1621.         else
  1622.         {
  1623.             LPCWSTR pID = pTextureNode->nResourceID ? (LPCWSTR)(size_t)pTextureNode->nResourceID : pTextureNode->strFilename;
  1624.             // Create texture from resource
  1625.             hr =  D3DXCreateTextureFromResourceEx( m_pd3dDevice, pTextureNode->hResourceModule, pID, D3DX_DEFAULT, D3DX_DEFAULT, 
  1626.                                                 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, 
  1627.                                                 D3DX_DEFAULT, D3DX_DEFAULT, 0, 
  1628.                                                 &info, NULL, &pTextureNode->pTexture );
  1629.             if( FAILED(hr) )
  1630.                 return DXTRACE_ERR( L"D3DXCreateTextureFromResourceEx", hr );
  1631.         }
  1632.     }
  1633.     else
  1634.     {
  1635.         // Make sure there's a texture to create
  1636.         if( pTextureNode->strFilename[0] == 0 )
  1637.             return S_OK;
  1638.         // Find the texture on the hard drive
  1639.         WCHAR strPath[MAX_PATH];
  1640.         hr = DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, pTextureNode->strFilename );
  1641.         if( FAILED(hr) )
  1642.         {
  1643.             return DXTRACE_ERR( L"DXUTFindDXSDKMediaFileCch", hr );
  1644.         }
  1645.         // Create texture from file
  1646.         hr =  D3DXCreateTextureFromFileEx( m_pd3dDevice, strPath, D3DX_DEFAULT, D3DX_DEFAULT, 
  1647.                                            1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, 
  1648.                                            D3DX_DEFAULT, D3DX_DEFAULT, 0, 
  1649.                                            &info, NULL, &pTextureNode->pTexture );
  1650.         if( FAILED(hr) )
  1651.         {
  1652.             return DXTRACE_ERR( L"D3DXCreateTextureFromFileEx", hr );
  1653.         }
  1654.     }
  1655.     // Store dimensions
  1656.     pTextureNode->dwWidth = info.Width;
  1657.     pTextureNode->dwHeight = info.Height;
  1658.     return S_OK;
  1659. }
  1660. //--------------------------------------------------------------------------------------
  1661. void CDXUTDialog::InitDefaultElements()
  1662. {
  1663.     SetFont( 0, L"Arial", 14, FW_NORMAL );
  1664.     CDXUTElement Element;
  1665.     RECT rcTexture;
  1666.     //-------------------------------------
  1667.     // Element for the caption
  1668.     //-------------------------------------
  1669.     m_CapElement.SetFont( 0 );
  1670.     SetRect( &rcTexture, 17, 269, 241, 287 );
  1671.     m_CapElement.SetTexture( 0, &rcTexture );
  1672.     m_CapElement.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB(255, 255, 255, 255);
  1673.     m_CapElement.FontColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB(255, 255, 255, 255);
  1674.     m_CapElement.SetFont( 0, D3DCOLOR_ARGB(255, 255, 255, 255), DT_LEFT | DT_VCENTER );
  1675.     // Pre-blend as we don't need to transition the state
  1676.     m_CapElement.TextureColor.Blend( DXUT_STATE_NORMAL, 10.0f );
  1677.     m_CapElement.FontColor.Blend( DXUT_STATE_NORMAL, 10.0f );
  1678.     //-------------------------------------
  1679.     // CDXUTStatic
  1680.     //-------------------------------------
  1681.     Element.SetFont( 0 );
  1682.     Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 );
  1683.     // Assign the Element
  1684.     SetDefaultElement( DXUT_CONTROL_STATIC, 0, &Element );
  1685.     
  1686.     //-------------------------------------
  1687.     // CDXUTButton - Button
  1688.     //-------------------------------------
  1689.     SetRect( &rcTexture, 0, 0, 136, 54 );
  1690.     Element.SetTexture( 0, &rcTexture );
  1691.     Element.SetFont( 0 );
  1692.     Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB(150, 255, 255, 255);
  1693.     Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB(200, 255, 255, 255);
  1694.     Element.FontColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB(255, 0, 0, 0);
  1695.     
  1696.     // Assign the Element
  1697.     SetDefaultElement( DXUT_CONTROL_BUTTON, 0, &Element );
  1698.     
  1699.     //-------------------------------------
  1700.     // CDXUTButton - Fill layer
  1701.     //-------------------------------------
  1702.     SetRect( &rcTexture, 136, 0, 252, 54 );
  1703.     Element.SetTexture( 0, &rcTexture, D3DCOLOR_ARGB(0, 255, 255, 255) );
  1704.     Element.TextureColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB(160, 255, 255, 255);
  1705.     Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB(60, 0, 0, 0);
  1706.     Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB(30, 255, 255, 255);
  1707.     
  1708.     
  1709.     // Assign the Element
  1710.     SetDefaultElement( DXUT_CONTROL_BUTTON, 1, &Element );
  1711.     //-------------------------------------
  1712.     // CDXUTCheckBox - Box
  1713.     //-------------------------------------
  1714.     SetRect( &rcTexture, 0, 54, 27, 81 );
  1715.     Element.SetTexture( 0, &rcTexture );
  1716.     Element.SetFont( 0, D3DCOLOR_ARGB(255, 255, 255, 255), DT_LEFT | DT_VCENTER );
  1717.     Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 );
  1718.     Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB(150, 255, 255, 255);
  1719.     Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB(200, 255, 255, 255);
  1720.     Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB(255, 255, 255, 255);
  1721.     
  1722.     // Assign the Element
  1723.     SetDefaultElement( DXUT_CONTROL_CHECKBOX, 0, &Element );
  1724.     //-------------------------------------
  1725.     // CDXUTCheckBox - Check
  1726.     //-------------------------------------
  1727.     SetRect( &rcTexture, 27, 54, 54, 81 );
  1728.     Element.SetTexture( 0, &rcTexture );
  1729.     
  1730.     // Assign the Element
  1731.     SetDefaultElement( DXUT_CONTROL_CHECKBOX, 1, &Element );
  1732.     //-------------------------------------
  1733.     // CDXUTRadioButton - Box
  1734.     //-------------------------------------
  1735.     SetRect( &rcTexture, 54, 54, 81, 81 );
  1736.     Element.SetTexture( 0, &rcTexture );
  1737.     Element.SetFont( 0, D3DCOLOR_ARGB(255, 255, 255, 255), DT_LEFT | DT_VCENTER );
  1738.     Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB( 200, 200, 200, 200 );
  1739.     Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB(150, 255, 255, 255);
  1740.     Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB(200, 255, 255, 255);
  1741.     Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB(255, 255, 255, 255);
  1742.     
  1743.     // Assign the Element
  1744.     SetDefaultElement( DXUT_CONTROL_RADIOBUTTON, 0, &Element );
  1745.     //-------------------------------------
  1746.     // CDXUTRadioButton - Check
  1747.     //-------------------------------------
  1748.     SetRect( &rcTexture, 81, 54, 108, 81 );
  1749.     Element.SetTexture( 0, &rcTexture );
  1750.     
  1751.     // Assign the Element
  1752.     SetDefaultElement( DXUT_CONTROL_RADIOBUTTON, 1, &Element );
  1753.     //-------------------------------------
  1754.     // CDXUTComboBox - Main
  1755.     //-------------------------------------
  1756.     SetRect( &rcTexture, 7, 81, 247, 123 );
  1757.     Element.SetTexture( 0, &rcTexture );
  1758.     Element.SetFont( 0 );
  1759.     Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB(150, 200, 200, 200);
  1760.     Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB(170, 230, 230, 230);
  1761.     Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB(70, 200, 200, 200);
  1762.     Element.FontColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB(255, 0, 0, 0);
  1763.     Element.FontColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB(255, 0, 0, 0);
  1764.     Element.FontColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB(200, 200, 200, 200);
  1765.     
  1766.     
  1767.     // Assign the Element
  1768.     SetDefaultElement( DXUT_CONTROL_COMBOBOX, 0, &Element );
  1769.     //-------------------------------------
  1770.     // CDXUTComboBox - Button
  1771.     //-------------------------------------
  1772.     SetRect( &rcTexture, 98, 189, 151, 238 );
  1773.     Element.SetTexture( 0, &rcTexture );
  1774.     Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB(150, 255, 255, 255);
  1775.     Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB(255, 150, 150, 150);
  1776.     Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB(200, 255, 255, 255);
  1777.     Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB(70, 255, 255, 255);
  1778.     
  1779.     // Assign the Element
  1780.     SetDefaultElement( DXUT_CONTROL_COMBOBOX, 1, &Element );
  1781.     //-------------------------------------
  1782.     // CDXUTComboBox - Dropdown
  1783.     //-------------------------------------
  1784.     SetRect( &rcTexture, 13, 123, 241, 160 );
  1785.     Element.SetTexture( 0, &rcTexture );
  1786.     Element.SetFont( 0, D3DCOLOR_ARGB(255, 0, 0, 0), DT_LEFT | DT_TOP );
  1787.     
  1788.     // Assign the Element
  1789.     SetDefaultElement( DXUT_CONTROL_COMBOBOX, 2, &Element );
  1790.     //-------------------------------------
  1791.     // CDXUTComboBox - Selection
  1792.     //-------------------------------------
  1793.     SetRect( &rcTexture, 12, 163, 239, 183 );
  1794.     Element.SetTexture( 0, &rcTexture );
  1795.     Element.SetFont( 0, D3DCOLOR_ARGB(255, 255, 255, 255), DT_LEFT | DT_TOP );
  1796.     
  1797.     // Assign the Element
  1798.     SetDefaultElement( DXUT_CONTROL_COMBOBOX, 3, &Element );
  1799.     //-------------------------------------
  1800.     // CDXUTSlider - Track
  1801.     //-------------------------------------
  1802.     SetRect( &rcTexture, 1, 187, 93, 228 );
  1803.     Element.SetTexture( 0, &rcTexture );
  1804.     Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB(150, 255, 255, 255);
  1805.     Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB(200, 255, 255, 255);
  1806.     Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB(70, 255, 255, 255);
  1807.     
  1808.     // Assign the Element
  1809.     SetDefaultElement( DXUT_CONTROL_SLIDER, 0, &Element );
  1810.     //-------------------------------------
  1811.     // CDXUTSlider - Button
  1812.     //-------------------------------------
  1813.     SetRect( &rcTexture, 151, 193, 192, 234 );
  1814.     Element.SetTexture( 0, &rcTexture );
  1815.     // Assign the Element
  1816.     SetDefaultElement( DXUT_CONTROL_SLIDER, 1, &Element );
  1817.     //-------------------------------------
  1818.     // CDXUTScrollBar - Track
  1819.     //-------------------------------------
  1820.     int nScrollBarStartX = 196;
  1821.     int nScrollBarStartY = 191;
  1822.     SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 21, nScrollBarStartX + 22, nScrollBarStartY + 32 );
  1823.     Element.SetTexture( 0, &rcTexture );
  1824.     Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB(255, 200, 200, 200);
  1825.         
  1826.     // Assign the Element
  1827.     SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 0, &Element );
  1828.     //-------------------------------------
  1829.     // CDXUTScrollBar - Up Arrow
  1830.     //-------------------------------------
  1831.     SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 1, nScrollBarStartX + 22, nScrollBarStartY + 21 );
  1832.     Element.SetTexture( 0, &rcTexture );
  1833.     Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB(255, 200, 200, 200);
  1834.     
  1835.     
  1836.     // Assign the Element
  1837.     SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 1, &Element );
  1838.     //-------------------------------------
  1839.     // CDXUTScrollBar - Down Arrow
  1840.     //-------------------------------------
  1841.     SetRect( &rcTexture, nScrollBarStartX + 0, nScrollBarStartY + 32, nScrollBarStartX + 22, nScrollBarStartY + 53 );
  1842.     Element.SetTexture( 0, &rcTexture );
  1843.     Element.TextureColor.States[ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB(255, 200, 200, 200);
  1844.     
  1845.     
  1846.     // Assign the Element
  1847.     SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 2, &Element );
  1848.     //-------------------------------------
  1849.     // CDXUTScrollBar - Button
  1850.     //-------------------------------------
  1851.     SetRect( &rcTexture, 220, 192, 238, 234 );
  1852.     Element.SetTexture( 0, &rcTexture );
  1853.     
  1854.     // Assign the Element
  1855.     SetDefaultElement( DXUT_CONTROL_SCROLLBAR, 3, &Element );
  1856.     //-------------------------------------
  1857.     // CDXUTEditBox
  1858.     //-------------------------------------
  1859.     // Element assignment:
  1860.     //   0 - text area
  1861.     //   1 - top left border
  1862.     //   2 - top border
  1863.     //   3 - top right border
  1864.     //   4 - left border
  1865.     //   5 - right border
  1866.     //   6 - lower left border
  1867.     //   7 - lower border
  1868.     //   8 - lower right border
  1869.     Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP );
  1870.     // Assign the style
  1871.     SetRect( &rcTexture, 14, 90, 241, 113 );
  1872.     Element.SetTexture( 0, &rcTexture );
  1873.     SetDefaultElement( DXUT_CONTROL_EDITBOX, 0, &Element );
  1874.     SetRect( &rcTexture, 8, 82, 14, 90 );
  1875.     Element.SetTexture( 0, &rcTexture );
  1876.     SetDefaultElement( DXUT_CONTROL_EDITBOX, 1, &Element );
  1877.     SetRect( &rcTexture, 14, 82, 241, 90 );
  1878.     Element.SetTexture( 0, &rcTexture );
  1879.     SetDefaultElement( DXUT_CONTROL_EDITBOX, 2, &Element );
  1880.     SetRect( &rcTexture, 241, 82, 246, 90 );
  1881.     Element.SetTexture( 0, &rcTexture );
  1882.     SetDefaultElement( DXUT_CONTROL_EDITBOX, 3, &Element );
  1883.     SetRect( &rcTexture, 8, 90, 14, 113 );
  1884.     Element.SetTexture( 0, &rcTexture );
  1885.     SetDefaultElement( DXUT_CONTROL_EDITBOX, 4, &Element );
  1886.     SetRect( &rcTexture, 241, 90, 246, 113 );
  1887.     Element.SetTexture( 0, &rcTexture );
  1888.     SetDefaultElement( DXUT_CONTROL_EDITBOX, 5, &Element );
  1889.     SetRect( &rcTexture, 8, 113, 14, 121 );
  1890.     Element.SetTexture( 0, &rcTexture );
  1891.     SetDefaultElement( DXUT_CONTROL_EDITBOX, 6, &Element );
  1892.     SetRect( &rcTexture, 14, 113, 241, 121 );
  1893.     Element.SetTexture( 0, &rcTexture );
  1894.     SetDefaultElement( DXUT_CONTROL_EDITBOX, 7, &Element );
  1895.     SetRect( &rcTexture, 241, 113, 246, 121 );
  1896.     Element.SetTexture( 0, &rcTexture );
  1897.     SetDefaultElement( DXUT_CONTROL_EDITBOX, 8, &Element );
  1898.     //-------------------------------------
  1899.     // CDXUTIMEEditBox
  1900.     //-------------------------------------
  1901.     Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP );
  1902.     // Assign the style
  1903.     SetRect( &rcTexture, 14, 90, 241, 113 );
  1904.     Element.SetTexture( 0, &rcTexture );
  1905.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 0, &Element );
  1906.     SetRect( &rcTexture, 8, 82, 14, 90 );
  1907.     Element.SetTexture( 0, &rcTexture );
  1908.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 1, &Element );
  1909.     SetRect( &rcTexture, 14, 82, 241, 90 );
  1910.     Element.SetTexture( 0, &rcTexture );
  1911.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 2, &Element );
  1912.     SetRect( &rcTexture, 241, 82, 246, 90 );
  1913.     Element.SetTexture( 0, &rcTexture );
  1914.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 3, &Element );
  1915.     SetRect( &rcTexture, 8, 90, 14, 113 );
  1916.     Element.SetTexture( 0, &rcTexture );
  1917.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 4, &Element );
  1918.     SetRect( &rcTexture, 241, 90, 246, 113 );
  1919.     Element.SetTexture( 0, &rcTexture );
  1920.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 5, &Element );
  1921.     SetRect( &rcTexture, 8, 113, 14, 121 );
  1922.     Element.SetTexture( 0, &rcTexture );
  1923.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 6, &Element );
  1924.     SetRect( &rcTexture, 14, 113, 241, 121 );
  1925.     Element.SetTexture( 0, &rcTexture );
  1926.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 7, &Element );
  1927.     SetRect( &rcTexture, 241, 113, 246, 121 );
  1928.     Element.SetTexture( 0, &rcTexture );
  1929.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 8, &Element );
  1930.     // Element 9 for IME text, and indicator button
  1931.     SetRect( &rcTexture, 0, 0, 136, 54 );
  1932.     Element.SetTexture( 0, &rcTexture );
  1933.     Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_CENTER | DT_VCENTER );
  1934.     SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 9, &Element );
  1935.     //-------------------------------------
  1936.     // CDXUTListBox - Main
  1937.     //-------------------------------------
  1938.     SetRect( &rcTexture, 13, 123, 241, 160 );
  1939.     Element.SetTexture( 0, &rcTexture );
  1940.     Element.SetFont( 0, D3DCOLOR_ARGB(255, 0, 0, 0), DT_LEFT | DT_TOP );
  1941.     // Assign the Element
  1942.     SetDefaultElement( DXUT_CONTROL_LISTBOX, 0, &Element );
  1943.     //-------------------------------------
  1944.     // CDXUTListBox - Selection
  1945.     //-------------------------------------
  1946.     SetRect( &rcTexture, 16, 166, 240, 183 );
  1947.     Element.SetTexture( 0, &rcTexture );
  1948.     Element.SetFont( 0, D3DCOLOR_ARGB(255, 255, 255, 255), DT_LEFT | DT_TOP );
  1949.     // Assign the Element
  1950.     SetDefaultElement( DXUT_CONTROL_LISTBOX, 1, &Element );
  1951. }
  1952. //--------------------------------------------------------------------------------------
  1953. // CDXUTControl class
  1954. //--------------------------------------------------------------------------------------
  1955. //--------------------------------------------------------------------------------------
  1956. CDXUTControl::CDXUTControl( CDXUTDialog *pDialog )
  1957. {
  1958.     m_Type = DXUT_CONTROL_BUTTON;
  1959.     m_pDialog = pDialog;
  1960.     m_ID = 0;
  1961.     m_Index = 0;
  1962.     m_pUserData = NULL;
  1963.     m_bEnabled = true;
  1964.     m_bVisible = true;
  1965.     m_bMouseOver = false;
  1966.     m_bHasFocus = false;
  1967.     m_bIsDefault = false;
  1968.     m_pDialog = NULL;
  1969.     m_x = 0;
  1970.     m_y = 0;
  1971.     m_width = 0;
  1972.     m_height = 0;
  1973.    ZeroMemory( &m_rcBoundingBox, sizeof( m_rcBoundingBox ) );
  1974. }
  1975. CDXUTControl::~CDXUTControl()
  1976. {
  1977.     for( int i = 0; i < m_Elements.GetSize(); ++i )
  1978.     {
  1979.         delete m_Elements[i];
  1980.     }
  1981.     m_Elements.RemoveAll();
  1982. }
  1983. //--------------------------------------------------------------------------------------
  1984. void CDXUTControl::SetTextColor( D3DCOLOR Color )
  1985. {
  1986.     CDXUTElement* pElement = m_Elements.GetAt( 0 );
  1987.     if( pElement )
  1988.         pElement->FontColor.States[DXUT_STATE_NORMAL] = Color;
  1989. }
  1990. //--------------------------------------------------------------------------------------
  1991. HRESULT CDXUTControl::SetElement( UINT iElement, CDXUTElement* pElement )
  1992. {
  1993.     HRESULT hr = S_OK;
  1994.     if( pElement == NULL )
  1995.         return E_INVALIDARG;
  1996.     // Make certain the array is this large
  1997.     for( UINT i=m_Elements.GetSize(); i <= iElement; i++ )
  1998.     {
  1999.         CDXUTElement* pNewElement = new CDXUTElement();
  2000.         if( pNewElement == NULL )
  2001.             return E_OUTOFMEMORY;
  2002.         hr = m_Elements.Add( pNewElement );
  2003.         if( FAILED(hr) )
  2004.         {
  2005.             SAFE_DELETE( pNewElement );
  2006.             return hr;
  2007.         }
  2008.     }
  2009.     // Update the data
  2010.     CDXUTElement* pCurElement = m_Elements.GetAt( iElement );
  2011.     *pCurElement = *pElement;
  2012.     
  2013.     return S_OK;
  2014. }
  2015. //--------------------------------------------------------------------------------------
  2016. void CDXUTControl::Refresh()
  2017. {
  2018.     m_bMouseOver = false;
  2019.     m_bHasFocus = false;
  2020.     for( int i=0; i < m_Elements.GetSize(); i++ )
  2021.     {
  2022.         CDXUTElement* pElement = m_Elements.GetAt( i );
  2023.         pElement->Refresh();
  2024.     }
  2025. }
  2026. //--------------------------------------------------------------------------------------
  2027. void CDXUTControl::UpdateRects()
  2028. {
  2029.     SetRect( &m_rcBoundingBox, m_x, m_y, m_x + m_width, m_y + m_height );
  2030. }
  2031. //--------------------------------------------------------------------------------------
  2032. // CDXUTStatic class
  2033. //--------------------------------------------------------------------------------------
  2034. //--------------------------------------------------------------------------------------
  2035. CDXUTStatic::CDXUTStatic( CDXUTDialog *pDialog )
  2036. {
  2037.     m_Type = DXUT_CONTROL_STATIC;
  2038.     m_pDialog = pDialog;
  2039.     ZeroMemory( &m_strText, sizeof(m_strText) );  
  2040.     for( int i=0; i < m_Elements.GetSize(); i++ )
  2041.     {
  2042.         CDXUTElement* pElement = m_Elements.GetAt( i );
  2043.         SAFE_DELETE( pElement );
  2044.     }
  2045.     m_Elements.RemoveAll();
  2046. }
  2047. //--------------------------------------------------------------------------------------
  2048. void CDXUTStatic::Render( IDirect3DDevice9* pd3dDevice, float fElapsedTime )
  2049. {    
  2050.     if( m_bVisible == false )
  2051.         return;
  2052.     DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
  2053.     if( m_bEnabled == false )
  2054.         iState = DXUT_STATE_DISABLED;
  2055.         
  2056.     CDXUTElement* pElement = m_Elements.GetAt( 0 );
  2057.     pElement->FontColor.Blend( iState, fElapsedTime );
  2058.     
  2059.     m_pDialog->DrawText( m_strText, pElement, &m_rcBoundingBox, true );
  2060. }
  2061. //--------------------------------------------------------------------------------------
  2062. HRESULT CDXUTStatic::GetTextCopy( LPWSTR strDest, UINT bufferCount )
  2063. {
  2064.     // Validate incoming parameters
  2065.     if( strDest == NULL || bufferCount == 0 )
  2066.     {
  2067.         return E_INVALIDARG;
  2068.     }
  2069.     // Copy the window text
  2070.     StringCchCopy( strDest, bufferCount, m_strText );
  2071.     return S_OK;
  2072. }
  2073. //--------------------------------------------------------------------------------------
  2074. HRESULT CDXUTStatic::SetText( LPCWSTR strText )
  2075. {
  2076.     if( strText == NULL )
  2077.     {
  2078.         m_strText[0] = 0;
  2079.         return S_OK;
  2080.     }
  2081.     
  2082.     StringCchCopy( m_strText, MAX_PATH, strText); 
  2083.     return S_OK;
  2084. }
  2085. //--------------------------------------------------------------------------------------
  2086. // CDXUTButton class
  2087. //--------------------------------------------------------------------------------------
  2088. //--------------------------------------------------------------------------------------
  2089. CDXUTButton::CDXUTButton( CDXUTDialog *pDialog )
  2090. {
  2091.     m_Type = DXUT_CONTROL_BUTTON;
  2092.     m_pDialog = pDialog;
  2093.     m_bPressed = false;
  2094.     m_nHotkey = 0;
  2095. }
  2096. //--------------------------------------------------------------------------------------
  2097. bool CDXUTButton::HandleKeyboard( UINT uMsg, WPARAM wParam, LPARAM lParam )
  2098. {
  2099.     if( !m_bEnabled || !m_bVisible )
  2100.         return false;
  2101.     switch( uMsg )
  2102.     {
  2103.         case WM_KEYDOWN:
  2104.         {
  2105.             switch( wParam )
  2106.             {
  2107.                 case VK_SPACE:
  2108.                     m_bPressed = true;
  2109.                     return true;
  2110.             }
  2111.         }
  2112.         case WM_KEYUP:
  2113.         {
  2114.             switch( wParam )
  2115.             {
  2116.                 case VK_SPACE:
  2117.                     if( m_bPressed == true )
  2118.                     {
  2119.                         m_bPressed = false;
  2120.                         m_pDialog->SendEvent( EVENT_BUTTON_CLICKED, true, this );
  2121.                     }
  2122.                     return true;
  2123.             }
  2124.         }
  2125.     }
  2126.     return false;
  2127. }
  2128. //--------------------------------------------------------------------------------------
  2129. bool CDXUTButton::HandleMouse( UINT uMsg, POINT pt, WPARAM wParam, LPARAM lParam )
  2130. {
  2131.     if( !m_bEnabled || !m_bVisible )
  2132.         return false;
  2133.     switch( uMsg )
  2134.     {
  2135.         case WM_LBUTTONDOWN:
  2136.         case WM_LBUTTONDBLCLK:
  2137.         {
  2138.             if( ContainsPoint( pt ) )
  2139.             {
  2140.                 // Pressed while inside the control
  2141.                 m_bPressed = true;
  2142.                 SetCapture( DXUTGetHWND() );
  2143.                 if( !m_bHasFocus )
  2144.                     m_pDialog->RequestFocus( this );
  2145.                 return true;
  2146.             }
  2147.             break;
  2148.         }
  2149.         case WM_LBUTTONUP:
  2150.         {
  2151.             if( m_bPressed )
  2152.             {
  2153.                 m_bPressed = false;
  2154.                 ReleaseCapture();
  2155.                 if( !m_pDialog->m_bKeyboardInput )
  2156.                     m_pDialog->ClearFocus();
  2157.                 // Button click
  2158.                 if( ContainsPoint( pt ) )
  2159.                     m_pDialog->SendEvent( EVENT_BUTTON_CLICKED, true, this );
  2160.                 return true;
  2161.             }
  2162.             break;
  2163.         }
  2164.     };
  2165.     
  2166.     return false;
  2167. }
  2168. //--------------------------------------------------------------------------------------
  2169. void CDXUTButton::Render( IDirect3DDevice9* pd3dDevice, float fElapsedTime )
  2170. {
  2171.     int nOffsetX = 0;
  2172.     int nOffsetY = 0;
  2173.     DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;
  2174.     if( m_bVisible == false )
  2175.     {
  2176.         iState = DXUT_STATE_HIDDEN;
  2177.     }
  2178.     else if( m_bEnabled == false )
  2179.     {
  2180.         iState = DXUT_STATE_DISABLED;
  2181.     }
  2182.     else if( m_bPressed )
  2183.     {
  2184.         iState = DXUT_STATE_PRESSED;
  2185.         nOffsetX = 1;
  2186.         nOffsetY = 2;
  2187.     }
  2188.     else if( m_bMouseOver )
  2189.     {
  2190.         iState = DXUT_STATE_MOUSEOVER;
  2191.         nOffsetX = -1;
  2192.         nOffsetY = -2;
  2193.     }
  2194.     else if( m_bHasFocus )
  2195.     {
  2196.         iState = DXUT_STATE_FOCUS;
  2197.     }
  2198.     
  2199.     // Background fill layer
  2200.     //TODO: remove magic numbers
  2201.     CDXUTElement* pElement = m_Elements.GetAt( 0 );
  2202.     
  2203.     float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;
  2204.     RECT rcWindow = m_rcBoundingBox;
  2205.     OffsetRect( &rcWindow, nOffsetX, nOffsetY );
  2206.  
  2207.     // Blend current color
  2208.     pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
  2209.     pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );
  2210.     m_pDialog->DrawSprite( pElement, &rcWindow );
  2211.     m_pDialog->DrawText( m_strText, pElement, &rcWindow );
  2212.     // Main button
  2213.     pElement = m_Elements.GetAt( 1 );
  2214.     // Blend current color
  2215.     pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );
  2216.     pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );
  2217.     m_pDialog->DrawSprite( pElement, &rcWindow );