📄 dxutguiime.cpp
字号:
//--------------------------------------------------------------------------------------
// File: DXUTguiIME.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "DXUT.h"
#include "DXUTgui.h"
#include "DXUTsettingsDlg.h"
#include "DXUTres.h"
#include "DXUTgui.h"
#include "DXUTguiIME.h"
#undef min // use __min instead
#undef max // use __max instead
#define DXUT_NEAR_BUTTON_DEPTH 0.6f
//--------------------------------------------------------------------------------------
// CDXUTIMEEditBox class
//--------------------------------------------------------------------------------------
// IME constants
POINT CDXUTIMEEditBox::s_ptCompString; // Composition string position. Updated every frame.
int CDXUTIMEEditBox::s_nFirstTargetConv; // Index of the first target converted char in comp string. If none, -1.
CUniBuffer CDXUTIMEEditBox::s_CompString = CUniBuffer( 0 );
DWORD CDXUTIMEEditBox::s_adwCompStringClause[MAX_COMPSTRING_SIZE];
WCHAR CDXUTIMEEditBox::s_wszReadingString[32];
CDXUTIMEEditBox::CCandList CDXUTIMEEditBox::s_CandList; // Data relevant to the candidate list
bool CDXUTIMEEditBox::s_bImeFlag = true;
#if defined(DEBUG) || defined(_DEBUG)
bool CDXUTIMEEditBox::m_bIMEStaticMsgProcCalled = false;
#endif
//--------------------------------------------------------------------------------------
HRESULT CDXUTIMEEditBox::CreateIMEEditBox( CDXUTDialog *pDialog, int ID, LPCWSTR strText, int x, int y, int width, int height, bool bIsDefault, CDXUTIMEEditBox** ppCreated )
{
CDXUTIMEEditBox *pEditBox = new CDXUTIMEEditBox( pDialog );
if( ppCreated != NULL )
*ppCreated = pEditBox;
if( pEditBox == NULL )
return E_OUTOFMEMORY;
// 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;
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox::InitDefaultElements( CDXUTDialog *pDialog )
{
//-------------------------------------
// CDXUTIMEEditBox
//-------------------------------------
CDXUTElement Element;
RECT rcTexture;
Element.SetFont( 0, D3DCOLOR_ARGB( 255, 0, 0, 0 ), DT_LEFT | DT_TOP );
// Assign the style
SetRect( &rcTexture, 14, 90, 241, 113 );
Element.SetTexture( 0, &rcTexture );
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 0, &Element );
SetRect( &rcTexture, 8, 82, 14, 90 );
Element.SetTexture( 0, &rcTexture );
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 1, &Element );
SetRect( &rcTexture, 14, 82, 241, 90 );
Element.SetTexture( 0, &rcTexture );
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 2, &Element );
SetRect( &rcTexture, 241, 82, 246, 90 );
Element.SetTexture( 0, &rcTexture );
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 3, &Element );
SetRect( &rcTexture, 8, 90, 14, 113 );
Element.SetTexture( 0, &rcTexture );
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 4, &Element );
SetRect( &rcTexture, 241, 90, 246, 113 );
Element.SetTexture( 0, &rcTexture );
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 5, &Element );
SetRect( &rcTexture, 8, 113, 14, 121 );
Element.SetTexture( 0, &rcTexture );
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 6, &Element );
SetRect( &rcTexture, 14, 113, 241, 121 );
Element.SetTexture( 0, &rcTexture );
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 7, &Element );
SetRect( &rcTexture, 241, 113, 246, 121 );
Element.SetTexture( 0, &rcTexture );
pDialog->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, 0, 0, 0 ), DT_CENTER | DT_VCENTER );
pDialog->SetDefaultElement( DXUT_CONTROL_IMEEDITBOX, 9, &Element );
}
//--------------------------------------------------------------------------------------
CDXUTIMEEditBox::CDXUTIMEEditBox( CDXUTDialog *pDialog )
{
m_Type = DXUT_CONTROL_IMEEDITBOX;
m_pDialog = pDialog;
m_nIndicatorWidth = 0;
m_ReadingColor = D3DCOLOR_ARGB( 188, 255, 255, 255 );
m_ReadingWinColor = D3DCOLOR_ARGB( 128, 0, 0, 0 );
m_ReadingSelColor = D3DCOLOR_ARGB( 255, 255, 0, 0 );
m_ReadingSelBkColor = D3DCOLOR_ARGB( 128, 80, 80, 80 );
m_CandidateColor = D3DCOLOR_ARGB( 255, 200, 200, 200 );
m_CandidateWinColor = D3DCOLOR_ARGB( 128, 0, 0, 0 );
m_CandidateSelColor = D3DCOLOR_ARGB( 255, 255, 255, 255 );
m_CandidateSelBkColor = D3DCOLOR_ARGB( 128, 158, 158, 158 );
m_CompColor = D3DCOLOR_ARGB( 255, 200, 200, 255 );
m_CompWinColor = D3DCOLOR_ARGB( 198, 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, 255, 255, 255 );
m_IndicatorEngColor = D3DCOLOR_ARGB( 255, 0, 0, 0 );
m_IndicatorBkColor = D3DCOLOR_ARGB( 255, 128, 128, 128 );
}
//--------------------------------------------------------------------------------------
CDXUTIMEEditBox::~CDXUTIMEEditBox()
{
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox::SendKey( BYTE nVirtKey )
{
keybd_event( nVirtKey, 0, 0, 0 );
keybd_event( nVirtKey, 0, KEYEVENTF_KEYUP, 0 );
}
//--------------------------------------------------------------------------------------
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)
//--------------------------------------------------------------------------------------
// Enable/disable the entire IME system. When disabled, the default IME handling
// kicks in.
void CDXUTIMEEditBox::EnableImeSystem( bool bEnable )
{
ImeUi_EnableIme( bEnable );
}
//--------------------------------------------------------------------------------------
// Resets the composition string.
void CDXUTIMEEditBox::ResetCompositionString()
{
s_CompString.SetText( L"" );
}
//--------------------------------------------------------------------------------------
// This function is used only briefly in CHT IME handling,
// so accelerator isn't processed.
void CDXUTIMEEditBox::PumpMessage()
{
MSG msg;
while( PeekMessageW( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
if( !GetMessageW( &msg, NULL, 0, 0 ) )
{
PostQuitMessage( (int)msg.wParam );
return;
}
TranslateMessage( &msg );
DispatchMessageA( &msg );
}
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox::OnFocusIn()
{
ImeUi_EnableIme( s_bImeFlag );
CDXUTEditBox::OnFocusIn();
}
//--------------------------------------------------------------------------------------
void CDXUTIMEEditBox::OnFocusOut()
{
ImeUi_FinalizeString();
ImeUi_EnableIme( false );
CDXUTEditBox::OnFocusOut();
}
//--------------------------------------------------------------------------------------
bool CDXUTIMEEditBox::StaticMsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( !ImeUi_IsEnabled() )
return false;
#if defined(DEBUG) || defined(_DEBUG)
m_bIMEStaticMsgProcCalled = true;
#endif
switch( uMsg )
{
case WM_INPUTLANGCHANGE:
DXUTTRACE( L"WM_INPUTLANGCHANGE\n" );
{
}
return true;
case WM_IME_SETCONTEXT:
DXUTTRACE( L"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( L"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_ENDCOMPOSITION:
DXUTTRACE( L"WM_IME_ENDCOMPOSITION\n" );
s_bHideCaret = false;
return false;
case WM_IME_COMPOSITION:
DXUTTRACE( L"WM_IME_COMPOSITION\n" );
return false;
}
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() )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -