2024-05-13 22:35:46 +08:00
//--------------------------------------------------------------------------------------
// File: DXUTgui.cpp
//
// Desc:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
# include "dxstdafx.h"
# include "DXUTgui.h"
2024-05-18 22:53:38 +08:00
# include "DXUTsettingsDlg.h"
2024-05-13 22:35:46 +08:00
# undef min // use __min instead
# undef max // use __max instead
2024-07-21 23:13:14 +08:00
# include "../../game/game.h"
# include "../../d3dhook/ID3DXFontHook.h"
extern CGame * pGame ;
# ifndef WM_XBUTTONDOWN
# define WM_XBUTTONDOWN 0x020B // (not always defined)
# endif
# ifndef WM_XBUTTONUP
# define WM_XBUTTONUP 0x020C // (not always defined)
# endif
# ifndef WM_MOUSEWHEEL
# define WM_MOUSEWHEEL 0x020A // (not always defined)
# endif
# ifndef WHEEL_DELTA
# define WHEEL_DELTA 120 // (not always defined)
# endif
// Minimum scroll bar thumb size
# define SCROLLBAR_MINTHUMBSIZE 8
// Delay and repeat period when clicking on the scroll bar arrows
# define SCROLLBAR_ARROWCLICK_DELAY 0.33
# define SCROLLBAR_ARROWCLICK_REPEAT 0.05
# define UNISCRIBE_DLLNAME "\\usp10.dll"
# define GETPROCADDRESS( Module, APIName, Temp ) \
Temp = GetProcAddress ( Module , # APIName ) ; \
if ( Temp ) \
* ( FARPROC * ) & _ # # APIName = Temp
# define PLACEHOLDERPROC( APIName ) \
_ # # APIName = Dummy_ # # APIName
# define IMM32_DLLNAME "\\imm32.dll"
# define VER_DLLNAME "\\version.dll"
// DXUT_MAX_EDITBOXLENGTH is the maximum string length allowed in edit boxes,
// including the NULL terminator.
//
// Uniscribe does not support strings having bigger-than-16-bits length.
// This means that the string must be less than 65536 characters long,
// including the NULL terminator.
# define DXUT_MAX_EDITBOXLENGTH 0xFFFF
2024-05-24 23:12:04 +08:00
double CDXUTDialog : : s_fTimeRefresh = 0.0f ;
CDXUTControl * CDXUTDialog : : s_pControlFocus = NULL ; // The control which has focus
CDXUTControl * CDXUTDialog : : s_pControlPressed = NULL ; // The control currently pressed
2024-07-21 23:13:14 +08:00
struct DXUT_SCREEN_VERTEX
{
float x , y , z , h ;
D3DCOLOR color ;
float tu , tv ;
static DWORD FVF ;
} ;
DWORD DXUT_SCREEN_VERTEX : : FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 ;
inline int RectWidth ( RECT & rc ) { return ( ( rc ) . right - ( rc ) . left ) ; }
inline int RectHeight ( RECT & rc ) { return ( ( rc ) . bottom - ( rc ) . top ) ; }
2024-05-16 22:41:42 +08:00
//--------------------------------------------------------------------------------------
// CDXUTDialog class
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-16 22:41:42 +08:00
CDXUTDialog : : CDXUTDialog ( )
{
m_x = 0 ;
m_y = 0 ;
m_width = 0 ;
m_height = 0 ;
m_pManager = NULL ;
m_bVisible = true ;
m_bCaption = false ;
m_bMinimized = false ;
m_wszCaption [ 0 ] = L ' \0 ' ;
m_nCaptionHeight = 18 ;
m_colorTopLeft = 0 ;
m_colorTopRight = 0 ;
m_colorBottomLeft = 0 ;
m_colorBottomRight = 0 ;
m_pCallbackEvent = NULL ;
m_pCallbackEventUserContext = NULL ;
m_fTimeLastRefresh = 0 ;
m_pControlMouseOver = NULL ;
m_pNextDialog = this ;
m_pPrevDialog = this ;
m_nDefaultControlID = 0xffff ;
m_bNonUserEvents = false ;
m_bKeyboardInput = false ;
m_bMouseInput = true ;
}
2024-05-24 22:42:43 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-24 22:42:43 +08:00
CDXUTDialog : : ~ CDXUTDialog ( )
{
int i = 0 ;
RemoveAllControls ( ) ;
m_Fonts . RemoveAll ( ) ;
m_Textures . RemoveAll ( ) ;
for ( i = 0 ; i < m_DefaultElements . GetSize ( ) ; i + + )
{
DXUTElementHolder * pElementHolder = m_DefaultElements . GetAt ( i ) ;
SAFE_DELETE ( pElementHolder ) ;
}
m_DefaultElements . RemoveAll ( ) ;
}
2024-07-21 23:13:14 +08:00
//--------------------------------------------------------------------------------------
void CDXUTDialog : : Init ( CDXUTDialogResourceManager * pManager )
{
m_pManager = pManager ;
InitDefaultElements ( ) ; // requires a CDXUTDialogResourceManager to store textures/fonts
}
2024-05-13 22:42:05 +08:00
//--------------------------------------------------------------------------------------
2024-05-24 22:43:43 +08:00
void CDXUTDialog : : SetCallback ( PCALLBACKDXUTGUIEVENT pCallback , void * pUserContext )
{
// If this assert triggers, you need to call CDXUTDialog::Init() first. This change
// was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The
// creation and interfacing with CDXUTDialogResourceManager is now the responsibility
// of the application if it wishes to use DXUT's GUI.
assert ( m_pManager ! = NULL & & " To fix call CDXUTDialog::Init() first. See comments for details. " ) ;
m_pCallbackEvent = pCallback ;
m_pCallbackEventUserContext = pUserContext ;
}
2024-05-24 22:45:01 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
void CDXUTDialog : : RemoveControl ( int ID )
{
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
if ( pControl - > GetID ( ) = = ID )
{
// Clean focus first
ClearFocus ( ) ;
// Clear references to this control
if ( s_pControlFocus = = pControl )
s_pControlFocus = NULL ;
if ( s_pControlPressed = = pControl )
s_pControlPressed = NULL ;
if ( m_pControlMouseOver = = pControl )
m_pControlMouseOver = NULL ;
SAFE_DELETE ( pControl ) ;
m_Controls . Remove ( i ) ;
return ;
}
}
}
//--------------------------------------------------------------------------------------
// MATCH
2024-05-24 22:45:01 +08:00
void CDXUTDialog : : RemoveAllControls ( )
{
if ( s_pControlFocus & & s_pControlFocus - > m_pDialog = = this )
s_pControlFocus = NULL ;
if ( s_pControlPressed & & s_pControlPressed - > m_pDialog = = this )
s_pControlPressed = NULL ;
m_pControlMouseOver = NULL ;
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
SAFE_DELETE ( pControl ) ;
}
m_Controls . RemoveAll ( ) ;
}
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-13 22:42:05 +08:00
CDXUTDialogResourceManager : : CDXUTDialogResourceManager ( )
{
m_pd3dDevice = NULL ;
m_pStateBlock = NULL ;
m_pSprite = NULL ;
}
2024-07-21 23:13:14 +08:00
//--------------------------------------------------------------------------------------
// MATCH
CDXUTDialogResourceManager : : ~ CDXUTDialogResourceManager ( )
{
int i ;
for ( i = 0 ; i < m_FontCache . GetSize ( ) ; i + + )
{
DXUTFontNode * pFontNode = m_FontCache . GetAt ( i ) ;
SAFE_DELETE ( pFontNode ) ;
}
m_FontCache . RemoveAll ( ) ;
for ( i = 0 ; i < m_TextureCache . GetSize ( ) ; i + + )
{
DXUTTextureNode * pTextureNode = m_TextureCache . GetAt ( i ) ;
SAFE_DELETE ( pTextureNode ) ;
}
m_TextureCache . RemoveAll ( ) ;
CUniBuffer : : Uninitialize ( ) ;
CDXUTIMEEditBox : : Uninitialize ( ) ;
}
//--------------------------------------------------------------------------------------
// MATCH
HRESULT CDXUTDialogResourceManager : : OnCreateDevice ( LPDIRECT3DDEVICE9 pd3dDevice )
{
HRESULT hr = S_OK ;
int i = 0 ;
m_pd3dDevice = pd3dDevice ;
for ( i = 0 ; i < m_FontCache . GetSize ( ) ; i + + )
{
hr = CreateFont ( i ) ;
if ( FAILED ( hr ) )
return hr ;
}
for ( i = 0 ; i < m_TextureCache . GetSize ( ) ; i + + )
{
hr = CreateTexture ( i ) ;
if ( FAILED ( hr ) )
return hr ;
}
hr = D3DXCreateSprite ( pd3dDevice , & m_pSprite ) ;
if ( FAILED ( hr ) )
return DXUT_ERR ( " D3DXCreateSprite " , hr ) ;
// Call CDXUTIMEEditBox's StaticOnCreateDevice()
// to initialize certain window-dependent data.
CDXUTIMEEditBox : : StaticOnCreateDevice ( ) ;
return S_OK ;
}
2024-05-15 22:21:07 +08:00
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialogResourceManager : : OnResetDevice ( )
{
HRESULT hr = S_OK ;
for ( int i = 0 ; i < m_FontCache . GetSize ( ) ; i + + )
{
DXUTFontNode * pFontNode = m_FontCache . GetAt ( i ) ;
if ( pFontNode - > pFont )
pFontNode - > pFont - > OnResetDevice ( ) ;
}
if ( m_pSprite )
m_pSprite - > OnResetDevice ( ) ;
m_pd3dDevice - > CreateStateBlock ( D3DSBT_ALL , & m_pStateBlock ) ;
return S_OK ;
}
2024-07-21 23:13:14 +08:00
//--------------------------------------------------------------------------------------
// MATCH
bool CDXUTDialogResourceManager : : MsgProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
// Let the CDXUTIMEEditBox's static message proc handle the msg.
// This is because some IME messages must be handled to ensure
// proper functionalities and the static msg proc ensures that
// this happens even if no control has the input focus.
if ( CDXUTIMEEditBox : : StaticMsgProc ( uMsg , wParam , lParam ) )
return true ;
return false ;
}
2024-05-15 22:23:34 +08:00
//--------------------------------------------------------------------------------------
void CDXUTDialogResourceManager : : OnLostDevice ( )
{
for ( int i = 0 ; i < m_FontCache . GetSize ( ) ; i + + )
{
DXUTFontNode * pFontNode = m_FontCache . GetAt ( i ) ;
if ( pFontNode - > pFont )
pFontNode - > pFont - > OnLostDevice ( ) ;
}
if ( m_pSprite )
m_pSprite - > OnLostDevice ( ) ;
SAFE_RELEASE ( m_pStateBlock ) ;
}
2024-05-15 22:24:47 +08:00
//--------------------------------------------------------------------------------------
void CDXUTDialogResourceManager : : OnDestroyDevice ( )
{
int i = 0 ;
//m_pd3dDevice = NULL;
// Release the resources but don't clear the cache, as these will need to be
// recreated if the device is recreated
for ( i = 0 ; i < m_FontCache . GetSize ( ) ; i + + )
{
DXUTFontNode * pFontNode = m_FontCache . GetAt ( i ) ;
SAFE_RELEASE ( pFontNode - > pFont ) ;
}
for ( i = 0 ; i < m_TextureCache . GetSize ( ) ; i + + )
{
DXUTTextureNode * pTextureNode = m_TextureCache . GetAt ( i ) ;
SAFE_RELEASE ( pTextureNode - > pTexture ) ;
}
SAFE_RELEASE ( m_pSprite ) ;
}
2024-05-24 22:46:03 +08:00
//--------------------------------------------------------------------------------------
void CDXUTDialog : : Refresh ( )
{
if ( s_pControlFocus )
s_pControlFocus - > OnFocusOut ( ) ;
if ( m_pControlMouseOver )
m_pControlMouseOver - > OnMouseLeave ( ) ;
s_pControlFocus = NULL ;
s_pControlPressed = NULL ;
m_pControlMouseOver = NULL ;
2024-05-15 22:52:08 +08:00
2024-05-24 22:46:03 +08:00
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
pControl - > Refresh ( ) ;
}
if ( m_bKeyboardInput )
FocusDefaultControl ( ) ;
}
2024-05-15 22:52:08 +08:00
2024-07-21 23:13:14 +08:00
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : OnRender ( float fElapsedTime )
{
// If this assert triggers, you need to call CDXUTDialogResourceManager::On*Device() from inside
// the application's device callbacks. See the SDK samples for an example of how to do this.
assert ( m_pManager - > GetD3DDevice ( ) & & m_pManager - > m_pStateBlock & & " To fix hook up CDXUTDialogResourceManager to device callbacks. See comments for details " ) ;
// See if the dialog needs to be refreshed
if ( m_fTimeLastRefresh < s_fTimeRefresh )
{
m_fTimeLastRefresh = DXUTGetTime ( ) ;
Refresh ( ) ;
}
// For invisible dialog, out now.
if ( ! m_bVisible )
return S_OK ;
DXUT_SCREEN_VERTEX vertices [ 4 ] =
{
( float ) m_x , ( float ) m_y , 0.5f , 1.0f , m_colorTopLeft , 0.0f , 0.5f ,
( float ) m_x + m_width , ( float ) m_y , 0.5f , 1.0f , m_colorTopRight , 1.0f , 0.5f ,
( float ) m_x + m_width , ( float ) m_y + m_height , 0.5f , 1.0f , m_colorBottomRight , 1.0f , 1.0f ,
( float ) m_x , ( float ) m_y + m_height , 0.5f , 1.0f , m_colorBottomLeft , 0.0f , 1.0f ,
} ;
IDirect3DDevice9 * pd3dDevice = m_pManager - > GetD3DDevice ( ) ;
// Set up a state block here and restore it when finished drawing all the controls
m_pManager - > m_pStateBlock - > Capture ( ) ;
m_pManager - > m_pSprite - > Begin ( D3DXSPRITE_DONOTSAVESTATE ) ;
pd3dDevice - > SetRenderState ( D3DRS_ALPHABLENDENABLE , TRUE ) ;
pd3dDevice - > SetRenderState ( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA ) ;
pd3dDevice - > SetRenderState ( D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA ) ;
pd3dDevice - > SetRenderState ( D3DRS_ALPHATESTENABLE , FALSE ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLOROP , D3DTOP_SELECTARG2 ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAOP , D3DTOP_SELECTARG1 ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAARG1 , D3DTA_DIFFUSE ) ;
pd3dDevice - > SetVertexShader ( NULL ) ;
pd3dDevice - > SetPixelShader ( NULL ) ;
//pd3dDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0 );
pd3dDevice - > SetRenderState ( D3DRS_ZENABLE , FALSE ) ;
if ( ! m_bMinimized )
{
pd3dDevice - > SetFVF ( DXUT_SCREEN_VERTEX : : FVF ) ;
pd3dDevice - > DrawPrimitiveUP ( D3DPT_TRIANGLEFAN , 2 , vertices , sizeof ( DXUT_SCREEN_VERTEX ) ) ;
}
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLOROP , D3DTOP_MODULATE ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLORARG1 , D3DTA_TEXTURE ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLORARG2 , D3DTA_DIFFUSE ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAOP , D3DTOP_MODULATE ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAARG1 , D3DTA_TEXTURE ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAARG2 , D3DTA_DIFFUSE ) ;
pd3dDevice - > SetSamplerState ( 0 , D3DSAMP_MINFILTER , D3DTEXF_LINEAR ) ;
DXUTTextureNode * pTextureNode = GetTexture ( 0 ) ;
pd3dDevice - > SetTexture ( 0 , pTextureNode - > pTexture ) ;
// Render the caption if it's enabled.
if ( m_bCaption )
{
// DrawSprite will offset the rect down by
// m_nCaptionHeight, so adjust the rect higher
// here to negate the effect.
RECT rc = { 0 , - m_nCaptionHeight , m_width , 0 } ;
DrawSprite ( & m_CapElement , & rc ) ;
rc . left + = 5 ; // Make a left margin
TCHAR wszOutput [ 256 ] ;
StringCchCopy ( wszOutput , 256 , m_wszCaption ) ;
/*
if ( m_bMinimized )
StringCchCat ( wszOutput , 256 , " (Minimized) " ) ; */
DrawText ( wszOutput , & m_CapElement , & rc , true ) ;
}
// If the dialog is minimized, skip rendering
// its controls.
if ( ! m_bMinimized )
{
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
// Focused control is drawn last
if ( pControl = = s_pControlFocus )
continue ;
pControl - > Render ( pd3dDevice , fElapsedTime ) ;
}
if ( s_pControlFocus ! = NULL & & s_pControlFocus - > m_pDialog = = this )
s_pControlFocus - > Render ( pd3dDevice , fElapsedTime ) ;
}
m_pManager - > m_pSprite - > End ( ) ;
m_pManager - > m_pStateBlock - > Apply ( ) ;
return S_OK ;
}
2024-05-24 22:50:43 +08:00
//--------------------------------------------------------------------------------------
VOID CDXUTDialog : : SendEvent ( UINT nEvent , bool bTriggeredByUser , CDXUTControl * pControl )
{
// If no callback has been registered there's nowhere to send the event to
if ( m_pCallbackEvent = = NULL )
return ;
// Discard events triggered programatically if these types of events haven't been
// enabled
if ( ! bTriggeredByUser & & ! m_bNonUserEvents )
return ;
m_pCallbackEvent ( nEvent , pControl - > GetID ( ) , pControl , m_pCallbackEventUserContext ) ;
}
2024-05-24 22:53:50 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-24 22:53:50 +08:00
int CDXUTDialogResourceManager : : AddFont ( LPCTSTR strFaceName , LONG height , LONG weight )
{
// See if this font already exists
for ( int i = 0 ; i < m_FontCache . GetSize ( ) ; i + + )
{
DXUTFontNode * pFontNode = m_FontCache . GetAt ( i ) ;
if ( 0 = = _strnicmp ( pFontNode - > strFace , strFaceName , MAX_PATH - 1 ) & &
pFontNode - > nHeight = = height & &
pFontNode - > nWeight = = weight )
{
return i ;
}
}
// Add a new font and try to create it
DXUTFontNode * pNewFontNode = new DXUTFontNode ( ) ;
if ( pNewFontNode = = NULL )
return - 1 ;
ZeroMemory ( pNewFontNode , sizeof ( DXUTFontNode ) ) ;
StringCchCopy ( pNewFontNode - > strFace , MAX_PATH , strFaceName ) ;
pNewFontNode - > nHeight = height ;
pNewFontNode - > nWeight = weight ;
m_FontCache . Add ( pNewFontNode ) ;
int iFont = m_FontCache . GetSize ( ) - 1 ;
// If a device is available, try to create immediately
if ( m_pd3dDevice )
CreateFont ( iFont ) ;
return iFont ;
}
2024-05-24 22:54:27 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-24 22:54:27 +08:00
HRESULT CDXUTDialog : : SetFont ( UINT index , LPCTSTR strFaceName , LONG height , LONG weight )
{
// If this assert triggers, you need to call CDXUTDialog::Init() first. This change
// was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The
// creation and interfacing with CDXUTDialogResourceManager is now the responsibility
// of the application if it wishes to use DXUT's GUI.
assert ( m_pManager ! = NULL & & " To fix call CDXUTDialog::Init() first. See comments for details. " ) ;
// Make sure the list is at least as large as the index being set
UINT i ;
for ( i = m_Fonts . GetSize ( ) ; i < = index ; i + + )
{
m_Fonts . Add ( - 1 ) ;
}
int iFont = m_pManager - > AddFont ( strFaceName , height , weight ) ;
m_Fonts . SetAt ( index , iFont ) ;
return S_OK ;
}
2024-05-24 22:55:03 +08:00
//--------------------------------------------------------------------------------------
DXUTFontNode * CDXUTDialog : : GetFont ( UINT index )
{
if ( NULL = = m_pManager )
return NULL ;
return m_pManager - > GetFontNode ( m_Fonts . GetAt ( index ) ) ;
}
2024-05-24 23:05:44 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
int CDXUTDialogResourceManager : : AddTexture ( LPCTSTR strFilename )
2024-05-24 23:05:44 +08:00
{
2024-07-21 23:13:14 +08:00
// See if this texture already exists
for ( int i = 0 ; i < m_TextureCache . GetSize ( ) ; i + + )
{
DXUTTextureNode * pTextureNode = m_TextureCache . GetAt ( i ) ;
if ( 0 = = _strnicmp ( pTextureNode - > strFilename , strFilename , MAX_PATH - 1 ) )
{
return i ;
}
}
2024-05-24 23:05:44 +08:00
2024-07-21 23:13:14 +08:00
// Add a new texture and try to create it
DXUTTextureNode * pNewTextureNode = new DXUTTextureNode ( ) ;
if ( pNewTextureNode = = NULL )
return - 1 ;
2024-05-24 23:05:44 +08:00
2024-07-21 23:13:14 +08:00
ZeroMemory ( pNewTextureNode , sizeof ( DXUTTextureNode ) ) ;
StringCchCopy ( pNewTextureNode - > strFilename , MAX_PATH , strFilename ) ;
m_TextureCache . Add ( pNewTextureNode ) ;
2024-05-24 23:05:44 +08:00
2024-07-21 23:13:14 +08:00
int iTexture = m_TextureCache . GetSize ( ) - 1 ;
2024-05-24 23:05:44 +08:00
2024-07-21 23:13:14 +08:00
// If a device is available, try to create immediately
if ( m_pd3dDevice )
CreateTexture ( iTexture ) ;
2024-05-24 23:05:44 +08:00
2024-07-21 23:13:14 +08:00
return iTexture ;
2024-05-24 23:05:44 +08:00
}
2024-05-24 23:06:24 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
HRESULT CDXUTDialog : : SetTexture ( UINT index , LPCTSTR strFilename )
2024-05-24 23:06:24 +08:00
{
2024-07-21 23:13:14 +08:00
// If this assert triggers, you need to call CDXUTDialog::Init() first. This change
// was made so that the DXUT's GUI could become seperate and optional from DXUT's core. The
// creation and interfacing with CDXUTDialogResourceManager is now the responsibility
// of the application if it wishes to use DXUT's GUI.
assert ( m_pManager ! = NULL & & " To fix call CDXUTDialog::Init() first. See comments for details. " ) ;
2024-05-24 23:06:24 +08:00
2024-07-21 23:13:14 +08:00
// Make sure the list is at least as large as the index being set
for ( UINT i = m_Textures . GetSize ( ) ; i < = index ; i + + )
2024-05-24 23:06:24 +08:00
{
2024-07-21 23:13:14 +08:00
m_Textures . Add ( - 1 ) ;
2024-05-24 23:06:24 +08:00
}
2024-07-21 23:13:14 +08:00
int iTexture = m_pManager - > AddTexture ( strFilename ) ;
m_Textures . SetAt ( index , iTexture ) ;
2024-05-24 23:06:24 +08:00
return S_OK ;
}
2024-05-24 23:07:39 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
DXUTTextureNode * CDXUTDialog : : GetTexture ( UINT index )
2024-05-24 23:07:39 +08:00
{
2024-07-21 23:13:14 +08:00
if ( NULL = = m_pManager )
return NULL ;
return m_pManager - > GetTextureNode ( m_Textures . GetAt ( index ) ) ;
}
//--------------------------------------------------------------------------------------
bool CDXUTDialog : : MsgProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
bool bHandled = false ;
//OutputDebugString("CDXUTDialog::MsgProc");
// For invisible dialog, do not handle anything.
if ( ! m_bVisible )
return false ;
// If automation command-line switch is on, enable this dialog's keyboard input
// upon any key press or mouse click.
if ( DXUTGetAutomation ( ) & &
( WM_LBUTTONDOWN = = uMsg | | WM_LBUTTONDBLCLK = = uMsg | | WM_KEYDOWN = = uMsg ) )
2024-05-24 23:07:39 +08:00
{
2024-07-21 23:13:14 +08:00
m_bKeyboardInput = true ;
}
2024-05-24 23:07:39 +08:00
2024-07-21 23:13:14 +08:00
// If caption is enable, check for clicks in the caption area.
if ( m_bCaption )
{
static bool bDrag ;
if ( uMsg = = WM_LBUTTONDOWN | | uMsg = = WM_LBUTTONDBLCLK )
2024-05-24 23:07:39 +08:00
{
2024-07-21 23:13:14 +08:00
POINT mousePoint = { short ( LOWORD ( lParam ) ) , short ( HIWORD ( lParam ) ) } ;
if ( mousePoint . x > = m_x & & mousePoint . x < m_x + m_width & &
mousePoint . y > = m_y & & mousePoint . y < m_y + m_nCaptionHeight )
{
bDrag = true ;
SetCapture ( DXUTGetHWND ( ) ) ;
return true ;
}
} else
if ( uMsg = = WM_LBUTTONUP & & bDrag )
{
POINT mousePoint = { short ( LOWORD ( lParam ) ) , short ( HIWORD ( lParam ) ) } ;
if ( mousePoint . x > = m_x & & mousePoint . x < m_x + m_width & &
mousePoint . y > = m_y & & mousePoint . y < m_y + m_nCaptionHeight )
{
ReleaseCapture ( ) ;
bDrag = false ;
m_bMinimized = ! m_bMinimized ;
return true ;
}
2024-05-24 23:07:39 +08:00
}
}
2024-07-21 23:13:14 +08:00
// If the dialog is minimized, don't send any messages to controls.
if ( m_bMinimized )
return false ;
// If a control is in focus, it belongs to this dialog, and it's enabled, then give
// it the first chance at handling the message.
if ( s_pControlFocus & &
s_pControlFocus - > m_pDialog = = this & &
s_pControlFocus - > GetEnabled ( ) )
{
// If the control MsgProc handles it, then we don't.
if ( s_pControlFocus - > MsgProc ( uMsg , wParam , lParam ) )
return true ;
}
switch ( uMsg )
{
case WM_SIZE :
case WM_MOVE :
{
// Handle sizing and moving messages so that in case the mouse cursor is moved out
// of an UI control because of the window adjustment, we can properly
// unhighlight the highlighted control.
POINT pt = { - 1 , - 1 } ;
OnMouseMove ( pt ) ;
break ;
}
case WM_ACTIVATEAPP :
// Call OnFocusIn()/OnFocusOut() of the control that currently has the focus
// as the application is activated/deactivated. This matches the Windows
// behavior.
if ( s_pControlFocus & &
s_pControlFocus - > m_pDialog = = this & &
s_pControlFocus - > GetEnabled ( ) )
{
if ( wParam )
s_pControlFocus - > OnFocusIn ( ) ;
else
s_pControlFocus - > OnFocusOut ( ) ;
}
break ;
// Keyboard messages
case WM_KEYDOWN :
case WM_SYSKEYDOWN :
case WM_KEYUP :
case WM_SYSKEYUP :
{
// If a control is in focus, it belongs to this dialog, and it's enabled, then give
// it the first chance at handling the message.
if ( s_pControlFocus & &
s_pControlFocus - > m_pDialog = = this & &
s_pControlFocus - > GetEnabled ( ) )
{
if ( s_pControlFocus - > HandleKeyboard ( uMsg , wParam , lParam ) )
return true ;
}
// Not yet handled, see if this matches a control's hotkey
// Activate the hotkey if the focus doesn't belong to an
// edit box.
if ( uMsg = = WM_KEYDOWN & & ( ! s_pControlFocus | |
( s_pControlFocus - > GetType ( ) ! = DXUT_CONTROL_EDITBOX
& & s_pControlFocus - > GetType ( ) ! = DXUT_CONTROL_IMEEDITBOX ) ) )
{
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
if ( pControl - > GetHotkey ( ) = = wParam )
{
pControl - > OnHotkey ( ) ;
return true ;
}
}
}
// Not yet handled, check for focus messages
if ( uMsg = = WM_KEYDOWN )
{
// If keyboard input is not enabled, this message should be ignored
if ( ! m_bKeyboardInput )
return false ;
switch ( wParam )
{
case VK_RIGHT :
case VK_DOWN :
if ( s_pControlFocus ! = NULL )
{
return OnCycleFocus ( true ) ;
}
break ;
case VK_LEFT :
case VK_UP :
if ( s_pControlFocus ! = NULL )
{
return OnCycleFocus ( false ) ;
}
break ;
case VK_TAB :
if ( s_pControlFocus = = NULL )
{
FocusDefaultControl ( ) ;
}
else
{
bool bShiftDown = ( ( GetAsyncKeyState ( VK_SHIFT ) & 0x8000 ) ! = 0 ) ;
return OnCycleFocus ( ! bShiftDown ) ;
}
return true ;
}
}
break ;
}
// Mouse messages
case WM_MOUSEMOVE :
case WM_LBUTTONDOWN :
case WM_LBUTTONUP :
case WM_MBUTTONDOWN :
case WM_MBUTTONUP :
case WM_RBUTTONDOWN :
case WM_RBUTTONUP :
case WM_XBUTTONDOWN :
case WM_XBUTTONUP :
case WM_LBUTTONDBLCLK :
case WM_MBUTTONDBLCLK :
case WM_RBUTTONDBLCLK :
case WM_MOUSEWHEEL :
{
OutputDebugString ( " CDXUTDialog::MsgProc(MOUSE) " ) ;
// If not accepting mouse input, return false to indicate the message should still
// be handled by the application (usually to move the camera).
if ( ! m_bMouseInput )
return false ;
POINT mousePoint = { short ( LOWORD ( lParam ) ) , short ( HIWORD ( lParam ) ) } ;
mousePoint . x - = m_x ;
mousePoint . y - = m_y ;
2024-05-24 23:07:39 +08:00
2024-07-21 23:13:14 +08:00
// If caption is enabled, offset the Y coordinate by the negative of its height.
if ( m_bCaption )
mousePoint . y - = m_nCaptionHeight ;
2024-05-24 23:07:39 +08:00
2024-07-21 23:13:14 +08:00
// If a control is in focus, it belongs to this dialog, and it's enabled, then give
// it the first chance at handling the message.
if ( s_pControlFocus & &
s_pControlFocus - > m_pDialog = = this & &
s_pControlFocus - > GetEnabled ( ) )
{
if ( s_pControlFocus - > HandleMouse ( uMsg , mousePoint , wParam , lParam ) )
return true ;
}
// Not yet handled, see if the mouse is over any controls
CDXUTControl * pControl = GetControlAtPoint ( mousePoint ) ;
if ( pControl ! = NULL & & pControl - > GetEnabled ( ) )
{
bHandled = pControl - > HandleMouse ( uMsg , mousePoint , wParam , lParam ) ;
if ( bHandled )
return true ;
}
else
{
// Mouse not over any controls in this dialog, if there was a control
// which had focus it just lost it
if ( uMsg = = WM_LBUTTONDOWN & &
s_pControlFocus & &
s_pControlFocus - > m_pDialog = = this )
{
s_pControlFocus - > OnFocusOut ( ) ;
s_pControlFocus = NULL ;
}
}
// Still not handled, hand this off to the dialog. Return false to indicate the
// message should still be handled by the application (usually to move the camera).
switch ( uMsg )
{
case WM_MOUSEMOVE :
OnMouseMove ( mousePoint ) ;
return false ;
}
break ;
}
}
return false ;
}
2024-05-24 23:07:39 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
CDXUTControl * CDXUTDialog : : GetControlAtPoint ( POINT pt )
2024-05-24 23:07:39 +08:00
{
2024-07-21 23:13:14 +08:00
// Search through all child controls for the first one which
// contains the mouse point
2024-05-24 23:07:39 +08:00
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
2024-07-21 23:13:14 +08:00
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
2024-05-24 23:07:39 +08:00
2024-07-21 23:13:14 +08:00
if ( pControl = = NULL )
{
continue ;
}
// We only return the current control if it is visible
// and enabled. Because GetControlAtPoint() is used to do mouse
// hittest, it makes sense to perform this filtering.
if ( pControl - > ContainsPoint ( pt ) & & pControl - > GetEnabled ( ) & & pControl - > GetVisible ( ) )
2024-05-24 23:07:39 +08:00
{
return pControl ;
}
}
return NULL ;
}
2024-07-21 23:13:14 +08:00
//--------------------------------------------------------------------------------------
bool CDXUTDialog : : GetControlEnabled ( int ID )
{
CDXUTControl * pControl = GetControl ( ID ) ;
if ( pControl = = NULL )
return false ;
return pControl - > GetEnabled ( ) ;
}
2024-05-24 23:07:39 +08:00
2024-05-24 23:09:12 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
void CDXUTDialog : : SetControlEnabled ( int ID , bool bEnabled )
2024-05-24 23:09:12 +08:00
{
2024-07-21 23:13:14 +08:00
CDXUTControl * pControl = GetControl ( ID ) ;
if ( pControl = = NULL )
return ;
2024-05-24 23:09:12 +08:00
2024-07-21 23:13:14 +08:00
pControl - > SetEnabled ( bEnabled ) ;
2024-05-24 23:09:12 +08:00
}
2024-07-21 23:13:14 +08:00
2024-05-24 23:12:04 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
void CDXUTDialog : : OnMouseUp ( POINT pt )
2024-05-24 23:12:04 +08:00
{
2024-07-21 23:13:14 +08:00
s_pControlPressed = NULL ;
m_pControlMouseOver = NULL ;
}
2024-05-24 23:12:04 +08:00
2024-07-21 23:13:14 +08:00
//--------------------------------------------------------------------------------------
void CDXUTDialog : : OnMouseMove ( POINT pt )
{
// Figure out which control the mouse is over now
CDXUTControl * pControl = GetControlAtPoint ( pt ) ;
// If the mouse is still over the same control, nothing needs to be done
if ( pControl = = m_pControlMouseOver )
return ;
// Handle mouse leaving the old control
if ( m_pControlMouseOver )
m_pControlMouseOver - > OnMouseLeave ( ) ;
// Handle mouse entering the new control
m_pControlMouseOver = pControl ;
if ( pControl ! = NULL )
m_pControlMouseOver - > OnMouseEnter ( ) ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : SetDefaultElement ( UINT nControlType , UINT iElement , CDXUTElement * pElement )
{
// If this Element type already exist in the list, simply update the stored Element
for ( int i = 0 ; i < m_DefaultElements . GetSize ( ) ; i + + )
2024-05-24 23:12:04 +08:00
{
2024-07-21 23:13:14 +08:00
DXUTElementHolder * pElementHolder = m_DefaultElements . GetAt ( i ) ;
if ( pElementHolder - > nControlType = = nControlType & &
pElementHolder - > iElement = = iElement )
{
pElementHolder - > Element = * pElement ;
return S_OK ;
}
}
2024-05-24 23:12:04 +08:00
2024-07-21 23:13:14 +08:00
// Otherwise, add a new entry
DXUTElementHolder * pNewHolder ;
pNewHolder = new DXUTElementHolder ;
if ( pNewHolder = = NULL )
return E_OUTOFMEMORY ;
pNewHolder - > nControlType = nControlType ;
pNewHolder - > iElement = iElement ;
pNewHolder - > Element = * pElement ;
m_DefaultElements . Add ( pNewHolder ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
CDXUTElement * CDXUTDialog : : GetDefaultElement ( UINT nControlType , UINT iElement )
{
for ( int i = 0 ; i < m_DefaultElements . GetSize ( ) ; i + + )
{
DXUTElementHolder * pElementHolder = m_DefaultElements . GetAt ( i ) ;
if ( pElementHolder - > nControlType = = nControlType & &
pElementHolder - > iElement = = iElement )
{
return & pElementHolder - > Element ;
}
2024-05-24 23:12:04 +08:00
}
2024-07-21 23:13:14 +08:00
return NULL ;
2024-05-24 23:12:04 +08:00
}
2024-07-21 23:13:14 +08:00
2024-05-15 22:52:08 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
HRESULT CDXUTDialog : : AddStatic ( int ID , LPCTSTR strText , int x , int y , int width , int height , bool bIsDefault , CDXUTStatic * * ppCreated )
{
HRESULT hr = S_OK ;
CDXUTStatic * pStatic = new CDXUTStatic ( this ) ;
if ( ppCreated ! = NULL )
* ppCreated = pStatic ;
if ( pStatic = = NULL )
return E_OUTOFMEMORY ;
hr = AddControl ( pStatic ) ;
if ( FAILED ( hr ) )
return hr ;
// Set the ID and list index
pStatic - > SetID ( ID ) ;
pStatic - > SetText ( strText ) ;
pStatic - > SetLocation ( x , y ) ;
pStatic - > SetSize ( width , height ) ;
pStatic - > m_bIsDefault = bIsDefault ;
return S_OK ;
}
2024-05-15 22:52:08 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
HRESULT CDXUTDialog : : AddButton ( int ID , LPCTSTR strText , int x , int y , int width , int height , UINT nHotkey , bool bIsDefault , CDXUTButton * * ppCreated )
{
HRESULT hr = S_OK ;
CDXUTButton * pButton = new CDXUTButton ( this ) ;
if ( ppCreated ! = NULL )
* ppCreated = pButton ;
if ( pButton = = NULL )
return E_OUTOFMEMORY ;
hr = AddControl ( pButton ) ;
if ( FAILED ( hr ) )
return hr ;
// Set the ID and list index
pButton - > SetID ( ID ) ;
pButton - > SetText ( strText ) ;
pButton - > SetLocation ( x , y ) ;
pButton - > SetSize ( width , height ) ;
pButton - > SetHotkey ( nHotkey ) ;
pButton - > m_bIsDefault = bIsDefault ;
return S_OK ;
}
2024-05-15 22:52:08 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
HRESULT CDXUTDialog : : AddCheckBox ( int ID , LPCTSTR strText , int x , int y , int width , int height , bool bChecked , UINT nHotkey , bool bIsDefault , CDXUTCheckBox * * ppCreated )
2024-05-15 22:52:08 +08:00
{
2024-07-21 23:13:14 +08:00
HRESULT hr = S_OK ;
2024-05-15 22:52:08 +08:00
2024-07-21 23:13:14 +08:00
CDXUTCheckBox * pCheckBox = new CDXUTCheckBox ( this ) ;
2024-05-15 22:52:08 +08:00
2024-07-21 23:13:14 +08:00
if ( ppCreated ! = NULL )
* ppCreated = pCheckBox ;
2024-05-15 22:52:08 +08:00
2024-07-21 23:13:14 +08:00
if ( pCheckBox = = NULL )
return E_OUTOFMEMORY ;
2024-05-15 22:52:08 +08:00
2024-07-21 23:13:14 +08:00
hr = AddControl ( pCheckBox ) ;
if ( FAILED ( hr ) )
return hr ;
// Set the ID and list index
pCheckBox - > SetID ( ID ) ;
pCheckBox - > SetText ( strText ) ;
pCheckBox - > SetLocation ( x , y ) ;
pCheckBox - > SetSize ( width , height ) ;
pCheckBox - > SetHotkey ( nHotkey ) ;
pCheckBox - > m_bIsDefault = bIsDefault ;
pCheckBox - > SetChecked ( bChecked ) ;
return S_OK ;
2024-05-15 22:52:08 +08:00
}
2024-07-21 23:13:14 +08:00
2024-05-16 22:23:43 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
HRESULT CDXUTDialog : : AddRadioButton ( int ID , UINT nButtonGroup , LPCTSTR strText , int x , int y , int width , int height , bool bChecked , UINT nHotkey , bool bIsDefault , CDXUTRadioButton * * ppCreated )
{
HRESULT hr = S_OK ;
CDXUTRadioButton * pRadioButton = new CDXUTRadioButton ( this ) ;
if ( ppCreated ! = NULL )
* ppCreated = pRadioButton ;
if ( pRadioButton = = NULL )
return E_OUTOFMEMORY ;
hr = AddControl ( pRadioButton ) ;
if ( FAILED ( hr ) )
return hr ;
// Set the ID and list index
pRadioButton - > SetID ( ID ) ;
pRadioButton - > SetText ( strText ) ;
pRadioButton - > SetButtonGroup ( nButtonGroup ) ;
pRadioButton - > SetLocation ( x , y ) ;
pRadioButton - > SetSize ( width , height ) ;
pRadioButton - > SetHotkey ( nHotkey ) ;
pRadioButton - > SetChecked ( bChecked ) ;
pRadioButton - > m_bIsDefault = bIsDefault ;
pRadioButton - > SetChecked ( bChecked ) ;
return S_OK ;
}
2024-05-16 22:23:43 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
HRESULT CDXUTDialog : : AddComboBox ( int ID , int x , int y , int width , int height , UINT nHotkey , bool bIsDefault , CDXUTComboBox * * ppCreated )
{
HRESULT hr = S_OK ;
CDXUTComboBox * pComboBox = new CDXUTComboBox ( this ) ;
if ( ppCreated ! = NULL )
* ppCreated = pComboBox ;
if ( pComboBox = = NULL )
return E_OUTOFMEMORY ;
hr = AddControl ( pComboBox ) ;
if ( FAILED ( hr ) )
return hr ;
// Set the ID and list index
pComboBox - > SetID ( ID ) ;
pComboBox - > SetLocation ( x , y ) ;
pComboBox - > SetSize ( width , height ) ;
pComboBox - > SetHotkey ( nHotkey ) ;
pComboBox - > m_bIsDefault = bIsDefault ;
return S_OK ;
}
2024-05-16 22:23:43 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
HRESULT CDXUTDialog : : AddSlider ( int ID , int x , int y , int width , int height , int min , int max , int value , bool bIsDefault , CDXUTSlider * * ppCreated )
2024-05-16 22:23:43 +08:00
{
2024-07-21 23:13:14 +08:00
HRESULT hr = S_OK ;
CDXUTSlider * pSlider = new CDXUTSlider ( this ) ;
if ( ppCreated ! = NULL )
* ppCreated = pSlider ;
if ( pSlider = = NULL )
return E_OUTOFMEMORY ;
hr = AddControl ( pSlider ) ;
if ( FAILED ( hr ) )
return hr ;
// Set the ID and list index
pSlider - > SetID ( ID ) ;
pSlider - > SetLocation ( x , y ) ;
pSlider - > SetSize ( width , height ) ;
pSlider - > m_bIsDefault = bIsDefault ;
pSlider - > SetRange ( min , max ) ;
pSlider - > SetValue ( value ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : AddEditBox ( int ID , LPCTSTR strText , int x , int y , int width , int height , bool bIsDefault , CDXUTEditBox * * ppCreated )
{
HRESULT hr = S_OK ;
CDXUTEditBox * pEditBox = new CDXUTEditBox ( this ) ;
if ( ppCreated ! = NULL )
* ppCreated = pEditBox ;
if ( pEditBox = = NULL )
return E_OUTOFMEMORY ;
hr = AddControl ( pEditBox ) ;
if ( FAILED ( hr ) )
return hr ;
// Set the ID and position
pEditBox - > SetID ( ID ) ;
pEditBox - > SetLocation ( x , y ) ;
pEditBox - > SetSize ( width , height ) ;
pEditBox - > m_bIsDefault = bIsDefault ;
if ( strText )
pEditBox - > SetText ( strText ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : AddIMEEditBox ( int ID , LPCTSTR strText , int x , int y , int width , int height , bool bIsDefault , CDXUTIMEEditBox * * ppCreated )
{
HRESULT hr = S_OK ;
CDXUTIMEEditBox * pEditBox = new CDXUTIMEEditBox ( this ) ;
if ( ppCreated ! = NULL )
* ppCreated = pEditBox ;
if ( pEditBox = = NULL )
return E_OUTOFMEMORY ;
hr = AddControl ( pEditBox ) ;
if ( FAILED ( hr ) )
return hr ;
// Set the ID and position
pEditBox - > SetID ( ID ) ;
pEditBox - > SetLocation ( x , y ) ;
pEditBox - > SetSize ( width , height ) ;
pEditBox - > m_bIsDefault = bIsDefault ;
if ( strText )
pEditBox - > SetText ( strText ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : AddListBox ( int ID , int x , int y , int width , int height , DWORD dwStyle , CDXUTListBox * * ppCreated )
{
HRESULT hr = S_OK ;
CDXUTListBox * pListBox = new CDXUTListBox ( this ) ;
if ( ppCreated ! = NULL )
* ppCreated = pListBox ;
if ( pListBox = = NULL )
return E_OUTOFMEMORY ;
hr = AddControl ( pListBox ) ;
if ( FAILED ( hr ) )
return hr ;
// Set the ID and position
pListBox - > SetID ( ID ) ;
pListBox - > SetLocation ( x , y ) ;
pListBox - > SetSize ( width , height ) ;
pListBox - > SetStyle ( dwStyle ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
// MATCH
HRESULT CDXUTDialog : : InitControl ( CDXUTControl * pControl )
{
HRESULT hr ;
if ( pControl = = NULL )
2024-05-16 22:23:43 +08:00
return E_INVALIDARG ;
2024-07-21 23:13:14 +08:00
pControl - > m_Index = m_Controls . GetSize ( ) ;
// Look for a default Element entries
for ( int i = 0 ; i < m_DefaultElements . GetSize ( ) ; i + + )
{
DXUTElementHolder * pElementHolder = m_DefaultElements . GetAt ( i ) ;
if ( pElementHolder - > nControlType = = pControl - > GetType ( ) )
pControl - > SetElement ( pElementHolder - > iElement , & pElementHolder - > Element ) ;
2024-05-16 22:23:43 +08:00
}
2024-07-21 23:13:14 +08:00
V_RETURN ( pControl - > OnInit ( ) ) ;
2024-05-16 22:23:43 +08:00
return S_OK ;
}
2024-05-18 22:59:21 +08:00
2024-07-21 23:13:14 +08:00
2024-05-18 22:59:21 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
HRESULT CDXUTDialog : : AddControl ( CDXUTControl * pControl )
{
HRESULT hr = S_OK ;
hr = InitControl ( pControl ) ;
if ( FAILED ( hr ) )
return DXTRACE_ERR ( " CDXUTDialog::InitControl " , hr ) ;
// Add to the list
hr = m_Controls . Add ( pControl ) ;
if ( FAILED ( hr ) )
{
return DXTRACE_ERR ( " CGrowableArray::Add " , hr ) ;
}
return S_OK ;
}
2024-05-18 22:59:21 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
CDXUTControl * CDXUTDialog : : GetControl ( int ID )
{
// Try to find the control with the given ID
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
if ( pControl - > GetID ( ) = = ID )
{
return pControl ;
}
}
// Not found
return NULL ;
}
2024-05-18 22:59:21 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
CDXUTControl * CDXUTDialog : : GetControl ( int ID , UINT nControlType )
2024-05-18 22:59:21 +08:00
{
2024-07-21 23:13:14 +08:00
// Try to find the control with the given ID
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
if ( pControl - > GetID ( ) = = ID & & pControl - > GetType ( ) = = nControlType )
{
return pControl ;
}
}
// Not found
return NULL ;
}
//--------------------------------------------------------------------------------------
CDXUTControl * CDXUTDialog : : GetNextControl ( CDXUTControl * pControl )
{
int index = pControl - > m_Index + 1 ;
CDXUTDialog * pDialog = pControl - > m_pDialog ;
// Cycle through dialogs in the loop to find the next control. Note
// that if only one control exists in all looped dialogs it will
// be the returned 'next' control.
while ( index > = ( int ) pDialog - > m_Controls . GetSize ( ) )
{
pDialog = pDialog - > m_pNextDialog ;
index = 0 ;
}
return pDialog - > m_Controls . GetAt ( index ) ;
}
//--------------------------------------------------------------------------------------
CDXUTControl * CDXUTDialog : : GetPrevControl ( CDXUTControl * pControl )
{
int index = pControl - > m_Index - 1 ;
CDXUTDialog * pDialog = pControl - > m_pDialog ;
// Cycle through dialogs in the loop to find the next control. Note
// that if only one control exists in all looped dialogs it will
// be the returned 'previous' control.
while ( index < 0 )
{
pDialog = pDialog - > m_pPrevDialog ;
if ( pDialog = = NULL )
pDialog = pControl - > m_pDialog ;
index = pDialog - > m_Controls . GetSize ( ) - 1 ;
}
return pDialog - > m_Controls . GetAt ( index ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTDialog : : ClearRadioButtonGroup ( UINT nButtonGroup )
{
// Find all radio buttons with the given group number
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
if ( pControl - > GetType ( ) = = DXUT_CONTROL_RADIOBUTTON )
{
CDXUTRadioButton * pRadioButton = ( CDXUTRadioButton * ) pControl ;
if ( pRadioButton - > GetButtonGroup ( ) = = nButtonGroup )
pRadioButton - > SetChecked ( false , false ) ;
}
}
}
//--------------------------------------------------------------------------------------
// MATCH
void CDXUTDialog : : ClearComboBox ( int ID )
{
CDXUTComboBox * pComboBox = GetComboBox ( ID ) ;
if ( pComboBox = = NULL )
return ;
pComboBox - > RemoveAllItems ( ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTDialog : : RequestFocus ( CDXUTControl * pControl )
{
if ( s_pControlFocus = = pControl )
return ;
if ( ! pControl - > CanHaveFocus ( ) )
return ;
if ( s_pControlFocus )
s_pControlFocus - > OnFocusOut ( ) ;
pControl - > OnFocusIn ( ) ;
s_pControlFocus = pControl ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : DrawRect ( RECT * pRect , D3DCOLOR color )
{
RECT rcScreen = * pRect ;
OffsetRect ( & rcScreen , m_x , m_y ) ;
// If caption is enabled, offset the Y position by its height.
if ( m_bCaption )
OffsetRect ( & rcScreen , 0 , m_nCaptionHeight ) ;
DXUT_SCREEN_VERTEX vertices [ 4 ] =
{
( float ) rcScreen . left - 0.5f , ( float ) rcScreen . top - 0.5f , 0.5f , 1.0f , color , 0 , 0 ,
( float ) rcScreen . right - 0.5f , ( float ) rcScreen . top - 0.5f , 0.5f , 1.0f , color , 0 , 0 ,
( float ) rcScreen . right - 0.5f , ( float ) rcScreen . bottom - 0.5f , 0.5f , 1.0f , color , 0 , 0 ,
( float ) rcScreen . left - 0.5f , ( float ) rcScreen . bottom - 0.5f , 0.5f , 1.0f , color , 0 , 0 ,
} ;
IDirect3DDevice9 * pd3dDevice = m_pManager - > GetD3DDevice ( ) ;
// Since we're doing our own drawing here we need to flush the sprites
m_pManager - > m_pSprite - > Flush ( ) ;
IDirect3DVertexDeclaration9 * pDecl = NULL ;
pd3dDevice - > GetVertexDeclaration ( & pDecl ) ; // Preserve the sprite's current vertex decl
pd3dDevice - > SetFVF ( DXUT_SCREEN_VERTEX : : FVF ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLOROP , D3DTOP_SELECTARG2 ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAOP , D3DTOP_SELECTARG2 ) ;
pd3dDevice - > DrawPrimitiveUP ( D3DPT_TRIANGLEFAN , 2 , vertices , sizeof ( DXUT_SCREEN_VERTEX ) ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLOROP , D3DTOP_MODULATE ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAOP , D3DTOP_MODULATE ) ;
// Restore the vertex decl
pd3dDevice - > SetVertexDeclaration ( pDecl ) ;
pDecl - > Release ( ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : DrawPolyLine ( POINT * apPoints , UINT nNumPoints , D3DCOLOR color )
{
DXUT_SCREEN_VERTEX * vertices = new DXUT_SCREEN_VERTEX [ nNumPoints ] ;
if ( vertices = = NULL )
return E_OUTOFMEMORY ;
DXUT_SCREEN_VERTEX * pVertex = vertices ;
POINT * pt = apPoints ;
for ( UINT i = 0 ; i < nNumPoints ; i + + )
{
pVertex - > x = m_x + ( float ) pt - > x ;
pVertex - > y = m_y + ( float ) pt - > y ;
pVertex - > z = 0.5f ;
pVertex - > h = 1.0f ;
pVertex - > color = color ;
pVertex - > tu = 0.0f ;
pVertex - > tv = 0.0f ;
pVertex + + ;
pt + + ;
}
IDirect3DDevice9 * pd3dDevice = m_pManager - > GetD3DDevice ( ) ;
// Since we're doing our own drawing here we need to flush the sprites
m_pManager - > m_pSprite - > Flush ( ) ;
IDirect3DVertexDeclaration9 * pDecl = NULL ;
pd3dDevice - > GetVertexDeclaration ( & pDecl ) ; // Preserve the sprite's current vertex decl
pd3dDevice - > SetFVF ( DXUT_SCREEN_VERTEX : : FVF ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLOROP , D3DTOP_SELECTARG2 ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAOP , D3DTOP_SELECTARG2 ) ;
pd3dDevice - > DrawPrimitiveUP ( D3DPT_LINESTRIP , nNumPoints - 1 , vertices , sizeof ( DXUT_SCREEN_VERTEX ) ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_COLOROP , D3DTOP_MODULATE ) ;
pd3dDevice - > SetTextureStageState ( 0 , D3DTSS_ALPHAOP , D3DTOP_MODULATE ) ;
// Restore the vertex decl
pd3dDevice - > SetVertexDeclaration ( pDecl ) ;
pDecl - > Release ( ) ;
SAFE_DELETE_ARRAY ( vertices ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : DrawSprite ( CDXUTElement * pElement , RECT * prcDest )
{
// No need to draw fully transparent layers
if ( pElement - > TextureColor . Current . a = = 0 )
return S_OK ;
RECT rcTexture = pElement - > rcTexture ;
RECT rcScreen = * prcDest ;
OffsetRect ( & rcScreen , m_x , m_y ) ;
// If caption is enabled, offset the Y position by its height.
if ( m_bCaption )
OffsetRect ( & rcScreen , 0 , m_nCaptionHeight ) ;
DXUTTextureNode * pTextureNode = GetTexture ( pElement - > iTexture ) ;
if ( pTextureNode = = NULL )
return E_FAIL ;
float fScaleX = ( float ) RectWidth ( rcScreen ) / RectWidth ( rcTexture ) ;
float fScaleY = ( float ) RectHeight ( rcScreen ) / RectHeight ( rcTexture ) ;
D3DXMATRIXA16 matTransform ;
D3DXMatrixScaling ( & matTransform , fScaleX , fScaleY , 1.0f ) ;
m_pManager - > m_pSprite - > SetTransform ( & matTransform ) ;
D3DXVECTOR3 vPos ( ( float ) rcScreen . left , ( float ) rcScreen . top , 0.0f ) ;
vPos . x / = fScaleX ;
vPos . y / = fScaleY ;
return m_pManager - > m_pSprite - > Draw ( pTextureNode - > pTexture , & rcTexture , NULL , & vPos , pElement - > TextureColor . Current ) ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : CalcTextRect ( LPCTSTR strText , CDXUTElement * pElement , RECT * prcDest , int nCount )
{
HRESULT hr = S_OK ;
DXUTFontNode * pFontNode = GetFont ( pElement - > iFont ) ;
if ( pFontNode = = NULL )
return E_FAIL ;
DWORD dwTextFormat = pElement - > dwTextFormat | DT_CALCRECT ;
// Since we are only computing the rectangle, we don't need a sprite.
hr = pFontNode - > pFont - > DrawText ( NULL , strText , nCount , prcDest , dwTextFormat , pElement - > FontColor . Current ) ;
if ( FAILED ( hr ) )
return hr ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialog : : CalcTextRect ( LPCWSTR strText , CDXUTElement * pElement , RECT * prcDest , int nCount )
{
HRESULT hr = S_OK ;
DXUTFontNode * pFontNode = GetFont ( pElement - > iFont ) ;
if ( pFontNode = = NULL )
return E_FAIL ;
DWORD dwTextFormat = pElement - > dwTextFormat | DT_CALCRECT ;
// Since we are only computing the rectangle, we don't need a sprite.
hr = pFontNode - > pFont - > DrawTextW ( NULL , strText , nCount , prcDest , dwTextFormat , pElement - > FontColor . Current ) ;
if ( FAILED ( hr ) )
return hr ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
// MATCH
HRESULT CDXUTDialog : : DrawText ( LPCTSTR strText , CDXUTElement * pElement , RECT * prcDest , bool bShadow , int nCount )
{
HRESULT hr = S_OK ;
// No need to draw fully transparent layers
if ( pElement - > FontColor . Current . a = = 0 )
return S_OK ;
RECT rcScreen = * prcDest ;
OffsetRect ( & rcScreen , m_x , m_y ) ;
// If caption is enabled, offset the Y position by its height.
if ( m_bCaption )
OffsetRect ( & rcScreen , 0 , m_nCaptionHeight ) ;
//debug
//DrawRect( &rcScreen, D3DCOLOR_ARGB(100, 255, 0, 0) );
D3DXMATRIXA16 matTransform ;
D3DXMatrixIdentity ( & matTransform ) ;
m_pManager - > m_pSprite - > SetTransform ( & matTransform ) ;
DXUTFontNode * pFontNode = GetFont ( pElement - > iFont ) ;
if ( bShadow )
{
RECT rcShadow = rcScreen ;
OffsetRect ( & rcShadow , 1 , 1 ) ;
if ( pFontNode - > pFont ) {
hr = pFontNode - > pFont - > DrawText ( m_pManager - > m_pSprite , strText , nCount , & rcShadow , pElement - > dwTextFormat , D3DCOLOR_ARGB ( DWORD ( pElement - > FontColor . Current . a * 255 ) , 0 , 0 , 0 ) ) ;
} else {
m_pManager - > CreateFont ( pElement - > iFont ) ;
}
if ( FAILED ( hr ) )
return hr ;
}
if ( pFontNode - > pFont ) {
hr = pFontNode - > pFont - > DrawText ( m_pManager - > m_pSprite , strText , nCount , & rcScreen , pElement - > dwTextFormat , pElement - > FontColor . Current ) ;
} else {
m_pManager - > CreateFont ( pElement - > iFont ) ;
}
if ( FAILED ( hr ) )
return hr ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
// MATCH
HRESULT CDXUTDialog : : DrawText ( LPCWSTR strText , CDXUTElement * pElement , RECT * prcDest , bool bShadow , int nCount )
{
HRESULT hr = S_OK ;
// No need to draw fully transparent layers
if ( pElement - > FontColor . Current . a = = 0 )
return S_OK ;
RECT rcScreen = * prcDest ;
OffsetRect ( & rcScreen , m_x , m_y ) ;
// If caption is enabled, offset the Y position by its height.
if ( m_bCaption )
OffsetRect ( & rcScreen , 0 , m_nCaptionHeight ) ;
//debug
//DrawRect( &rcScreen, D3DCOLOR_ARGB(100, 255, 0, 0) );
D3DXMATRIXA16 matTransform ;
D3DXMatrixIdentity ( & matTransform ) ;
m_pManager - > m_pSprite - > SetTransform ( & matTransform ) ;
DXUTFontNode * pFontNode = GetFont ( pElement - > iFont ) ;
if ( bShadow )
{
RECT rcShadow = rcScreen ;
OffsetRect ( & rcShadow , 1 , 1 ) ;
if ( pFontNode - > pFont ) {
hr = pFontNode - > pFont - > DrawTextW ( m_pManager - > m_pSprite , strText , nCount , & rcShadow , pElement - > dwTextFormat , D3DCOLOR_ARGB ( DWORD ( pElement - > FontColor . Current . a * 255 ) , 0 , 0 , 0 ) ) ;
} else {
m_pManager - > CreateFont ( pElement - > iFont ) ;
}
if ( FAILED ( hr ) )
return hr ;
}
if ( pFontNode - > pFont ) {
hr = pFontNode - > pFont - > DrawTextW ( m_pManager - > m_pSprite , strText , nCount , & rcScreen , pElement - > dwTextFormat , pElement - > FontColor . Current ) ;
} else {
m_pManager - > CreateFont ( pElement - > iFont ) ;
}
if ( FAILED ( hr ) )
return hr ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
void CDXUTDialog : : SetBackgroundColors ( D3DCOLOR colorTopLeft , D3DCOLOR colorTopRight , D3DCOLOR colorBottomLeft , D3DCOLOR colorBottomRight )
{
m_colorTopLeft = colorTopLeft ;
m_colorTopRight = colorTopRight ;
m_colorBottomLeft = colorBottomLeft ;
m_colorBottomRight = colorBottomRight ;
}
//--------------------------------------------------------------------------------------
void CDXUTDialog : : SetNextDialog ( CDXUTDialog * pNextDialog )
{
if ( pNextDialog = = NULL )
pNextDialog = this ;
m_pNextDialog = pNextDialog ;
m_pNextDialog - > m_pPrevDialog = this ;
}
//--------------------------------------------------------------------------------------
void CDXUTDialog : : ClearFocus ( )
{
if ( s_pControlFocus )
{
s_pControlFocus - > OnFocusOut ( ) ;
s_pControlFocus = NULL ;
}
ReleaseCapture ( ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTDialog : : FocusDefaultControl ( )
{
// Check for default control in this dialog
for ( int i = 0 ; i < m_Controls . GetSize ( ) ; i + + )
{
CDXUTControl * pControl = m_Controls . GetAt ( i ) ;
if ( pControl - > m_bIsDefault )
{
// Remove focus from the current control
ClearFocus ( ) ;
// Give focus to the default control
s_pControlFocus = pControl ;
s_pControlFocus - > OnFocusIn ( ) ;
return ;
}
}
}
//--------------------------------------------------------------------------------------
bool CDXUTDialog : : OnCycleFocus ( bool bForward )
{
// This should only be handled by the dialog which owns the focused control, and
// only if a control currently has focus
if ( s_pControlFocus = = NULL | | s_pControlFocus - > m_pDialog ! = this )
return false ;
CDXUTControl * pControl = s_pControlFocus ;
for ( int i = 0 ; i < 0xffff ; i + + )
{
pControl = ( bForward ) ? GetNextControl ( pControl ) : GetPrevControl ( pControl ) ;
// If we've gone in a full circle then focus doesn't change
if ( pControl = = s_pControlFocus )
return true ;
// If the dialog accepts keybord input and the control can have focus then
// move focus
if ( pControl - > m_pDialog - > m_bKeyboardInput & & pControl - > CanHaveFocus ( ) )
{
s_pControlFocus - > OnFocusOut ( ) ;
s_pControlFocus = pControl ;
s_pControlFocus - > OnFocusIn ( ) ;
return true ;
}
}
// If we reached this point, the chain of dialogs didn't form a complete loop
DXTRACE_ERR ( " CDXUTDialog: Multiple dialogs are improperly chained together " , E_FAIL ) ;
return false ;
}
//--------------------------------------------------------------------------------------
// MATCH
HRESULT CDXUTDialogResourceManager : : CreateFont ( UINT iFont )
{
HRESULT hr = S_OK ;
DXUTFontNode * pFontNode = m_FontCache . GetAt ( iFont ) ;
SAFE_RELEASE ( pFontNode - > pFont ) ;
D3DXCreateFont ( m_pd3dDevice , pFontNode - > nHeight , 0 , pFontNode - > nWeight , 1 , FALSE , DEFAULT_CHARSET ,
OUT_DEFAULT_PRECIS , DEFAULT_QUALITY , DEFAULT_PITCH | FF_DONTCARE ,
pFontNode - > strFace , & pFontNode - > pFont ) ;
ID3DXFontHook * pFontHook = new ID3DXFontHook ;
pFontHook - > m_pD3DFont = pFontNode - > pFont ;
pFontNode - > pFont = ( ID3DXFont * ) pFontHook ;
char szDebug [ 260 ] ;
sprintf ( szDebug , " CDXUTDialogResourceManager::CreateFont(pFont=0x%X,pD3DDevice=0x%X) " , pFontNode - > pFont , m_pd3dDevice ) ;
//OutputDebugString(szDebug);
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDialogResourceManager : : CreateTexture ( UINT iTexture )
{
HRESULT hr = S_OK ;
DXUTTextureNode * pTextureNode = m_TextureCache . GetAt ( iTexture ) ;
//_ASSERT(pTextureNode->strFilename[0] == 0);
// Make sure there's a texture to create
if ( pTextureNode - > strFilename [ 0 ] = = 0 )
{
//OutputDebugString("CDXUTDialogResourceManager::CreateTexture(BAD_TEXFILE)");
return S_OK ;
}
// Find the texture on the hard drive
TCHAR strPath [ MAX_PATH ] ;
hr = DXUTFindDXSDKMediaFileCch ( strPath , MAX_PATH , pTextureNode - > strFilename ) ;
if ( FAILED ( hr ) )
{
return DXTRACE_ERR ( " DXUTFindDXSDKMediaFileCch " , hr ) ;
}
// Create texture
D3DXIMAGE_INFO info ;
hr = D3DXCreateTextureFromFileEx ( m_pd3dDevice , strPath , D3DX_DEFAULT , D3DX_DEFAULT ,
D3DX_DEFAULT , 0 , D3DFMT_UNKNOWN , D3DPOOL_MANAGED ,
D3DX_DEFAULT , D3DX_DEFAULT , 0 ,
& info , NULL , & pTextureNode - > pTexture ) ;
if ( FAILED ( hr ) )
{
return DXTRACE_ERR ( " D3DXCreateTextureFromFileEx " , hr ) ;
}
// Store dimensions
pTextureNode - > dwWidth = info . Width ;
pTextureNode - > dwHeight = info . Height ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
int GetUIFontSize ( ) ;
int GetFontWeight ( ) ;
char * GetFontFace ( ) ;
// MATCH
void CDXUTDialog : : UpdateFont ( )
{
int nFontSize = GetUIFontSize ( ) ;
int nFontWeight = GetFontWeight ( ) ;
SetFont ( 0 , GetFontFace ( ) , nFontSize , nFontWeight ) ;
SetFont ( 1 , GetFontFace ( ) , nFontSize - 2 , nFontWeight ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTDialog : : InitDefaultElements ( )
{
//SetTexture( 0, "DXUTControls.dds" );
SetTexture ( 0 , " sampgui.png " ) ;
//SetFont( 0, "Arial", 16, FW_BOLD );
UpdateFont ( ) ;
CDXUTElement Element ;
RECT rcTexture ;
//-------------------------------------
// Element for the caption
//-------------------------------------
m_CapElement . SetFont ( 1 ) ;
SetRect ( & rcTexture , 17 , 269 , 241 , 287 ) ;
m_CapElement . SetTexture ( 0 , & rcTexture ) ;
m_CapElement . TextureColor . States [ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB ( 200 , 10 , 10 , 10 ) ;
m_CapElement . FontColor . States [ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB ( 255 , 210 , 210 , 210 ) ;
m_CapElement . SetFont ( 1 , D3DCOLOR_ARGB ( 255 , 210 , 210 , 210 ) , DT_LEFT | DT_VCENTER ) ;
// Pre-blend as we don't need to transition the state
m_CapElement . TextureColor . Blend ( DXUT_STATE_NORMAL , 10.0f ) ;
m_CapElement . FontColor . Blend ( DXUT_STATE_NORMAL , 10.0f ) ;
//-------------------------------------
// CDXUTStatic
//-------------------------------------
Element . SetFont ( 1 ) ;
Element . SetFont ( 1 , D3DCOLOR_ARGB ( 255 , 190 , 190 , 190 ) , DT_VCENTER | DT_EXPANDTABS ) ;
Element . FontColor . States [ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB ( 200 , 200 , 200 , 200 ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_STATIC , 0 , & Element ) ;
//-------------------------------------
// CDXUTButton - Button
//-------------------------------------
SetRect ( & rcTexture , 0 , 0 , 136 , 54 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . SetFont ( 0 ) ;
Element . TextureColor . States [ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB ( 200 , 255 , 255 , 255 ) ;
Element . TextureColor . States [ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB ( 255 , 149 , 176 , 208 ) ;
Element . TextureColor . States [ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB ( 255 , 185 , 34 , 40 ) ;
Element . FontColor . States [ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
Element . FontColor . States [ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB ( 255 , 200 , 200 , 200 ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_BUTTON , 0 , & Element ) ;
//-------------------------------------
// CDXUTButton - Fill layer
//-------------------------------------
SetRect ( & rcTexture , 0 , 0 , 136 , 54 ) ;
Element . SetTexture ( 0 , & rcTexture , D3DCOLOR_ARGB ( 0 , 255 , 255 , 255 ) ) ;
Element . TextureColor . States [ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB ( 255 , 185 , 34 , 40 ) ;
Element . TextureColor . States [ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB ( 60 , 80 , 80 , 80 ) ;
Element . TextureColor . States [ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB ( 200 , 255 , 255 , 255 ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_BUTTON , 1 , & Element ) ;
//-------------------------------------
// CDXUTCheckBox - Box
//-------------------------------------
SetRect ( & rcTexture , 0 , 54 , 27 , 81 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . SetFont ( 0 , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , DT_LEFT | DT_VCENTER ) ;
Element . FontColor . States [ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB ( 200 , 200 , 200 , 200 ) ;
Element . TextureColor . States [ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB ( 150 , 255 , 255 , 255 ) ;
Element . TextureColor . States [ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB ( 200 , 255 , 255 , 255 ) ;
Element . TextureColor . States [ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_CHECKBOX , 0 , & Element ) ;
//-------------------------------------
// CDXUTCheckBox - Check
//-------------------------------------
SetRect ( & rcTexture , 27 , 54 , 54 , 81 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_CHECKBOX , 1 , & Element ) ;
//-------------------------------------
// CDXUTRadioButton - Box
//-------------------------------------
SetRect ( & rcTexture , 54 , 54 , 81 , 81 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . SetFont ( 0 , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , DT_LEFT | DT_VCENTER ) ;
Element . FontColor . States [ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB ( 200 , 200 , 200 , 200 ) ;
Element . TextureColor . States [ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB ( 150 , 255 , 255 , 255 ) ;
Element . TextureColor . States [ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB ( 200 , 255 , 255 , 255 ) ;
Element . TextureColor . States [ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_RADIOBUTTON , 0 , & Element ) ;
//-------------------------------------
// CDXUTRadioButton - Check
//-------------------------------------
SetRect ( & rcTexture , 81 , 54 , 108 , 81 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_RADIOBUTTON , 1 , & Element ) ;
//-------------------------------------
// CDXUTComboBox - Main
//-------------------------------------
SetRect ( & rcTexture , 7 , 81 , 247 , 123 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . SetFont ( 0 ) ;
Element . TextureColor . States [ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB ( 200 , 255 , 255 , 255 ) ;
Element . TextureColor . States [ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB ( 255 , 185 , 34 , 40 ) ;
Element . TextureColor . States [ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB ( 255 , 185 , 34 , 40 ) ;
Element . TextureColor . States [ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB ( 70 , 200 , 200 , 200 ) ;
Element . FontColor . States [ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
Element . FontColor . States [ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB ( 255 , 0 , 0 , 0 ) ;
Element . FontColor . States [ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB ( 200 , 200 , 200 , 200 ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_COMBOBOX , 0 , & Element ) ;
//-------------------------------------
// CDXUTComboBox - Button
//-------------------------------------
SetRect ( & rcTexture , 272 , 0 , 325 , 49 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . TextureColor . States [ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB ( 200 , 255 , 255 , 255 ) ;
Element . TextureColor . States [ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB ( 255 , 150 , 150 , 150 ) ;
Element . TextureColor . States [ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB ( 255 , 150 , 150 , 150 ) ;
Element . TextureColor . States [ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB ( 70 , 255 , 255 , 255 ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_COMBOBOX , 1 , & Element ) ;
//-------------------------------------
// CDXUTComboBox - Dropdown
//-------------------------------------
SetRect ( & rcTexture , 7 , 123 , 241 , 265 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . SetFont ( 0 , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , DT_LEFT | DT_TOP ) ;
Element . TextureColor . Init ( D3DCOLOR_ARGB ( 255 , 185 , 34 , 40 ) ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_COMBOBOX , 2 , & Element ) ;
//-------------------------------------
// CDXUTComboBox - Selection
//-------------------------------------
SetRect ( & rcTexture , 7 , 266 , 241 , 289 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . SetFont ( 0 , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , DT_LEFT | DT_TOP ) ;
Element . TextureColor . Init ( D3DCOLOR_ARGB ( 255 , 200 , 200 , 200 ) ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_COMBOBOX , 3 , & Element ) ;
//-------------------------------------
// CDXUTSlider - Track
//-------------------------------------
SetRect ( & rcTexture , 1 , 290 , 280 , 331 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . TextureColor . States [ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB ( 150 , 255 , 255 , 255 ) ;
Element . TextureColor . States [ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB ( 200 , 255 , 255 , 255 ) ;
Element . TextureColor . States [ DXUT_STATE_DISABLED ] = D3DCOLOR_ARGB ( 70 , 255 , 255 , 255 ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_SLIDER , 0 , & Element ) ;
//-------------------------------------
// CDXUTSlider - Button
//-------------------------------------
SetRect ( & rcTexture , 54 , 54 , 81 , 81 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . TextureColor . Init ( D3DCOLOR_ARGB ( 255 , 185 , 34 , 40 ) , D3DCOLOR_ARGB ( 255 , 149 , 176 , 208 ) ) ;
Element . TextureColor . States [ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB ( 255 , 240 , 240 , 240 ) ;
Element . TextureColor . States [ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB ( 255 , 185 , 34 , 40 ) ;
Element . TextureColor . States [ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB ( 255 , 220 , 220 , 220 ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_SLIDER , 1 , & Element ) ;
//-------------------------------------
// CDXUTScrollBar - Track
//-------------------------------------
SetRect ( & rcTexture , 243 , 144 , 265 , 155 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . TextureColor . Init ( D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_SCROLLBAR , 0 , & Element ) ;
//-------------------------------------
// CDXUTScrollBar - Up Arrow
//-------------------------------------
SetRect ( & rcTexture , 243 , 124 , 265 , 144 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . TextureColor . Init ( D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_SCROLLBAR , 1 , & Element ) ;
//-------------------------------------
// CDXUTScrollBar - Down Arrow
//-------------------------------------
SetRect ( & rcTexture , 243 , 155 , 265 , 176 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . TextureColor . Init ( D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_SCROLLBAR , 2 , & Element ) ;
//-------------------------------------
// CDXUTScrollBar - Button
//-------------------------------------
SetRect ( & rcTexture , 266 , 123 , 286 , 167 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . TextureColor . Init ( D3DCOLOR_ARGB ( 255 , 185 , 34 , 40 ) , D3DCOLOR_ARGB ( 255 , 149 , 176 , 208 ) ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_SCROLLBAR , 3 , & Element ) ;
//-------------------------------------
// CDXUTEditBox
//-------------------------------------
// Element assignment:
// 0 - text area
// 1 - top left border
// 2 - top border
// 3 - top right border
// 4 - left border
// 5 - right border
// 6 - lower left border
// 7 - lower border
// 8 - lower right border
Element . SetFont ( 0 , D3DCOLOR_ARGB ( 255 , 0 , 0 , 0 ) , DT_LEFT | DT_TOP | DT_VCENTER ) ;
// Assign the style
SetRect ( & rcTexture , 14 , 90 , 241 , 113 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_EDITBOX , 0 , & Element ) ;
SetRect ( & rcTexture , 8 , 82 , 14 , 90 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_EDITBOX , 1 , & Element ) ;
SetRect ( & rcTexture , 14 , 82 , 241 , 90 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_EDITBOX , 2 , & Element ) ;
SetRect ( & rcTexture , 241 , 82 , 246 , 90 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_EDITBOX , 3 , & Element ) ;
SetRect ( & rcTexture , 8 , 90 , 14 , 113 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_EDITBOX , 4 , & Element ) ;
SetRect ( & rcTexture , 241 , 90 , 246 , 113 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_EDITBOX , 5 , & Element ) ;
SetRect ( & rcTexture , 8 , 113 , 14 , 121 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_EDITBOX , 6 , & Element ) ;
SetRect ( & rcTexture , 14 , 113 , 241 , 121 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_EDITBOX , 7 , & Element ) ;
SetRect ( & rcTexture , 241 , 113 , 246 , 121 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_EDITBOX , 8 , & Element ) ;
//-------------------------------------
// CDXUTIMEEditBox
//-------------------------------------
Element . SetFont ( 0 , D3DCOLOR_ARGB ( 255 , 0 , 0 , 0 ) , DT_LEFT | DT_TOP | DT_VCENTER ) ;
// Assign the style
SetRect ( & rcTexture , 14 , 90 , 241 , 113 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 0 , & Element ) ;
SetRect ( & rcTexture , 8 , 82 , 14 , 90 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 1 , & Element ) ;
SetRect ( & rcTexture , 14 , 82 , 241 , 90 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 2 , & Element ) ;
SetRect ( & rcTexture , 241 , 82 , 246 , 90 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 3 , & Element ) ;
SetRect ( & rcTexture , 8 , 90 , 14 , 113 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 4 , & Element ) ;
SetRect ( & rcTexture , 241 , 90 , 246 , 113 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 5 , & Element ) ;
SetRect ( & rcTexture , 8 , 113 , 14 , 121 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 6 , & Element ) ;
SetRect ( & rcTexture , 14 , 113 , 241 , 121 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 7 , & Element ) ;
SetRect ( & rcTexture , 241 , 113 , 246 , 121 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 8 , & Element ) ;
// Element 9 for IME text, and indicator button
SetRect ( & rcTexture , 0 , 0 , 136 , 54 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . SetFont ( 0 , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , DT_CENTER | DT_VCENTER ) ;
SetDefaultElement ( DXUT_CONTROL_IMEEDITBOX , 9 , & Element ) ;
//-------------------------------------
// CDXUTListBox - Main
//-------------------------------------
SetRect ( & rcTexture , 13 , 124 , 241 , 265 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . SetFont ( 1 , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , DT_LEFT | DT_TOP | DT_EXPANDTABS ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_LISTBOX , 0 , & Element ) ;
//-------------------------------------
// CDXUTListBox - Selection
//-------------------------------------
SetRect ( & rcTexture , 17 , 269 , 241 , 287 ) ;
Element . SetTexture ( 0 , & rcTexture ) ;
Element . SetFont ( 1 , D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) , DT_LEFT | DT_TOP | DT_EXPANDTABS ) ;
Element . TextureColor . Init ( D3DCOLOR_ARGB ( 255 , 185 , 34 , 40 ) ) ;
// Assign the Element
SetDefaultElement ( DXUT_CONTROL_LISTBOX , 1 , & Element ) ;
}
//--------------------------------------------------------------------------------------
// CDXUTControl class
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CDXUTControl : : CDXUTControl ( CDXUTDialog * pDialog )
{
m_Type = DXUT_CONTROL_BUTTON ;
m_pDialog = pDialog ;
m_ID = 0 ;
m_Index = 0 ;
m_pUserData = NULL ;
m_bEnabled = true ;
m_bVisible = true ;
m_bMouseOver = false ;
m_bHasFocus = false ;
m_bIsDefault = false ;
m_pDialog = NULL ;
m_x = 0 ;
m_y = 0 ;
m_width = 0 ;
m_height = 0 ;
ZeroMemory ( & m_rcBoundingBox , sizeof ( m_rcBoundingBox ) ) ;
}
CDXUTControl : : ~ CDXUTControl ( )
{
for ( int i = 0 ; i < m_Elements . GetSize ( ) ; + + i )
{
delete m_Elements [ i ] ;
}
m_Elements . RemoveAll ( ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTControl : : SetTextColor ( D3DCOLOR Color )
{
CDXUTElement * pElement = m_Elements . GetAt ( 0 ) ;
if ( pElement )
pElement - > FontColor . States [ DXUT_STATE_NORMAL ] = Color ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTControl : : SetElement ( UINT iElement , CDXUTElement * pElement )
{
HRESULT hr = S_OK ;
if ( pElement = = NULL )
return E_INVALIDARG ;
// Make certain the array is this large
for ( UINT i = m_Elements . GetSize ( ) ; i < = iElement ; i + + )
{
CDXUTElement * pNewElement = new CDXUTElement ( ) ;
if ( pNewElement = = NULL )
return E_OUTOFMEMORY ;
hr = m_Elements . Add ( pNewElement ) ;
if ( FAILED ( hr ) )
{
SAFE_DELETE ( pNewElement ) ;
return hr ;
}
}
// Update the data
CDXUTElement * pCurElement = m_Elements . GetAt ( iElement ) ;
* pCurElement = * pElement ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
void CDXUTControl : : Refresh ( )
{
m_bMouseOver = false ;
m_bHasFocus = false ;
for ( int i = 0 ; i < m_Elements . GetSize ( ) ; i + + )
{
CDXUTElement * pElement = m_Elements . GetAt ( i ) ;
pElement - > Refresh ( ) ;
}
}
//--------------------------------------------------------------------------------------
void CDXUTControl : : UpdateRects ( )
{
SetRect ( & m_rcBoundingBox , m_x , m_y , m_x + m_width , m_y + m_height ) ;
}
//--------------------------------------------------------------------------------------
// CDXUTStatic class
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CDXUTStatic : : CDXUTStatic ( CDXUTDialog * pDialog )
{
m_Type = DXUT_CONTROL_STATIC ;
m_pDialog = pDialog ;
ZeroMemory ( & m_strText , sizeof ( m_strText ) ) ;
for ( int i = 0 ; i < m_Elements . GetSize ( ) ; i + + )
{
CDXUTElement * pElement = m_Elements . GetAt ( i ) ;
SAFE_DELETE ( pElement ) ;
}
m_Elements . RemoveAll ( ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTStatic : : Render ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
if ( m_bVisible = = false )
return ;
DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL ;
if ( m_bEnabled = = false )
iState = DXUT_STATE_DISABLED ;
CDXUTElement * pElement = m_Elements . GetAt ( 0 ) ;
pElement - > FontColor . Blend ( iState , fElapsedTime ) ;
m_pDialog - > DrawText ( m_strText , pElement , & m_rcBoundingBox , true ) ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTStatic : : GetTextCopy ( PCHAR strDest , UINT bufferCount )
{
// Validate incoming parameters
if ( strDest = = NULL | | bufferCount = = 0 )
{
return E_INVALIDARG ;
}
// Copy the window text
StringCchCopy ( strDest , bufferCount , m_strText ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTStatic : : SetText ( LPCTSTR strText )
{
if ( strText = = NULL )
{
m_strText [ 0 ] = 0 ;
return S_OK ;
}
StringCchCopy ( m_strText , MAX_PATH , strText ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
// CDXUTButton class
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CDXUTButton : : CDXUTButton ( CDXUTDialog * pDialog )
{
m_Type = DXUT_CONTROL_BUTTON ;
m_pDialog = pDialog ;
m_bPressed = false ;
m_nHotkey = 0 ;
}
//--------------------------------------------------------------------------------------
bool CDXUTButton : : HandleKeyboard ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_KEYDOWN :
{
switch ( wParam )
{
case VK_SPACE :
m_bPressed = true ;
return true ;
}
}
case WM_KEYUP :
{
switch ( wParam )
{
case VK_SPACE :
if ( m_bPressed = = true )
{
m_bPressed = false ;
m_pDialog - > SendEvent ( EVENT_BUTTON_CLICKED , true , this ) ;
}
return true ;
}
}
}
return false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTButton : : HandleMouse ( UINT uMsg , POINT pt , WPARAM wParam , LPARAM lParam )
{
OutputDebugString ( " CDXUTButton::HandleMouse " ) ;
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_LBUTTONDOWN :
case WM_LBUTTONDBLCLK :
{
if ( ContainsPoint ( pt ) )
{
// Pressed while inside the control
m_bPressed = true ;
SetCapture ( DXUTGetHWND ( ) ) ;
if ( ! m_bHasFocus )
m_pDialog - > RequestFocus ( this ) ;
return true ;
}
break ;
}
case WM_LBUTTONUP :
{
if ( m_bPressed )
{
m_bPressed = false ;
ReleaseCapture ( ) ;
if ( ! m_pDialog - > m_bKeyboardInput )
m_pDialog - > ClearFocus ( ) ;
// Button click
if ( ContainsPoint ( pt ) )
m_pDialog - > SendEvent ( EVENT_BUTTON_CLICKED , true , this ) ;
return true ;
}
break ;
}
} ;
return false ;
}
//--------------------------------------------------------------------------------------
void CDXUTButton : : Render ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
int nOffsetX = 0 ;
int nOffsetY = 0 ;
DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL ;
if ( m_bVisible = = false )
{
iState = DXUT_STATE_HIDDEN ;
}
else if ( m_bEnabled = = false )
{
iState = DXUT_STATE_DISABLED ;
}
else if ( m_bPressed )
{
iState = DXUT_STATE_PRESSED ;
nOffsetX = 1 ;
nOffsetY = 2 ;
}
else if ( m_bMouseOver )
{
iState = DXUT_STATE_MOUSEOVER ;
nOffsetX = - 1 ;
nOffsetY = - 2 ;
}
else if ( m_bHasFocus )
{
iState = DXUT_STATE_FOCUS ;
}
// Background fill layer
//TODO: remove magic numbers
CDXUTElement * pElement = m_Elements . GetAt ( 0 ) ;
float fBlendRate = ( iState = = DXUT_STATE_PRESSED ) ? 0.0f : 0.8f ;
RECT rcWindow = m_rcBoundingBox ;
OffsetRect ( & rcWindow , nOffsetX , nOffsetY ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
pElement - > FontColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & rcWindow ) ;
m_pDialog - > DrawText ( m_strText , pElement , & rcWindow ) ;
// Main button
pElement = m_Elements . GetAt ( 1 ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
pElement - > FontColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & rcWindow ) ;
m_pDialog - > DrawText ( m_strText , pElement , & rcWindow ) ;
}
//--------------------------------------------------------------------------------------
// CDXUTCheckBox class
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CDXUTCheckBox : : CDXUTCheckBox ( CDXUTDialog * pDialog )
{
m_Type = DXUT_CONTROL_CHECKBOX ;
m_pDialog = pDialog ;
m_bChecked = false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTCheckBox : : HandleKeyboard ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_KEYDOWN :
{
switch ( wParam )
{
case VK_SPACE :
m_bPressed = true ;
return true ;
}
}
case WM_KEYUP :
{
switch ( wParam )
{
case VK_SPACE :
if ( m_bPressed = = true )
{
m_bPressed = false ;
SetCheckedInternal ( ! m_bChecked , true ) ;
}
return true ;
}
}
}
return false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTCheckBox : : HandleMouse ( UINT uMsg , POINT pt , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_LBUTTONDOWN :
case WM_LBUTTONDBLCLK :
{
if ( ContainsPoint ( pt ) )
{
// Pressed while inside the control
m_bPressed = true ;
SetCapture ( DXUTGetHWND ( ) ) ;
if ( ! m_bHasFocus )
m_pDialog - > RequestFocus ( this ) ;
return true ;
}
break ;
}
case WM_LBUTTONUP :
{
if ( m_bPressed )
{
m_bPressed = false ;
ReleaseCapture ( ) ;
// Button click
if ( ContainsPoint ( pt ) )
SetCheckedInternal ( ! m_bChecked , true ) ;
return true ;
}
break ;
}
} ;
return false ;
}
//--------------------------------------------------------------------------------------
void CDXUTCheckBox : : SetCheckedInternal ( bool bChecked , bool bFromInput )
{
m_bChecked = bChecked ;
m_pDialog - > SendEvent ( EVENT_CHECKBOX_CHANGED , bFromInput , this ) ;
}
//--------------------------------------------------------------------------------------
BOOL CDXUTCheckBox : : ContainsPoint ( POINT pt )
{
return ( PtInRect ( & m_rcBoundingBox , pt ) | |
PtInRect ( & m_rcButton , pt ) ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTCheckBox : : UpdateRects ( )
{
CDXUTButton : : UpdateRects ( ) ;
m_rcButton = m_rcBoundingBox ;
m_rcButton . right = m_rcButton . left + RectHeight ( m_rcButton ) ;
m_rcText = m_rcBoundingBox ;
m_rcText . left + = ( int ) ( 1.25f * RectWidth ( m_rcButton ) ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTCheckBox : : Render ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL ;
if ( m_bVisible = = false )
iState = DXUT_STATE_HIDDEN ;
else if ( m_bEnabled = = false )
iState = DXUT_STATE_DISABLED ;
else if ( m_bPressed )
iState = DXUT_STATE_PRESSED ;
else if ( m_bMouseOver )
iState = DXUT_STATE_MOUSEOVER ;
else if ( m_bHasFocus )
iState = DXUT_STATE_FOCUS ;
CDXUTElement * pElement = m_Elements . GetAt ( 0 ) ;
float fBlendRate = ( iState = = DXUT_STATE_PRESSED ) ? 0.0f : 0.8f ;
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
pElement - > FontColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcButton ) ;
m_pDialog - > DrawText ( m_strText , pElement , & m_rcText , true ) ;
if ( ! m_bChecked )
iState = DXUT_STATE_HIDDEN ;
pElement = m_Elements . GetAt ( 1 ) ;
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcButton ) ;
}
//--------------------------------------------------------------------------------------
// CDXUTRadioButton class
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CDXUTRadioButton : : CDXUTRadioButton ( CDXUTDialog * pDialog )
{
m_Type = DXUT_CONTROL_RADIOBUTTON ;
m_pDialog = pDialog ;
}
//--------------------------------------------------------------------------------------
bool CDXUTRadioButton : : HandleKeyboard ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_KEYDOWN :
{
switch ( wParam )
{
case VK_SPACE :
m_bPressed = true ;
return true ;
}
}
case WM_KEYUP :
{
switch ( wParam )
{
case VK_SPACE :
if ( m_bPressed = = true )
{
m_bPressed = false ;
m_pDialog - > ClearRadioButtonGroup ( m_nButtonGroup ) ;
m_bChecked = ! m_bChecked ;
m_pDialog - > SendEvent ( EVENT_RADIOBUTTON_CHANGED , true , this ) ;
}
return true ;
}
}
}
return false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTRadioButton : : HandleMouse ( UINT uMsg , POINT pt , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_LBUTTONDOWN :
case WM_LBUTTONDBLCLK :
{
if ( ContainsPoint ( pt ) )
{
// Pressed while inside the control
m_bPressed = true ;
SetCapture ( DXUTGetHWND ( ) ) ;
if ( ! m_bHasFocus )
m_pDialog - > RequestFocus ( this ) ;
return true ;
}
break ;
}
case WM_LBUTTONUP :
{
if ( m_bPressed )
{
m_bPressed = false ;
ReleaseCapture ( ) ;
// Button click
if ( ContainsPoint ( pt ) )
{
m_pDialog - > ClearRadioButtonGroup ( m_nButtonGroup ) ;
m_bChecked = ! m_bChecked ;
m_pDialog - > SendEvent ( EVENT_RADIOBUTTON_CHANGED , true , this ) ;
}
return true ;
}
break ;
}
} ;
return false ;
}
//--------------------------------------------------------------------------------------
void CDXUTRadioButton : : SetCheckedInternal ( bool bChecked , bool bClearGroup , bool bFromInput )
{
if ( bChecked & & bClearGroup )
m_pDialog - > ClearRadioButtonGroup ( m_nButtonGroup ) ;
m_bChecked = bChecked ;
m_pDialog - > SendEvent ( EVENT_RADIOBUTTON_CHANGED , bFromInput , this ) ;
}
//--------------------------------------------------------------------------------------
// CDXUTComboBox class
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CDXUTComboBox : : CDXUTComboBox ( CDXUTDialog * pDialog ) :
m_ScrollBar ( pDialog )
{
m_Type = DXUT_CONTROL_COMBOBOX ;
m_pDialog = pDialog ;
m_nDropHeight = 100 ;
m_nSBWidth = 16 ;
m_bOpened = false ;
m_iSelected = - 1 ;
m_iFocused = - 1 ;
}
//--------------------------------------------------------------------------------------
CDXUTComboBox : : ~ CDXUTComboBox ( )
{
RemoveAllItems ( ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTComboBox : : SetTextColor ( D3DCOLOR Color )
{
CDXUTElement * pElement = m_Elements . GetAt ( 0 ) ;
if ( pElement )
pElement - > FontColor . States [ DXUT_STATE_NORMAL ] = Color ;
pElement = m_Elements . GetAt ( 2 ) ;
if ( pElement )
pElement - > FontColor . States [ DXUT_STATE_NORMAL ] = Color ;
}
//--------------------------------------------------------------------------------------
void CDXUTComboBox : : UpdateRects ( )
{
CDXUTButton : : UpdateRects ( ) ;
m_rcButton = m_rcBoundingBox ;
m_rcButton . left = m_rcButton . right - RectHeight ( m_rcButton ) ;
m_rcText = m_rcBoundingBox ;
m_rcText . right = m_rcButton . left ;
m_rcDropdown = m_rcText ;
OffsetRect ( & m_rcDropdown , 0 , ( int ) ( 0.90f * RectHeight ( m_rcText ) ) ) ;
m_rcDropdown . bottom + = m_nDropHeight ;
m_rcDropdown . right - = m_nSBWidth ;
m_rcDropdownText = m_rcDropdown ;
m_rcDropdownText . left + = ( int ) ( 0.1f * RectWidth ( m_rcDropdown ) ) ;
m_rcDropdownText . right - = ( int ) ( 0.1f * RectWidth ( m_rcDropdown ) ) ;
m_rcDropdownText . top + = ( int ) ( 0.1f * RectHeight ( m_rcDropdown ) ) ;
m_rcDropdownText . bottom - = ( int ) ( 0.1f * RectHeight ( m_rcDropdown ) ) ;
// Update the scrollbar's rects
m_ScrollBar . SetLocation ( m_rcDropdown . right , m_rcDropdown . top + 2 ) ;
m_ScrollBar . SetSize ( m_nSBWidth , RectHeight ( m_rcDropdown ) - 2 ) ;
DXUTFontNode * pFontNode = m_pDialog - > GetManager ( ) - > GetFontNode ( m_Elements . GetAt ( 2 ) - > iFont ) ;
if ( pFontNode & & pFontNode - > nHeight )
{
m_ScrollBar . SetPageSize ( RectHeight ( m_rcDropdownText ) / pFontNode - > nHeight ) ;
// The selected item may have been scrolled off the page.
// Ensure that it is in page again.
m_ScrollBar . ShowItem ( m_iSelected ) ;
}
}
//--------------------------------------------------------------------------------------
void CDXUTComboBox : : OnFocusOut ( )
{
CDXUTButton : : OnFocusOut ( ) ;
m_bOpened = false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTComboBox : : HandleKeyboard ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
const DWORD REPEAT_MASK = ( 0x40000000 ) ;
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
// Let the scroll bar have a chance to handle it first
if ( m_ScrollBar . HandleKeyboard ( uMsg , wParam , lParam ) )
return true ;
switch ( uMsg )
{
case WM_KEYDOWN :
{
switch ( wParam )
{
case VK_RETURN :
if ( m_bOpened )
{
if ( m_iSelected ! = m_iFocused )
{
m_iSelected = m_iFocused ;
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , true , this ) ;
}
m_bOpened = false ;
if ( ! m_pDialog - > m_bKeyboardInput )
m_pDialog - > ClearFocus ( ) ;
return true ;
}
break ;
case VK_F4 :
// Filter out auto-repeats
if ( lParam & REPEAT_MASK )
return true ;
m_bOpened = ! m_bOpened ;
if ( ! m_bOpened )
{
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , true , this ) ;
if ( ! m_pDialog - > m_bKeyboardInput )
m_pDialog - > ClearFocus ( ) ;
}
return true ;
case VK_LEFT :
case VK_UP :
if ( m_iFocused > 0 )
{
m_iFocused - - ;
m_iSelected = m_iFocused ;
if ( ! m_bOpened )
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , true , this ) ;
}
return true ;
case VK_RIGHT :
case VK_DOWN :
if ( m_iFocused + 1 < ( int ) GetNumItems ( ) )
{
m_iFocused + + ;
m_iSelected = m_iFocused ;
if ( ! m_bOpened )
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , true , this ) ;
}
return true ;
}
break ;
}
}
return false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTComboBox : : HandleMouse ( UINT uMsg , POINT pt , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
// Let the scroll bar handle it first.
if ( m_ScrollBar . HandleMouse ( uMsg , pt , wParam , lParam ) )
return true ;
switch ( uMsg )
{
case WM_MOUSEMOVE :
{
if ( m_bOpened & & PtInRect ( & m_rcDropdown , pt ) )
{
// Determine which item has been selected
for ( int i = 0 ; i < m_Items . GetSize ( ) ; i + + )
{
DXUTComboBoxItem * pItem = m_Items . GetAt ( i ) ;
if ( pItem - > bVisible & &
PtInRect ( & pItem - > rcActive , pt ) )
{
m_iFocused = i ;
}
}
return true ;
}
break ;
}
case WM_LBUTTONDOWN :
case WM_LBUTTONDBLCLK :
{
if ( ContainsPoint ( pt ) )
{
// Pressed while inside the control
m_bPressed = true ;
SetCapture ( DXUTGetHWND ( ) ) ;
if ( ! m_bHasFocus )
m_pDialog - > RequestFocus ( this ) ;
// Toggle dropdown
if ( m_bHasFocus )
{
m_bOpened = ! m_bOpened ;
if ( ! m_bOpened )
{
if ( ! m_pDialog - > m_bKeyboardInput )
m_pDialog - > ClearFocus ( ) ;
}
}
return true ;
}
// Perhaps this click is within the dropdown
if ( m_bOpened & & PtInRect ( & m_rcDropdown , pt ) )
{
// Determine which item has been selected
for ( int i = m_ScrollBar . GetTrackPos ( ) ; i < m_Items . GetSize ( ) ; i + + )
{
DXUTComboBoxItem * pItem = m_Items . GetAt ( i ) ;
if ( pItem - > bVisible & &
PtInRect ( & pItem - > rcActive , pt ) )
{
m_iFocused = m_iSelected = i ;
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , true , this ) ;
m_bOpened = false ;
if ( ! m_pDialog - > m_bKeyboardInput )
m_pDialog - > ClearFocus ( ) ;
break ;
}
}
return true ;
}
// Mouse click not on main control or in dropdown, fire an event if needed
if ( m_bOpened )
{
m_iFocused = m_iSelected ;
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , true , this ) ;
m_bOpened = false ;
}
// Make sure the control is no longer in a pressed state
m_bPressed = false ;
// Release focus if appropriate
if ( ! m_pDialog - > m_bKeyboardInput )
{
m_pDialog - > ClearFocus ( ) ;
}
break ;
}
case WM_LBUTTONUP :
{
if ( m_bPressed & & ContainsPoint ( pt ) )
{
// Button click
m_bPressed = false ;
ReleaseCapture ( ) ;
return true ;
}
break ;
}
case WM_MOUSEWHEEL :
{
int zDelta = ( short ) HIWORD ( wParam ) / WHEEL_DELTA ;
if ( m_bOpened )
{
UINT uLines ;
SystemParametersInfo ( SPI_GETWHEELSCROLLLINES , 0 , & uLines , 0 ) ;
m_ScrollBar . Scroll ( - zDelta * uLines ) ;
} else
{
if ( zDelta > 0 )
{
if ( m_iFocused > 0 )
{
m_iFocused - - ;
m_iSelected = m_iFocused ;
if ( ! m_bOpened )
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , true , this ) ;
}
}
else
{
if ( m_iFocused + 1 < ( int ) GetNumItems ( ) )
{
m_iFocused + + ;
m_iSelected = m_iFocused ;
if ( ! m_bOpened )
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , true , this ) ;
}
}
}
return true ;
}
} ;
return false ;
}
//--------------------------------------------------------------------------------------
void CDXUTComboBox : : OnHotkey ( )
{
if ( m_bOpened )
return ;
if ( m_iSelected = = - 1 )
return ;
m_pDialog - > RequestFocus ( this ) ;
m_iSelected + + ;
if ( m_iSelected > = ( int ) m_Items . GetSize ( ) )
m_iSelected = 0 ;
m_iFocused = m_iSelected ;
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , true , this ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTComboBox : : Render ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL ;
if ( ! m_bOpened )
iState = DXUT_STATE_HIDDEN ;
// Dropdown box
CDXUTElement * pElement = m_Elements . GetAt ( 2 ) ;
// If we have not initialized the scroll bar page size,
// do that now.
static bool bSBInit ;
if ( ! bSBInit )
{
// Update the page size of the scroll bar
if ( m_pDialog - > GetManager ( ) - > GetFontNode ( pElement - > iFont ) - > nHeight )
m_ScrollBar . SetPageSize ( RectHeight ( m_rcDropdownText ) / m_pDialog - > GetManager ( ) - > GetFontNode ( pElement - > iFont ) - > nHeight ) ;
else
m_ScrollBar . SetPageSize ( RectHeight ( m_rcDropdownText ) ) ;
bSBInit = true ;
}
// Scroll bar
if ( m_bOpened )
m_ScrollBar . Render ( pd3dDevice , fElapsedTime ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime ) ;
pElement - > FontColor . Blend ( iState , fElapsedTime ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcDropdown ) ;
// Selection outline
CDXUTElement * pSelectionElement = m_Elements . GetAt ( 3 ) ;
pSelectionElement - > TextureColor . Current = pElement - > TextureColor . Current ;
pSelectionElement - > FontColor . Current = pSelectionElement - > FontColor . States [ DXUT_STATE_NORMAL ] ;
DXUTFontNode * pFont = m_pDialog - > GetFont ( pElement - > iFont ) ;
if ( pFont )
{
int curY = m_rcDropdownText . top ;
int nRemainingHeight = RectHeight ( m_rcDropdownText ) ;
//TCHAR strDropdown[4096] = {0};
for ( int i = m_ScrollBar . GetTrackPos ( ) ; i < m_Items . GetSize ( ) ; i + + )
{
DXUTComboBoxItem * pItem = m_Items . GetAt ( i ) ;
// Make sure there's room left in the dropdown
nRemainingHeight - = pFont - > nHeight ;
if ( nRemainingHeight < 0 )
{
pItem - > bVisible = false ;
continue ;
}
SetRect ( & pItem - > rcActive , m_rcDropdownText . left , curY , m_rcDropdownText . right , curY + pFont - > nHeight ) ;
curY + = pFont - > nHeight ;
//debug
//int blue = 50 * i;
//m_pDialog->DrawRect( &pItem->rcActive, 0xFFFF0000 | blue );
pItem - > bVisible = true ;
if ( m_bOpened )
{
if ( ( int ) i = = m_iFocused )
{
RECT rc ;
SetRect ( & rc , m_rcDropdown . left , pItem - > rcActive . top - 2 , m_rcDropdown . right , pItem - > rcActive . bottom + 2 ) ;
m_pDialog - > DrawSprite ( pSelectionElement , & rc ) ;
m_pDialog - > DrawText ( pItem - > strText , pSelectionElement , & pItem - > rcActive ) ;
}
else
{
m_pDialog - > DrawText ( pItem - > strText , pElement , & pItem - > rcActive ) ;
}
}
}
}
int nOffsetX = 0 ;
int nOffsetY = 0 ;
iState = DXUT_STATE_NORMAL ;
if ( m_bVisible = = false )
iState = DXUT_STATE_HIDDEN ;
else if ( m_bEnabled = = false )
iState = DXUT_STATE_DISABLED ;
else if ( m_bPressed )
{
iState = DXUT_STATE_PRESSED ;
nOffsetX = 1 ;
nOffsetY = 2 ;
}
else if ( m_bMouseOver )
{
iState = DXUT_STATE_MOUSEOVER ;
nOffsetX = - 1 ;
nOffsetY = - 2 ;
}
else if ( m_bHasFocus )
iState = DXUT_STATE_FOCUS ;
float fBlendRate = ( iState = = DXUT_STATE_PRESSED ) ? 0.0f : 0.8f ;
// Button
pElement = m_Elements . GetAt ( 1 ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
RECT rcWindow = m_rcButton ;
OffsetRect ( & rcWindow , nOffsetX , nOffsetY ) ;
m_pDialog - > DrawSprite ( pElement , & rcWindow ) ;
if ( m_bOpened )
iState = DXUT_STATE_PRESSED ;
// Main text box
//TODO: remove magic numbers
pElement = m_Elements . GetAt ( 0 ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
pElement - > FontColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcText ) ;
if ( m_iSelected > = 0 & & m_iSelected < ( int ) m_Items . GetSize ( ) )
{
DXUTComboBoxItem * pItem = m_Items . GetAt ( m_iSelected ) ;
if ( pItem ! = NULL )
{
m_pDialog - > DrawText ( pItem - > strText , pElement , & m_rcText ) ;
}
}
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTComboBox : : AddItem ( const TCHAR * strText , void * pData )
{
// Validate parameters
if ( strText = = NULL )
{
return E_INVALIDARG ;
}
// Create a new item and set the data
DXUTComboBoxItem * pItem = new DXUTComboBoxItem ;
if ( pItem = = NULL )
{
return DXTRACE_ERR_MSGBOX ( " new " , E_OUTOFMEMORY ) ;
}
ZeroMemory ( pItem , sizeof ( DXUTComboBoxItem ) ) ;
StringCchCopy ( pItem - > strText , 256 , strText ) ;
pItem - > pData = pData ;
m_Items . Add ( pItem ) ;
// Update the scroll bar with new range
m_ScrollBar . SetTrackRange ( 0 , m_Items . GetSize ( ) ) ;
// If this is the only item in the list, it's selected
if ( GetNumItems ( ) = = 1 )
{
m_iSelected = 0 ;
m_iFocused = 0 ;
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , false , this ) ;
}
return S_OK ;
}
//--------------------------------------------------------------------------------------
void CDXUTComboBox : : RemoveItem ( UINT index )
{
DXUTComboBoxItem * pItem = m_Items . GetAt ( index ) ;
SAFE_DELETE ( pItem ) ;
m_Items . Remove ( index ) ;
m_ScrollBar . SetTrackRange ( 0 , m_Items . GetSize ( ) ) ;
if ( m_iSelected > = m_Items . GetSize ( ) )
m_iSelected = m_Items . GetSize ( ) - 1 ;
}
//--------------------------------------------------------------------------------------
// MATCH
void CDXUTComboBox : : RemoveAllItems ( )
{
for ( int i = 0 ; i < m_Items . GetSize ( ) ; i + + )
{
DXUTComboBoxItem * pItem = m_Items . GetAt ( i ) ;
SAFE_DELETE ( pItem ) ;
}
m_Items . RemoveAll ( ) ;
m_ScrollBar . SetTrackRange ( 0 , 1 ) ;
m_iFocused = m_iSelected = - 1 ;
}
//--------------------------------------------------------------------------------------
bool CDXUTComboBox : : ContainsItem ( const TCHAR * strText , UINT iStart )
{
return ( - 1 ! = FindItem ( strText , iStart ) ) ;
}
//--------------------------------------------------------------------------------------
int CDXUTComboBox : : FindItem ( const TCHAR * strText , UINT iStart )
{
if ( strText = = NULL )
return - 1 ;
for ( int i = iStart ; i < m_Items . GetSize ( ) ; i + + )
{
DXUTComboBoxItem * pItem = m_Items . GetAt ( i ) ;
if ( 0 = = strcmp ( pItem - > strText , strText ) )
{
return i ;
}
}
return - 1 ;
}
//--------------------------------------------------------------------------------------
void * CDXUTComboBox : : GetSelectedData ( )
{
if ( m_iSelected < 0 )
return NULL ;
DXUTComboBoxItem * pItem = m_Items . GetAt ( m_iSelected ) ;
return pItem - > pData ;
}
//--------------------------------------------------------------------------------------
DXUTComboBoxItem * CDXUTComboBox : : GetSelectedItem ( )
{
if ( m_iSelected < 0 )
return NULL ;
return m_Items . GetAt ( m_iSelected ) ;
}
//--------------------------------------------------------------------------------------
void * CDXUTComboBox : : GetItemData ( const TCHAR * strText )
{
int index = FindItem ( strText ) ;
if ( index = = - 1 )
{
return NULL ;
}
DXUTComboBoxItem * pItem = m_Items . GetAt ( index ) ;
if ( pItem = = NULL )
{
DXTRACE_ERR ( " CGrowableArray::GetAt " , E_FAIL ) ;
return NULL ;
}
return pItem - > pData ;
}
//--------------------------------------------------------------------------------------
void * CDXUTComboBox : : GetItemData ( int nIndex )
{
if ( nIndex < 0 | | nIndex > = m_Items . GetSize ( ) )
return NULL ;
return m_Items . GetAt ( nIndex ) - > pData ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTComboBox : : SetSelectedByIndex ( UINT index )
{
if ( index > = GetNumItems ( ) )
return E_INVALIDARG ;
m_iFocused = m_iSelected = index ;
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , false , this ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTComboBox : : SetSelectedByText ( const TCHAR * strText )
{
if ( strText = = NULL )
return E_INVALIDARG ;
int index = FindItem ( strText ) ;
if ( index = = - 1 )
return E_FAIL ;
m_iFocused = m_iSelected = index ;
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , false , this ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTComboBox : : SetSelectedByData ( void * pData )
{
for ( int i = 0 ; i < m_Items . GetSize ( ) ; i + + )
{
DXUTComboBoxItem * pItem = m_Items . GetAt ( i ) ;
if ( pItem - > pData = = pData )
{
m_iFocused = m_iSelected = i ;
m_pDialog - > SendEvent ( EVENT_COMBOBOX_SELECTION_CHANGED , false , this ) ;
return S_OK ;
}
}
return E_FAIL ;
}
//--------------------------------------------------------------------------------------
CDXUTSlider : : CDXUTSlider ( CDXUTDialog * pDialog )
{
m_Type = DXUT_CONTROL_SLIDER ;
m_pDialog = pDialog ;
m_nMin = 0 ;
m_nMax = 100 ;
m_nValue = 50 ;
m_bPressed = false ;
field_76 = false ;
}
//--------------------------------------------------------------------------------------
BOOL CDXUTSlider : : ContainsPoint ( POINT pt )
{
return ( PtInRect ( & m_rcBoundingBox , pt ) | |
PtInRect ( & m_rcButton , pt ) ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTSlider : : UpdateRects ( )
{
CDXUTControl : : UpdateRects ( ) ;
m_rcButton = m_rcBoundingBox ;
m_rcButton . right = m_rcButton . left + RectHeight ( m_rcButton ) ;
OffsetRect ( & m_rcButton , - RectWidth ( m_rcButton ) / 2 , 0 ) ;
m_nButtonX = ( int ) ( ( m_nValue - m_nMin ) * ( float ) RectWidth ( m_rcBoundingBox ) / ( m_nMax - m_nMin ) ) ;
OffsetRect ( & m_rcButton , m_nButtonX , 0 ) ;
}
int CDXUTSlider : : ValueFromPos ( int x )
{
float fValuePerPixel = ( float ) ( m_nMax - m_nMin ) / RectWidth ( m_rcBoundingBox ) ;
return ( int ) ( 0.5f + m_nMin + fValuePerPixel * ( x - m_rcBoundingBox . left ) ) ;
}
//--------------------------------------------------------------------------------------
bool CDXUTSlider : : HandleKeyboard ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_KEYDOWN :
{
switch ( wParam )
{
case VK_HOME :
SetValueInternal ( m_nMin , true ) ;
return true ;
case VK_END :
SetValueInternal ( m_nMax , true ) ;
return true ;
case VK_PRIOR :
case VK_LEFT :
case VK_DOWN :
SetValueInternal ( m_nValue - 1 , true ) ;
return true ;
case VK_NEXT :
case VK_RIGHT :
case VK_UP :
SetValueInternal ( m_nValue + 1 , true ) ;
return true ;
}
break ;
}
}
return false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTSlider : : HandleMouse ( UINT uMsg , POINT pt , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_LBUTTONDOWN :
case WM_LBUTTONDBLCLK :
{
if ( PtInRect ( & m_rcButton , pt ) )
{
// Pressed while inside the control
m_bPressed = true ;
SetCapture ( DXUTGetHWND ( ) ) ;
m_nDragX = pt . x ;
//m_nDragY = pt.y;
m_nDragOffset = m_nButtonX - m_nDragX ;
//m_nDragValue = m_nValue;
if ( ! m_bHasFocus )
m_pDialog - > RequestFocus ( this ) ;
return true ;
}
if ( PtInRect ( & m_rcBoundingBox , pt ) )
{
m_nDragX = pt . x ;
m_nDragOffset = 0 ;
m_bPressed = true ;
if ( ! m_bHasFocus )
m_pDialog - > RequestFocus ( this ) ;
if ( pt . x > m_nButtonX + m_x )
{
SetValueInternal ( m_nValue + 1 , true ) ;
return true ;
}
if ( pt . x < m_nButtonX + m_x )
{
SetValueInternal ( m_nValue - 1 , true ) ;
return true ;
}
}
break ;
}
case WM_LBUTTONUP :
{
if ( m_bPressed )
{
m_bPressed = false ;
ReleaseCapture ( ) ;
m_pDialog - > SendEvent ( EVENT_SLIDER_VALUE_CHANGED , true , this ) ;
SetValueInternal ( 0 , false ) ;
return true ;
}
break ;
}
case WM_MOUSEMOVE :
{
if ( m_bPressed )
{
SetValueInternal ( ValueFromPos ( m_x + pt . x + m_nDragOffset ) , true ) ;
return true ;
}
break ;
}
} ;
return false ;
}
//--------------------------------------------------------------------------------------
void CDXUTSlider : : SetRange ( int nMin , int nMax )
{
m_nMin = nMin ;
m_nMax = nMax ;
SetValueInternal ( m_nValue , false ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTSlider : : SetValueInternal ( int nValue , bool bFromInput )
{
// Clamp to range
nValue = __max ( m_nMin , nValue ) ;
nValue = __min ( m_nMax , nValue ) ;
if ( nValue = = m_nValue )
return ;
m_nValue = nValue ;
UpdateRects ( ) ;
m_pDialog - > SendEvent ( EVENT_SLIDER_VALUE_CHANGED , bFromInput , this ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTSlider : : Render ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
int nOffsetX = 0 ;
int nOffsetY = 0 ;
DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL ;
if ( m_bVisible = = false )
{
iState = DXUT_STATE_HIDDEN ;
}
else if ( m_bEnabled = = false )
{
iState = DXUT_STATE_DISABLED ;
}
else if ( m_bPressed )
{
iState = DXUT_STATE_PRESSED ;
nOffsetX = 1 ;
nOffsetY = 2 ;
}
else if ( m_bMouseOver )
{
iState = DXUT_STATE_MOUSEOVER ;
nOffsetX = - 1 ;
nOffsetY = - 2 ;
}
else if ( m_bHasFocus )
{
iState = DXUT_STATE_FOCUS ;
}
float fBlendRate = ( iState = = DXUT_STATE_PRESSED ) ? 0.0f : 0.8f ;
CDXUTElement * pElement = m_Elements . GetAt ( 0 ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcBoundingBox ) ;
//TODO: remove magic numbers
pElement = m_Elements . GetAt ( 1 ) ;
// Blend current color
if ( field_76 )
pElement - > TextureColor . Current = field_77 ;
else
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcButton ) ;
}
//--------------------------------------------------------------------------------------
// CDXUTScrollBar class
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CDXUTScrollBar : : CDXUTScrollBar ( CDXUTDialog * pDialog )
{
m_Type = DXUT_CONTROL_SCROLLBAR ;
m_pDialog = pDialog ;
m_bShowThumb = true ;
SetRect ( & m_rcUpButton , 0 , 0 , 0 , 0 ) ;
SetRect ( & m_rcDownButton , 0 , 0 , 0 , 0 ) ;
SetRect ( & m_rcTrack , 0 , 0 , 0 , 0 ) ;
SetRect ( & m_rcThumb , 0 , 0 , 0 , 0 ) ;
m_nPosition = 0 ;
m_nPageSize = 1 ;
m_nStart = 0 ;
m_nEnd = 1 ;
m_Arrow = CLEAR ;
m_dArrowTS = 0.0 ;
}
//--------------------------------------------------------------------------------------
CDXUTScrollBar : : ~ CDXUTScrollBar ( )
{
}
//--------------------------------------------------------------------------------------
void CDXUTScrollBar : : UpdateRects ( )
{
CDXUTControl : : UpdateRects ( ) ;
// Make the buttons square
SetRect ( & m_rcUpButton , m_rcBoundingBox . left , m_rcBoundingBox . top ,
m_rcBoundingBox . right , m_rcBoundingBox . top + RectWidth ( m_rcBoundingBox ) ) ;
SetRect ( & m_rcDownButton , m_rcBoundingBox . left , m_rcBoundingBox . bottom - RectWidth ( m_rcBoundingBox ) ,
m_rcBoundingBox . right , m_rcBoundingBox . bottom ) ;
SetRect ( & m_rcTrack , m_rcUpButton . left , m_rcUpButton . bottom ,
m_rcDownButton . right , m_rcDownButton . top ) ;
m_rcThumb . left = m_rcUpButton . left ;
m_rcThumb . right = m_rcUpButton . right ;
UpdateThumbRect ( ) ;
}
//--------------------------------------------------------------------------------------
// Compute the dimension of the scroll thumb
void CDXUTScrollBar : : UpdateThumbRect ( )
{
if ( m_nEnd - m_nStart > m_nPageSize )
{
int nThumbHeight = __max ( RectHeight ( m_rcTrack ) * m_nPageSize / ( m_nEnd - m_nStart ) , SCROLLBAR_MINTHUMBSIZE ) ;
int nMaxPosition = m_nEnd - m_nStart - m_nPageSize ;
m_rcThumb . top = m_rcTrack . top + ( m_nPosition - m_nStart ) * ( RectHeight ( m_rcTrack ) - nThumbHeight )
/ nMaxPosition ;
m_rcThumb . bottom = m_rcThumb . top + nThumbHeight ;
m_bShowThumb = true ;
}
else
{
// No content to scroll
m_rcThumb . bottom = m_rcThumb . top ;
m_bShowThumb = false ;
}
}
//--------------------------------------------------------------------------------------
// Scroll() scrolls by nDelta items. A positive value scrolls down, while a negative
// value scrolls up.
void CDXUTScrollBar : : Scroll ( int nDelta )
{
// Perform scroll
m_nPosition + = nDelta ;
// Cap position
Cap ( ) ;
// Update thumb position
UpdateThumbRect ( ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTScrollBar : : ShowItem ( int nIndex )
{
// Cap the index
if ( nIndex < 0 )
nIndex = 0 ;
if ( nIndex > = m_nEnd )
nIndex = m_nEnd - 1 ;
// Adjust position
if ( m_nPosition > nIndex )
m_nPosition = nIndex ;
else
if ( m_nPosition + m_nPageSize < = nIndex )
m_nPosition = nIndex - m_nPageSize + 1 ;
UpdateThumbRect ( ) ;
}
//--------------------------------------------------------------------------------------
bool CDXUTScrollBar : : HandleKeyboard ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
return false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTScrollBar : : HandleMouse ( UINT uMsg , POINT pt , WPARAM wParam , LPARAM lParam )
{
static int ThumbOffsetY ;
static bool bDrag ;
m_LastMouse = pt ;
switch ( uMsg )
{
case WM_LBUTTONDOWN :
case WM_LBUTTONDBLCLK :
{
// Check for click on up button
if ( PtInRect ( & m_rcUpButton , pt ) )
{
SetCapture ( DXUTGetHWND ( ) ) ;
if ( m_nPosition > m_nStart )
- - m_nPosition ;
UpdateThumbRect ( ) ;
m_Arrow = CLICKED_UP ;
m_dArrowTS = DXUTGetTime ( ) ;
return true ;
}
// Check for click on down button
if ( PtInRect ( & m_rcDownButton , pt ) )
{
SetCapture ( DXUTGetHWND ( ) ) ;
if ( m_nPosition + m_nPageSize < m_nEnd )
+ + m_nPosition ;
UpdateThumbRect ( ) ;
m_Arrow = CLICKED_DOWN ;
m_dArrowTS = DXUTGetTime ( ) ;
return true ;
}
// Check for click on thumb
if ( PtInRect ( & m_rcThumb , pt ) )
{
SetCapture ( DXUTGetHWND ( ) ) ;
bDrag = true ;
ThumbOffsetY = pt . y - m_rcThumb . top ;
return true ;
}
// Check for click on track
if ( m_rcThumb . left < = pt . x & &
m_rcThumb . right > pt . x )
{
SetCapture ( DXUTGetHWND ( ) ) ;
if ( m_rcThumb . top > pt . y & &
m_rcTrack . top < = pt . y )
{
Scroll ( - ( m_nPageSize - 1 ) ) ;
return true ;
} else
if ( m_rcThumb . bottom < = pt . y & &
m_rcTrack . bottom > pt . y )
{
Scroll ( m_nPageSize - 1 ) ;
return true ;
}
}
break ;
}
case WM_LBUTTONUP :
{
bDrag = false ;
ReleaseCapture ( ) ;
UpdateThumbRect ( ) ;
m_Arrow = CLEAR ;
break ;
}
case WM_MOUSEMOVE :
{
if ( bDrag )
{
m_rcThumb . bottom + = pt . y - ThumbOffsetY - m_rcThumb . top ;
m_rcThumb . top = pt . y - ThumbOffsetY ;
if ( m_rcThumb . top < m_rcTrack . top )
OffsetRect ( & m_rcThumb , 0 , m_rcTrack . top - m_rcThumb . top ) ;
else
if ( m_rcThumb . bottom > m_rcTrack . bottom )
OffsetRect ( & m_rcThumb , 0 , m_rcTrack . bottom - m_rcThumb . bottom ) ;
// Compute first item index based on thumb position
int nMaxFirstItem = m_nEnd - m_nStart - m_nPageSize ; // Largest possible index for first item
int nMaxThumb = RectHeight ( m_rcTrack ) - RectHeight ( m_rcThumb ) ; // Largest possible thumb position from the top
m_nPosition = m_nStart +
( m_rcThumb . top - m_rcTrack . top +
nMaxThumb / ( nMaxFirstItem * 2 ) ) * // Shift by half a row to avoid last row covered by only one pixel
nMaxFirstItem / nMaxThumb ;
return true ;
}
break ;
}
}
return false ;
}
//--------------------------------------------------------------------------------------
void CDXUTScrollBar : : Render ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
// Check if the arrow button has been held for a while.
// If so, update the thumb position to simulate repeated
// scroll.
if ( m_Arrow ! = CLEAR )
{
double dCurrTime = DXUTGetTime ( ) ;
if ( PtInRect ( & m_rcUpButton , m_LastMouse ) )
{
switch ( m_Arrow )
{
case CLICKED_UP :
if ( SCROLLBAR_ARROWCLICK_DELAY < dCurrTime - m_dArrowTS )
{
Scroll ( - 1 ) ;
m_Arrow = HELD_UP ;
m_dArrowTS = dCurrTime ;
}
break ;
case HELD_UP :
if ( SCROLLBAR_ARROWCLICK_REPEAT < dCurrTime - m_dArrowTS )
{
Scroll ( - 1 ) ;
m_dArrowTS = dCurrTime ;
}
break ;
}
} else
if ( PtInRect ( & m_rcDownButton , m_LastMouse ) )
{
switch ( m_Arrow )
{
case CLICKED_DOWN :
if ( SCROLLBAR_ARROWCLICK_DELAY < dCurrTime - m_dArrowTS )
{
Scroll ( 1 ) ;
m_Arrow = HELD_DOWN ;
m_dArrowTS = dCurrTime ;
}
break ;
case HELD_DOWN :
if ( SCROLLBAR_ARROWCLICK_REPEAT < dCurrTime - m_dArrowTS )
{
Scroll ( 1 ) ;
m_dArrowTS = dCurrTime ;
}
break ;
}
}
}
DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL ;
if ( m_bVisible = = false )
iState = DXUT_STATE_HIDDEN ;
else if ( m_bEnabled = = false | | m_bShowThumb = = false )
iState = DXUT_STATE_DISABLED ;
else if ( m_bMouseOver )
iState = DXUT_STATE_MOUSEOVER ;
else if ( m_bHasFocus )
iState = DXUT_STATE_FOCUS ;
float fBlendRate = ( iState = = DXUT_STATE_PRESSED ) ? 0.0f : 0.8f ;
// Background track layer
CDXUTElement * pElement = m_Elements . GetAt ( 0 ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcTrack ) ;
// Up Arrow
pElement = m_Elements . GetAt ( 1 ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcUpButton ) ;
// Down Arrow
pElement = m_Elements . GetAt ( 2 ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcDownButton ) ;
// Thumb button
pElement = m_Elements . GetAt ( 3 ) ;
// Blend current color
pElement - > TextureColor . Blend ( iState , fElapsedTime , fBlendRate ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcThumb ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTScrollBar : : SetTrackRange ( int nStart , int nEnd )
{
m_nStart = nStart ; m_nEnd = nEnd ;
Cap ( ) ;
UpdateThumbRect ( ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTScrollBar : : Cap ( ) // Clips position at boundaries. Ensures it stays within legal range.
{
if ( m_nPosition < m_nStart | |
m_nEnd - m_nStart < = m_nPageSize )
{
m_nPosition = m_nStart ;
}
else
if ( m_nPosition + m_nPageSize > m_nEnd )
m_nPosition = m_nEnd - m_nPageSize ;
}
//--------------------------------------------------------------------------------------
// CDXUTListBox class
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CDXUTListBox : : CDXUTListBox ( CDXUTDialog * pDialog ) :
m_ScrollBar ( pDialog )
{
m_Type = DXUT_CONTROL_LISTBOX ;
m_pDialog = pDialog ;
m_dwStyle = 0 ;
m_nSBWidth = 16 ;
m_nSelected = - 1 ;
m_nSelStart = 0 ;
m_bDrag = false ;
m_nBorder = 6 ;
m_nMargin = 5 ;
m_nTextHeight = 0 ;
}
//--------------------------------------------------------------------------------------
CDXUTListBox : : ~ CDXUTListBox ( )
{
RemoveAllItems ( ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTListBox : : UpdateRects ( )
{
CDXUTControl : : UpdateRects ( ) ;
m_rcSelection = m_rcBoundingBox ;
m_rcSelection . right - = m_nSBWidth ;
InflateRect ( & m_rcSelection , - m_nBorder , - m_nBorder ) ;
m_rcText = m_rcSelection ;
InflateRect ( & m_rcText , - m_nMargin , 0 ) ;
// Update the scrollbar's rects
m_ScrollBar . SetLocation ( m_rcBoundingBox . right - m_nSBWidth , m_rcBoundingBox . top ) ;
m_ScrollBar . SetSize ( m_nSBWidth , m_height ) ;
DXUTFontNode * pFontNode = m_pDialog - > GetManager ( ) - > GetFontNode ( m_Elements . GetAt ( 0 ) - > iFont ) ;
if ( pFontNode & & pFontNode - > nHeight )
{
m_ScrollBar . SetPageSize ( RectHeight ( m_rcText ) / pFontNode - > nHeight ) ;
// The selected item may have been scrolled off the page.
// Ensure that it is in page again.
m_ScrollBar . ShowItem ( m_nSelected ) ;
}
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTListBox : : AddItem ( const TCHAR * wszText , void * pData )
{
DXUTListBoxItem * pNewItem = new DXUTListBoxItem ;
if ( ! pNewItem )
return E_OUTOFMEMORY ;
StringCchCopy ( pNewItem - > strText , 256 , wszText ) ;
pNewItem - > pData = pData ;
SetRect ( & pNewItem - > rcActive , 0 , 0 , 0 , 0 ) ;
pNewItem - > bSelected = false ;
HRESULT hr = m_Items . Add ( pNewItem ) ;
if ( FAILED ( hr ) )
{
SAFE_DELETE ( pNewItem ) ;
}
else
{
m_ScrollBar . SetTrackRange ( 0 , m_Items . GetSize ( ) ) ;
}
return hr ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTListBox : : InsertItem ( int nIndex , const TCHAR * wszText , void * pData )
{
DXUTListBoxItem * pNewItem = new DXUTListBoxItem ;
if ( ! pNewItem )
return E_OUTOFMEMORY ;
StringCchCopy ( pNewItem - > strText , 256 , wszText ) ;
pNewItem - > pData = pData ;
SetRect ( & pNewItem - > rcActive , 0 , 0 , 0 , 0 ) ;
pNewItem - > bSelected = false ;
HRESULT hr = m_Items . Insert ( nIndex , pNewItem ) ;
if ( SUCCEEDED ( hr ) )
m_ScrollBar . SetTrackRange ( 0 , m_Items . GetSize ( ) ) ;
else
SAFE_DELETE ( pNewItem ) ;
return hr ;
}
//--------------------------------------------------------------------------------------
void CDXUTListBox : : RemoveItem ( int nIndex )
{
if ( nIndex < 0 | | nIndex > = ( int ) m_Items . GetSize ( ) )
return ;
DXUTListBoxItem * pItem = m_Items . GetAt ( nIndex ) ;
delete pItem ;
m_Items . Remove ( nIndex ) ;
m_ScrollBar . SetTrackRange ( 0 , m_Items . GetSize ( ) ) ;
if ( m_nSelected > = ( int ) m_Items . GetSize ( ) )
m_nSelected = m_Items . GetSize ( ) - 1 ;
m_pDialog - > SendEvent ( EVENT_LISTBOX_SELECTION , true , this ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTListBox : : RemoveItemByText ( TCHAR * wszText )
{
}
//--------------------------------------------------------------------------------------
void CDXUTListBox : : RemoveItemByData ( void * pData )
{
}
//--------------------------------------------------------------------------------------
// MATCH
void CDXUTListBox : : RemoveAllItems ( )
{
for ( int i = 0 ; i < m_Items . GetSize ( ) ; + + i )
{
DXUTListBoxItem * pItem = m_Items . GetAt ( i ) ;
delete pItem ;
}
m_Items . RemoveAll ( ) ;
m_ScrollBar . SetTrackRange ( 0 , 1 ) ;
}
//--------------------------------------------------------------------------------------
DXUTListBoxItem * CDXUTListBox : : GetItem ( int nIndex )
{
if ( nIndex < 0 | | nIndex > = ( int ) m_Items . GetSize ( ) )
return NULL ;
return m_Items [ nIndex ] ;
}
//--------------------------------------------------------------------------------------
// For single-selection listbox, returns the index of the selected item.
// For multi-selection, returns the first selected item after the nPreviousSelected position.
// To search for the first selected item, the app passes -1 for nPreviousSelected. For
// subsequent searches, the app passes the returned index back to GetSelectedIndex as.
// nPreviousSelected.
// Returns -1 on error or if no item is selected.
int CDXUTListBox : : GetSelectedIndex ( int nPreviousSelected )
{
if ( nPreviousSelected < - 1 )
return - 1 ;
if ( m_dwStyle & MULTISELECTION )
{
// Multiple selection enabled. Search for the next item with the selected flag.
for ( int i = nPreviousSelected + 1 ; i < ( int ) m_Items . GetSize ( ) ; + + i )
{
DXUTListBoxItem * pItem = m_Items . GetAt ( i ) ;
if ( pItem - > bSelected )
return i ;
}
return - 1 ;
}
else
{
// Single selection
return m_nSelected ;
}
}
//--------------------------------------------------------------------------------------
void CDXUTListBox : : SelectItem ( int nNewIndex )
{
// If no item exists, do nothing.
if ( m_Items . GetSize ( ) = = 0 )
return ;
int nOldSelected = m_nSelected ;
// Adjust m_nSelected
m_nSelected = nNewIndex ;
// Perform capping
if ( m_nSelected < 0 )
m_nSelected = 0 ;
if ( m_nSelected > = ( int ) m_Items . GetSize ( ) )
m_nSelected = m_Items . GetSize ( ) - 1 ;
if ( nOldSelected ! = m_nSelected )
{
if ( m_dwStyle & MULTISELECTION )
{
m_Items [ m_nSelected ] - > bSelected = true ;
}
// Update selection start
m_nSelStart = m_nSelected ;
// Adjust scroll bar
m_ScrollBar . ShowItem ( m_nSelected ) ;
}
m_pDialog - > SendEvent ( EVENT_LISTBOX_SELECTION , true , this ) ;
}
//--------------------------------------------------------------------------------------
bool CDXUTListBox : : HandleKeyboard ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
// Let the scroll bar have a chance to handle it first
if ( m_ScrollBar . HandleKeyboard ( uMsg , wParam , lParam ) )
return true ;
switch ( uMsg )
{
case WM_KEYDOWN :
switch ( wParam )
{
case VK_UP :
case VK_DOWN :
case VK_NEXT :
case VK_PRIOR :
case VK_HOME :
case VK_END :
// If no item exists, do nothing.
if ( m_Items . GetSize ( ) = = 0 )
return true ;
int nOldSelected = m_nSelected ;
// Adjust m_nSelected
switch ( wParam )
{
case VK_UP : - - m_nSelected ; break ;
case VK_DOWN : + + m_nSelected ; break ;
case VK_NEXT : m_nSelected + = m_ScrollBar . GetPageSize ( ) - 1 ; break ;
case VK_PRIOR : m_nSelected - = m_ScrollBar . GetPageSize ( ) - 1 ; break ;
case VK_HOME : m_nSelected = 0 ; break ;
case VK_END : m_nSelected = m_Items . GetSize ( ) - 1 ; break ;
}
// Perform capping
if ( m_nSelected < 0 )
m_nSelected = 0 ;
if ( m_nSelected > = ( int ) m_Items . GetSize ( ) )
m_nSelected = m_Items . GetSize ( ) - 1 ;
if ( nOldSelected ! = m_nSelected )
{
if ( m_dwStyle & MULTISELECTION )
{
// Multiple selection
// Clear all selection
for ( int i = 0 ; i < ( int ) m_Items . GetSize ( ) ; + + i )
{
DXUTListBoxItem * pItem = m_Items [ i ] ;
pItem - > bSelected = false ;
}
if ( GetKeyState ( VK_SHIFT ) < 0 )
{
// Select all items from m_nSelStart to
// m_nSelected
int nEnd = __max ( m_nSelStart , m_nSelected ) ;
for ( int n = __min ( m_nSelStart , m_nSelected ) ; n < = nEnd ; + + n )
m_Items [ n ] - > bSelected = true ;
}
else
{
m_Items [ m_nSelected ] - > bSelected = true ;
// Update selection start
m_nSelStart = m_nSelected ;
}
} else
m_nSelStart = m_nSelected ;
// Adjust scroll bar
m_ScrollBar . ShowItem ( m_nSelected ) ;
// Send notification
m_pDialog - > SendEvent ( EVENT_LISTBOX_SELECTION , true , this ) ;
}
return true ;
}
break ;
}
return false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTListBox : : HandleMouse ( UINT uMsg , POINT pt , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
// First acquire focus
if ( WM_LBUTTONDOWN = = uMsg )
if ( ! m_bHasFocus )
m_pDialog - > RequestFocus ( this ) ;
// Let the scroll bar handle it first.
if ( m_ScrollBar . HandleMouse ( uMsg , pt , wParam , lParam ) )
return true ;
switch ( uMsg )
{
case WM_LBUTTONDOWN :
case WM_LBUTTONDBLCLK :
// Check for clicks in the text area
if ( m_Items . GetSize ( ) > 0 & & PtInRect ( & m_rcSelection , pt ) )
{
// Compute the index of the clicked item
int nClicked ;
if ( m_nTextHeight )
nClicked = m_ScrollBar . GetTrackPos ( ) + ( pt . y - m_rcText . top ) / m_nTextHeight ;
else
nClicked = - 1 ;
// Only proceed if the click falls on top of an item.
if ( nClicked > = m_ScrollBar . GetTrackPos ( ) & &
nClicked < ( int ) m_Items . GetSize ( ) & &
nClicked < m_ScrollBar . GetTrackPos ( ) + m_ScrollBar . GetPageSize ( ) )
{
SetCapture ( DXUTGetHWND ( ) ) ;
m_bDrag = true ;
// If this is a double click, fire off an event and exit
// since the first click would have taken care of the selection
// updating.
if ( uMsg = = WM_LBUTTONDBLCLK )
{
m_pDialog - > SendEvent ( EVENT_LISTBOX_ITEM_DBLCLK , true , this ) ;
return true ;
}
m_nSelected = nClicked ;
if ( ! ( wParam & MK_SHIFT ) )
m_nSelStart = m_nSelected ;
// If this is a multi-selection listbox, update per-item
// selection data.
if ( m_dwStyle & MULTISELECTION )
{
// Determine behavior based on the state of Shift and Ctrl
DXUTListBoxItem * pSelItem = m_Items . GetAt ( m_nSelected ) ;
if ( ( wParam & ( MK_SHIFT | MK_CONTROL ) ) = = MK_CONTROL )
{
// Control click. Reverse the selection of this item.
pSelItem - > bSelected = ! pSelItem - > bSelected ;
} else
if ( ( wParam & ( MK_SHIFT | MK_CONTROL ) ) = = MK_SHIFT )
{
// Shift click. Set the selection for all items
// from last selected item to the current item.
// Clear everything else.
int nBegin = __min ( m_nSelStart , m_nSelected ) ;
int nEnd = __max ( m_nSelStart , m_nSelected ) ;
for ( int i = 0 ; i < nBegin ; + + i )
{
DXUTListBoxItem * pItem = m_Items . GetAt ( i ) ;
pItem - > bSelected = false ;
}
for ( int i = nEnd + 1 ; i < ( int ) m_Items . GetSize ( ) ; + + i )
{
DXUTListBoxItem * pItem = m_Items . GetAt ( i ) ;
pItem - > bSelected = false ;
}
for ( int i = nBegin ; i < = nEnd ; + + i )
{
DXUTListBoxItem * pItem = m_Items . GetAt ( i ) ;
pItem - > bSelected = true ;
}
} else
if ( ( wParam & ( MK_SHIFT | MK_CONTROL ) ) = = ( MK_SHIFT | MK_CONTROL ) )
{
// Control-Shift-click.
// The behavior is:
// Set all items from m_nSelStart to m_nSelected to
// the same state as m_nSelStart, not including m_nSelected.
// Set m_nSelected to selected.
int nBegin = __min ( m_nSelStart , m_nSelected ) ;
int nEnd = __max ( m_nSelStart , m_nSelected ) ;
// The two ends do not need to be set here.
bool bLastSelected = m_Items . GetAt ( m_nSelStart ) - > bSelected ;
for ( int i = nBegin + 1 ; i < nEnd ; + + i )
{
DXUTListBoxItem * pItem = m_Items . GetAt ( i ) ;
pItem - > bSelected = bLastSelected ;
}
pSelItem - > bSelected = true ;
// Restore m_nSelected to the previous value
// This matches the Windows behavior
m_nSelected = m_nSelStart ;
} else
{
// Simple click. Clear all items and select the clicked
// item.
for ( int i = 0 ; i < ( int ) m_Items . GetSize ( ) ; + + i )
{
DXUTListBoxItem * pItem = m_Items . GetAt ( i ) ;
pItem - > bSelected = false ;
}
pSelItem - > bSelected = true ;
}
} // End of multi-selection case
m_pDialog - > SendEvent ( EVENT_LISTBOX_SELECTION , true , this ) ;
}
return true ;
}
break ;
case WM_LBUTTONUP :
{
ReleaseCapture ( ) ;
m_bDrag = false ;
if ( m_nSelected ! = - 1 )
{
// Set all items between m_nSelStart and m_nSelected to
// the same state as m_nSelStart
int nEnd = __max ( m_nSelStart , m_nSelected ) ;
for ( int n = __min ( m_nSelStart , m_nSelected ) + 1 ; n < nEnd ; + + n )
m_Items [ n ] - > bSelected = m_Items [ m_nSelStart ] - > bSelected ;
m_Items [ m_nSelected ] - > bSelected = m_Items [ m_nSelStart ] - > bSelected ;
// If m_nSelStart and m_nSelected are not the same,
// the user has dragged the mouse to make a selection.
// Notify the application of this.
if ( m_nSelStart ! = m_nSelected )
m_pDialog - > SendEvent ( EVENT_LISTBOX_SELECTION , true , this ) ;
}
return false ;
}
case WM_MOUSEMOVE :
if ( m_bDrag )
{
// Compute the index of the item below cursor
int nItem ;
if ( m_nTextHeight )
nItem = m_ScrollBar . GetTrackPos ( ) + ( pt . y - m_rcText . top ) / m_nTextHeight ;
else
nItem = - 1 ;
// Only proceed if the cursor is on top of an item.
if ( nItem > = ( int ) m_ScrollBar . GetTrackPos ( ) & &
nItem < ( int ) m_Items . GetSize ( ) & &
nItem < m_ScrollBar . GetTrackPos ( ) + m_ScrollBar . GetPageSize ( ) )
{
m_nSelected = nItem ;
m_pDialog - > SendEvent ( EVENT_LISTBOX_SELECTION , true , this ) ;
} else
if ( nItem < ( int ) m_ScrollBar . GetTrackPos ( ) )
{
// User drags the mouse above window top
m_ScrollBar . Scroll ( - 1 ) ;
m_nSelected = m_ScrollBar . GetTrackPos ( ) ;
m_pDialog - > SendEvent ( EVENT_LISTBOX_SELECTION , true , this ) ;
} else
if ( nItem > = m_ScrollBar . GetTrackPos ( ) + m_ScrollBar . GetPageSize ( ) )
{
// User drags the mouse below window bottom
m_ScrollBar . Scroll ( 1 ) ;
m_nSelected = __min ( ( int ) m_Items . GetSize ( ) , m_ScrollBar . GetTrackPos ( ) + m_ScrollBar . GetPageSize ( ) ) - 1 ;
m_pDialog - > SendEvent ( EVENT_LISTBOX_SELECTION , true , this ) ;
}
}
break ;
case WM_MOUSEWHEEL :
{
UINT uLines ;
SystemParametersInfo ( SPI_GETWHEELSCROLLLINES , 0 , & uLines , 0 ) ;
int nScrollAmount = int ( ( short ) HIWORD ( wParam ) ) / WHEEL_DELTA * uLines ;
m_ScrollBar . Scroll ( - nScrollAmount ) ;
return true ;
}
}
return false ;
}
//--------------------------------------------------------------------------------------
void CDXUTListBox : : Render ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
if ( m_bVisible = = false )
return ;
CDXUTElement * pElement = m_Elements . GetAt ( 0 ) ;
pElement - > TextureColor . Blend ( DXUT_STATE_NORMAL , fElapsedTime ) ;
pElement - > FontColor . Blend ( DXUT_STATE_NORMAL , fElapsedTime ) ;
CDXUTElement * pSelElement = m_Elements . GetAt ( 1 ) ;
pSelElement - > TextureColor . Blend ( DXUT_STATE_NORMAL , fElapsedTime ) ;
pSelElement - > FontColor . Blend ( DXUT_STATE_NORMAL , fElapsedTime ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcBoundingBox ) ;
// Render the text
if ( m_Items . GetSize ( ) > 0 )
{
// Find out the height of a single line of text
/*RECT rc = m_rcText;
RECT rcSel = m_rcSelection ;
rc . bottom = rc . top + m_pDialog - > GetManager ( ) - > GetFontNode ( pElement - > iFont ) - > nHeight ;
// Update the line height formation
m_nTextHeight = rc . bottom - rc . top ;
static bool bSBInit ;
if ( ! bSBInit )
{
// Update the page size of the scroll bar
if ( m_nTextHeight )
m_ScrollBar . SetPageSize ( RectHeight ( m_rcText ) / m_nTextHeight ) ;
else
m_ScrollBar . SetPageSize ( RectHeight ( m_rcText ) ) ;
bSBInit = true ;
}
rc . right = m_rcText . right ;
for ( int i = m_ScrollBar . GetTrackPos ( ) ; i < ( int ) m_Items . GetSize ( ) ; + + i )
{
if ( rc . bottom > m_rcText . bottom )
break ;
DXUTListBoxItem * pItem = m_Items . GetAt ( i ) ;
// Determine if we need to render this item with the
// selected element.
bool bSelectedStyle = false ;
if ( ! ( m_dwStyle & MULTISELECTION ) & & i = = m_nSelected )
bSelectedStyle = true ;
else
if ( m_dwStyle & MULTISELECTION )
{
if ( m_bDrag & &
( ( i > = m_nSelected & & i < m_nSelStart ) | |
( i < = m_nSelected & & i > m_nSelStart ) ) )
bSelectedStyle = m_Items [ m_nSelStart ] - > bSelected ;
else
if ( pItem - > bSelected )
bSelectedStyle = true ;
}
if ( bSelectedStyle )
{
rcSel . top = rc . top ; rcSel . bottom = rc . bottom ;
m_pDialog - > DrawSprite ( pSelElement , & rcSel ) ;
m_pDialog - > DrawText ( pItem - > strText , pSelElement , & rc ) ;
}
else
m_pDialog - > DrawText ( pItem - > strText , pElement , & rc ) ;
OffsetRect ( & rc , 0 , m_nTextHeight ) ;
} */
}
// Render the scroll bar
m_ScrollBar . Render ( pd3dDevice , fElapsedTime ) ;
}
// Static member initialization
HINSTANCE CUniBuffer : : s_hDll = NULL ;
HRESULT ( WINAPI * CUniBuffer : : _ScriptApplyDigitSubstitution ) ( const SCRIPT_DIGITSUBSTITUTE * , SCRIPT_CONTROL * , SCRIPT_STATE * ) = Dummy_ScriptApplyDigitSubstitution ;
HRESULT ( WINAPI * CUniBuffer : : _ScriptStringAnalyse ) ( HDC , const void * , int , int , int , DWORD , int , SCRIPT_CONTROL * , SCRIPT_STATE * , const int * , SCRIPT_TABDEF * , const BYTE * , SCRIPT_STRING_ANALYSIS * ) = Dummy_ScriptStringAnalyse ;
HRESULT ( WINAPI * CUniBuffer : : _ScriptStringCPtoX ) ( SCRIPT_STRING_ANALYSIS , int , BOOL , int * ) = Dummy_ScriptStringCPtoX ;
HRESULT ( WINAPI * CUniBuffer : : _ScriptStringXtoCP ) ( SCRIPT_STRING_ANALYSIS , int , int * , int * ) = Dummy_ScriptStringXtoCP ;
HRESULT ( WINAPI * CUniBuffer : : _ScriptStringFree ) ( SCRIPT_STRING_ANALYSIS * ) = Dummy_ScriptStringFree ;
const SCRIPT_LOGATTR * ( WINAPI * CUniBuffer : : _ScriptString_pLogAttr ) ( SCRIPT_STRING_ANALYSIS ) = Dummy_ScriptString_pLogAttr ;
const int * ( WINAPI * CUniBuffer : : _ScriptString_pcOutChars ) ( SCRIPT_STRING_ANALYSIS ) = Dummy_ScriptString_pcOutChars ;
bool CDXUTEditBox : : s_bHideCaret ; // If true, we don't render the caret.
//--------------------------------------------------------------------------------------
// CDXUTEditBox class
//--------------------------------------------------------------------------------------
// When scrolling, EDITBOX_SCROLLEXTENT is reciprocal of the amount to scroll.
// If EDITBOX_SCROLLEXTENT = 4, then we scroll 1/4 of the control each time.
# define EDITBOX_SCROLLEXTENT 4
//--------------------------------------------------------------------------------------
CDXUTEditBox : : CDXUTEditBox ( CDXUTDialog * pDialog )
{
m_Type = DXUT_CONTROL_EDITBOX ;
m_pDialog = pDialog ;
m_nBorder = 5 ; // Default border width
m_nSpacing = 4 ; // Default spacing
m_bCaretOn = true ;
m_dfBlink = GetCaretBlinkTime ( ) * 0.001f ;
m_dfLastBlink = DXUTGetGlobalTimer ( ) - > GetAbsoluteTime ( ) ;
s_bHideCaret = false ;
m_nFirstVisible = 0 ;
m_TextColor = D3DCOLOR_ARGB ( 255 , 16 , 16 , 16 ) ;
m_SelTextColor = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
m_SelBkColor = D3DCOLOR_ARGB ( 255 , 40 , 50 , 92 ) ;
m_CaretColor = D3DCOLOR_ARGB ( 255 , 0 , 0 , 0 ) ;
m_nCaret = m_nSelStart = 0 ;
m_bInsertMode = true ;
m_bMouseDrag = false ;
field_126 = 0 ;
}
//--------------------------------------------------------------------------------------
CDXUTEditBox : : ~ CDXUTEditBox ( )
{
}
//--------------------------------------------------------------------------------------
// PlaceCaret: Set the caret to a character position, and adjust the scrolling if
// necessary.
//--------------------------------------------------------------------------------------
void CDXUTEditBox : : PlaceCaret ( int nCP )
{
assert ( nCP > = 0 & & nCP < = m_Buffer . GetTextSize ( ) ) ;
m_nCaret = nCP ;
// Obtain the X offset of the character.
int nX1st , nX , nX2 ;
m_Buffer . CPtoX ( m_nFirstVisible , FALSE , & nX1st ) ; // 1st visible char
m_Buffer . CPtoX ( nCP , FALSE , & nX ) ; // LEAD
// If nCP is the NULL terminator, get the leading edge instead of trailing.
if ( nCP = = m_Buffer . GetTextSize ( ) )
nX2 = nX ;
else
m_Buffer . CPtoX ( nCP , TRUE , & nX2 ) ; // TRAIL
// If the left edge of the char is smaller than the left edge of the 1st visible char,
// we need to scroll left until this char is visible.
if ( nX < nX1st )
{
// Simply make the first visible character the char at the new caret position.
m_nFirstVisible = nCP ;
}
else
// If the right of the character is bigger than the offset of the control's
// right edge, we need to scroll right to this character.
if ( nX2 > nX1st + RectWidth ( m_rcText ) )
{
// Compute the X of the new left-most pixel
int nXNewLeft = nX2 - RectWidth ( m_rcText ) ;
// Compute the char position of this character
int nCPNew1st , nNewTrail ;
m_Buffer . XtoCP ( nXNewLeft , & nCPNew1st , & nNewTrail ) ;
// If this coordinate is not on a character border,
// start from the next character so that the caret
// position does not fall outside the text rectangle.
int nXNew1st ;
m_Buffer . CPtoX ( nCPNew1st , FALSE , & nXNew1st ) ;
if ( nXNew1st < nXNewLeft )
+ + nCPNew1st ;
m_nFirstVisible = nCPNew1st ;
}
}
//--------------------------------------------------------------------------------------
void CDXUTEditBox : : ClearText ( )
{
m_Buffer . Clear ( ) ;
m_nFirstVisible = 0 ;
PlaceCaret ( 0 ) ;
m_nSelStart = 0 ;
}
//--------------------------------------------------------------------------------------
void CDXUTEditBox : : SetText ( LPCTSTR wszText , bool bSelected )
{
assert ( wszText ! = NULL ) ;
m_Buffer . SetText ( wszText ) ;
m_nFirstVisible = 0 ;
// Move the caret to the end of the text
PlaceCaret ( m_Buffer . GetTextSize ( ) ) ;
m_nSelStart = bSelected ? 0 : m_nCaret ;
}
//--------------------------------------------------------------------------------------
PCHAR ConvertWideToAnsi ( PWCHAR wszText )
{
static CHAR MultiByteStr [ 2048 ] ;
ZeroMemory ( & MultiByteStr [ 0 ] , sizeof ( MultiByteStr ) ) ;
int nRequiredSize = WideCharToMultiByte ( CP_ACP , 0 , wszText , wcslen ( wszText ) , NULL , 0 , NULL , NULL ) ;
if ( nRequiredSize < = 2048 )
{
WideCharToMultiByte ( CP_ACP , 0 , wszText , wcslen ( wszText ) , MultiByteStr , nRequiredSize , NULL , NULL ) ;
MultiByteStr [ nRequiredSize ] = 0 ;
}
return MultiByteStr ;
}
PCHAR CDXUTEditBox : : GetTextA ( )
{
return ConvertWideToAnsi ( ( PWCHAR ) m_Buffer . GetBuffer ( ) ) ;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTEditBox : : GetTextCopy ( PWCHAR strDest , UINT bufferCount )
{
assert ( strDest ) ;
StringCchCopyW ( strDest , bufferCount , m_Buffer . GetBuffer ( ) ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
void CDXUTEditBox : : DeleteSelectionText ( )
{
int nFirst = __min ( m_nCaret , m_nSelStart ) ;
int nLast = __max ( m_nCaret , m_nSelStart ) ;
// Update caret and selection
PlaceCaret ( nFirst ) ;
m_nSelStart = m_nCaret ;
// Remove the characters
for ( int i = nFirst ; i < nLast ; + + i )
m_Buffer . RemoveChar ( nFirst ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTEditBox : : UpdateRects ( )
{
CDXUTControl : : UpdateRects ( ) ;
// Update the text rectangle
m_rcText = m_rcBoundingBox ;
// First inflate by m_nBorder to compute render rects
InflateRect ( & m_rcText , - m_nBorder , - m_nBorder ) ;
// Update the render rectangles
m_rcRender [ 0 ] = m_rcText ;
SetRect ( & m_rcRender [ 1 ] , m_rcBoundingBox . left , m_rcBoundingBox . top , m_rcText . left , m_rcText . top ) ;
SetRect ( & m_rcRender [ 2 ] , m_rcText . left , m_rcBoundingBox . top , m_rcText . right , m_rcText . top ) ;
SetRect ( & m_rcRender [ 3 ] , m_rcText . right , m_rcBoundingBox . top , m_rcBoundingBox . right , m_rcText . top ) ;
SetRect ( & m_rcRender [ 4 ] , m_rcBoundingBox . left , m_rcText . top , m_rcText . left , m_rcText . bottom ) ;
SetRect ( & m_rcRender [ 5 ] , m_rcText . right , m_rcText . top , m_rcBoundingBox . right , m_rcText . bottom ) ;
SetRect ( & m_rcRender [ 6 ] , m_rcBoundingBox . left , m_rcText . bottom , m_rcText . left , m_rcBoundingBox . bottom ) ;
SetRect ( & m_rcRender [ 7 ] , m_rcText . left , m_rcText . bottom , m_rcText . right , m_rcBoundingBox . bottom ) ;
SetRect ( & m_rcRender [ 8 ] , m_rcText . right , m_rcText . bottom , m_rcBoundingBox . right , m_rcBoundingBox . bottom ) ;
// Inflate further by m_nSpacing
InflateRect ( & m_rcText , - m_nSpacing , - m_nSpacing ) ;
}
void CDXUTEditBox : : CopyToClipboard ( )
{
// Copy the selection text to the clipboard
if ( m_nCaret ! = m_nSelStart & & OpenClipboard ( NULL ) )
{
EmptyClipboard ( ) ;
HGLOBAL hBlock = GlobalAlloc ( GMEM_MOVEABLE , sizeof ( TCHAR ) * ( m_Buffer . GetTextSize ( ) + 1 ) ) ;
if ( hBlock )
{
TCHAR * pwszText = ( TCHAR * ) GlobalLock ( hBlock ) ;
if ( pwszText )
{
int nFirst = __min ( m_nCaret , m_nSelStart ) ;
int nLast = __max ( m_nCaret , m_nSelStart ) ;
if ( nLast - nFirst > 0 )
CopyMemory ( pwszText , m_Buffer . GetBuffer ( ) + nFirst , ( nLast - nFirst ) * sizeof ( TCHAR ) ) ;
pwszText [ nLast - nFirst ] = L ' \0 ' ; // Terminate it
GlobalUnlock ( hBlock ) ;
}
SetClipboardData ( CF_OEMTEXT , hBlock ) ;
}
CloseClipboard ( ) ;
// We must not free the object until CloseClipboard is called.
if ( hBlock )
GlobalFree ( hBlock ) ;
}
}
void CDXUTEditBox : : PasteFromClipboard ( )
{
DeleteSelectionText ( ) ;
if ( OpenClipboard ( NULL ) )
{
HANDLE handle = GetClipboardData ( CF_OEMTEXT ) ;
if ( handle )
{
// Convert the ANSI string to Unicode, then
// insert to our buffer.
WCHAR * pwszText = ( WCHAR * ) GlobalLock ( handle ) ;
if ( pwszText )
{
// Copy all characters up to null.
if ( m_Buffer . InsertString ( m_nCaret , pwszText ) )
PlaceCaret ( m_nCaret + lstrlenW ( pwszText ) ) ;
m_nSelStart = m_nCaret ;
GlobalUnlock ( handle ) ;
}
}
CloseClipboard ( ) ;
}
}
//--------------------------------------------------------------------------------------
bool CDXUTEditBox : : HandleKeyboard ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
bool bHandled = false ;
switch ( uMsg )
{
case WM_KEYDOWN :
{
switch ( wParam )
{
case VK_TAB :
// We don't process Tab in case keyboard input is enabled and the user
// wishes to Tab to other controls.
break ;
case VK_HOME :
PlaceCaret ( 0 ) ;
if ( GetKeyState ( VK_SHIFT ) > = 0 )
// Shift is not down. Update selection
// start along with the caret.
m_nSelStart = m_nCaret ;
ResetCaretBlink ( ) ;
bHandled = true ;
break ;
case VK_END :
PlaceCaret ( m_Buffer . GetTextSize ( ) ) ;
if ( GetKeyState ( VK_SHIFT ) > = 0 )
// Shift is not down. Update selection
// start along with the caret.
m_nSelStart = m_nCaret ;
ResetCaretBlink ( ) ;
bHandled = true ;
break ;
case VK_INSERT :
if ( GetKeyState ( VK_CONTROL ) < 0 )
{
// Control Insert. Copy to clipboard
CopyToClipboard ( ) ;
} else
if ( GetKeyState ( VK_SHIFT ) < 0 )
{
// Shift Insert. Paste from clipboard
PasteFromClipboard ( ) ;
} else
{
// Toggle caret insert mode
m_bInsertMode = ! m_bInsertMode ;
}
break ;
case VK_DELETE :
// Check if there is a text selection.
if ( m_nCaret ! = m_nSelStart )
{
DeleteSelectionText ( ) ;
m_pDialog - > SendEvent ( EVENT_EDITBOX_CHANGE , true , this ) ;
}
else
{
// Deleting one character
if ( m_Buffer . RemoveChar ( m_nCaret ) )
m_pDialog - > SendEvent ( EVENT_EDITBOX_CHANGE , true , this ) ;
}
ResetCaretBlink ( ) ;
bHandled = true ;
break ;
case VK_LEFT :
if ( GetKeyState ( VK_CONTROL ) < 0 )
{
// Control is down. Move the caret to a new item
// instead of a character.
m_Buffer . GetPriorItemPos ( m_nCaret , & m_nCaret ) ;
PlaceCaret ( m_nCaret ) ;
}
else
if ( m_nCaret > 0 )
PlaceCaret ( m_nCaret - 1 ) ;
if ( GetKeyState ( VK_SHIFT ) > = 0 )
// Shift is not down. Update selection
// start along with the caret.
m_nSelStart = m_nCaret ;
ResetCaretBlink ( ) ;
bHandled = true ;
break ;
case VK_RIGHT :
if ( GetKeyState ( VK_CONTROL ) < 0 )
{
// Control is down. Move the caret to a new item
// instead of a character.
m_Buffer . GetNextItemPos ( m_nCaret , & m_nCaret ) ;
PlaceCaret ( m_nCaret ) ;
}
else
if ( m_nCaret < m_Buffer . GetTextSize ( ) )
PlaceCaret ( m_nCaret + 1 ) ;
if ( GetKeyState ( VK_SHIFT ) > = 0 )
// Shift is not down. Update selection
// start along with the caret.
m_nSelStart = m_nCaret ;
ResetCaretBlink ( ) ;
bHandled = true ;
break ;
case VK_UP :
case VK_DOWN :
// Trap up and down arrows so that the dialog
// does not switch focus to another control.
bHandled = true ;
break ;
default :
bHandled = wParam ! = VK_ESCAPE ; // Let the application handle Esc.
}
}
}
return bHandled ;
}
//--------------------------------------------------------------------------------------
bool CDXUTEditBox : : HandleMouse ( UINT uMsg , POINT pt , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_LBUTTONDOWN :
case WM_LBUTTONDBLCLK :
{
if ( ! m_bHasFocus )
m_pDialog - > RequestFocus ( this ) ;
if ( ! ContainsPoint ( pt ) )
return false ;
m_bMouseDrag = true ;
SetCapture ( DXUTGetHWND ( ) ) ;
// Determine the character corresponding to the coordinates.
int nCP , nTrail , nX1st ;
m_Buffer . CPtoX ( m_nFirstVisible , FALSE , & nX1st ) ; // X offset of the 1st visible char
if ( SUCCEEDED ( m_Buffer . XtoCP ( pt . x - m_rcText . left + nX1st , & nCP , & nTrail ) ) )
{
// Cap at the NULL character.
if ( nTrail & & nCP < m_Buffer . GetTextSize ( ) )
PlaceCaret ( nCP + 1 ) ;
else
PlaceCaret ( nCP ) ;
m_nSelStart = m_nCaret ;
ResetCaretBlink ( ) ;
}
return true ;
}
case WM_LBUTTONUP :
ReleaseCapture ( ) ;
m_bMouseDrag = false ;
break ;
case WM_MOUSEMOVE :
if ( m_bMouseDrag )
{
// Determine the character corresponding to the coordinates.
int nCP , nTrail , nX1st ;
m_Buffer . CPtoX ( m_nFirstVisible , FALSE , & nX1st ) ; // X offset of the 1st visible char
if ( SUCCEEDED ( m_Buffer . XtoCP ( pt . x - m_rcText . left + nX1st , & nCP , & nTrail ) ) )
{
// Cap at the NULL character.
if ( nTrail & & nCP < m_Buffer . GetTextSize ( ) )
PlaceCaret ( nCP + 1 ) ;
else
PlaceCaret ( nCP ) ;
}
}
break ;
}
return false ;
}
//--------------------------------------------------------------------------------------
void CDXUTEditBox : : OnFocusIn ( )
{
CDXUTControl : : OnFocusIn ( ) ;
ResetCaretBlink ( ) ;
}
//--------------------------------------------------------------------------------------
bool CDXUTEditBox : : MsgProc ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_CHAR :
{
switch ( ( TCHAR ) wParam )
{
// Backspace
case VK_BACK :
{
// If there's a selection, treat this
// like a delete key.
if ( m_nCaret ! = m_nSelStart )
{
DeleteSelectionText ( ) ;
m_pDialog - > SendEvent ( EVENT_EDITBOX_CHANGE , true , this ) ;
}
else
if ( m_nCaret > 0 )
{
// Move the caret, then delete the char.
PlaceCaret ( m_nCaret - 1 ) ;
m_nSelStart = m_nCaret ;
m_Buffer . RemoveChar ( m_nCaret ) ;
m_pDialog - > SendEvent ( EVENT_EDITBOX_CHANGE , true , this ) ;
}
ResetCaretBlink ( ) ;
break ;
}
case 24 : // Ctrl-X Cut
case VK_CANCEL : // Ctrl-C Copy
{
CopyToClipboard ( ) ;
// If the key is Ctrl-X, delete the selection too.
if ( ( TCHAR ) wParam = = 24 )
{
DeleteSelectionText ( ) ;
m_pDialog - > SendEvent ( EVENT_EDITBOX_CHANGE , true , this ) ;
}
break ;
}
// Ctrl-V Paste
case 22 :
{
PasteFromClipboard ( ) ;
m_pDialog - > SendEvent ( EVENT_EDITBOX_CHANGE , true , this ) ;
break ;
}
// Ctrl-A Select All
case 1 :
if ( m_nSelStart = = m_nCaret )
{
m_nSelStart = 0 ;
PlaceCaret ( m_Buffer . GetTextSize ( ) ) ;
}
break ;
// Enter char does nothing
case VK_RETURN :
break ;
// Junk characters we don't want in the string
case 26 : // Ctrl Z
case 2 : // Ctrl B
case 14 : // Ctrl N
case 19 : // Ctrl S
case 4 : // Ctrl D
case 6 : // Ctrl F
case 7 : // Ctrl G
case 10 : // Ctrl J
case 11 : // Ctrl K
case 12 : // Ctrl L
case 17 : // Ctrl Q
case 23 : // Ctrl W
case 5 : // Ctrl E
case 18 : // Ctrl R
case 20 : // Ctrl T
case 25 : // Ctrl Y
case 21 : // Ctrl U
case 9 : // Ctrl I
case 15 : // Ctrl O
case 16 : // Ctrl P
case 27 : // Ctrl [
case 29 : // Ctrl ]
case 28 : // Ctrl \
break ;
default :
{
// If there's a selection and the user
// starts to type, the selection should
// be deleted.
if ( m_nCaret ! = m_nSelStart )
DeleteSelectionText ( ) ;
if ( strlen ( GetTextA ( ) ) > = 128 ) return true ;
bool bPlaceCaret ;
// If we are in overwrite mode and there is already
// a char at the caret's position, simply replace it.
// Otherwise, we insert the char as normal.
if ( ! m_bInsertMode & & m_nCaret < m_Buffer . GetTextSize ( ) )
{
if ( ( WCHAR ) wParam > 255 )
{
m_Buffer [ m_nCaret ] = ( WCHAR ) wParam ;
PlaceCaret ( m_nCaret + 1 ) ;
m_nSelStart = m_nCaret ;
}
else
{
}
} else
{
// Insert the char
if ( ( WCHAR ) wParam < = 255 )
bPlaceCaret = m_Buffer . InsertChar ( m_nCaret , ( WCHAR ) wParam ) ;
else
bPlaceCaret = m_Buffer . InsertChar ( m_nCaret , ( CHAR ) wParam ) ;
}
ResetCaretBlink ( ) ;
m_pDialog - > SendEvent ( EVENT_EDITBOX_CHANGE , true , this ) ;
}
}
return true ;
}
case WM_KEYUP :
{
if ( wParam = = VK_RETURN ) {
// Invoke the callback when the user presses Enter.
m_pDialog - > SendEvent ( EVENT_EDITBOX_STRING , true , this ) ;
return true ;
}
break ;
}
}
return false ;
}
//--------------------------------------------------------------------------------------
void CDXUTEditBox : : Render ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
if ( m_bVisible = = false )
return ;
HRESULT hr ;
int nSelStartX = 0 , nCaretX = 0 ; // Left and right X cordinates of the selection region
CDXUTElement * pElement = GetElement ( 0 ) ;
if ( pElement )
{
m_Buffer . SetFontNode ( m_pDialog - > GetFont ( pElement - > iFont ) ) ;
PlaceCaret ( m_nCaret ) ; // Call PlaceCaret now that we have the font info (node),
// so that scrolling can be handled.
}
// Render the control graphics
for ( int e = 0 ; e < 9 ; + + e )
{
pElement = m_Elements . GetAt ( e ) ;
pElement - > TextureColor . Blend ( DXUT_STATE_NORMAL , fElapsedTime ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcRender [ e ] ) ;
}
//
// Compute the X coordinates of the first visible character.
//
int nXFirst ;
m_Buffer . CPtoX ( m_nFirstVisible , FALSE , & nXFirst ) ;
//
// Compute the X coordinates of the selection rectangle
//
hr = m_Buffer . CPtoX ( m_nCaret , FALSE , & nCaretX ) ;
if ( m_nCaret ! = m_nSelStart )
hr = m_Buffer . CPtoX ( m_nSelStart , FALSE , & nSelStartX ) ;
else
nSelStartX = nCaretX ;
//
// Render the selection rectangle
//
RECT rcSelection ; // Make this available for rendering selected text
if ( m_nCaret ! = m_nSelStart )
{
int nSelLeftX = nCaretX , nSelRightX = nSelStartX ;
// Swap if left is bigger than right
if ( nSelLeftX > nSelRightX )
{ int nTemp = nSelLeftX ; nSelLeftX = nSelRightX ; nSelRightX = nTemp ; }
SetRect ( & rcSelection , nSelLeftX , m_rcText . top , nSelRightX , m_rcText . bottom ) ;
OffsetRect ( & rcSelection , m_rcText . left - nXFirst , 0 ) ;
IntersectRect ( & rcSelection , & m_rcText , & rcSelection ) ;
m_pDialog - > DrawRect ( & rcSelection , m_SelBkColor ) ;
}
//
// Render the text
//
// Element 0 for text
m_Elements . GetAt ( 0 ) - > FontColor . Current = m_TextColor ;
m_pDialog - > DrawText ( m_Buffer . GetBuffer ( ) + m_nFirstVisible , m_Elements . GetAt ( 0 ) , & m_rcText ) ;
// Render the selected text
if ( m_nCaret ! = m_nSelStart )
{
int nFirstToRender = __max ( m_nFirstVisible , __min ( m_nSelStart , m_nCaret ) ) ;
int nNumChatToRender = __max ( m_nSelStart , m_nCaret ) - nFirstToRender ;
m_Elements . GetAt ( 0 ) - > FontColor . Current = m_SelTextColor ;
m_pDialog - > DrawText ( m_Buffer . GetBuffer ( ) + nFirstToRender ,
m_Elements . GetAt ( 0 ) , & rcSelection , false , nNumChatToRender ) ;
}
//
/* Blink the caret
//
if ( DXUTGetGlobalTimer ( ) - > GetAbsoluteTime ( ) - m_dfLastBlink > = m_dfBlink )
{
m_bCaretOn = ! m_bCaretOn ;
m_dfLastBlink = DXUTGetGlobalTimer ( ) - > GetAbsoluteTime ( ) ;
} */
//
// Render the caret if this control has the focus
//
//if( m_bHasFocus && m_bCaretOn && !s_bHideCaret )
//{
if ( m_bVisible & & m_bEnabled ) {
// Start the rectangle with insert mode caret
RECT rcCaret = { m_rcText . left - nXFirst + nCaretX - 1 , m_rcText . top ,
m_rcText . left - nXFirst + nCaretX + 1 , m_rcText . bottom } ;
// If we are in overwrite mode, adjust the caret rectangle
// to fill the entire character.
if ( ! m_bInsertMode )
{
// Obtain the right edge X coord of the current character
int nRightEdgeX ;
m_Buffer . CPtoX ( m_nCaret , TRUE , & nRightEdgeX ) ;
rcCaret . right = m_rcText . left - nXFirst + nRightEdgeX ;
}
m_pDialog - > DrawRect ( & rcCaret , m_CaretColor ) ;
}
}
# define IN_FLOAT_CHARSET( c ) \
( ( c ) = = L ' - ' | | ( c ) = = L ' . ' | | ( ( c ) > = L ' 0 ' & & ( c ) < = L ' 9 ' ) )
void CDXUTEditBox : : ParseFloatArray ( float * pNumbers , int nCount )
{
int nWritten = 0 ; // Number of floats written
const WCHAR * pToken , * pEnd ;
WCHAR wszToken [ 60 ] ;
pToken = m_Buffer . GetBuffer ( ) ;
while ( nWritten < nCount & & * pToken ! = L ' \0 ' )
{
// Skip leading spaces
while ( * pToken = = L ' ' )
+ + pToken ;
if ( * pToken = = L ' \0 ' )
break ;
// Locate the end of number
pEnd = pToken ;
while ( IN_FLOAT_CHARSET ( * pEnd ) )
+ + pEnd ;
// Copy the token to our buffer
int nTokenLen = __min ( sizeof ( wszToken ) / sizeof ( wszToken [ 0 ] ) - 1 , int ( pEnd - pToken ) ) ;
StringCchCopyW ( wszToken , nTokenLen , pToken ) ;
* pNumbers = ( float ) wcstod ( wszToken , NULL ) ;
+ + nWritten ;
+ + pNumbers ;
pToken = pEnd ;
}
}
void CDXUTEditBox : : SetTextFloatArray ( const float * pNumbers , int nCount )
{
TCHAR wszBuffer [ 512 ] = { 0 } ;
TCHAR wszTmp [ 64 ] ;
if ( pNumbers = = NULL )
return ;
for ( int i = 0 ; i < nCount ; + + i )
{
StringCchPrintf ( wszTmp , 64 , " %.4f " , pNumbers [ i ] ) ;
StringCchCat ( wszBuffer , 512 , wszTmp ) ;
}
// Don't want the last space
if ( nCount > 0 & & strlen ( wszBuffer ) > 0 )
wszBuffer [ strlen ( wszBuffer ) - 1 ] = 0 ;
SetText ( wszBuffer ) ;
}
//--------------------------------------------------------------------------------------
// CDXUTIMEEditBox class
//--------------------------------------------------------------------------------------
// IME constants
# define CHT_IMEFILENAME1 "TINTLGNT.IME" // New Phonetic
# define CHT_IMEFILENAME2 "CINTLGNT.IME" // New Chang Jie
# define CHT_IMEFILENAME3 "MSTCIPHA.IME" // Phonetic 5.1
# define CHS_IMEFILENAME1 "PINTLGNT.IME" // MSPY1.5/2/3
# define CHS_IMEFILENAME2 "MSSCIPYA.IME" // MSPY3 for OfficeXP
# define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
# define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
# define _CHT_HKL ( (HKL)(INT_PTR)0xE0080404 ) // New Phonetic
# define _CHT_HKL2 ( (HKL)(INT_PTR)0xE0090404 ) // New Chang Jie
# define _CHS_HKL ( (HKL)(INT_PTR)0xE00E0804 ) // MSPY
# define MAKEIMEVERSION( major, minor ) ( (DWORD)( ( (BYTE)( major ) << 24 ) | ( (BYTE)( minor ) << 16 ) ) )
# define IMEID_CHT_VER42 ( LANG_CHT | MAKEIMEVERSION( 4, 2 ) ) // New(Phonetic/ChanJie)IME98 : 4.2.x.x // Win98
# define IMEID_CHT_VER43 ( LANG_CHT | MAKEIMEVERSION( 4, 3 ) ) // New(Phonetic/ChanJie)IME98a : 4.3.x.x // Win2k
# define IMEID_CHT_VER44 ( LANG_CHT | MAKEIMEVERSION( 4, 4 ) ) // New ChanJie IME98b : 4.4.x.x // WinXP
# define IMEID_CHT_VER50 ( LANG_CHT | MAKEIMEVERSION( 5, 0 ) ) // New(Phonetic/ChanJie)IME5.0 : 5.0.x.x // WinME
# define IMEID_CHT_VER51 ( LANG_CHT | MAKEIMEVERSION( 5, 1 ) ) // New(Phonetic/ChanJie)IME5.1 : 5.1.x.x // IME2002(w/OfficeXP)
# define IMEID_CHT_VER52 ( LANG_CHT | MAKEIMEVERSION( 5, 2 ) ) // New(Phonetic/ChanJie)IME5.2 : 5.2.x.x // IME2002a(w/Whistler)
# define IMEID_CHT_VER60 ( LANG_CHT | MAKEIMEVERSION( 6, 0 ) ) // New(Phonetic/ChanJie)IME6.0 : 6.0.x.x // IME XP(w/WinXP SP1)
# define IMEID_CHS_VER41 ( LANG_CHS | MAKEIMEVERSION( 4, 1 ) ) // MSPY1.5 // SCIME97 or MSPY1.5 (w/Win98, Office97)
# define IMEID_CHS_VER42 ( LANG_CHS | MAKEIMEVERSION( 4, 2 ) ) // MSPY2 // Win2k/WinME
# define IMEID_CHS_VER53 ( LANG_CHS | MAKEIMEVERSION( 5, 3 ) ) // MSPY3 // WinXP
// Function pointers
INPUTCONTEXT * ( WINAPI * CDXUTIMEEditBox : : _ImmLockIMC ) ( HIMC ) = CDXUTIMEEditBox : : Dummy_ImmLockIMC ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmUnlockIMC ) ( HIMC ) = CDXUTIMEEditBox : : Dummy_ImmUnlockIMC ;
LPVOID ( WINAPI * CDXUTIMEEditBox : : _ImmLockIMCC ) ( HIMCC ) = CDXUTIMEEditBox : : Dummy_ImmLockIMCC ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmUnlockIMCC ) ( HIMCC ) = CDXUTIMEEditBox : : Dummy_ImmUnlockIMCC ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmDisableTextFrameService ) ( DWORD ) = CDXUTIMEEditBox : : Dummy_ImmDisableTextFrameService ;
LONG ( WINAPI * CDXUTIMEEditBox : : _ImmGetCompositionStringW ) ( HIMC , DWORD , LPVOID , DWORD ) = CDXUTIMEEditBox : : Dummy_ImmGetCompositionStringW ;
DWORD ( WINAPI * CDXUTIMEEditBox : : _ImmGetCandidateListW ) ( HIMC , DWORD , LPCANDIDATELIST , DWORD ) = CDXUTIMEEditBox : : Dummy_ImmGetCandidateListW ;
HIMC ( WINAPI * CDXUTIMEEditBox : : _ImmGetContext ) ( HWND ) = CDXUTIMEEditBox : : Dummy_ImmGetContext ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmReleaseContext ) ( HWND , HIMC ) = CDXUTIMEEditBox : : Dummy_ImmReleaseContext ;
HIMC ( WINAPI * CDXUTIMEEditBox : : _ImmAssociateContext ) ( HWND , HIMC ) = CDXUTIMEEditBox : : Dummy_ImmAssociateContext ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmGetOpenStatus ) ( HIMC ) = CDXUTIMEEditBox : : Dummy_ImmGetOpenStatus ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmSetOpenStatus ) ( HIMC , BOOL ) = CDXUTIMEEditBox : : Dummy_ImmSetOpenStatus ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmGetConversionStatus ) ( HIMC , LPDWORD , LPDWORD ) = CDXUTIMEEditBox : : Dummy_ImmGetConversionStatus ;
HWND ( WINAPI * CDXUTIMEEditBox : : _ImmGetDefaultIMEWnd ) ( HWND ) = CDXUTIMEEditBox : : Dummy_ImmGetDefaultIMEWnd ;
UINT ( WINAPI * CDXUTIMEEditBox : : _ImmGetIMEFileNameA ) ( HKL , LPSTR , UINT ) = CDXUTIMEEditBox : : Dummy_ImmGetIMEFileNameA ;
UINT ( WINAPI * CDXUTIMEEditBox : : _ImmGetVirtualKey ) ( HWND ) = CDXUTIMEEditBox : : Dummy_ImmGetVirtualKey ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmNotifyIME ) ( HIMC , DWORD , DWORD , DWORD ) = CDXUTIMEEditBox : : Dummy_ImmNotifyIME ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmSetConversionStatus ) ( HIMC , DWORD , DWORD ) = CDXUTIMEEditBox : : Dummy_ImmSetConversionStatus ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmSimulateHotKey ) ( HWND , DWORD ) = CDXUTIMEEditBox : : Dummy_ImmSimulateHotKey ;
BOOL ( WINAPI * CDXUTIMEEditBox : : _ImmIsIME ) ( HKL ) = CDXUTIMEEditBox : : Dummy_ImmIsIME ;
UINT ( WINAPI * CDXUTIMEEditBox : : _GetReadingString ) ( HIMC , UINT , PCHAR , PINT , BOOL * , PUINT ) = CDXUTIMEEditBox : : Dummy_GetReadingString ; // Traditional Chinese IME
BOOL ( WINAPI * CDXUTIMEEditBox : : _ShowReadingWindow ) ( HIMC , BOOL ) = CDXUTIMEEditBox : : Dummy_ShowReadingWindow ; // Traditional Chinese IME
BOOL ( APIENTRY * CDXUTIMEEditBox : : _VerQueryValueA ) ( const LPVOID , LPSTR , LPVOID * , PUINT ) = CDXUTIMEEditBox : : Dummy_VerQueryValueA ;
BOOL ( APIENTRY * CDXUTIMEEditBox : : _GetFileVersionInfoA ) ( LPSTR , DWORD , DWORD , LPVOID ) = CDXUTIMEEditBox : : Dummy_GetFileVersionInfoA ;
DWORD ( APIENTRY * CDXUTIMEEditBox : : _GetFileVersionInfoSizeA ) ( LPSTR , LPDWORD ) = CDXUTIMEEditBox : : Dummy_GetFileVersionInfoSizeA ;
DWORD dwImeWaitTick ;
HINSTANCE CDXUTIMEEditBox : : s_hDllImm32 ; // IMM32 DLL handle
HINSTANCE CDXUTIMEEditBox : : s_hDllVer ; // Version DLL handle
HKL CDXUTIMEEditBox : : s_hklCurrent ; // Current keyboard layout of the process
bool CDXUTIMEEditBox : : s_bVerticalCand ; // Indicates that the candidates are listed vertically
WCHAR CDXUTIMEEditBox : : s_aszIndicator [ 5 ] [ 3 ] = // String to draw to indicate current input locale
{
L " En " ,
L " \x7B80 " ,
L " \x7E41 " ,
L " \xAC00 " ,
L " \x3042 " ,
} ;
PWCHAR CDXUTIMEEditBox : : s_wszCurrIndicator = CDXUTIMEEditBox : : s_aszIndicator [ 0 ] ; // Points to an indicator string that corresponds to current input locale
bool CDXUTIMEEditBox : : s_bInsertOnType ; // Insert the character as soon as a key is pressed (Korean behavior)
HINSTANCE CDXUTIMEEditBox : : s_hDllIme ; // Instance handle of the current IME module
HIMC CDXUTIMEEditBox : : s_hImcDef ; // Default input context
CDXUTIMEEditBox : : IMESTATE CDXUTIMEEditBox : : s_ImeState = IMEUI_STATE_OFF ;
bool CDXUTIMEEditBox : : s_bEnableImeSystem ; // Whether the IME system is active
POINT CDXUTIMEEditBox : : s_ptCompString ; // Composition string position. Updated every frame.
int CDXUTIMEEditBox : : s_nCompCaret ;
int CDXUTIMEEditBox : : s_nFirstTargetConv ; // Index of the first target converted char in comp string. If none, -1.
CUniBuffer CDXUTIMEEditBox : : s_CompString = CUniBuffer ( 0 ) ;
BYTE CDXUTIMEEditBox : : s_abCompStringAttr [ MAX_COMPSTRING_SIZE ] ;
DWORD CDXUTIMEEditBox : : s_adwCompStringClause [ MAX_COMPSTRING_SIZE ] ;
TCHAR CDXUTIMEEditBox : : s_wszReadingString [ 32 ] ;
CDXUTIMEEditBox : : CCandList CDXUTIMEEditBox : : s_CandList ; // Data relevant to the candidate list
bool CDXUTIMEEditBox : : s_bShowReadingWindow ; // Indicates whether reading window is visible
bool CDXUTIMEEditBox : : s_bHorizontalReading ; // Indicates whether the reading window is vertical or horizontal
bool CDXUTIMEEditBox : : s_bChineseIME ;
CGrowableArray < CDXUTIMEEditBox : : CInputLocale > CDXUTIMEEditBox : : s_Locale ; // Array of loaded keyboard layout on system
# if defined(DEBUG) | defined(_DEBUG)
bool CDXUTIMEEditBox : : m_bIMEStaticMsgProcCalled = false ;
# endif
//--------------------------------------------------------------------------------------
CDXUTIMEEditBox : : CDXUTIMEEditBox ( CDXUTDialog * pDialog )
{
CDXUTIMEEditBox : : Initialize ( ) ; // ensure static vars are properly init'ed first
m_Type = DXUT_CONTROL_IMEEDITBOX ;
m_pDialog = pDialog ;
s_bEnableImeSystem = false ;
m_nIndicatorWidth = 0 ;
m_ReadingColor = D3DCOLOR_ARGB ( 240 , 255 , 255 , 255 ) ;
m_ReadingWinColor = D3DCOLOR_ARGB ( 240 , 0 , 0 , 0 ) ;
m_ReadingSelColor = D3DCOLOR_ARGB ( 255 , 255 , 0 , 0 ) ;
m_ReadingSelBkColor = D3DCOLOR_ARGB ( 240 , 80 , 80 , 80 ) ;
m_CandidateColor = D3DCOLOR_ARGB ( 255 , 200 , 200 , 200 ) ;
m_CandidateWinColor = D3DCOLOR_ARGB ( 240 , 0 , 0 , 0 ) ;
m_CandidateSelColor = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
m_CandidateSelBkColor = D3DCOLOR_ARGB ( 240 , 158 , 158 , 158 ) ;
m_CompColor = D3DCOLOR_ARGB ( 255 , 200 , 200 , 255 ) ;
m_CompWinColor = D3DCOLOR_ARGB ( 240 , 0 , 0 , 0 ) ;
m_CompCaretColor = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
m_CompTargetColor = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
m_CompTargetBkColor = D3DCOLOR_ARGB ( 255 , 150 , 150 , 150 ) ;
m_CompTargetNonColor = D3DCOLOR_ARGB ( 255 , 255 , 255 , 0 ) ;
m_CompTargetNonBkColor = D3DCOLOR_ARGB ( 255 , 150 , 150 , 150 ) ;
m_IndicatorImeColor = D3DCOLOR_ARGB ( 255 , 200 , 200 , 255 ) ;
m_IndicatorEngColor = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
m_IndicatorBkColor = D3DCOLOR_ARGB ( 255 , 255 , 255 , 255 ) ;
}
//--------------------------------------------------------------------------------------
CDXUTIMEEditBox : : ~ CDXUTIMEEditBox ( )
{
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : SendKey ( BYTE nVirtKey )
{
keybd_event ( nVirtKey , 0 , 0 , 0 ) ;
keybd_event ( nVirtKey , 0 , KEYEVENTF_KEYUP , 0 ) ;
}
//--------------------------------------------------------------------------------------
// Called by CDXUTResourceCache's OnCreateDevice. This gives the class a
// chance to initialize its default input context associated with the app window.
HRESULT CDXUTIMEEditBox : : StaticOnCreateDevice ( )
{
_ImmDisableTextFrameService ( - 1 ) ;
// Save the default input context
s_hImcDef = _ImmGetContext ( pGame - > GetMainWindowHwnd ( ) ) ;
_ImmReleaseContext ( pGame - > GetMainWindowHwnd ( ) , s_hImcDef ) ;
return S_OK ;
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : UpdateRects ( )
{
// Temporary adjust m_width so that CDXUTEditBox can compute
// the correct rects for its rendering since we need to make space
// for the indicator button
int nWidth = m_width ;
m_width - = m_nIndicatorWidth + m_nBorder * 2 ; // Make room for the indicator button
CDXUTEditBox : : UpdateRects ( ) ;
m_width = nWidth ; // Restore
// Compute the indicator button rectangle
SetRect ( & m_rcIndicator , m_rcBoundingBox . right , m_rcBoundingBox . top , m_x + m_width , m_rcBoundingBox . bottom ) ;
// InflateRect( &m_rcIndicator, -m_nBorder, -m_nBorder );
m_rcBoundingBox . right = m_rcBoundingBox . left + m_width ;
}
//--------------------------------------------------------------------------------------
// GetImeId( UINT uIndex )
// returns
// returned value:
// 0: In the following cases
// - Non Chinese IME input locale
// - Older Chinese IME
// - Other error cases
//
// Othewise:
// When uIndex is 0 (default)
// bit 31-24: Major version
// bit 23-16: Minor version
// bit 15-0: Language ID
// When uIndex is 1
// pVerFixedInfo->dwFileVersionLS
//
// Use IMEID_VER and IMEID_LANG macro to extract version and language information.
//
// We define the locale-invariant ID ourselves since it doesn't exist prior to WinXP
// For more information, see the CompareString() reference.
# define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
DWORD CDXUTIMEEditBox : : GetImeId ( UINT uIndex )
{
static HKL hklPrev = 0 ;
static DWORD dwID [ 2 ] = { 0 , 0 } ; // Cache the result
DWORD dwVerSize ;
DWORD dwVerHandle ;
LPVOID lpVerBuffer ;
LPVOID lpVerData ;
UINT cbVerData ;
char szTmp [ 1024 ] ;
if ( uIndex > = sizeof ( dwID ) / sizeof ( dwID [ 0 ] ) )
return 0 ;
if ( hklPrev = = s_hklCurrent )
return dwID [ uIndex ] ;
hklPrev = s_hklCurrent ; // Save for the next invocation
// Check if we are using an older Chinese IME
if ( ! ( ( s_hklCurrent = = _CHT_HKL ) | | ( s_hklCurrent = = _CHT_HKL2 ) | | ( s_hklCurrent = = _CHS_HKL ) ) )
{
dwID [ 0 ] = dwID [ 1 ] = 0 ;
return dwID [ uIndex ] ;
}
// Obtain the IME file name
if ( ! _ImmGetIMEFileNameA ( s_hklCurrent , szTmp , ( sizeof ( szTmp ) / sizeof ( szTmp [ 0 ] ) ) - 1 ) )
{
dwID [ 0 ] = dwID [ 1 ] = 0 ;
return dwID [ uIndex ] ;
}
// Check for IME that doesn't implement reading string API
if ( ! _GetReadingString )
{
if ( ( CompareStringA ( LCID_INVARIANT , NORM_IGNORECASE , szTmp , - 1 , CHT_IMEFILENAME1 , - 1 ) ! = CSTR_EQUAL ) & &
( CompareStringA ( LCID_INVARIANT , NORM_IGNORECASE , szTmp , - 1 , CHT_IMEFILENAME2 , - 1 ) ! = CSTR_EQUAL ) & &
( CompareStringA ( LCID_INVARIANT , NORM_IGNORECASE , szTmp , - 1 , CHT_IMEFILENAME3 , - 1 ) ! = CSTR_EQUAL ) & &
( CompareStringA ( LCID_INVARIANT , NORM_IGNORECASE , szTmp , - 1 , CHS_IMEFILENAME1 , - 1 ) ! = CSTR_EQUAL ) & &
( CompareStringA ( LCID_INVARIANT , NORM_IGNORECASE , szTmp , - 1 , CHS_IMEFILENAME2 , - 1 ) ! = CSTR_EQUAL ) )
{
dwID [ 0 ] = dwID [ 1 ] = 0 ;
return dwID [ uIndex ] ;
}
}
dwVerSize = _GetFileVersionInfoSizeA ( szTmp , & dwVerHandle ) ;
if ( dwVerSize )
{
lpVerBuffer = HeapAlloc ( GetProcessHeap ( ) , 0 , dwVerSize ) ;
if ( lpVerBuffer )
{
if ( _GetFileVersionInfoA ( szTmp , dwVerHandle , dwVerSize , lpVerBuffer ) )
{
if ( _VerQueryValueA ( lpVerBuffer , " \\ " , & lpVerData , & cbVerData ) )
{
DWORD dwVer = ( ( VS_FIXEDFILEINFO * ) lpVerData ) - > dwFileVersionMS ;
dwVer = ( dwVer & 0x00ff0000 ) < < 8 | ( dwVer & 0x000000ff ) < < 16 ;
if ( _GetReadingString
| |
( GetLanguage ( ) = = LANG_CHT & &
( dwVer = = MAKEIMEVERSION ( 4 , 2 ) | |
dwVer = = MAKEIMEVERSION ( 4 , 3 ) | |
dwVer = = MAKEIMEVERSION ( 4 , 4 ) | |
dwVer = = MAKEIMEVERSION ( 5 , 0 ) | |
dwVer = = MAKEIMEVERSION ( 5 , 1 ) | |
dwVer = = MAKEIMEVERSION ( 5 , 2 ) | |
dwVer = = MAKEIMEVERSION ( 6 , 0 ) ) )
| |
( GetLanguage ( ) = = LANG_CHS & &
( dwVer = = MAKEIMEVERSION ( 4 , 1 ) | |
dwVer = = MAKEIMEVERSION ( 4 , 2 ) | |
dwVer = = MAKEIMEVERSION ( 5 , 3 ) ) )
)
{
dwID [ 0 ] = dwVer | GetLanguage ( ) ;
dwID [ 1 ] = ( ( VS_FIXEDFILEINFO * ) lpVerData ) - > dwFileVersionLS ;
}
}
}
HeapFree ( GetProcessHeap ( ) , 0 , lpVerBuffer ) ;
}
}
return dwID [ uIndex ] ;
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : CheckInputLocale ( )
{
static HKL hklPrev = 0 ;
s_hklCurrent = GetKeyboardLayout ( 0 ) ;
if ( hklPrev = = s_hklCurrent )
return ;
hklPrev = s_hklCurrent ;
switch ( GetPrimaryLanguage ( ) )
{
// Simplified Chinese
case LANG_CHINESE :
s_bVerticalCand = true ;
switch ( GetSubLanguage ( ) )
{
case SUBLANG_CHINESE_SIMPLIFIED :
s_wszCurrIndicator = s_aszIndicator [ INDICATOR_CHS ] ;
s_bVerticalCand = GetImeId ( ) = = 0 ;
break ;
case SUBLANG_CHINESE_TRADITIONAL :
s_wszCurrIndicator = s_aszIndicator [ INDICATOR_CHT ] ;
break ;
default : // unsupported sub-language
s_wszCurrIndicator = s_aszIndicator [ INDICATOR_NON_IME ] ;
break ;
}
break ;
// Korean
case LANG_KOREAN :
s_wszCurrIndicator = s_aszIndicator [ INDICATOR_KOREAN ] ;
s_bVerticalCand = false ;
break ;
// Japanese
case LANG_JAPANESE :
s_wszCurrIndicator = s_aszIndicator [ INDICATOR_JAPANESE ] ;
s_bVerticalCand = true ;
break ;
default :
// A non-IME language. Obtain the language abbreviation
// and store it for rendering the indicator later.
s_wszCurrIndicator = s_aszIndicator [ INDICATOR_NON_IME ] ;
}
// If non-IME, use the language abbreviation.
if ( s_wszCurrIndicator = = s_aszIndicator [ INDICATOR_NON_IME ] )
{
WCHAR wszLang [ 5 ] ;
GetLocaleInfoW ( MAKELCID ( LOWORD ( s_hklCurrent ) , SORT_DEFAULT ) , LOCALE_SABBREVLANGNAME , wszLang , 5 ) ;
s_wszCurrIndicator [ 0 ] = wszLang [ 0 ] ;
s_wszCurrIndicator [ 1 ] = tolower ( wszLang [ 1 ] ) ;
}
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : CheckToggleState ( )
{
CheckInputLocale ( ) ;
bool bIme = _ImmIsIME ( s_hklCurrent ) ! = 0 ;
s_bChineseIME = ( GetPrimaryLanguage ( ) = = LANG_CHINESE ) & & bIme ;
HIMC hImc ;
if ( NULL ! = ( hImc = _ImmGetContext ( DXUTGetHWND ( ) ) ) )
{
if ( s_bChineseIME )
{
DWORD dwConvMode , dwSentMode ;
_ImmGetConversionStatus ( hImc , & dwConvMode , & dwSentMode ) ;
s_ImeState = ( dwConvMode & IME_CMODE_NATIVE ) ? IMEUI_STATE_ON : IMEUI_STATE_ENGLISH ;
}
else
{
s_ImeState = ( bIme & & _ImmGetOpenStatus ( hImc ) ! = 0 ) ? IMEUI_STATE_ON : IMEUI_STATE_OFF ;
}
_ImmReleaseContext ( DXUTGetHWND ( ) , hImc ) ;
}
else
s_ImeState = IMEUI_STATE_OFF ;
}
//--------------------------------------------------------------------------------------
// Enable/disable the entire IME system. When disabled, the default IME handling
// kicks in.
void CDXUTIMEEditBox : : EnableImeSystem ( bool bEnable )
{
s_bEnableImeSystem = bEnable ;
}
//--------------------------------------------------------------------------------------
// Sets up IME-specific APIs for the IME edit controls. This is called every time
// the input locale changes.
void CDXUTIMEEditBox : : SetupImeApi ( )
{
char szImeFile [ MAX_PATH + 1 ] ;
_GetReadingString = NULL ;
_ShowReadingWindow = NULL ;
if ( _ImmGetIMEFileNameA ( s_hklCurrent , szImeFile , sizeof ( szImeFile ) / sizeof ( szImeFile [ 0 ] ) - 1 ) = = 0 )
return ;
if ( s_hDllIme ) FreeLibrary ( s_hDllIme ) ;
s_hDllIme = LoadLibraryA ( szImeFile ) ;
if ( ! s_hDllIme )
return ;
_GetReadingString = ( UINT ( WINAPI * ) ( HIMC , UINT , PCHAR , PINT , BOOL * , PUINT ) )
( GetProcAddress ( s_hDllIme , " GetReadingString " ) ) ;
_ShowReadingWindow = ( BOOL ( WINAPI * ) ( HIMC , BOOL ) )
( GetProcAddress ( s_hDllIme , " ShowReadingWindow " ) ) ;
}
//--------------------------------------------------------------------------------------
// Resets the composition string.
void CDXUTIMEEditBox : : ResetCompositionString ( )
{
s_nCompCaret = 0 ;
s_CompString . SetText ( " " ) ;
ZeroMemory ( s_abCompStringAttr , sizeof ( s_abCompStringAttr ) ) ;
}
//--------------------------------------------------------------------------------------
// Truncate composition string by sending keystrokes to the window.
void CDXUTIMEEditBox : : TruncateCompString ( bool bUseBackSpace , int iNewStrLen )
{
if ( ! s_bInsertOnType )
return ;
int cc = ( int ) lstrlenW ( s_CompString . GetBuffer ( ) ) ;
assert ( iNewStrLen = = 0 | | iNewStrLen > = cc ) ;
// Send right arrow keystrokes to move the caret
// to the end of the composition string.
for ( int i = 0 ; i < cc - s_nCompCaret ; + + i )
SendMessage ( pGame - > GetMainWindowHwnd ( ) , WM_KEYDOWN , VK_RIGHT , 0 ) ;
SendMessage ( pGame - > GetMainWindowHwnd ( ) , WM_KEYUP , VK_RIGHT , 0 ) ;
if ( bUseBackSpace | | m_bInsertMode )
iNewStrLen = 0 ;
// The caller sets bUseBackSpace to false if there's possibility of sending
// new composition string to the app right after this function call.
//
// If the app is in overwriting mode and new comp string is
// shorter than current one, delete previous comp string
// till it's same long as the new one. Then move caret to the beginning of comp string.
// New comp string will overwrite old one.
if ( iNewStrLen < cc )
{
for ( int i = 0 ; i < cc - iNewStrLen ; + + i )
{
SendMessage ( pGame - > GetMainWindowHwnd ( ) , WM_KEYDOWN , VK_BACK , 0 ) ; // Backspace character
SendMessageW ( pGame - > GetMainWindowHwnd ( ) , WM_CHAR , VK_BACK , 0 ) ;
}
SendMessage ( pGame - > GetMainWindowHwnd ( ) , WM_KEYUP , VK_BACK , 0 ) ;
}
else
iNewStrLen = cc ;
// Move the caret to the beginning by sending left keystrokes
for ( int i = 0 ; i < iNewStrLen ; + + i )
SendMessage ( pGame - > GetMainWindowHwnd ( ) , WM_KEYDOWN , VK_LEFT , 0 ) ;
SendMessage ( pGame - > GetMainWindowHwnd ( ) , WM_KEYUP , VK_LEFT , 0 ) ;
}
//--------------------------------------------------------------------------------------
// Sends the current composition string to the application by sending keystroke
// messages.
void CDXUTIMEEditBox : : SendCompString ( )
{
for ( int i = 0 ; i < lstrlenW ( s_CompString . GetBuffer ( ) ) ; + + i )
MsgProc ( WM_CHAR , ( WPARAM ) s_CompString [ i ] , 0 ) ;
}
//--------------------------------------------------------------------------------------
// Outputs current composition string then cleans up the composition task.
void CDXUTIMEEditBox : : FinalizeString ( bool bSend )
{
HIMC hImc ;
if ( NULL = = ( hImc = _ImmGetContext ( pGame - > GetMainWindowHwnd ( ) ) ) )
return ;
static bool bProcessing = false ;
if ( bProcessing ) // avoid infinite recursion
{
DXUTTRACE ( " CDXUTIMEEditBox::FinalizeString: Reentrant detected! \n " ) ;
_ImmReleaseContext ( pGame - > GetMainWindowHwnd ( ) , hImc ) ;
return ;
}
bProcessing = true ;
if ( ! s_bInsertOnType & & bSend )
{
// Send composition string to app.
LONG lLength = lstrlenW ( s_CompString . GetBuffer ( ) ) ;
// In case of CHT IME, don't send the trailing double byte space, if it exists.
if ( GetLanguage ( ) = = LANG_CHT
& & s_CompString [ lLength - 1 ] = = 0x3000 )
{
s_CompString [ lLength - 1 ] = 0 ;
}
SendCompString ( ) ;
}
ResetCompositionString ( ) ;
// Clear composition string in IME
_ImmNotifyIME ( hImc , NI_COMPOSITIONSTR , CPS_CANCEL , 0 ) ;
// the following line is necessary as Korean IME doesn't close cand list
// when comp string is cancelled.
_ImmNotifyIME ( hImc , NI_CLOSECANDIDATE , 0 , 0 ) ;
_ImmReleaseContext ( pGame - > GetMainWindowHwnd ( ) , hImc ) ;
bProcessing = false ;
}
//--------------------------------------------------------------------------------------
// Determine whether the reading window should be vertical or horizontal.
void CDXUTIMEEditBox : : GetReadingWindowOrientation ( DWORD dwId )
{
s_bHorizontalReading = ( s_hklCurrent = = _CHS_HKL ) | | ( s_hklCurrent = = _CHT_HKL2 ) | | ( dwId = = 0 ) ;
if ( ! s_bHorizontalReading & & ( dwId & 0x0000FFFF ) = = LANG_CHT )
{
TCHAR wszRegPath [ MAX_PATH ] ;
HKEY hKey ;
DWORD dwVer = dwId & 0xFFFF0000 ;
StringCchCopy ( wszRegPath , MAX_PATH , " software \\ microsoft \\ windows \\ currentversion \\ " ) ;
StringCchCat ( wszRegPath , MAX_PATH , ( dwVer > = MAKEIMEVERSION ( 5 , 1 ) ) ? " MSTCIPH " : " TINTLGNT " ) ;
LONG lRc = RegOpenKeyExA ( HKEY_CURRENT_USER , wszRegPath , 0 , KEY_READ , & hKey ) ;
if ( lRc = = ERROR_SUCCESS )
{
DWORD dwSize = sizeof ( DWORD ) , dwMapping , dwType ;
lRc = RegQueryValueExA ( hKey , " Keyboard Mapping " , NULL , & dwType , ( PBYTE ) & dwMapping , & dwSize ) ;
if ( lRc = = ERROR_SUCCESS )
{
if ( ( dwVer < = MAKEIMEVERSION ( 5 , 0 ) & &
( ( BYTE ) dwMapping = = 0x22 | | ( BYTE ) dwMapping = = 0x23 ) )
| |
( ( dwVer = = MAKEIMEVERSION ( 5 , 1 ) | | dwVer = = MAKEIMEVERSION ( 5 , 2 ) ) & &
( BYTE ) dwMapping > = 0x22 & & ( BYTE ) dwMapping < = 0x24 )
)
{
s_bHorizontalReading = true ;
}
}
RegCloseKey ( hKey ) ;
}
}
}
//--------------------------------------------------------------------------------------
// Obtain the reading string upon WM_IME_NOTIFY/INM_PRIVATE notification.
void CDXUTIMEEditBox : : GetPrivateReadingString ( )
{
return ;
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : OnFocusIn ( )
{
CDXUTEditBox : : OnFocusIn ( ) ;
if ( s_bEnableImeSystem )
{
_ImmAssociateContext ( DXUTGetHWND ( ) , s_hImcDef ) ;
CheckToggleState ( ) ;
} else
_ImmAssociateContext ( DXUTGetHWND ( ) , NULL ) ;
//
// Set up the IME global state according to the current instance state
//
HIMC hImc ;
if ( NULL ! = ( hImc = _ImmGetContext ( DXUTGetHWND ( ) ) ) )
{
if ( ! s_bEnableImeSystem )
s_ImeState = IMEUI_STATE_OFF ;
_ImmReleaseContext ( DXUTGetHWND ( ) , hImc ) ;
CheckToggleState ( ) ;
}
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : OnFocusOut ( )
{
CDXUTEditBox : : OnFocusOut ( ) ;
FinalizeString ( false ) ; // Don't send the comp string as to match RichEdit behavior
_ImmAssociateContext ( DXUTGetHWND ( ) , NULL ) ;
}
//--------------------------------------------------------------------------------------
// MATCH
bool CDXUTIMEEditBox : : StaticMsgProc ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
HIMC hImc ;
if ( ! s_bEnableImeSystem )
return false ;
# if defined(DEBUG) | defined(_DEBUG)
m_bIMEStaticMsgProcCalled = true ;
# endif
switch ( uMsg )
{
case WM_ACTIVATEAPP :
if ( wParam )
{
// Populate s_Locale with the list of keyboard layouts.
UINT cKL = GetKeyboardLayoutList ( 0 , NULL ) ;
s_Locale . RemoveAll ( ) ;
HKL * phKL = new HKL [ cKL ] ;
if ( phKL )
{
GetKeyboardLayoutList ( cKL , phKL ) ;
for ( UINT i = 0 ; i < cKL ; + + i )
{
CInputLocale Locale ;
// Filter out East Asian languages that are not IME.
if ( ( PRIMARYLANGID ( LOWORD ( phKL [ i ] ) ) = = LANG_CHINESE | |
PRIMARYLANGID ( LOWORD ( phKL [ i ] ) ) = = LANG_JAPANESE | |
PRIMARYLANGID ( LOWORD ( phKL [ i ] ) ) = = LANG_KOREAN ) & &
! _ImmIsIME ( phKL [ i ] ) )
continue ;
// If this language is already in the list, don't add it again.
bool bBreak = false ;
for ( int e = 0 ; e < s_Locale . GetSize ( ) ; + + e )
if ( LOWORD ( s_Locale . GetAt ( e ) . m_hKL ) = =
LOWORD ( phKL [ i ] ) )
{
bBreak = true ;
break ;
}
if ( bBreak )
break ;
Locale . m_hKL = phKL [ i ] ;
WCHAR wszDesc [ 128 ] = L " " ;
switch ( PRIMARYLANGID ( LOWORD ( phKL [ i ] ) ) )
{
// Simplified Chinese
case LANG_CHINESE :
switch ( SUBLANGID ( LOWORD ( phKL [ i ] ) ) )
{
case SUBLANG_CHINESE_SIMPLIFIED :
StringCchCopyW ( Locale . m_wszLangAbb , 3 , s_aszIndicator [ INDICATOR_CHS ] ) ;
break ;
case SUBLANG_CHINESE_TRADITIONAL :
StringCchCopyW ( Locale . m_wszLangAbb , 3 , s_aszIndicator [ INDICATOR_CHT ] ) ;
break ;
default : // unsupported sub-language
GetLocaleInfoW ( MAKELCID ( LOWORD ( phKL [ i ] ) , SORT_DEFAULT ) , LOCALE_SABBREVLANGNAME , wszDesc , 128 ) ;
Locale . m_wszLangAbb [ 0 ] = wszDesc [ 0 ] ;
Locale . m_wszLangAbb [ 1 ] = tolower ( wszDesc [ 1 ] ) ;
Locale . m_wszLangAbb [ 2 ] = ' \0 ' ;
break ;
}
break ;
// Korean
case LANG_KOREAN :
StringCchCopyW ( Locale . m_wszLangAbb , 3 , s_aszIndicator [ INDICATOR_KOREAN ] ) ;
break ;
// Japanese
case LANG_JAPANESE :
StringCchCopyW ( Locale . m_wszLangAbb , 3 , s_aszIndicator [ INDICATOR_JAPANESE ] ) ;
break ;
default :
// A non-IME language. Obtain the language abbreviation
// and store it for rendering the indicator later.
GetLocaleInfoW ( MAKELCID ( LOWORD ( phKL [ i ] ) , SORT_DEFAULT ) , LOCALE_SABBREVLANGNAME , wszDesc , 128 ) ;
Locale . m_wszLangAbb [ 0 ] = wszDesc [ 0 ] ;
Locale . m_wszLangAbb [ 1 ] = towlower ( wszDesc [ 1 ] ) ;
Locale . m_wszLangAbb [ 2 ] = ' \0 ' ;
break ;
}
GetLocaleInfoW ( MAKELCID ( LOWORD ( phKL [ i ] ) , SORT_DEFAULT ) , LOCALE_SLANGUAGE , wszDesc , 128 ) ;
StringCchCopyW ( Locale . m_wszLang , 64 , wszDesc ) ;
s_Locale . Add ( Locale ) ;
}
delete [ ] phKL ;
}
}
break ;
case WM_INPUTLANGCHANGE :
DXUTTRACE ( " WM_INPUTLANGCHANGE \n " ) ;
{
UINT uLang = GetPrimaryLanguage ( ) ;
CheckToggleState ( ) ;
if ( uLang ! = GetPrimaryLanguage ( ) )
{
// Korean IME always inserts on keystroke. Other IMEs do not.
s_bInsertOnType = ( GetPrimaryLanguage ( ) = = LANG_KOREAN ) ;
}
// IME changed. Setup the new IME.
SetupImeApi ( ) ;
if ( _ShowReadingWindow )
{
if ( NULL ! = ( hImc = _ImmGetContext ( pGame - > GetMainWindowHwnd ( ) ) ) )
{
_ShowReadingWindow ( hImc , false ) ;
_ImmReleaseContext ( pGame - > GetMainWindowHwnd ( ) , hImc ) ;
}
}
}
return true ;
case WM_IME_SETCONTEXT :
DXUTTRACE ( " WM_IME_SETCONTEXT \n " ) ;
//
// We don't want anything to display, so we have to clear this
//
lParam = 0 ;
return false ;
// Handle WM_IME_STARTCOMPOSITION here since
// we do not want the default IME handler to see
// this when our fullscreen app is running.
case WM_IME_STARTCOMPOSITION :
DXUTTRACE ( " WM_IME_STARTCOMPOSITION \n " ) ;
ResetCompositionString ( ) ;
// Since the composition string has its own caret, we don't render
// the edit control's own caret to avoid double carets on screen.
s_bHideCaret = true ;
return true ;
case WM_IME_COMPOSITION :
DXUTTRACE ( " WM_IME_COMPOSITION \n " ) ;
return true ;
}
return false ;
}
//--------------------------------------------------------------------------------------
bool CDXUTIMEEditBox : : HandleMouse ( UINT uMsg , POINT pt , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
switch ( uMsg )
{
case WM_LBUTTONDOWN :
case WM_LBUTTONDBLCLK :
{
DXUTFontNode * pFont = m_pDialog - > GetFont ( m_Elements . GetAt ( 9 ) - > iFont ) ;
// Check if this click is on top of the composition string
int nCompStrWidth ;
s_CompString . CPtoX ( s_CompString . GetTextSize ( ) , FALSE , & nCompStrWidth ) ;
if ( s_ptCompString . x < = pt . x & &
s_ptCompString . y < = pt . y & &
s_ptCompString . x + nCompStrWidth > pt . x & &
s_ptCompString . y + pFont - > nHeight > pt . y )
{
int nCharBodyHit , nCharHit ;
int nTrail ;
// Determine the character clicked on.
s_CompString . XtoCP ( pt . x - s_ptCompString . x , & nCharBodyHit , & nTrail ) ;
if ( nTrail & & nCharBodyHit < s_CompString . GetTextSize ( ) )
nCharHit = nCharBodyHit + 1 ;
else
nCharHit = nCharBodyHit ;
// Now generate keypress events to move the comp string cursor
// to the click point. First, if the candidate window is displayed,
// send Esc to close it.
HIMC hImc = _ImmGetContext ( DXUTGetHWND ( ) ) ;
if ( ! hImc )
return true ;
_ImmNotifyIME ( hImc , NI_CLOSECANDIDATE , 0 , 0 ) ;
_ImmReleaseContext ( DXUTGetHWND ( ) , hImc ) ;
switch ( GetPrimaryLanguage ( ) )
{
case LANG_JAPANESE :
// For Japanese, there are two cases. If s_nFirstTargetConv is
// -1, the comp string hasn't been converted yet, and we use
// s_nCompCaret. For any other value of s_nFirstTargetConv,
// the string has been converted, so we use clause information.
if ( s_nFirstTargetConv ! = - 1 )
{
int nClauseClicked = 0 ;
while ( ( int ) s_adwCompStringClause [ nClauseClicked + 1 ] < = nCharBodyHit )
+ + nClauseClicked ;
int nClauseSelected = 0 ;
while ( ( int ) s_adwCompStringClause [ nClauseSelected + 1 ] < = s_nFirstTargetConv )
+ + nClauseSelected ;
BYTE nVirtKey = nClauseClicked > nClauseSelected ? VK_RIGHT : VK_LEFT ;
int nSendCount = abs ( nClauseClicked - nClauseSelected ) ;
while ( nSendCount - - > 0 )
SendKey ( nVirtKey ) ;
return true ;
}
// Not converted case. Fall thru to Chinese case.
case LANG_CHINESE :
{
// For Chinese, use s_nCompCaret.
BYTE nVirtKey = nCharHit > s_nCompCaret ? VK_RIGHT : VK_LEFT ;
int nSendCount = abs ( nCharHit - s_nCompCaret ) ;
while ( nSendCount - - > 0 )
SendKey ( nVirtKey ) ;
break ;
}
}
return true ;
}
// Check if the click is on top of the candidate window
if ( s_CandList . bShowWindow & & PtInRect ( & s_CandList . rcCandidate , pt ) )
{
if ( s_bVerticalCand )
{
// Vertical candidate window
// Compute the row the click is on
int nRow = ( pt . y - s_CandList . rcCandidate . top ) / pFont - > nHeight ;
if ( nRow < ( int ) s_CandList . dwCount )
{
// nRow is a valid entry.
// Now emulate keystrokes to select the candidate at this row.
switch ( GetPrimaryLanguage ( ) )
{
case LANG_CHINESE :
case LANG_KOREAN :
// For Chinese and Korean, simply send the number keystroke.
SendKey ( ( BYTE ) ( ' 0 ' + nRow + 1 ) ) ;
break ;
case LANG_JAPANESE :
// For Japanese, move the selection to the target row,
// then send Right, then send Left.
BYTE nVirtKey ;
if ( nRow > ( int ) s_CandList . dwSelection )
nVirtKey = VK_DOWN ;
else
nVirtKey = VK_UP ;
int nNumToHit = abs ( int ( nRow - s_CandList . dwSelection ) ) ;
for ( int nStrike = 0 ; nStrike < nNumToHit ; + + nStrike )
SendKey ( nVirtKey ) ;
// Do this to close the candidate window without ending composition.
SendKey ( VK_RIGHT ) ;
SendKey ( VK_LEFT ) ;
break ;
}
}
} else
{
// Horizontal candidate window
// Determine which the character the click has hit.
int nCharHit ;
int nTrail ;
s_CandList . HoriCand . XtoCP ( pt . x - s_CandList . rcCandidate . left , & nCharHit , & nTrail ) ;
// Determine which candidate string the character belongs to.
int nCandidate = s_CandList . dwCount - 1 ;
int nEntryStart = 0 ;
for ( UINT i = 0 ; i < s_CandList . dwCount ; + + i )
{
if ( nCharHit > = nEntryStart )
{
// Haven't found it.
nEntryStart + = lstrlenA ( s_CandList . awszCandidate [ i ] ) + 1 ; // plus space separator
} else
{
// Found it. This entry starts at the right side of the click point,
// so the char belongs to the previous entry.
nCandidate = i - 1 ;
break ;
}
}
// Now emulate keystrokes to select the candidate entry.
switch ( GetPrimaryLanguage ( ) )
{
case LANG_CHINESE :
case LANG_KOREAN :
// For Chinese and Korean, simply send the number keystroke.
SendKey ( ( BYTE ) ( ' 0 ' + nCandidate + 1 ) ) ;
break ;
}
}
return true ;
}
}
}
// If we didn't care for the msg, let the parent process it.
return CDXUTEditBox : : HandleMouse ( uMsg , pt , wParam , lParam ) ;
}
//--------------------------------------------------------------------------------------
bool CDXUTIMEEditBox : : MsgProc ( UINT uMsg , WPARAM wParam , LPARAM lParam )
{
if ( ! m_bEnabled | | ! m_bVisible )
return false ;
# if defined(DEBUG) | defined(_DEBUG)
// DXUT.cpp used to call CDXUTIMEEditBox::StaticMsgProc() so that, but now
// this is the application's responsiblity. To do this, call
// CDXUTDialogResourceManager::MsgProc() before calling this function.
assert ( m_bIMEStaticMsgProcCalled & & " To fix, call CDXUTDialogResourceManager::MsgProc() first " ) ;
# endif
bool trappedData ;
bool * trapped = & trappedData ;
HIMC hImc ;
static LPARAM lAlt = 0x80000000 , lCtrl = 0x80000000 , lShift = 0x80000000 ;
* trapped = false ;
if ( ! s_bEnableImeSystem )
return CDXUTEditBox : : MsgProc ( uMsg , wParam , lParam ) ;
switch ( uMsg )
{
//
// IME Handling
//
case WM_IME_COMPOSITION :
DXUTTRACE ( " WM_IME_COMPOSITION \n " ) ;
{
LONG lRet ; // Returned count in CHARACTERS
TCHAR wszCompStr [ MAX_COMPSTRING_SIZE ] ;
* trapped = true ;
if ( NULL = = ( hImc = _ImmGetContext ( DXUTGetHWND ( ) ) ) )
{
break ;
}
// Get the caret position in composition string
if ( lParam & GCS_CURSORPOS )
{
s_nCompCaret = _ImmGetCompositionStringW ( hImc , GCS_CURSORPOS , NULL , 0 ) ;
if ( s_nCompCaret < 0 )
s_nCompCaret = 0 ; // On error, set caret to pos 0.
}
// ResultStr must be processed before composition string.
//
// This is because for some IMEs, such as CHT, pressing Enter
// to complete the composition sends WM_IME_COMPOSITION with both
// GCS_RESULTSTR and GCS_COMPSTR. Retrieving the result string
// gives the correct string, while retrieving the comp string
// (GCS_COMPSTR) gives empty string. GCS_RESULTSTR should be
// handled first so that the application receives the string. Then
// GCS_COMPSTR can be handled to clear the comp string buffer.
if ( lParam & GCS_RESULTSTR )
{
DXUTTRACE ( " GCS_RESULTSTR \n " ) ;
lRet = _ImmGetCompositionStringW ( hImc , GCS_RESULTSTR , wszCompStr , sizeof ( wszCompStr ) ) ;
if ( lRet > 0 )
{
lRet / = sizeof ( TCHAR ) ;
wszCompStr [ lRet ] = 0 ; // Force terminate
TruncateCompString ( false , ( int ) strlen ( wszCompStr ) ) ;
s_CompString . SetText ( wszCompStr ) ;
SendCompString ( ) ;
ResetCompositionString ( ) ;
}
}
//
// Reads in the composition string.
//
if ( lParam & GCS_COMPSTR )
{
DXUTTRACE ( " GCS_COMPSTR \n " ) ;
//////////////////////////////////////////////////////
// Retrieve the latest user-selected IME candidates
lRet = _ImmGetCompositionStringW ( hImc , GCS_COMPSTR , wszCompStr , sizeof ( wszCompStr ) ) ;
if ( lRet > 0 )
{
lRet / = sizeof ( TCHAR ) ; // Convert size in byte to size in char
wszCompStr [ lRet ] = 0 ; // Force terminate
//
// Remove the whole of the string
//
TruncateCompString ( false , ( int ) strlen ( wszCompStr ) ) ;
s_CompString . SetText ( wszCompStr ) ;
// Older CHT IME uses composition string for reading string
if ( GetLanguage ( ) = = LANG_CHT & & ! GetImeId ( ) )
{
if ( lstrlenW ( s_CompString . GetBuffer ( ) ) )
{
s_CandList . dwCount = 4 ; // Maximum possible length for reading string is 4
s_CandList . dwSelection = ( DWORD ) - 1 ; // don't select any candidate
// Copy the reading string to the candidate list
for ( int i = 3 ; i > = 0 ; - - i )
{
if ( i > lstrlenW ( s_CompString . GetBuffer ( ) ) - 1 )
s_CandList . awszCandidate [ i ] [ 0 ] = 0 ; // Doesn't exist
else
{
s_CandList . awszCandidate [ i ] [ 0 ] = s_CompString [ i ] ;
s_CandList . awszCandidate [ i ] [ 1 ] = 0 ;
}
}
s_CandList . dwPageSize = MAX_CANDLIST ;
// Clear comp string after we are done copying
ZeroMemory ( ( LPVOID ) s_CompString . GetBuffer ( ) , 4 * sizeof ( TCHAR ) ) ;
s_bShowReadingWindow = true ;
GetReadingWindowOrientation ( 0 ) ;
if ( s_bHorizontalReading )
{
s_CandList . nReadingError = - 1 ; // Clear error
// Create a string that consists of the current
// reading string. Since horizontal reading window
// is used, we take advantage of this by rendering
// one string instead of several.
//
// Copy the reading string from the candidate list
// to the reading string buffer.
s_wszReadingString [ 0 ] = 0 ;
for ( UINT i = 0 ; i < s_CandList . dwCount ; + + i )
{
if ( s_CandList . dwSelection = = i )
s_CandList . nReadingError = lstrlen ( s_wszReadingString ) ;
StringCchCat ( s_wszReadingString , 32 , s_CandList . awszCandidate [ i ] ) ;
}
}
}
else
{
s_CandList . dwCount = 0 ;
s_bShowReadingWindow = false ;
}
}
if ( s_bInsertOnType )
{
// Send composition string to the edit control
SendCompString ( ) ;
// Restore the caret to the correct location.
// It's at the end right now, so compute the number
// of times left arrow should be pressed to
// send it to the original position.
int nCount = lstrlenW ( s_CompString . GetBuffer ( ) + s_nCompCaret ) ;
// Send left keystrokes
for ( int i = 0 ; i < nCount ; + + i )
SendMessage ( DXUTGetHWND ( ) , WM_KEYDOWN , VK_LEFT , 0 ) ;
SendMessage ( DXUTGetHWND ( ) , WM_KEYUP , VK_LEFT , 0 ) ;
}
}
ResetCaretBlink ( ) ;
}
// Retrieve comp string attributes
if ( lParam & GCS_COMPATTR )
{
lRet = _ImmGetCompositionStringW ( hImc , GCS_COMPATTR , s_abCompStringAttr , sizeof ( s_abCompStringAttr ) ) ;
if ( lRet > 0 )
s_abCompStringAttr [ lRet ] = 0 ; // ??? Is this needed for attributes?
}
// Retrieve clause information
if ( lParam & GCS_COMPCLAUSE )
{
lRet = _ImmGetCompositionStringW ( hImc , GCS_COMPCLAUSE , s_adwCompStringClause , sizeof ( s_adwCompStringClause ) ) ;
s_adwCompStringClause [ lRet / sizeof ( DWORD ) ] = 0 ; // Terminate
}
_ImmReleaseContext ( DXUTGetHWND ( ) , hImc ) ;
}
break ;
case WM_IME_ENDCOMPOSITION :
DXUTTRACE ( " WM_IME_ENDCOMPOSITION \n " ) ;
TruncateCompString ( ) ;
ResetCompositionString ( ) ;
// We can show the edit control's caret again.
s_bHideCaret = false ;
// Hide reading window
s_bShowReadingWindow = false ;
dwImeWaitTick = GetTickCount ( ) ;
break ;
case WM_IME_NOTIFY :
DXUTTRACE ( " WM_IME_NOTIFY %u \n " , wParam ) ;
switch ( wParam )
{
case IMN_SETCONVERSIONMODE :
DXUTTRACE ( " IMN_SETCONVERSIONMODE \n " ) ;
case IMN_SETOPENSTATUS :
DXUTTRACE ( " IMN_SETOPENSTATUS \n " ) ;
CheckToggleState ( ) ;
break ;
case IMN_OPENCANDIDATE :
case IMN_CHANGECANDIDATE :
{
DXUTTRACE ( wParam = = IMN_CHANGECANDIDATE ? " IMN_CHANGECANDIDATE \n " : " IMN_OPENCANDIDATE \n " ) ;
s_CandList . bShowWindow = true ;
* trapped = true ;
if ( NULL = = ( hImc = _ImmGetContext ( DXUTGetHWND ( ) ) ) )
break ;
LPCANDIDATELIST lpCandList = NULL ;
DWORD dwLenRequired ;
s_bShowReadingWindow = false ;
// Retrieve the candidate list
dwLenRequired = _ImmGetCandidateListW ( hImc , 0 , NULL , 0 ) ;
if ( dwLenRequired )
{
lpCandList = ( LPCANDIDATELIST ) HeapAlloc ( GetProcessHeap ( ) , 0 , dwLenRequired ) ;
dwLenRequired = _ImmGetCandidateListW ( hImc , 0 , lpCandList , dwLenRequired ) ;
}
if ( lpCandList )
{
// Update candidate list data
s_CandList . dwSelection = lpCandList - > dwSelection ;
s_CandList . dwCount = lpCandList - > dwCount ;
int nPageTopIndex = 0 ;
s_CandList . dwPageSize = __min ( lpCandList - > dwPageSize , MAX_CANDLIST ) ;
if ( GetPrimaryLanguage ( ) = = LANG_JAPANESE )
{
// Japanese IME organizes its candidate list a little
// differently from the other IMEs.
nPageTopIndex = ( s_CandList . dwSelection / s_CandList . dwPageSize ) * s_CandList . dwPageSize ;
}
else
nPageTopIndex = lpCandList - > dwPageStart ;
// Make selection index relative to first entry of page
s_CandList . dwSelection = ( GetLanguage ( ) = = LANG_CHS & & ! GetImeId ( ) ) ? ( DWORD ) - 1
: s_CandList . dwSelection - nPageTopIndex ;
ZeroMemory ( s_CandList . awszCandidate , sizeof ( s_CandList . awszCandidate ) ) ;
for ( UINT i = nPageTopIndex , j = 0 ;
( DWORD ) i < lpCandList - > dwCount & & j < s_CandList . dwPageSize ;
i + + , j + + )
{
// Initialize the candidate list strings
PCHAR pwsz = s_CandList . awszCandidate [ j ] ;
// For every candidate string entry,
// write [index] + Space + [String] if vertical,
// write [index] + [String] + Space if horizontal.
* pwsz + + = ( TCHAR ) ( L ' 0 ' + ( ( j + 1 ) % 10 ) ) ; // Index displayed is 1 based
if ( s_bVerticalCand )
* pwsz + + = L ' ' ;
TCHAR * pwszNewCand = ( PCHAR ) ( ( LPBYTE ) lpCandList + lpCandList - > dwOffset [ i ] ) ;
while ( * pwszNewCand )
* pwsz + + = * pwszNewCand + + ;
if ( ! s_bVerticalCand )
* pwsz + + = L ' ' ;
* pwsz = 0 ; // Terminate
}
// Make dwCount in s_CandList be number of valid entries in the page.
s_CandList . dwCount = lpCandList - > dwCount - lpCandList - > dwPageStart ;
if ( s_CandList . dwCount > lpCandList - > dwPageSize )
s_CandList . dwCount = lpCandList - > dwPageSize ;
HeapFree ( GetProcessHeap ( ) , 0 , lpCandList ) ;
_ImmReleaseContext ( DXUTGetHWND ( ) , hImc ) ;
// Korean and old Chinese IME can't have selection.
// User must use the number hotkey or Enter to select
// a candidate.
if ( GetPrimaryLanguage ( ) = = LANG_KOREAN | |
GetLanguage ( ) = = LANG_CHT & & ! GetImeId ( ) )
{
s_CandList . dwSelection = ( DWORD ) - 1 ;
}
// Initialize s_CandList.HoriCand if we have a
// horizontal candidate window.
if ( ! s_bVerticalCand )
{
TCHAR wszCand [ 256 ] = " " ;
s_CandList . nFirstSelected = 0 ;
s_CandList . nHoriSelectedLen = 0 ;
for ( UINT i = 0 ; i < MAX_CANDLIST ; + + i )
{
if ( s_CandList . awszCandidate [ i ] [ 0 ] = = L ' \0 ' )
break ;
TCHAR wszEntry [ 32 ] ;
StringCchPrintf ( wszEntry , 32 , " %s " , s_CandList . awszCandidate [ i ] ) ;
// If this is the selected entry, mark its char position.
if ( s_CandList . dwSelection = = i )
{
s_CandList . nFirstSelected = lstrlen ( wszCand ) ;
s_CandList . nHoriSelectedLen = lstrlen ( wszEntry ) - 1 ; // Minus space
}
StringCchCat ( wszCand , 256 , wszEntry ) ;
}
wszCand [ lstrlen ( wszCand ) - 1 ] = L ' \0 ' ; // Remove the last space
s_CandList . HoriCand . SetText ( wszCand ) ;
}
}
break ;
}
case IMN_CLOSECANDIDATE :
{
DXUTTRACE ( " IMN_CLOSECANDIDATE \n " ) ;
s_CandList . bShowWindow = false ;
if ( ! s_bShowReadingWindow )
{
s_CandList . dwCount = 0 ;
ZeroMemory ( s_CandList . awszCandidate , sizeof ( s_CandList . awszCandidate ) ) ;
}
* trapped = true ;
break ;
}
case IMN_PRIVATE :
DXUTTRACE ( " IMN_PRIVATE \n " ) ;
{
if ( ! s_CandList . bShowWindow )
GetPrivateReadingString ( ) ;
// Trap some messages to hide reading window
DWORD dwId = GetImeId ( ) ;
switch ( dwId )
{
case IMEID_CHT_VER42 :
case IMEID_CHT_VER43 :
case IMEID_CHT_VER44 :
case IMEID_CHS_VER41 :
case IMEID_CHS_VER42 :
if ( ( lParam = = 1 ) | | ( lParam = = 2 ) )
{
* trapped = true ;
}
break ;
case IMEID_CHT_VER50 :
case IMEID_CHT_VER51 :
case IMEID_CHT_VER52 :
case IMEID_CHT_VER60 :
case IMEID_CHS_VER53 :
if ( ( lParam = = 16 ) | | ( lParam = = 17 ) | | ( lParam = = 26 ) | | ( lParam = = 27 ) | | ( lParam = = 28 ) )
{
* trapped = true ;
}
break ;
}
}
break ;
default :
* trapped = true ;
break ;
}
break ;
// When Text Service Framework is installed in Win2K, Alt+Shift and Ctrl+Shift combination (to switch input
// locale / keyboard layout) doesn't send WM_KEYUP message for the key that is released first. We need to check
// if these keys are actually up whenever we receive key up message for other keys.
case WM_KEYUP :
case WM_SYSKEYUP :
if ( ! ( lAlt & 0x80000000 ) & & wParam ! = VK_MENU & & ( GetAsyncKeyState ( VK_MENU ) & 0x8000 ) = = 0 )
{
PostMessageW ( GetFocus ( ) , WM_KEYUP , ( WPARAM ) VK_MENU , ( lAlt & 0x01ff0000 ) | 0xC0000001 ) ;
}
else if ( ! ( lCtrl & 0x80000000 ) & & wParam ! = VK_CONTROL & & ( GetAsyncKeyState ( VK_CONTROL ) & 0x8000 ) = = 0 )
{
PostMessageW ( GetFocus ( ) , WM_KEYUP , ( WPARAM ) VK_CONTROL , ( lCtrl & 0x01ff0000 ) | 0xC0000001 ) ;
}
else if ( ! ( lShift & 0x80000000 ) & & wParam ! = VK_SHIFT & & ( GetAsyncKeyState ( VK_SHIFT ) & 0x8000 ) = = 0 )
{
PostMessageW ( GetFocus ( ) , WM_KEYUP , ( WPARAM ) VK_SHIFT , ( lShift & 0x01ff0000 ) | 0xC0000001 ) ;
}
// fall through WM_KEYDOWN / WM_SYSKEYDOWN
case WM_KEYDOWN :
case WM_SYSKEYDOWN :
switch ( wParam )
{
case VK_MENU :
lAlt = lParam ;
break ;
case VK_SHIFT :
lShift = lParam ;
break ;
case VK_CONTROL :
lCtrl = lParam ;
break ;
}
//break;
// Fall through to default case
// so we invoke the parent.
default :
// Let the parent handle the message that we
// don't handle.
return CDXUTEditBox : : MsgProc ( uMsg , wParam , lParam ) ;
} // switch
return * trapped ;
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : RenderCandidateReadingWindow ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime , bool bReading )
{
RECT rc ;
UINT nNumEntries = bReading ? 4 : MAX_CANDLIST ;
D3DCOLOR TextColor , TextBkColor , SelTextColor , SelBkColor ;
int nX , nXFirst , nXComp ;
m_Buffer . CPtoX ( m_nCaret , FALSE , & nX ) ;
m_Buffer . CPtoX ( m_nFirstVisible , FALSE , & nXFirst ) ;
if ( bReading )
{
TextColor = m_ReadingColor ;
TextBkColor = m_ReadingWinColor ;
SelTextColor = m_ReadingSelColor ;
SelBkColor = m_ReadingSelBkColor ;
} else
{
TextColor = m_CandidateColor ;
TextBkColor = m_CandidateWinColor ;
SelTextColor = m_CandidateSelColor ;
SelBkColor = m_CandidateSelBkColor ;
}
// For Japanese IME, align the window with the first target converted character.
// For all other IMEs, align with the caret. This is because the caret
// does not move for Japanese IME.
if ( GetLanguage ( ) = = LANG_CHT & & ! GetImeId ( ) )
nXComp = 0 ;
else
if ( GetPrimaryLanguage ( ) = = LANG_JAPANESE )
s_CompString . CPtoX ( s_nFirstTargetConv , FALSE , & nXComp ) ;
else
s_CompString . CPtoX ( s_nCompCaret , FALSE , & nXComp ) ;
// Compute the size of the candidate window
int nWidthRequired = 0 ;
int nHeightRequired = 0 ;
int nSingleLineHeight = 0 ;
if ( ( s_bVerticalCand & & ! bReading ) | |
( ! s_bHorizontalReading & & bReading ) )
{
// Vertical window
for ( UINT i = 0 ; i < nNumEntries ; + + i )
{
if ( s_CandList . awszCandidate [ i ] [ 0 ] = = L ' \0 ' )
break ;
SetRect ( & rc , 0 , 0 , 0 , 0 ) ;
m_pDialog - > CalcTextRect ( s_CandList . awszCandidate [ i ] , m_Elements . GetAt ( 1 ) , & rc ) ;
nWidthRequired = __max ( nWidthRequired , rc . right - rc . left ) ;
nSingleLineHeight = __max ( nSingleLineHeight , rc . bottom - rc . top ) ;
}
nHeightRequired = nSingleLineHeight * nNumEntries ;
} else
{
// Horizontal window
SetRect ( & rc , 0 , 0 , 0 , 0 ) ;
if ( bReading )
m_pDialog - > CalcTextRect ( s_wszReadingString , m_Elements . GetAt ( 1 ) , & rc ) ;
else
m_pDialog - > CalcTextRect ( s_CandList . HoriCand . GetBuffer ( ) , m_Elements . GetAt ( 1 ) , & rc ) ;
nWidthRequired = rc . right - rc . left ;
nSingleLineHeight = nHeightRequired = rc . bottom - rc . top ;
}
// Now that we have the dimension, calculate the location for the candidate window.
// We attempt to fit the window in this order:
// bottom, top, right, left.
bool bHasPosition = false ;
// Bottom
SetRect ( & rc , s_ptCompString . x + nXComp , s_ptCompString . y + m_rcText . bottom - m_rcText . top ,
s_ptCompString . x + nXComp + nWidthRequired , s_ptCompString . y + m_rcText . bottom - m_rcText . top + nHeightRequired ) ;
// if the right edge is cut off, move it left.
if ( rc . right > m_pDialog - > GetWidth ( ) )
{
rc . left - = rc . right - m_pDialog - > GetWidth ( ) ;
rc . right = m_pDialog - > GetWidth ( ) ;
}
if ( rc . bottom < = m_pDialog - > GetHeight ( ) )
bHasPosition = true ;
// Top
if ( ! bHasPosition )
{
SetRect ( & rc , s_ptCompString . x + nXComp , s_ptCompString . y - nHeightRequired ,
s_ptCompString . x + nXComp + nWidthRequired , s_ptCompString . y ) ;
// if the right edge is cut off, move it left.
if ( rc . right > m_pDialog - > GetWidth ( ) )
{
rc . left - = rc . right - m_pDialog - > GetWidth ( ) ;
rc . right = m_pDialog - > GetWidth ( ) ;
}
if ( rc . top > = 0 )
bHasPosition = true ;
}
// Right
if ( ! bHasPosition )
{
int nXCompTrail ;
s_CompString . CPtoX ( s_nCompCaret , TRUE , & nXCompTrail ) ;
SetRect ( & rc , s_ptCompString . x + nXCompTrail , 0 ,
s_ptCompString . x + nXCompTrail + nWidthRequired , nHeightRequired ) ;
if ( rc . right < = m_pDialog - > GetWidth ( ) )
bHasPosition = true ;
}
// Left
if ( ! bHasPosition )
{
SetRect ( & rc , s_ptCompString . x + nXComp - nWidthRequired , 0 ,
s_ptCompString . x + nXComp , nHeightRequired ) ;
if ( rc . right > = 0 )
bHasPosition = true ;
}
if ( ! bHasPosition )
{
// The dialog is too small for the candidate window.
// Fall back to render at 0, 0. Some part of the window
// will be cut off.
rc . left = 0 ;
rc . right = nWidthRequired ;
}
// If we are rendering the candidate window, save the position
// so that mouse clicks are checked properly.
if ( ! bReading )
s_CandList . rcCandidate = rc ;
// Render the elements
m_pDialog - > DrawRect ( & rc , TextBkColor ) ;
if ( ( s_bVerticalCand & & ! bReading ) | |
( ! s_bHorizontalReading & & bReading ) )
{
// Vertical candidate window
for ( UINT i = 0 ; i < nNumEntries ; + + i )
{
// Here we are rendering one line at a time
rc . bottom = rc . top + nSingleLineHeight ;
// Use a different color for the selected string
if ( s_CandList . dwSelection = = i )
{
m_pDialog - > DrawRect ( & rc , SelBkColor ) ;
m_Elements . GetAt ( 1 ) - > FontColor . Current = SelTextColor ;
} else
m_Elements . GetAt ( 1 ) - > FontColor . Current = TextColor ;
m_pDialog - > DrawText ( s_CandList . awszCandidate [ i ] , m_Elements . GetAt ( 1 ) , & rc ) ;
rc . top + = nSingleLineHeight ;
}
} else
{
// Horizontal candidate window
m_Elements . GetAt ( 1 ) - > FontColor . Current = TextColor ;
if ( bReading )
m_pDialog - > DrawText ( s_wszReadingString , m_Elements . GetAt ( 1 ) , & rc ) ;
else
m_pDialog - > DrawText ( s_CandList . HoriCand . GetBuffer ( ) , m_Elements . GetAt ( 1 ) , & rc ) ;
// Render the selected entry differently
if ( ! bReading )
{
int nXLeft , nXRight ;
s_CandList . HoriCand . CPtoX ( s_CandList . nFirstSelected , FALSE , & nXLeft ) ;
s_CandList . HoriCand . CPtoX ( s_CandList . nFirstSelected + s_CandList . nHoriSelectedLen , FALSE , & nXRight ) ;
rc . right = rc . left + nXRight ;
rc . left + = nXLeft ;
m_pDialog - > DrawRect ( & rc , SelBkColor ) ;
m_Elements . GetAt ( 1 ) - > FontColor . Current = SelTextColor ;
m_pDialog - > DrawText ( s_CandList . HoriCand . GetBuffer ( ) + s_CandList . nFirstSelected ,
m_Elements . GetAt ( 1 ) , & rc , false , s_CandList . nHoriSelectedLen ) ;
}
}
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : RenderComposition ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
RECT rcCaret = { 0 , 0 , 0 , 0 } ;
int nX , nXFirst ;
m_Buffer . CPtoX ( m_nCaret , FALSE , & nX ) ;
m_Buffer . CPtoX ( m_nFirstVisible , FALSE , & nXFirst ) ;
CDXUTElement * pElement = m_Elements . GetAt ( 1 ) ;
// Get the required width
RECT rc = { m_rcText . left + nX - nXFirst , m_rcText . top ,
m_rcText . left + nX - nXFirst , m_rcText . bottom } ;
m_pDialog - > CalcTextRect ( s_CompString . GetBuffer ( ) , pElement , & rc ) ;
// If the composition string is too long to fit within
// the text area, move it to below the current line.
// This matches the behavior of the default IME.
if ( rc . right > m_rcText . right )
OffsetRect ( & rc , m_rcText . left - rc . left , rc . bottom - rc . top ) ;
// Save the rectangle position for processing highlighted text.
RECT rcFirst = rc ;
// Update s_ptCompString for RenderCandidateReadingWindow().
s_ptCompString . x = rc . left ; s_ptCompString . y = rc . top ;
D3DCOLOR TextColor = m_CompColor ;
// Render the window and string.
// If the string is too long, we must wrap the line.
pElement - > FontColor . Current = TextColor ;
const WCHAR * pwszComp = s_CompString . GetBuffer ( ) ;
int nCharLeft = s_CompString . GetTextSize ( ) ;
for ( ; ; )
{
// Find the last character that can be drawn on the same line.
int nLastInLine ;
int bTrail ;
s_CompString . XtoCP ( m_rcText . right - rc . left , & nLastInLine , & bTrail ) ;
int nNumCharToDraw = __min ( nCharLeft , nLastInLine ) ;
m_pDialog - > CalcTextRect ( pwszComp , pElement , & rc , nNumCharToDraw ) ;
// Draw the background
// For Korean IME, blink the composition window background as if it
// is a cursor.
if ( GetPrimaryLanguage ( ) = = LANG_KOREAN )
{
if ( m_bCaretOn )
{
m_pDialog - > DrawRect ( & rc , m_CompWinColor ) ;
}
else
{
// Not drawing composition string background. We
// use the editbox's text color for composition
// string text.
TextColor = m_Elements . GetAt ( 0 ) - > FontColor . States [ DXUT_STATE_NORMAL ] ;
}
} else
{
// Non-Korean IME. Always draw composition background.
m_pDialog - > DrawRect ( & rc , m_CompWinColor ) ;
}
// Draw the text
pElement - > FontColor . Current = TextColor ;
m_pDialog - > DrawText ( pwszComp , pElement , & rc , false , nNumCharToDraw ) ;
// Advance pointer and counter
nCharLeft - = nNumCharToDraw ;
pwszComp + = nNumCharToDraw ;
if ( nCharLeft < = 0 )
break ;
// Advance rectangle coordinates to beginning of next line
OffsetRect ( & rc , m_rcText . left - rc . left , rc . bottom - rc . top ) ;
}
// Load the rect for the first line again.
rc = rcFirst ;
// Inspect each character in the comp string.
// For target-converted and target-non-converted characters,
// we display a different background color so they appear highlighted.
int nCharFirst = 0 ;
nXFirst = 0 ;
s_nFirstTargetConv = - 1 ;
BYTE * pAttr ;
const WCHAR * pcComp ;
for ( pcComp = s_CompString . GetBuffer ( ) , pAttr = s_abCompStringAttr ;
* pcComp ! = L ' \0 ' ; + + pcComp , + + pAttr )
{
D3DCOLOR bkColor ;
// Render a different background for this character
int nXLeft , nXRight ;
s_CompString . CPtoX ( int ( pcComp - s_CompString . GetBuffer ( ) ) , FALSE , & nXLeft ) ;
s_CompString . CPtoX ( int ( pcComp - s_CompString . GetBuffer ( ) ) , TRUE , & nXRight ) ;
// Check if this character is off the right edge and should
// be wrapped to the next line.
if ( nXRight - nXFirst > m_rcText . right - rc . left )
{
// Advance rectangle coordinates to beginning of next line
OffsetRect ( & rc , m_rcText . left - rc . left , rc . bottom - rc . top ) ;
// Update the line's first character information
nCharFirst = int ( pcComp - s_CompString . GetBuffer ( ) ) ;
s_CompString . CPtoX ( nCharFirst , FALSE , & nXFirst ) ;
}
// If the caret is on this character, save the coordinates
// for drawing the caret later.
if ( s_nCompCaret = = int ( pcComp - s_CompString . GetBuffer ( ) ) )
{
rcCaret = rc ;
rcCaret . left + = nXLeft - nXFirst - 1 ;
rcCaret . right = rcCaret . left + 2 ;
}
// Set up color based on the character attribute
if ( * pAttr = = ATTR_TARGET_CONVERTED )
{
pElement - > FontColor . Current = m_CompTargetColor ;
bkColor = m_CompTargetBkColor ;
}
else
if ( * pAttr = = ATTR_TARGET_NOTCONVERTED )
{
pElement - > FontColor . Current = m_CompTargetNonColor ;
bkColor = m_CompTargetNonBkColor ;
}
else
{
continue ;
}
RECT rcTarget = { rc . left + nXLeft - nXFirst , rc . top , rc . left + nXRight - nXFirst , rc . bottom } ;
m_pDialog - > DrawRect ( & rcTarget , bkColor ) ;
m_pDialog - > DrawText ( pcComp , pElement , & rcTarget , false , 1 ) ;
// Record the first target converted character's index
if ( - 1 = = s_nFirstTargetConv )
s_nFirstTargetConv = int ( pAttr - s_abCompStringAttr ) ;
}
// Render the composition caret
if ( m_bCaretOn )
{
// If the caret is at the very end, its position would not have
// been computed in the above loop. We compute it here.
if ( s_nCompCaret = = s_CompString . GetTextSize ( ) )
{
s_CompString . CPtoX ( s_nCompCaret , FALSE , & nX ) ;
rcCaret = rc ;
rcCaret . left + = nX - nXFirst - 1 ;
rcCaret . right = rcCaret . left + 2 ;
}
m_pDialog - > DrawRect ( & rcCaret , m_CompCaretColor ) ;
}
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : RenderIndicator ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
CDXUTElement * pElement = m_Elements . GetAt ( 9 ) ;
pElement - > TextureColor . Blend ( DXUT_STATE_NORMAL , fElapsedTime ) ;
m_pDialog - > DrawSprite ( pElement , & m_rcIndicator ) ;
RECT rc = m_rcIndicator ;
InflateRect ( & rc , - m_nSpacing , - m_nSpacing ) ;
pElement - > FontColor . Current = s_ImeState = = IMEUI_STATE_ON & & s_bEnableImeSystem ? m_IndicatorImeColor : m_IndicatorEngColor ;
RECT rcCalc = { 0 , 0 , 0 , 0 } ;
// If IME system is off, draw English indicator.
WCHAR * pwszIndicator = s_bEnableImeSystem ? s_wszCurrIndicator : s_aszIndicator [ 0 ] ;
m_pDialog - > CalcTextRect ( pwszIndicator , pElement , & rcCalc ) ;
m_pDialog - > DrawText ( pwszIndicator , pElement , & rc ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : Render ( IDirect3DDevice9 * pd3dDevice , float fElapsedTime )
{
if ( m_bVisible = = false )
return ;
// If we have not computed the indicator symbol width,
// do it.
if ( ! m_nIndicatorWidth )
{
for ( int i = 0 ; i < 5 ; + + i )
{
RECT rc = { 0 , 0 , 0 , 0 } ;
m_pDialog - > CalcTextRect ( s_aszIndicator [ i ] , m_Elements . GetAt ( 9 ) , & rc ) ;
m_nIndicatorWidth = __max ( m_nIndicatorWidth , rc . right - rc . left ) ;
}
// Update the rectangles now that we have the indicator's width
UpdateRects ( ) ;
}
// Let the parent render first (edit control)
CDXUTEditBox : : Render ( pd3dDevice , fElapsedTime ) ;
CDXUTElement * pElement = GetElement ( 1 ) ;
if ( pElement )
{
s_CompString . SetFontNode ( m_pDialog - > GetFont ( pElement - > iFont ) ) ;
s_CandList . HoriCand . SetFontNode ( m_pDialog - > GetFont ( pElement - > iFont ) ) ;
}
//
// Now render the IME elements
//
if ( m_bHasFocus )
{
// Render the input locale indicator
RenderIndicator ( pd3dDevice , fElapsedTime ) ;
// Display the composition string.
// This method should also update s_ptCompString
// for RenderCandidateReadingWindow.
RenderComposition ( pd3dDevice , fElapsedTime ) ;
// Display the reading/candidate window. RenderCandidateReadingWindow()
// uses s_ptCompString to position itself. s_ptCompString must have
// been filled in by RenderComposition().
if ( s_bShowReadingWindow )
// Reading window
RenderCandidateReadingWindow ( pd3dDevice , fElapsedTime , true ) ;
else
if ( s_CandList . bShowWindow )
// Candidate list window
RenderCandidateReadingWindow ( pd3dDevice , fElapsedTime , false ) ;
}
}
//--------------------------------------------------------------------------------------
void CUniBuffer : : Initialize ( )
{
if ( s_hDll ) // Only need to do once
return ;
TCHAR wszPath [ MAX_PATH + 1 ] ;
if ( ! : : GetSystemDirectory ( wszPath , MAX_PATH + 1 ) )
return ;
// Verify whether it is safe to concatenate these strings
int len1 = lstrlen ( wszPath ) ;
int len2 = lstrlen ( UNISCRIBE_DLLNAME ) ;
if ( len1 + len2 > MAX_PATH )
{
return ;
}
// We have verified that the concatenated string will fit into wszPath,
// so it is safe to concatenate them.
StringCchCat ( wszPath , MAX_PATH , UNISCRIBE_DLLNAME ) ;
s_hDll = LoadLibrary ( wszPath ) ;
if ( s_hDll )
{
FARPROC Temp ;
GETPROCADDRESS ( s_hDll , ScriptApplyDigitSubstitution , Temp ) ;
GETPROCADDRESS ( s_hDll , ScriptStringAnalyse , Temp ) ;
GETPROCADDRESS ( s_hDll , ScriptStringCPtoX , Temp ) ;
GETPROCADDRESS ( s_hDll , ScriptStringXtoCP , Temp ) ;
GETPROCADDRESS ( s_hDll , ScriptStringFree , Temp ) ;
GETPROCADDRESS ( s_hDll , ScriptString_pLogAttr , Temp ) ;
GETPROCADDRESS ( s_hDll , ScriptString_pcOutChars , Temp ) ;
}
}
//--------------------------------------------------------------------------------------
void CUniBuffer : : Uninitialize ( )
{
if ( s_hDll )
{
PLACEHOLDERPROC ( ScriptApplyDigitSubstitution ) ;
PLACEHOLDERPROC ( ScriptStringAnalyse ) ;
PLACEHOLDERPROC ( ScriptStringCPtoX ) ;
PLACEHOLDERPROC ( ScriptStringXtoCP ) ;
PLACEHOLDERPROC ( ScriptStringFree ) ;
PLACEHOLDERPROC ( ScriptString_pLogAttr ) ;
PLACEHOLDERPROC ( ScriptString_pcOutChars ) ;
FreeLibrary ( s_hDll ) ;
s_hDll = NULL ;
}
}
//--------------------------------------------------------------------------------------
bool CUniBuffer : : SetBufferSize ( int nNewSize )
{
// If the current size is already the maximum allowed,
// we can't possibly allocate more.
if ( m_nBufferSize = = DXUT_MAX_EDITBOXLENGTH )
return false ;
int nAllocateSize = ( nNewSize = = - 1 | | nNewSize < m_nBufferSize * 2 ) ? ( m_nBufferSize ? m_nBufferSize * 2 : 256 ) : nNewSize * 2 ;
// Cap the buffer size at the maximum allowed.
if ( nAllocateSize > DXUT_MAX_EDITBOXLENGTH )
nAllocateSize = DXUT_MAX_EDITBOXLENGTH ;
WCHAR * pTempBuffer = new WCHAR [ nAllocateSize ] ;
if ( ! pTempBuffer )
return false ;
if ( m_pwszBuffer )
{
CopyMemory ( pTempBuffer , m_pwszBuffer , m_nBufferSize * sizeof ( WCHAR ) ) ;
delete [ ] m_pwszBuffer ;
}
else
{
ZeroMemory ( pTempBuffer , sizeof ( WCHAR ) * nAllocateSize ) ;
}
m_pwszBuffer = pTempBuffer ;
m_nBufferSize = nAllocateSize ;
return true ;
}
//--------------------------------------------------------------------------------------
// Uniscribe -- Analyse() analyses the string in the buffer
//--------------------------------------------------------------------------------------
HRESULT CUniBuffer : : Analyse ( )
{
if ( m_Analysis )
_ScriptStringFree ( & m_Analysis ) ;
SCRIPT_CONTROL ScriptControl ; // For uniscribe
SCRIPT_STATE ScriptState ; // For uniscribe
ZeroMemory ( & ScriptControl , sizeof ( ScriptControl ) ) ;
ZeroMemory ( & ScriptState , sizeof ( ScriptState ) ) ;
_ScriptApplyDigitSubstitution ( NULL , & ScriptControl , & ScriptState ) ;
if ( ! m_pFontNode )
return E_FAIL ;
HRESULT hr = _ScriptStringAnalyse ( m_pFontNode - > pFont ? m_pFontNode - > pFont - > GetDC ( ) : NULL ,
m_pwszBuffer ,
lstrlenW ( m_pwszBuffer ) + 1 , // NULL is also analyzed.
lstrlenW ( m_pwszBuffer ) * 3 / 2 + 16 ,
DEFAULT_CHARSET ,
SSA_BREAK | SSA_GLYPHS | SSA_FALLBACK | SSA_LINK ,
0 ,
& ScriptControl ,
& ScriptState ,
NULL ,
NULL ,
NULL ,
& m_Analysis ) ;
if ( SUCCEEDED ( hr ) )
m_bAnalyseRequired = false ; // Analysis is up-to-date
return hr ;
}
//--------------------------------------------------------------------------------------
CUniBuffer : : CUniBuffer ( int nInitialSize )
{
CUniBuffer : : Initialize ( ) ; // ensure static vars are properly init'ed first
m_nBufferSize = 0 ;
m_pwszBuffer = NULL ;
m_bAnalyseRequired = true ;
m_Analysis = NULL ;
m_pFontNode = NULL ;
field_8 = 0 ;
field_12 = 0 ;
if ( nInitialSize > 0 )
SetBufferSize ( nInitialSize ) ;
}
//--------------------------------------------------------------------------------------
CUniBuffer : : ~ CUniBuffer ( )
{
delete [ ] m_pwszBuffer ;
if ( m_Analysis )
_ScriptStringFree ( & m_Analysis ) ;
}
//--------------------------------------------------------------------------------------
WCHAR & CUniBuffer : : operator [ ] ( int n ) // No param checking
{
// This version of operator[] is called only
// if we are asking for write access, so
// re-analysis is required.
m_bAnalyseRequired = true ;
return m_pwszBuffer [ n ] ;
}
//--------------------------------------------------------------------------------------
void CUniBuffer : : Clear ( )
{
* m_pwszBuffer = L ' \0 ' ;
m_bAnalyseRequired = true ;
}
//--------------------------------------------------------------------------------------
// Inserts the char at specified index.
// If nIndex == -1, insert to the end.
//--------------------------------------------------------------------------------------
bool CUniBuffer : : InsertChar ( int nIndex , WCHAR tchr )
{
assert ( nIndex > = 0 ) ;
if ( nIndex < 0 | | nIndex > lstrlenW ( m_pwszBuffer ) )
return false ; // invalid index
// Check for maximum length allowed
if ( GetTextSize ( ) + 1 > = DXUT_MAX_EDITBOXLENGTH )
return false ;
if ( lstrlenW ( m_pwszBuffer ) + 1 > = m_nBufferSize )
{
if ( ! SetBufferSize ( - 1 ) )
return false ; // out of memory
}
assert ( m_nBufferSize > = 2 ) ;
// Shift the characters after the index, start by copying the null terminator
WCHAR * dest = m_pwszBuffer + lstrlenW ( m_pwszBuffer ) + 1 ;
WCHAR * stop = m_pwszBuffer + nIndex ;
WCHAR * src = dest - 1 ;
while ( dest > stop )
{
* dest - - = * src - - ;
}
// Set new character
m_pwszBuffer [ nIndex ] = tchr ;
m_bAnalyseRequired = true ;
return true ;
}
bool CUniBuffer : : InsertChar ( int nIndex , CHAR tchr )
{
WCHAR WideCharStr [ 2 ] ;
ZeroMemory ( & WideCharStr [ 0 ] , sizeof ( WideCharStr ) ) ;
if ( field_8 )
{
CHAR MultiByteStr [ 3 ] ;
MultiByteStr [ 0 ] = field_8 ;
MultiByteStr [ 1 ] = tchr ;
MultiByteStr [ 2 ] = 0 ;
MultiByteToWideChar ( CP_ACP , 0 , MultiByteStr , 2 , WideCharStr , 1 ) ;
InsertChar ( nIndex , WideCharStr [ 0 ] ) ;
field_8 = 0 ;
return true ;
}
else if ( IsDBCSLeadByteEx ( CP_ACP , tchr ) )
{
field_8 = tchr ;
return false ;
}
else
{
MultiByteToWideChar ( CP_ACP , 0 , & tchr , 1 , WideCharStr , 1 ) ;
InsertChar ( nIndex , WideCharStr [ 0 ] ) ;
return true ;
}
}
//--------------------------------------------------------------------------------------
// Removes the char at specified index.
// If nIndex == -1, remove the last char.
//--------------------------------------------------------------------------------------
bool CUniBuffer : : RemoveChar ( int nIndex )
{
if ( ! lstrlenW ( m_pwszBuffer ) | | nIndex < 0 | | nIndex > = lstrlenW ( m_pwszBuffer ) )
return false ; // Invalid index
MoveMemory ( m_pwszBuffer + nIndex , m_pwszBuffer + nIndex + 1 , sizeof ( TCHAR ) * ( lstrlenW ( m_pwszBuffer ) - nIndex ) ) ;
m_bAnalyseRequired = true ;
return true ;
}
//--------------------------------------------------------------------------------------
// Inserts the first nCount characters of the string pStr at specified index.
// If nCount == -1, the entire string is inserted.
// If nIndex == -1, insert to the end.
//--------------------------------------------------------------------------------------
bool CUniBuffer : : InsertString ( int nIndex , const WCHAR * pStr , int nCount )
{
assert ( nIndex > = 0 ) ;
if ( nIndex > lstrlenW ( m_pwszBuffer ) )
return false ; // invalid index
if ( - 1 = = nCount )
nCount = lstrlenW ( pStr ) ;
// Check for maximum length allowed
if ( GetTextSize ( ) + nCount > = DXUT_MAX_EDITBOXLENGTH )
return false ;
if ( lstrlenW ( m_pwszBuffer ) + nCount > = m_nBufferSize )
{
if ( ! SetBufferSize ( lstrlenW ( m_pwszBuffer ) + nCount + 1 ) )
return false ; // out of memory
}
MoveMemory ( m_pwszBuffer + nIndex + nCount , m_pwszBuffer + nIndex , sizeof ( TCHAR ) * ( lstrlenW ( m_pwszBuffer ) - nIndex + 1 ) ) ;
CopyMemory ( m_pwszBuffer + nIndex , pStr , nCount * sizeof ( TCHAR ) ) ;
m_bAnalyseRequired = true ;
return true ;
}
//--------------------------------------------------------------------------------------
bool CUniBuffer : : SetText ( LPCWSTR wszText )
{
assert ( wszText ! = NULL ) ;
int nRequired = int ( lstrlenW ( wszText ) + 1 ) ;
// Check for maximum length allowed
if ( nRequired > = DXUT_MAX_EDITBOXLENGTH )
return false ;
while ( GetBufferSize ( ) < nRequired )
if ( ! SetBufferSize ( - 1 ) )
break ;
// Check again in case out of memory occurred inside while loop.
if ( GetBufferSize ( ) > = nRequired )
{
StringCchCopyW ( m_pwszBuffer , GetBufferSize ( ) , wszText ) ;
m_bAnalyseRequired = true ;
return true ;
}
else
return false ;
}
//--------------------------------------------------------------------------------------
void ConvertAnsiToWide ( LPCSTR wszSrc , LPWSTR wszDest , int nSize )
{
memset ( wszDest , 0 , sizeof ( WCHAR ) * nSize ) ;
int nCount = MultiByteToWideChar ( CP_ACP , 0 , wszSrc , strlen ( wszSrc ) , NULL , 0 ) ;
if ( nCount < nSize )
MultiByteToWideChar ( CP_ACP , 0 , wszSrc , strlen ( wszSrc ) , wszDest , nCount ) ;
}
//--------------------------------------------------------------------------------------
bool CUniBuffer : : SetText ( LPCTSTR wszText )
{
if ( lstrlenA ( wszText ) > 1024 ) return false ;
WCHAR szBuffer [ 2048 ] ;
ConvertAnsiToWide ( wszText , szBuffer , 2048 ) ;
SetText ( szBuffer ) ;
2024-10-28 00:00:41 +08:00
return true ;
2024-07-21 23:13:14 +08:00
}
//--------------------------------------------------------------------------------------
HRESULT CUniBuffer : : CPtoX ( int nCP , BOOL bTrail , int * pX )
{
assert ( pX ) ;
* pX = 0 ; // Default
HRESULT hr = S_OK ;
if ( m_bAnalyseRequired )
hr = Analyse ( ) ;
if ( SUCCEEDED ( hr ) )
hr = _ScriptStringCPtoX ( m_Analysis , nCP , bTrail , pX ) ;
return hr ;
}
//--------------------------------------------------------------------------------------
HRESULT CUniBuffer : : XtoCP ( int nX , int * pCP , int * pnTrail )
{
assert ( pCP & & pnTrail ) ;
* pCP = 0 ; * pnTrail = FALSE ; // Default
HRESULT hr = S_OK ;
if ( m_bAnalyseRequired )
hr = Analyse ( ) ;
if ( SUCCEEDED ( hr ) )
hr = _ScriptStringXtoCP ( m_Analysis , nX , pCP , pnTrail ) ;
// If the coordinate falls outside the text region, we
// can get character positions that don't exist. We must
// filter them here and convert them to those that do exist.
if ( * pCP = = - 1 & & * pnTrail = = TRUE )
{
* pCP = 0 ; * pnTrail = FALSE ;
} else
if ( * pCP > lstrlenW ( m_pwszBuffer ) & & * pnTrail = = FALSE )
{
* pCP = lstrlenW ( m_pwszBuffer ) ; * pnTrail = TRUE ;
}
return hr ;
}
//--------------------------------------------------------------------------------------
void CUniBuffer : : GetPriorItemPos ( int nCP , int * pPrior )
{
* pPrior = nCP ; // Default is the char itself
if ( m_bAnalyseRequired )
if ( FAILED ( Analyse ( ) ) )
return ;
const SCRIPT_LOGATTR * pLogAttr = _ScriptString_pLogAttr ( m_Analysis ) ;
if ( ! pLogAttr )
return ;
if ( ! _ScriptString_pcOutChars ( m_Analysis ) )
return ;
int nInitial = * _ScriptString_pcOutChars ( m_Analysis ) ;
if ( nCP - 1 < nInitial )
nInitial = nCP - 1 ;
for ( int i = nInitial ; i > 0 ; - - i )
if ( pLogAttr [ i ] . fWordStop | | // Either the fWordStop flag is set
( ! pLogAttr [ i ] . fWhiteSpace & & // Or the previous char is whitespace but this isn't.
pLogAttr [ i - 1 ] . fWhiteSpace ) )
{
* pPrior = i ;
return ;
}
// We have reached index 0. 0 is always a break point, so simply return it.
* pPrior = 0 ;
}
//--------------------------------------------------------------------------------------
void CUniBuffer : : GetNextItemPos ( int nCP , int * pPrior )
{
* pPrior = nCP ; // Default is the char itself
HRESULT hr = S_OK ;
if ( m_bAnalyseRequired )
hr = Analyse ( ) ;
if ( FAILED ( hr ) )
return ;
const SCRIPT_LOGATTR * pLogAttr = _ScriptString_pLogAttr ( m_Analysis ) ;
if ( ! pLogAttr )
return ;
if ( ! _ScriptString_pcOutChars ( m_Analysis ) )
return ;
int nInitial = * _ScriptString_pcOutChars ( m_Analysis ) ;
if ( nCP + 1 < nInitial )
nInitial = nCP + 1 ;
for ( int i = nInitial ; i < * _ScriptString_pcOutChars ( m_Analysis ) - 1 ; + + i )
{
if ( pLogAttr [ i ] . fWordStop ) // Either the fWordStop flag is set
{
* pPrior = i ;
return ;
}
else
if ( pLogAttr [ i ] . fWhiteSpace & & // Or this whitespace but the next char isn't.
! pLogAttr [ i + 1 ] . fWhiteSpace )
{
* pPrior = i + 1 ; // The next char is a word stop
return ;
}
}
// We have reached the end. It's always a word stop, so simply return it.
* pPrior = * _ScriptString_pcOutChars ( m_Analysis ) - 1 ;
}
//--------------------------------------------------------------------------------------
void CDXUTEditBox : : ResetCaretBlink ( )
{
m_bCaretOn = true ;
m_dfLastBlink = DXUTGetGlobalTimer ( ) - > GetAbsoluteTime ( ) ;
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : Initialize ( )
{
if ( s_hDllImm32 ) // Only need to do once
return ;
FARPROC Temp ;
dwImeWaitTick = GetTickCount ( ) ;
s_CompString . SetBufferSize ( MAX_COMPSTRING_SIZE ) ;
TCHAR wszPath [ MAX_PATH + 1 ] ;
if ( ! : : GetSystemDirectory ( wszPath , MAX_PATH + 1 ) )
return ;
StringCchCat ( wszPath , MAX_PATH , IMM32_DLLNAME ) ;
s_hDllImm32 = LoadLibrary ( wszPath ) ;
if ( s_hDllImm32 )
{
GETPROCADDRESS ( s_hDllImm32 , ImmLockIMC , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmUnlockIMC , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmLockIMCC , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmUnlockIMCC , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmDisableTextFrameService , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmGetCompositionStringW , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmGetCandidateListW , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmGetContext , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmReleaseContext , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmAssociateContext , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmGetOpenStatus , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmSetOpenStatus , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmGetConversionStatus , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmGetDefaultIMEWnd , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmGetIMEFileNameA , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmGetVirtualKey , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmNotifyIME , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmSetConversionStatus , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmSimulateHotKey , Temp ) ;
GETPROCADDRESS ( s_hDllImm32 , ImmIsIME , Temp ) ;
}
if ( ! : : GetSystemDirectory ( wszPath , MAX_PATH + 1 ) )
return ;
StringCchCat ( wszPath , MAX_PATH , VER_DLLNAME ) ;
s_hDllVer = LoadLibrary ( wszPath ) ;
if ( s_hDllVer )
{
GETPROCADDRESS ( s_hDllVer , VerQueryValueA , Temp ) ;
GETPROCADDRESS ( s_hDllVer , GetFileVersionInfoA , Temp ) ;
GETPROCADDRESS ( s_hDllVer , GetFileVersionInfoSizeA , Temp ) ;
}
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox : : Uninitialize ( )
{
if ( s_hDllImm32 )
{
PLACEHOLDERPROC ( ImmLockIMC ) ;
PLACEHOLDERPROC ( ImmUnlockIMC ) ;
PLACEHOLDERPROC ( ImmLockIMCC ) ;
PLACEHOLDERPROC ( ImmUnlockIMCC ) ;
PLACEHOLDERPROC ( ImmDisableTextFrameService ) ;
PLACEHOLDERPROC ( ImmGetCompositionStringW ) ;
PLACEHOLDERPROC ( ImmGetCandidateListW ) ;
PLACEHOLDERPROC ( ImmGetContext ) ;
PLACEHOLDERPROC ( ImmReleaseContext ) ;
PLACEHOLDERPROC ( ImmAssociateContext ) ;
PLACEHOLDERPROC ( ImmGetOpenStatus ) ;
PLACEHOLDERPROC ( ImmSetOpenStatus ) ;
PLACEHOLDERPROC ( ImmGetConversionStatus ) ;
PLACEHOLDERPROC ( ImmGetDefaultIMEWnd ) ;
PLACEHOLDERPROC ( ImmGetIMEFileNameA ) ;
PLACEHOLDERPROC ( ImmGetVirtualKey ) ;
PLACEHOLDERPROC ( ImmNotifyIME ) ;
PLACEHOLDERPROC ( ImmSetConversionStatus ) ;
PLACEHOLDERPROC ( ImmSimulateHotKey ) ;
PLACEHOLDERPROC ( ImmIsIME ) ;
FreeLibrary ( s_hDllImm32 ) ;
s_hDllImm32 = NULL ;
}
if ( s_hDllIme )
{
PLACEHOLDERPROC ( GetReadingString ) ;
PLACEHOLDERPROC ( ShowReadingWindow ) ;
FreeLibrary ( s_hDllIme ) ;
s_hDllIme = NULL ;
}
if ( s_hDllVer )
{
PLACEHOLDERPROC ( VerQueryValueA ) ;
PLACEHOLDERPROC ( GetFileVersionInfoA ) ;
PLACEHOLDERPROC ( GetFileVersionInfoSizeA ) ;
FreeLibrary ( s_hDllVer ) ;
s_hDllVer = NULL ;
}
2024-05-18 22:59:21 +08:00
}
2024-05-13 22:35:46 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-13 22:35:46 +08:00
void DXUTBlendColor : : Init ( D3DCOLOR defaultColor , D3DCOLOR disabledColor , D3DCOLOR hiddenColor )
{
for ( int i = 0 ; i < MAX_CONTROL_STATES ; i + + )
{
States [ i ] = defaultColor ;
}
States [ DXUT_STATE_DISABLED ] = disabledColor ;
States [ DXUT_STATE_HIDDEN ] = hiddenColor ;
Current = hiddenColor ;
}
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-13 22:35:46 +08:00
void DXUTBlendColor : : Blend ( UINT iState , float fElapsedTime , float fRate )
{
D3DXCOLOR destColor = States [ iState ] ;
D3DXColorLerp ( & Current , & Current , & destColor , 1.0f - powf ( fRate , 30 * fElapsedTime ) ) ;
}
2024-05-18 22:53:38 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-18 22:53:38 +08:00
void CDXUTElement : : SetTexture ( UINT iTexture , RECT * prcTexture , D3DCOLOR defaultTextureColor )
{
this - > iTexture = iTexture ;
if ( prcTexture )
rcTexture = * prcTexture ;
else
SetRectEmpty ( & rcTexture ) ;
TextureColor . Init ( defaultTextureColor ) ;
}
2024-05-18 22:54:36 +08:00
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-18 22:54:36 +08:00
void CDXUTElement : : SetFont ( UINT iFont , D3DCOLOR defaultFontColor , DWORD dwTextFormat )
{
this - > iFont = iFont ;
this - > dwTextFormat = dwTextFormat ;
FontColor . Init ( defaultFontColor ) ;
}
//--------------------------------------------------------------------------------------
2024-07-21 23:13:14 +08:00
// MATCH
2024-05-18 22:55:23 +08:00
void CDXUTElement : : Refresh ( )
{
TextureColor . Current = TextureColor . States [ DXUT_STATE_HIDDEN ] ;
FontColor . Current = FontColor . States [ DXUT_STATE_HIDDEN ] ;
}