//******************************************************************// // // 做这个东西的时候得到了论坛上网友的热心帮助,整理之后再送给大家 // 这是个在DX程序下使用系统输入法的解决方案,可能有little bug :-) // 不过还没发现,如果发现了,告诉我啊 jerrywang@163.net // 程序中使用的CHK()CHKB()是为了监测内存泄漏,可以去掉,CTTFFONT // 为显示信息用,可以用其他方法替换如 TxtOut() 等 // //******************************************************************//
////////////////////////////////////////////////////////////////////// // // IM.h: CIM class (使用系统)输入法类 // 2001/4/30 Write by Jerry Wang // 感谢大大鱼的帮助 // Need Lib: imm32.lib // //////////////////////////////////////////////////////////////////////
#if !defined(AFX_IM_H__6887B165_972D_4D17_8A75_FE07930CE59C__INCLUDED_) #define AFX_IM_H__6887B165_972D_4D17_8A75_FE07930CE59C__INCLUDED_
#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
#define _CIM_MAXINPUTCHARNUMBER 24 //最多输入的字节数
#include "FindMe.h"
class CIM { private: CTTFFont ttffont; //显示信息 LPCANDIDATELIST m_lpCandList; //输入法候选文字列表 LPSTR m_lpszImeInput; //指向IME输入的文字字符串指针 LPSTR m_lpszCurInputLanguageDesc; //指向当前输入语言描述的指针 char m_cCandidateList[255]; //候选文字列表缓冲区 char m_cInput[64]; //输入的字母
BOOL CandidateToString( LPCANDIDATELIST lpCandidateList ); //转换候选文字列表到字符串
public:
CIM(); virtual ~CIM();
LPSTR GetResultString( void ); //取得输入的字符串
void UpdateShow( ); //显示输入法信息
LPSTR GetCurInputLanguageDesc( ); //取得应用程序当前使用语言的描述 void ClearCandidateList( void ); //清除输入法文字候选列表 BOOL GetCandidateList( HWND hWnd ); //取得输入法文字候选列表 BOOL ImeIsOpen( void ); //输入法是否打开 void OnChar( TCHAR ch ); //处理WM_IME_CHAR消息 void OnImeNotify( HWND hWnd,WPARAM wParam ); //处理WM_IME_NOTIFY消息 void OnImeComposition( HWND hWnd, LPARAM lParam ); //处理WM_IME_COMPOSITION消息 };
#endif // !defined(AFX_IM_H__6887B165_972D_4D17_8A75_FE07930CE59C__INCLUDED_)
//*********************************************************************************************//
////////////////////////////////////////////////////////////////////// // // IM.cpp: CIM class (使用系统)输入法类 // 2001/4/30 Write by Jerry Wang // 感谢大大鱼的帮助 // Need Lib: imm32.lib // //////////////////////////////////////////////////////////////////////
#include "imm.h"
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
CIM::CIM() { m_lpszImeInput = new char[_CIM_MAXINPUTCHARNUMBER]; ZeroMemory( m_lpszImeInput,_CIM_MAXINPUTCHARNUMBER ); *m_lpszImeInput = '\0'; *m_cInput = '\0';
ttffont.Create( "黑体",15,RGB(255,255,255) ); GetCurInputLanguageDesc(); }
CIM::~CIM() { ZeroMemory( m_lpszImeInput,_CIM_MAXINPUTCHARNUMBER );
CHKB( delete m_lpszImeInput ); if( m_lpszCurInputLanguageDesc != NULL ) CHKB( delete m_lpszCurInputLanguageDesc ); }
void CIM::OnImeComposition(HWND hWnd, LPARAM lParam) { if (lParam & GCS_RESULTSTR) { HIMC hIMC; //输入设备上下文 DWORD dwLen; LPSTR lpResultStr;
hIMC = ImmGetContext(hWnd); //取得输入上下文
if (!hIMC) return;
dwLen = ImmGetCompositionString(hIMC,GCS_RESULTSTR,NULL,0L); dwLen+=1;
if(dwLen) { lpResultStr = new char[ dwLen ];
//// 缓冲区已经满了 if( strlen( m_lpszImeInput ) + dwLen > _CIM_MAXINPUTCHARNUMBER - 2 ) { MessageBeep( 0 ); return; } ZeroMemory( lpResultStr ,dwLen ); if (lpResultStr) { ImmGetCompositionString(hIMC,GCS_RESULTSTR, lpResultStr,dwLen); strcat( m_lpszImeInput,lpResultStr ); } delete lpResultStr; }
ImmReleaseContext(hWnd,hIMC); //释放输入上下文 }
}
void CIM::OnImeNotify(HWND hWnd, WPARAM wParam) { DWORD dwCommand = (DWORD) wParam; switch( dwCommand ) { case IMN_CHANGECANDIDATE: GetCandidateList( hWnd ); break;
case IMN_CLOSECANDIDATE: ClearCandidateList(); break;
case IMN_OPENCANDIDATE: GetCandidateList( hWnd ); break; } }
void CIM::OnChar( TCHAR ch ) { int len = strlen( m_lpszImeInput );
if( ImeIsOpen() ) //输入法打开状态 {
} else //输入法关闭状态 { if( ch >= 32 && ch < 128 && len < _CIM_MAXINPUTCHARNUMBER - 1 ) //输入的是英文字母 { *( m_lpszImeInput + len ) = ch; *( m_lpszImeInput + len + 1) = '\0'; } }
if( ch == 8 ) //BackSpace字符 { if( len == 0 ) //字符串长度为零 return;
if( len == 1 ) //只有一个字符 { *m_lpszImeInput = '\0'; return; }
BYTE cc1,cc2; cc1 = *(m_lpszImeInput + len -1); //分离字节 cc2 = *(m_lpszImeInput + len -2);
if( cc1 > 0xA0 && cc2 > 0xA0 ) //中文双字节的每个字节都>0xA0 *( m_lpszImeInput + len -2 ) = '\0'; else //是英文字符(单字节) *( m_lpszImeInput + len -1 ) = '\0'; } }
BOOL CIM::GetCandidateList(HWND hWnd) { DWORD dwSize; HIMC hIMC;
ZeroMemory( m_cCandidateList,sizeof(m_cCandidateList) );
if( m_lpCandList ) { delete m_lpCandList; m_lpCandList = NULL; }
if( GetKeyboardLayout(0)==0 ) { return FALSE; }
hIMC = ImmGetContext(hWnd); //取得输入上下文 if(hIMC == NULL) { return FALSE; }
ZeroMemory( m_cCandidateList,sizeof(m_cCandidateList) ); if(dwSize = ImmGetCandidateList(hIMC,0x0,NULL,0)) { m_lpCandList = (LPCANDIDATELIST)new char[dwSize]; if(m_lpCandList) { ImmGetCandidateList(hIMC,0x0,m_lpCandList,dwSize); CandidateToString(m_lpCandList); } }
ImmReleaseContext(hWnd,hIMC);
return TRUE; }
void CIM::ClearCandidateList() { if(m_lpCandList) { delete m_lpCandList; m_lpCandList = NULL; } ZeroMemory( m_cCandidateList,sizeof( m_cCandidateList ) ); }
LPSTR CIM::GetCurInputLanguageDesc() { HKL hKL = GetKeyboardLayout(0);
if( m_lpszCurInputLanguageDesc != NULL ) CHKB( delete m_lpszCurInputLanguageDesc ); //删除先 ^o^
int lengh = ImmGetDescription(hKL,NULL,0); //取得描述的长度
CHK( m_lpszCurInputLanguageDesc = new char[ lengh ] );
if( lengh ) { ImmGetDescription(hKL,m_lpszCurInputLanguageDesc,lengh); } else { strcpy( m_lpszCurInputLanguageDesc,"输入法关闭" ); }
return m_lpszCurInputLanguageDesc; }
void CIM::UpdateShow() { POINT pt; pt.y = 450; pt.x = 400; ttffont.SetSurface( DD_GetBackScreen() ); ttffont.ShowText( m_lpszCurInputLanguageDesc,&pt,RGB( 255,255,0 )); //显示输入法描述
pt.y = 420; pt.x = 20; ttffont.ShowText( m_cCandidateList,&pt );
pt.y = 450; pt.x = 20; if( *m_lpszImeInput == '\0' ) return;
ttffont.ShowText( m_lpszImeInput,&pt,RGB( 255,255,0 )); //输入的文字 }
LPSTR CIM::GetResultString() { return m_lpszImeInput; }
BOOL CIM::CandidateToString(LPCANDIDATELIST lpCandidateList) { if( !m_lpCandList ) return FALSE;
if( m_lpCandList->dwCount>0 ) { LPDWORD lpdwOffset;
lpdwOffset = &m_lpCandList->dwOffset[0];
lpdwOffset += m_lpCandList->dwPageStart;
ZeroMemory( m_lpCandList,sizeof( m_lpCandList ) );
DWORD z=1; for (DWORD i = m_lpCandList->dwPageStart; (i < lpCandidateList->dwCount) && (i < m_lpCandList->dwPageStart + m_lpCandList->dwPageSize); i++) { LPSTR lpstr = (LPSTR)m_lpCandList + *lpdwOffset++; char buf[255]; sprintf( buf,"%d.%s",z,lpstr ); strcat( m_cCandidateList,buf ); z++; }
return TRUE; }
return FALSE; }
BOOL CIM::ImeIsOpen() { return ImmIsIME( GetKeyboardLayout(0) ); }
|