/**************************************************/ /* */ /* */ /* Chinese IME Batch Mode */ /* (Dialogbox) */ /* */ /* */ /* Copyright (c) 1997-1999 Microsoft Corporation. */ /**************************************************/ #include "stdafx.h" #include "eudcedit.h" #if 1 // use function in imeblink.c! #include "imeblink.h" #endif #include "blinkdlg.h" #include "util.h" #define SIGN_CWIN 0x4E495743 /* Sign of CWin */ #define SIGN__TBL 0x4C42545F /* Sign of IME Table */ #if 0 // move to imeblink.c! #define UNICODE_CP 1200 #define BIG5_CP 950 #define ALT_BIG5_CP 938 #define GB2312_CP 936 typedef struct _tagCOUNTRYSETTING { UINT uCodePage; LPCTSTR szCodePage; } COUNTRYSETTING; static const COUNTRYSETTING sCountry[] = { { BIG5_CP, TEXT("BIG5") } , { ALT_BIG5_CP, TEXT("BIG5") } #if defined(UNICODE) , { UNICODE_CP, TEXT("UNICODE") } #endif , { GB2312_CP, TEXT("GB2312") } }; #endif // move to imeblink.c! #ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #endif /****************************************/ /* */ /* Constructor */ /* */ /****************************************/ CBLinkDlg::CBLinkDlg( CWnd *pParent) : CDialog( CBLinkDlg::IDD, pParent) { //{{AFX_DATA_INIT(CBLinkDlg) //}}AFX_DATA_INIT } /****************************************/ /* */ /* MESSAGE "WM_INITDIALOG" */ /* */ /****************************************/ BOOL CBLinkDlg::OnInitDialog() { CString DlgTtl; CDialog::OnInitDialog(); // Increment contexthelp mark "?" in dialog caption. // LONG WindowStyle = GetWindowLong( this->GetSafeHwnd(), GWL_EXSTYLE); // WindowStyle |= WS_EX_CONTEXTHELP; // SetWindowLong( this->GetSafeHwnd(), GWL_EXSTYLE, WindowStyle); // Set dialog title name. DlgTtl.LoadString( IDS_BATCHLNK_DLGTITLE); this->SetWindowText( DlgTtl); return TRUE; } /****************************************/ /* */ /* COMMAND "BROWSE" */ /* */ /****************************************/ void CBLinkDlg::OnBrowsetable() { OPENFILENAME ofn; CString DlgTtl, DlgMsg; CString sFilter; TCHAR chReplace; TCHAR szFilter[64]; TCHAR szFileName[MAX_PATH]; TCHAR szDirName[MAX_PATH]; TCHAR szTitleName[MAX_PATH]; // Check size of IME batch table structure if( sizeof( USRDICIMHDR) != 256){ OutputMessageBox( this->GetSafeHwnd(), IDS_INTERNAL_TITLE, IDS_INTERNAL_MSG, TRUE); return; } // Set filter of file( from string table) GetStringRes(szFilter, IDS_BATCHIME_FILTER); int StringLength = lstrlen( szFilter); chReplace = szFilter[StringLength-1]; for( int i = 0; szFilter[i]; i++){ if( szFilter[i] == chReplace) szFilter[i] = '\0'; } GetSystemWindowsDirectory( szDirName, sizeof(szDirName)/sizeof(TCHAR)); lstrcpy( szFileName, TEXT("*.TBL")); DlgTtl.LoadString( IDS_BROWSETABLE_DLGTITLE); // Set data in structure of OPENFILENAME ofn.lStructSize = sizeof( OPENFILENAME); ofn.hwndOwner = this->GetSafeHwnd(); ofn.lpstrFilter = szFilter; ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; ofn.nFilterIndex = 0; ofn.lpstrFileTitle = szTitleName; ofn.nMaxFileTitle = sizeof( szTitleName) / sizeof(TCHAR); ofn.lpstrFile = szFileName; ofn.nMaxFile = sizeof( szFileName) / sizeof(TCHAR); ofn.lpstrInitialDir = szDirName; ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_CREATEPROMPT | OFN_PATHMUSTEXIST; ofn.lpstrDefExt = NULL; ofn.lpstrTitle = DlgTtl; if( !GetOpenFileName( &ofn)) return; this->SetDlgItemText( IDC_IMETABLE, ofn.lpstrFile); CWnd *cWnd = GetDlgItem( IDOK); GotoDlgCtrl( cWnd); } /****************************************/ /* */ /* COMMAND "IDOK" */ /* */ /****************************************/ void CBLinkDlg::OnOK() { if( !RegistStringTable()) return; CDialog::OnOK(); } /****************************************/ /* */ /* Register reading string */ /* */ /****************************************/ BOOL CBLinkDlg::RegistStringTable() { LPUSRDICIMHDR lpIsvUsrDic; HANDLE hIsvUsrDicFile, hIsvUsrDic; DWORD dwSize, dwFileSize; BOOL stFunc; TCHAR szTableFile[MAX_PATH]; TCHAR szFileName[MAX_PATH]; CString DlgMsg, DlgTtl; this->GetDlgItemText( IDC_IMETABLE, szTableFile, sizeof( szTableFile)/sizeof(TCHAR)); lstrcpy( szFileName, TEXT("*.TBL")); // Create file( to read) hIsvUsrDicFile = CreateFile( szTableFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if( hIsvUsrDicFile == INVALID_HANDLE_VALUE){ DlgTtl.LoadString( IDS_NOTOPEN_TITLE); DlgMsg.LoadString( IDS_NOTOPEN_MSG); this->MessageBox( DlgMsg, DlgTtl, MB_OK | MB_ICONHAND | MB_TASKMODAL | MB_TOPMOST); return FALSE; } #if 0 for( i = 0; i < sizeof( szFileName); i++){ if( szFileName[i] == '\\'){ szFileName[i] = ' '; } } #endif // Create file mapping( read only) hIsvUsrDic = CreateFileMapping((HANDLE)hIsvUsrDicFile, NULL, PAGE_READONLY, 0, 0, NULL); if( !hIsvUsrDic){ stFunc = FALSE; DlgTtl.LoadString( IDS_NOTOPEN_TITLE); DlgMsg.LoadString( IDS_NOTOPEN_MSG); this->MessageBox( DlgMsg, DlgTtl, MB_OK | MB_ICONHAND | MB_TASKMODAL | MB_TOPMOST); goto BatchCloseUsrDicFile; } // Set view file lpIsvUsrDic = (LPUSRDICIMHDR)MapViewOfFile( hIsvUsrDic, FILE_MAP_READ, 0, 0, 0); if( !lpIsvUsrDic){ stFunc = FALSE; DlgTtl.LoadString( IDS_NOTOPEN_TITLE); DlgMsg.LoadString( IDS_NOTOPEN_MSG); this->MessageBox( DlgMsg, DlgTtl, MB_OK | MB_ICONHAND | MB_TASKMODAL | MB_TOPMOST); goto BatchCloseUsrDic; } dwSize = lpIsvUsrDic->ulTableCount * ( sizeof(WORD) + sizeof(WORD) + lpIsvUsrDic->cMethodKeySize) + 256; dwFileSize = GetFileSize( hIsvUsrDicFile, (LPDWORD)NULL); #if 0 dwSize = dwFileSize; #endif // Check table file data if( dwSize != dwFileSize){ stFunc = FALSE; OutputMessageBox( this->GetSafeHwnd(), IDS_FILESIZE_MSGTITLE, IDS_FILESIZE_MSG, TRUE); }else if( lpIsvUsrDic->uHeaderSize != 256){ stFunc = FALSE; OutputMessageBox( this->GetSafeHwnd(), IDS_FILEHEADER_MSGTITLE, IDS_FILEHEADER_MSG, TRUE); }else if( lpIsvUsrDic->uInfoSize != 13){ stFunc = FALSE; OutputMessageBox( this->GetSafeHwnd(), IDS_INMETHOD_MSGTITLE, IDS_INMETHOD_MSG, TRUE); }else if( CodePageInfo( lpIsvUsrDic->idCP) == -1){ stFunc = FALSE; OutputMessageBox( this->GetSafeHwnd(), IDS_CODEPAGE_MSGTITLE, IDS_CODEPAGE_MSG, TRUE); }else if( *(DWORD UNALIGNED *)lpIsvUsrDic->idUserCharInfoSign != SIGN_CWIN){ stFunc = FALSE; OutputMessageBox( this->GetSafeHwnd(), IDS_SIGN_MSGTITLE, IDS_SIGN_MSG, TRUE); }else if( *(DWORD UNALIGNED *)((LPBYTE)lpIsvUsrDic->idUserCharInfoSign + sizeof(DWORD)) != SIGN__TBL){ stFunc = FALSE; OutputMessageBox( this->GetSafeHwnd(), IDS_SIGN_MSGTITLE, IDS_SIGN_MSG, TRUE); }else{ stFunc = TRUE; if( !RegisterTable( this->GetSafeHwnd(), lpIsvUsrDic, dwFileSize, lpIsvUsrDic->idCP)){ OutputMessageBox( this->GetSafeHwnd(), IDS_UNMATCHED_TITLE, IDS_UNMATCHED_MSG, TRUE); stFunc = FALSE; } } UnmapViewOfFile( lpIsvUsrDic); BatchCloseUsrDic: CloseHandle( hIsvUsrDic); BatchCloseUsrDicFile: CloseHandle( hIsvUsrDicFile); return stFunc; } #if 0 // move to imeblink.c! /****************************************/ /* */ /* Register reading string */ /* */ /****************************************/ HKL CBLinkDlg::RegisterTable( HWND hWnd, LPUSRDICIMHDR lpIsvUsrDic, DWORD dwFileSize, UINT uCodePage) { HKL hKL; DWORD i; LPBYTE lpCurr, lpEnd; BOOL fRet; TCHAR szStr[16]; WORD wInternalCode[256]; WORD wAltInternalCode[256]; #ifdef UNICODE if (uCodePage == UNICODE_CP) { LPUNATSTR lpszMethodName; lpszMethodName = (LPUNATSTR)lpIsvUsrDic->achMethodName; for (i = 0; i < sizeof(lpIsvUsrDic->achMethodName) / sizeof(TCHAR); i++) { szStr[i] = *lpszMethodName++; } szStr[i] = '\0'; } else { UINT uLen; uLen = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, (LPCSTR)lpIsvUsrDic->achMethodName, sizeof(lpIsvUsrDic->achMethodName), szStr, sizeof(szStr) / sizeof(TCHAR)); szStr[uLen] = '\0'; } #else for( i = 0; i < sizeof( lpIsvUsrDic->achMethodName); i++){ szStr[i] = lpIsvUsrDic->achMethodName[i]; } szStr[i] = '\0'; #endif hKL = MatchImeName( szStr); if( !hKL) return (hKL); for( i = 0; i < sizeof(wInternalCode) / sizeof(WORD); i++) { LRESULT lRet; lRet = ImmEscape(hKL, (HIMC)NULL, IME_ESC_SEQUENCE_TO_INTERNAL, &i); if (HIWORD(lRet) == 0xFFFF) { // This is caused by sign extent in Win9x in the return value of // ImmEscape, it causes an invalid internal code. wAltInternalCode[i] = 0; } else { wAltInternalCode[i] = HIWORD(lRet); } #ifndef UNICODE if( wAltInternalCode[i] > 0xFF) { wAltInternalCode[i] = LOBYTE(wAltInternalCode[i]) << 8 | HIBYTE(wAltInternalCode[i]); } if( wInternalCode[i] > 0xFF) { wInternalCode[i] = LOBYTE(wInternalCode[i]) << 8 | HIBYTE(wInternalCode[i]); } #endif } lpCurr = (LPBYTE)(lpIsvUsrDic + 1) + sizeof(WORD); lpEnd = (LPBYTE)lpIsvUsrDic + dwFileSize; for (; lpCurr < lpEnd; lpCurr += sizeof(WORD) + lpIsvUsrDic->cMethodKeySize + sizeof(WORD)) { int j; *(LPDWORD)szStr = 0; #ifdef UNICODE if (uCodePage == UNICODE_CP) { szStr[0] = *(LPUNATSTR)lpCurr; } else { CHAR szMultiByte[4]; szMultiByte[0] = HIBYTE(*(LPUNASTR)lpCurr); szMultiByte[1] = LOBYTE(*(LPUNASTR)lpCurr); MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, szMultiByte, 2, szStr, 2); } #else szStr[1] = *lpCurr; szStr[0] = *(lpCurr + 1); #endif for (i = 0, j = 0; i < lpIsvUsrDic->cMethodKeySize; i++) { if (!wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)]) { } else if (wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)] < 0xFF) { *(LPTSTR)&szStr[4 + j] = (TCHAR) wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)]; j += sizeof(TCHAR) / sizeof(TCHAR); } else { *(LPWSTR)&szStr[4 + j] = (WCHAR) wAltInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)]; j += sizeof(WCHAR) / sizeof(TCHAR); } if (wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)] < 0xFF) { *(LPTSTR)&szStr[4 + j] = (TCHAR) wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)]; j += sizeof(TCHAR) / sizeof(TCHAR); } else { *(LPWSTR)&szStr[4 + j] = (WCHAR) wInternalCode[*(LPBYTE)(lpCurr + sizeof(WORD) + i)]; j += sizeof(WCHAR) / sizeof(TCHAR); } } szStr[4 + j] = szStr[4 + j + 1] = szStr[4 + j + 2] = '\0'; fRet = ImmRegisterWord(hKL, &szStr[4], IME_REGWORD_STYLE_EUDC, szStr); } return (hKL); } /****************************************/ /* */ /* Get keyboard layout handle */ /* */ /****************************************/ HKL CBLinkDlg::MatchImeName( LPCTSTR szStr) { TCHAR szImeName[16]; int nLayout; HKL hKL; HGLOBAL hMem; HKL FAR *lpMem; int i; nLayout = GetKeyboardLayoutList( 0, NULL); hMem = GlobalAlloc( GHND, sizeof(HKL) * nLayout); if( !hMem) return NULL; lpMem = (HKL FAR *)GlobalLock( hMem); if( !lpMem){ GlobalFree( hMem); return NULL; } GetKeyboardLayoutList( nLayout, lpMem); for( i = 0; i < nLayout; i++){ BOOL fRet; hKL = *(lpMem + i); for( j = 0; j < uLen; j++){ szImeName[j] = '\0'; } fRet = ImmEscape(hKL, (HIMC)NULL, IME_ESC_IME_NAME, szImeName); if( !fRet) continue; if(lstrcmp(szStr, szImeName) == 0){ goto MatchOvr; } } hKL = NULL; MatchOvr: GlobalUnlock( hMem); GlobalFree( hMem); return( hKL); } /****************************************/ /* */ /* CodePage Info */ /* */ /****************************************/ int CBLinkDlg::CodePageInfo( UINT uCodePage) { int i; for (i = 0; i < sizeof(sCountry) / sizeof(COUNTRYSETTING); i++) { if (sCountry[i].uCodePage == uCodePage) { return(i); } } return (-1); } #endif // move to imeblink.c! static DWORD aIds[] = { IDC_STATICIMETBL, IDH_EUDC_BLINK_EDITTBL, IDC_IMETABLE, IDH_EUDC_BLINK_EDITTBL, IDC_BROWSETABLE, IDH_EUDC_BROWSE, 0, 0 }; /****************************************/ /* */ /* Window Procedure */ /* */ /****************************************/ LRESULT CBLinkDlg::WindowProc( UINT message, WPARAM wParam, LPARAM lParam) {/* if( message == WM_HELP){ ::WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, HelpPath, HELP_WM_HELP, (DWORD_PTR)(LPDWORD)aIds); return(0); } if( message == WM_CONTEXTMENU){ ::WinHelp((HWND)wParam, HelpPath, HELP_CONTEXTMENU, (DWORD_PTR)(LPDWORD)aIds); return(0); } */ return CDialog::WindowProc(message, wParam, lParam); } BEGIN_MESSAGE_MAP(CBLinkDlg, CDialog) //{{AFX_MSG_MAP(CBLinkDlg) ON_BN_CLICKED(IDC_BROWSETABLE, OnBrowsetable) //}}AFX_MSG_MAP END_MESSAGE_MAP()