You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2224 lines
62 KiB
2224 lines
62 KiB
|
|
/*************************************************
|
|
* uimetool.c *
|
|
* *
|
|
* Copyright (C) 1995-1999 Microsoft Inc. *
|
|
* *
|
|
*************************************************/
|
|
|
|
//
|
|
// Change log:
|
|
// define UNIIME identifier
|
|
// @D03 Fix Bug Use wrong miniime.tpl file name
|
|
// @D04 Fix Bug Does show error message when invalid table file
|
|
// @D05 Modified Add UNALIGNED to meet MIPS system
|
|
//
|
|
// 1/17/96
|
|
// @E01 Change for multi-threading
|
|
// @E02 Untest DBCS for NT version
|
|
// @E03 Change for multi-threading without extending function
|
|
|
|
#include <windows.h> // required for all Windows applications
|
|
#include <windowsx.h>
|
|
#include <tchar.h>
|
|
|
|
#define STRSAFE_NO_DEPRECATE
|
|
#include "strsafe.h"
|
|
|
|
#include "rc.h" // prototypes specific to this application
|
|
#include "uimetool.h"
|
|
#include "imeattr.h"
|
|
#include "imerc.h"
|
|
|
|
#ifdef UNICODE
|
|
typedef DWORD UNALIGNED FAR *LPUNADWORD;
|
|
typedef WORD UNALIGNED FAR *LPUNAWORD;
|
|
typedef TCHAR UNALIGNED FAR *LPUNATCHAR;
|
|
#else
|
|
typedef DWORD FAR *LPUNADWORD;
|
|
typedef WORD FAR *LPUNAWORD;
|
|
typedef TCHAR FAR *LPUNATCHAR;
|
|
#define TCHAR BYTE
|
|
#endif
|
|
|
|
HWND hwndMain;
|
|
TCHAR szIme_Name[IME_NAME_LEN_TOOL];
|
|
TCHAR szTab_Name[MAX_PATH];
|
|
TCHAR szKey_Num_Str[KEY_NUM_STR_LEN];
|
|
TCHAR szFile_Out_Name[TAB_NAME_LEN];
|
|
TCHAR Show_Mess[MAX_PATH];
|
|
TCHAR Msg_buf[MAX_PATH];
|
|
BOOL bCandBeep;
|
|
BOOL bOverMaxRadical; //@D02A
|
|
HCURSOR hCursorWait;
|
|
HCURSOR hCursorArrow;
|
|
|
|
VALIDCHAR Valid;
|
|
TABLEFILES Table;
|
|
UINT uGenericID[]={ IDS_FILEDESCRIPTION_STR,
|
|
IDS_VER_INTERNALNAME_STR,
|
|
IDS_PRODUCTNAME_STR,
|
|
IDS_IMENAME };
|
|
|
|
#ifdef UNICODE
|
|
int cntChar = 2;
|
|
#else
|
|
int cntChar = 1;
|
|
#endif
|
|
|
|
UINT idxLine;
|
|
|
|
extern HINSTANCE hInst;
|
|
|
|
UINT SearchMem(BYTE *, UINT, BYTE *, UINT);
|
|
BOOL Process_Bitmap(HWND, BYTE *, UINT);
|
|
BOOL Process_Icon(HWND, BYTE *, UINT);
|
|
BOOL Process_RT(HFILE, BYTE *, UINT, TCHAR *);
|
|
BOOL WritetoFile(TCHAR *);
|
|
WORD GetPhrase(UINT, TCHAR *);
|
|
BOOL Parse(TCHAR *, UINT);
|
|
BOOL PutRadical(TCHAR, WORD);
|
|
BOOL PutPhrase(TCHAR *, TCHAR *, UINT);
|
|
BOOL AllocRadical();
|
|
BOOL AllocPhrase();
|
|
void ErrMsg(UINT, UINT);
|
|
void ErrIOMsg(UINT, TCHAR *);
|
|
|
|
void MyFillMemory(TCHAR *dst, DWORD cnt, TCHAR v);
|
|
|
|
void GetOpenFile(
|
|
HWND hDlg)
|
|
{
|
|
OPENFILENAME ofn;
|
|
TCHAR *pszFilterSpec;
|
|
TCHAR szFilterSpec[128];
|
|
TCHAR szFileOpen[25];
|
|
TCHAR szExt[10];
|
|
TCHAR szCustFilter[10];
|
|
TCHAR szFileName[MAX_PATH];
|
|
TCHAR szFilePath[MAX_PATH];
|
|
TCHAR szStr[MAX_PATH];
|
|
|
|
szFileName[0]=0;
|
|
LoadString (hInst, IDS_FILTERSPEC, szFilterSpec, sizeof(szFilterSpec) / sizeof(TCHAR));
|
|
LoadString (hInst, IDS_DEFAULTFILEEXT, szExt, sizeof(szExt) / sizeof(TCHAR));
|
|
pszFilterSpec = szFilterSpec;
|
|
pszFilterSpec += lstrlen(pszFilterSpec) + 1;
|
|
StringCchCopy(pszFilterSpec,
|
|
ARRAYSIZE(szFilterSpec)-(pszFilterSpec-szFilterSpec), szExt);
|
|
LoadString (hInst, IDS_FILTERSPEC_ALL, szStr, sizeof(szStr) / sizeof(TCHAR));
|
|
pszFilterSpec += lstrlen(pszFilterSpec) + 1;
|
|
if (ARRAYSIZE(szFilterSpec) > (pszFilterSpec-szFilterSpec))
|
|
{
|
|
StringCchCopy(
|
|
pszFilterSpec,
|
|
ARRAYSIZE(szFilterSpec)-(pszFilterSpec-szFilterSpec),
|
|
szStr);
|
|
|
|
LoadString (hInst, IDS_ALLFILEEXT, szStr, sizeof(szStr) / sizeof(TCHAR));
|
|
pszFilterSpec += lstrlen(pszFilterSpec) + 1;
|
|
}
|
|
|
|
if (ARRAYSIZE(szFilterSpec) > (pszFilterSpec-szFilterSpec))
|
|
{
|
|
StringCchCopy(
|
|
pszFilterSpec,
|
|
ARRAYSIZE(szFilterSpec)-(pszFilterSpec-szFilterSpec),
|
|
szStr);
|
|
pszFilterSpec += lstrlen(pszFilterSpec) + 1;
|
|
}
|
|
|
|
if (ARRAYSIZE(szFilterSpec) > (pszFilterSpec-szFilterSpec))
|
|
{
|
|
*pszFilterSpec = 0;
|
|
}
|
|
|
|
LoadString (hInst, IDS_OPENTITLE, szFileOpen, sizeof(szFileOpen) / sizeof(TCHAR));
|
|
szCustFilter[0] = 0;
|
|
lstrcpy(&szCustFilter[1], szExt);
|
|
lstrcpy(szFilePath, szExt);
|
|
|
|
/* fill in non-variant fields of OPENFILENAME struct. */
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = hDlg;
|
|
ofn.lpstrFilter = szFilterSpec;
|
|
ofn.lpstrCustomFilter = szCustFilter;
|
|
ofn.nMaxCustFilter = sizeof(szCustFilter) / sizeof(TCHAR);
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = szFilePath;
|
|
ofn.nMaxFile = MAX_PATH;
|
|
ofn.lpstrInitialDir = NULL;
|
|
ofn.lpstrFileTitle = szFileName;
|
|
ofn.nMaxFileTitle = MAX_PATH;
|
|
ofn.lpstrTitle = szFileOpen;
|
|
ofn.lpstrDefExt = szExt + 3;
|
|
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY |
|
|
OFN_PATHMUSTEXIST;
|
|
|
|
/* call common open dialog and return result */
|
|
if(GetOpenFileName ((LPOPENFILENAME)&ofn))
|
|
SetDlgItemText(hDlg, IDD_TABLE_NAME, szFilePath);
|
|
}
|
|
|
|
// <== @E01
|
|
//unsigned _stdcall MakeNewImeThread(LPVOID voidparam)
|
|
void MakeNewImeThread(LPVOID voidparam) // <== @E03
|
|
{
|
|
BOOL bOk;
|
|
extern HWND hProgMain;
|
|
extern BOOL bFinish;
|
|
|
|
bOk = MakeNewIme(NULL);
|
|
if (hProgMain)
|
|
PostMessage(hProgMain, WM_CLOSE, 0, 0);
|
|
|
|
if (!bOk)
|
|
bFinish = 0;
|
|
else
|
|
bFinish = 1;
|
|
|
|
//return bOk;
|
|
}
|
|
|
|
// <== @E01
|
|
void HideProgress(void)
|
|
{
|
|
extern HWND hProgMain;
|
|
if (hProgMain)
|
|
ShowWindow(hProgMain, SW_HIDE);
|
|
}
|
|
|
|
// <== @E01
|
|
void ShowProgress(void)
|
|
{
|
|
extern HWND hProgMain;
|
|
if (hProgMain)
|
|
ShowWindow(hProgMain, SW_SHOWNORMAL);
|
|
}
|
|
|
|
#define IDM_NEWSHELL 249
|
|
|
|
void HandleTaskBar_IME( )
|
|
{
|
|
|
|
HWND hwndIndicate;
|
|
TCHAR szIndicator[] = TEXT("Indicator");
|
|
|
|
// Handle the task bar indicator option.
|
|
|
|
hwndIndicate = FindWindow(szIndicator, NULL);
|
|
|
|
//
|
|
// See if the indicator is already enabled.
|
|
//
|
|
if (hwndIndicate && IsWindow(hwndIndicate))
|
|
{
|
|
SendMessage(hwndIndicate, WM_COMMAND, IDM_NEWSHELL, 0L);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
BOOL MakeNewIme(HWND hWnd)
|
|
{
|
|
HFILE hfFile,hfMainFile;
|
|
BYTE *szImeBuf;
|
|
TCHAR szBig5[MAX_PATH],szUniCode[MAX_PATH],szGeneric[MAX_PATH];
|
|
TCHAR szClass[MAX_PATH];
|
|
TCHAR szPure_Name[100];
|
|
TCHAR Ime_File_Name[MAX_PATH];
|
|
TCHAR Src_File_Name[MAX_PATH];
|
|
TCHAR szSystem[MAX_PATH];
|
|
UINT uLen,flen,len,unilen,classlen,genericlen;
|
|
UINT uAddr;
|
|
int i;
|
|
|
|
|
|
// Get Windows System directory
|
|
uLen = GetSystemDirectory((LPTSTR)szSystem, ARRAYSIZE(szSystem));
|
|
if (szSystem[uLen - 1] != _TEXT('\\')) // consider C:\ ;
|
|
{
|
|
szSystem[uLen ++] = _TEXT('\\');
|
|
szSystem[uLen] = 0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Check input data
|
|
//---------------------------------------------------------------------------
|
|
//let Pure_Name be without .ime name, this is prevent user to input .ime
|
|
for(i = 0; i < (int)lstrlen(szFile_Out_Name); i++)
|
|
{
|
|
if(szFile_Out_Name[i] == _TEXT('.'))
|
|
break;
|
|
|
|
szPure_Name[i] = szFile_Out_Name[i];
|
|
}
|
|
|
|
szPure_Name[i] = 0; //end of string
|
|
if(szPure_Name[0] == 0)
|
|
{
|
|
ErrMsg(IDS_ERR_INPUTIME, 0);
|
|
return FALSE; //do nothing because didnt set ok
|
|
}
|
|
|
|
//limit it length <= 8
|
|
if(lstrlen(szPure_Name) > 8) szPure_Name[8] = 0;
|
|
|
|
//Check if is reserved name miniime
|
|
if(!lstrcmp(SOURCE_IME_NAME, szPure_Name))
|
|
{
|
|
//is with reserved file name for .ime
|
|
ErrMsg(IDS_ERR_USE_RESERVE, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
//Check input IME Name
|
|
len = lstrlen(szIme_Name);
|
|
|
|
#ifdef UNICODE
|
|
if(len < 2)
|
|
szIme_Name[1] = 0x3000;
|
|
|
|
szIme_Name[2]=0;
|
|
|
|
{
|
|
char fname[MAX_PATH * 2];
|
|
int lenx = lstrlen(szTab_Name);
|
|
WideCharToMultiByte(950, WC_COMPOSITECHECK, szTab_Name, lenx,
|
|
(LPSTR)fname, lenx, NULL, NULL);
|
|
fname[lenx] = 0;
|
|
hfMainFile=_lopen(fname, OF_READ);
|
|
}
|
|
#else
|
|
if(len < 4)
|
|
{
|
|
szIme_Name[2] = (BYTE) 0xa1;
|
|
szIme_Name[3] = (BYTE) 0x40;
|
|
}
|
|
|
|
szIme_Name[4]=0;
|
|
|
|
hfMainFile=_lopen(szTab_Name, OF_READ);
|
|
#endif
|
|
|
|
if(hfMainFile==-1)
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEOPEN, szTab_Name);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Read Base IME file - miniime.tpl
|
|
//---------------------------------------------------------------------------
|
|
StringCchCopy(Src_File_Name, ARRAYSIZE(Src_File_Name), szSystem); //System directory
|
|
StringCchCat(Src_File_Name, ARRAYSIZE(Src_File_Name), LIBRARY_NAME);
|
|
|
|
#ifdef UNICODE
|
|
{
|
|
char fname[MAX_PATH * 2];
|
|
int ilen = lstrlen(Src_File_Name); // <== @D03
|
|
WideCharToMultiByte(950, WC_COMPOSITECHECK, Src_File_Name, ilen,
|
|
(LPSTR)fname, sizeof(fname), NULL, NULL);
|
|
fname[ilen] = 0;
|
|
hfFile=_lopen(fname,OF_READ);
|
|
}
|
|
#else
|
|
hfFile=_lopen(Src_File_Name, OF_READ);
|
|
#endif
|
|
|
|
if(hfFile==-1)
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEOPEN, Src_File_Name);
|
|
_lclose(hfMainFile);
|
|
return TRUE; // Can not continue
|
|
}
|
|
|
|
flen=_llseek(hfFile, 0L, 2); // get file length
|
|
|
|
// Allocate Memory
|
|
szImeBuf = (BYTE *)GlobalAlloc(GMEM_FIXED, flen);
|
|
if(!szImeBuf)
|
|
{
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
_lclose(hfMainFile);
|
|
return TRUE; // Can not continue
|
|
}
|
|
|
|
_llseek(hfFile, 0L, 0); //set to beginning
|
|
|
|
if(flen != _lread(hfFile,szImeBuf,flen))
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEREAD, Src_File_Name);
|
|
_lclose(hfMainFile);
|
|
GlobalFree((HGLOBAL)szImeBuf);
|
|
return TRUE; // Can not continue
|
|
}
|
|
|
|
_lclose(hfFile);
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Search string and Patch them
|
|
//---------------------------------------------------------------------------
|
|
|
|
// Translate input IME name to Unicod to instead of generic string
|
|
LoadString(hInst, IDS_IMENAME, szBig5, sizeof(szBig5) / sizeof(TCHAR));
|
|
len = lstrlen(szBig5);
|
|
|
|
#ifdef UNICODE
|
|
lstrcpy(szUniCode, szBig5);
|
|
unilen = len;
|
|
#else
|
|
unilen=MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
|
|
(LPWSTR)szUniCode, len);
|
|
#endif
|
|
|
|
lstrcpy(szBig5, szIme_Name);
|
|
len=lstrlen(szBig5);
|
|
|
|
#ifdef UNICODE
|
|
lstrcpy(szGeneric, szBig5);
|
|
genericlen = lstrlen(szBig5);
|
|
#else
|
|
for(i = len; i < (int)(len+unilen-2); i++)
|
|
szBig5[i] = ' ';
|
|
|
|
szBig5[i] = 0;
|
|
len = lstrlen(szBig5);
|
|
genericlen = MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
|
|
(LPWSTR)szGeneric, len);
|
|
genericlen *= 2;
|
|
#endif
|
|
|
|
// Process Generic string
|
|
#ifdef UNICODE
|
|
|
|
for(i=0; i<(sizeof(uGenericID)/sizeof(UINT)); i++)
|
|
{
|
|
LoadString(hInst, uGenericID[i], szBig5, sizeof(szBig5) / sizeof(TCHAR));
|
|
len=lstrlen(szBig5);
|
|
uAddr=SearchMem((LPSTR)szBig5, len * 2, szImeBuf, flen);
|
|
if(uAddr == 0) {
|
|
continue;
|
|
} else
|
|
if ( i == 0 ) {
|
|
// this is for IDS_FILEDESCRIPTION_STR,
|
|
// We just replace the first two Chinese Characters
|
|
// and keep the rest.
|
|
|
|
CopyMemory(&szImeBuf[uAddr], szGeneric,genericlen*2 );
|
|
}
|
|
else
|
|
CopyMemory(&szImeBuf[uAddr], szGeneric, (genericlen + 1) * 2);
|
|
}
|
|
|
|
#else
|
|
|
|
for(i=0; i<(sizeof(uGenericID)/sizeof(UINT)); i++)
|
|
{
|
|
LoadString(hInst, uGenericID[i], szBig5, sizeof(szBig5) / sizeof(TCHAR));
|
|
len=lstrlen(szBig5);
|
|
unilen=MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
|
|
(LPWSTR)szUniCode, len);
|
|
uAddr=SearchMem(szUniCode, unilen*2, szImeBuf, flen);
|
|
if(uAddr == 0) {
|
|
// ErrMsg(IDS_ERR_BASEIME, 0);
|
|
// _lclose(hfMainFile);
|
|
// GlobalFree((HGLOBAL)szImeBuf);
|
|
// return TRUE;
|
|
continue;
|
|
}
|
|
CopyMemory(&szImeBuf[uAddr], szGeneric, genericlen);
|
|
}
|
|
#endif
|
|
// Process LIBERAY NAME
|
|
{
|
|
TCHAR szLibName[MAX_PATH];
|
|
int liblen;
|
|
|
|
LoadString(hInst, IDS_LIBERARY_NAME, szLibName, sizeof(szLibName) / sizeof(TCHAR));
|
|
liblen = lstrlen(szLibName);
|
|
|
|
#ifdef UNICODE
|
|
{
|
|
char name[MAX_PATH * 2];
|
|
WideCharToMultiByte(950, WC_COMPOSITECHECK, szLibName, liblen,
|
|
(LPSTR)name, liblen, NULL, NULL);
|
|
uAddr=SearchMem((LPSTR)name, liblen, szImeBuf, flen);
|
|
}
|
|
#else
|
|
uAddr=SearchMem((LPSTR)szLibName, liblen, szImeBuf, flen);
|
|
#endif
|
|
|
|
if(uAddr == 0)
|
|
{
|
|
ErrMsg(IDS_ERR_BASEIME, 0);
|
|
_lclose(hfMainFile);
|
|
GlobalFree((HGLOBAL)szImeBuf);
|
|
return TRUE;
|
|
}
|
|
|
|
lstrcpy(szLibName, szPure_Name);
|
|
len=lstrlen(szPure_Name);
|
|
szLibName[liblen-4] = 0;
|
|
for(i=len; i<liblen-4; i++)
|
|
szLibName[i] = _TEXT('$');
|
|
lstrcat(szLibName, _TEXT(".IME"));
|
|
|
|
#ifdef UNICODE
|
|
{
|
|
char name[MAX_PATH * 2];
|
|
WideCharToMultiByte(950, WC_COMPOSITECHECK, szLibName, liblen,
|
|
(LPSTR)name, liblen, NULL, NULL);
|
|
CopyMemory(&szImeBuf[uAddr], name, liblen * sizeof(TCHAR));
|
|
}
|
|
#else
|
|
CopyMemory(&szImeBuf[uAddr], szLibName, liblen * sizeof(TCHAR));
|
|
#endif
|
|
}
|
|
|
|
// Process DEFINETION NAME
|
|
|
|
// Process IMEUICLASS String
|
|
LoadString(hInst, IDS_IMEUICLASS, szBig5, sizeof(szBig5) / sizeof(TCHAR));
|
|
len=lstrlen(szBig5);
|
|
#ifdef UNICODE
|
|
uAddr=SearchMem((LPSTR)szBig5, len*2, szImeBuf, flen);
|
|
#else
|
|
classlen=MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
|
|
(LPWSTR)szClass, len);
|
|
uAddr=SearchMem((LPSTR)szClass, classlen*2, szImeBuf, flen);
|
|
#endif
|
|
if(uAddr == 0)
|
|
{
|
|
ErrMsg(IDS_ERR_BASEIME, 0);
|
|
_lclose(hfMainFile);
|
|
GlobalFree((HGLOBAL)szImeBuf);
|
|
return TRUE;
|
|
}
|
|
|
|
lstrcpy(szBig5, szPure_Name);
|
|
len=lstrlen(szBig5);
|
|
for(i = len; i < 8; i++) szBig5[i] = _TEXT(' ');
|
|
szBig5[8] = 0;
|
|
len = 8;
|
|
|
|
#ifdef UNICODE
|
|
lstrcpy(szUniCode, szBig5);
|
|
unilen = len;
|
|
#else
|
|
unilen = MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
|
|
(LPWSTR)szUniCode, len);
|
|
#endif
|
|
|
|
while(TRUE)
|
|
{
|
|
LoadString(hInst, IDS_IMEUICLASS, szBig5, sizeof(szBig5) / sizeof(TCHAR));
|
|
len=lstrlen(szBig5);
|
|
#ifdef UNICODE
|
|
lstrcpy(szClass, szBig5);
|
|
classlen = len;
|
|
#else
|
|
classlen=MultiByteToWideChar(950, MB_PRECOMPOSED, szBig5, len,
|
|
(LPWSTR)szClass, len);
|
|
#endif
|
|
uAddr=SearchMem((BYTE *)szClass, classlen * 2, szImeBuf, flen);
|
|
if(uAddr == 0)
|
|
break;
|
|
CopyMemory(&szImeBuf[uAddr], szUniCode, unilen * 2);
|
|
}
|
|
|
|
// Process Bitmap file
|
|
if(!Process_Bitmap(hWnd, szImeBuf, flen))
|
|
{
|
|
_lclose(hfMainFile);
|
|
GlobalFree((HGLOBAL)szImeBuf);
|
|
return TRUE;
|
|
}
|
|
|
|
// Process Icon file
|
|
if(!Process_Icon(hWnd, szImeBuf, flen))
|
|
{
|
|
_lclose(hfMainFile);
|
|
GlobalFree((HGLOBAL)szImeBuf);
|
|
return TRUE;
|
|
}
|
|
|
|
// Process RT_RCDATA
|
|
bOverMaxRadical=FALSE;
|
|
if(!Process_RT(hfMainFile, szImeBuf, flen, szPure_Name))
|
|
{
|
|
_lclose(hfMainFile);
|
|
// Bug #53630
|
|
// _lclose(hfFile);
|
|
GlobalFree((HGLOBAL)szImeBuf);
|
|
|
|
// ErrIOMsg(IDS_ERR_FILEREAD, szTab_Name); // <== @D04
|
|
|
|
if(bOverMaxRadical)
|
|
return FALSE;
|
|
else
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
_lclose(hfMainFile);
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Save to input IME file
|
|
//---------------------------------------------------------------------------
|
|
StringCchCopy(Ime_File_Name, ARRAYSIZE(Ime_File_Name), szSystem);
|
|
StringCchCat(Ime_File_Name, ARRAYSIZE(Ime_File_Name), szPure_Name);
|
|
StringCchCat(Ime_File_Name, ARRAYSIZE(Ime_File_Name), _TEXT(".IME"));
|
|
|
|
#ifdef UNICODE
|
|
{
|
|
char fname[MAX_PATH * 2];
|
|
int ulen = lstrlen(Ime_File_Name);
|
|
WideCharToMultiByte(950, WC_COMPOSITECHECK, Ime_File_Name, ulen,
|
|
(LPSTR)fname, ulen, NULL, NULL);
|
|
fname[ulen] = 0;
|
|
hfFile=_lcreat(fname,0);
|
|
}
|
|
#else
|
|
hfFile=_lcreat(Ime_File_Name,0);
|
|
#endif
|
|
|
|
if(hfFile==-1)
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEOPEN, Ime_File_Name);
|
|
return TRUE;
|
|
}
|
|
|
|
if(flen != _lwrite(hfFile, szImeBuf, flen))
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEREAD, Ime_File_Name);
|
|
_lclose(hfFile);
|
|
return TRUE;
|
|
}
|
|
_lclose(hfFile);
|
|
GlobalFree((HGLOBAL)szImeBuf);
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Install IME and register it
|
|
//---------------------------------------------------------------------------
|
|
if(!ImmInstallIME(Ime_File_Name,szIme_Name))
|
|
{
|
|
HideProgress(); // <== @E01
|
|
|
|
LoadString(hInst, IDS_ERR_IME_ACCESS, Msg_buf, sizeof(Msg_buf) / sizeof(TCHAR));
|
|
wsprintf(Show_Mess, Msg_buf, Ime_File_Name);
|
|
LoadString(hInst, IDS_ERR_ERROR, Msg_buf, sizeof(Msg_buf) / sizeof(TCHAR));
|
|
MessageBox(NULL, Show_Mess, Msg_buf, MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
|
|
return TRUE;
|
|
}
|
|
|
|
HandleTaskBar_IME( );
|
|
|
|
// show message for had produced files
|
|
//let Show_Mess be message to be shown
|
|
HideProgress(); // <== @E01
|
|
|
|
LoadString(hInst, IDS_MSG_PROCESS_OK, Msg_buf, sizeof(Msg_buf) / sizeof(TCHAR));
|
|
wsprintf(Show_Mess, Msg_buf, szPure_Name);
|
|
LoadString(hInst, IDS_MSG_INFOMATION, Msg_buf, sizeof(Msg_buf) / sizeof(TCHAR));
|
|
MessageBox(NULL, Show_Mess, Msg_buf,MB_OK|MB_ICONINFORMATION | MB_SETFOREGROUND);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
BOOL Process_Bitmap(
|
|
HWND hWnd,
|
|
BYTE *szImeBuf,
|
|
UINT flen)
|
|
{
|
|
BITMAPINFO *bmif;
|
|
HRSRC hResource,hMem;
|
|
HBITMAP hBitmap, hOldBitmap;
|
|
BYTE *lpBitmap;
|
|
UINT reslen,uAddr,nColor,nHead;
|
|
HDC hDC,hMemDC;
|
|
HFONT hOldFont;
|
|
LOGFONT lfFont;
|
|
TCHAR szFont[MAX_PATH];
|
|
RECT rect;
|
|
UINT i,nBitmap;
|
|
|
|
|
|
// Get bitmap from resource, use to find base ime bitmap address
|
|
hResource=FindResource(hInst, MAKEINTRESOURCE(IDBM_CMODE_NATIVE), RT_BITMAP);
|
|
if (hResource == NULL )
|
|
return FALSE;
|
|
|
|
hMem=LoadResource(hInst, hResource);
|
|
|
|
if ( hMem == NULL )
|
|
return FALSE;
|
|
|
|
lpBitmap=LockResource(hMem);
|
|
|
|
if ( lpBitmap == NULL )
|
|
{
|
|
FreeResource(hMem);
|
|
return FALSE;
|
|
}
|
|
|
|
reslen=SizeofResource(hInst,hResource);
|
|
|
|
uAddr=SearchMem(lpBitmap, reslen, szImeBuf, flen);
|
|
|
|
if(uAddr == 0) {
|
|
UnlockResource(hMem);
|
|
FreeResource(hMem);
|
|
ErrMsg(IDS_ERR_BASEIME, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
bmif=(BITMAPINFO *)lpBitmap;
|
|
|
|
for(nColor=1, i=0; i<bmif->bmiHeader.biBitCount; i++)
|
|
nColor*=2;
|
|
|
|
nHead=sizeof(BITMAPINFOHEADER)+nColor*sizeof(RGBQUAD);
|
|
bmif=(BITMAPINFO *)GlobalAlloc(LMEM_FIXED, nHead);
|
|
if(!bmif) {
|
|
UnlockResource(hMem);
|
|
FreeResource(hMem);
|
|
ErrMsg(IDS_ERR_BASEIME, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
CopyMemory(bmif, lpBitmap, nHead);
|
|
|
|
UnlockResource(hMem);
|
|
FreeResource(hMem);
|
|
|
|
// Create a Memory DC, and load bitmap to it
|
|
hDC = GetDC(hWnd);
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
hBitmap = LoadBitmap(hInst, MAKEINTRESOURCE(IDBM_CMODE_NATIVE));
|
|
ReleaseDC(hWnd, hDC);
|
|
hOldBitmap = SelectObject(hMemDC, hBitmap);
|
|
|
|
|
|
// Select 16 point size font
|
|
hOldFont = GetCurrentObject(hMemDC, OBJ_FONT);
|
|
GetObject(hOldFont, sizeof(lfFont), &lfFont);
|
|
lfFont.lfWeight=400;
|
|
lfFont.lfHeight=-16;
|
|
lfFont.lfWidth = 8;
|
|
lfFont.lfOutPrecision= OUT_TT_ONLY_PRECIS;
|
|
lfFont.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
|
|
LoadString(hInst, IDS_FONT_NAME, szFont, sizeof(szFont) / sizeof(TCHAR));
|
|
lstrcpy(lfFont.lfFaceName, szFont);
|
|
SelectObject(hMemDC, CreateFontIndirect(&lfFont));
|
|
|
|
// Set color
|
|
SetTextColor(hMemDC, RGB(0x80, 0x00, 0x00)); // Dark red
|
|
SetBkColor(hMemDC, RGB(0xC0, 0xC0, 0xC0)); // Light gray
|
|
|
|
// Set rectangle, and write IME name 1st DBCS to Memory DC
|
|
rect.left=3;
|
|
rect.top=3;
|
|
rect.right=rect.left-lfFont.lfHeight;
|
|
rect.bottom=rect.top-lfFont.lfHeight;
|
|
ExtTextOut(hMemDC, rect.left, rect.top, ETO_OPAQUE,
|
|
&rect, szIme_Name, (cntChar == 2) ? 1 : 2, NULL);
|
|
|
|
// Allocate bitmap buffer
|
|
nBitmap=(UINT)bmif->bmiHeader.biSizeImage;
|
|
lpBitmap=(BYTE *)GlobalAlloc(LMEM_FIXED, nBitmap);
|
|
if(!lpBitmap) {
|
|
GlobalFree((HGLOBAL)bmif);
|
|
DeleteObject(SelectObject(hMemDC, hOldFont));
|
|
DeleteObject(SelectObject(hMemDC, hOldBitmap));
|
|
DeleteDC(hMemDC);
|
|
ErrMsg(IDS_ERR_BASEIME, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
// Get Device Independent bitmap from Memory DC
|
|
GetDIBits(hMemDC, hBitmap, 0, bmif->bmiHeader.biHeight,
|
|
lpBitmap, bmif, DIB_RGB_COLORS);
|
|
|
|
CopyMemory(&szImeBuf[uAddr], bmif, nHead);
|
|
CopyMemory(&szImeBuf[uAddr+nHead], lpBitmap, nBitmap);
|
|
|
|
DeleteObject(SelectObject(hMemDC, hOldFont));
|
|
DeleteObject(SelectObject(hMemDC, hOldBitmap));
|
|
DeleteDC(hMemDC);
|
|
GlobalFree((HGLOBAL)bmif);
|
|
GlobalFree((HGLOBAL)lpBitmap);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
#define ENBOLD_ICONSIZE 24
|
|
|
|
BOOL UpdateMiniIMEIcon(
|
|
HWND hWnd,
|
|
LPBYTE lpbMiniImeFileImage,
|
|
UINT uLen,
|
|
int nIconID)
|
|
{
|
|
UINT uAddr;
|
|
LPBITMAPINFOHEADER lpbmIconInfoHeader;
|
|
DWORD dwHeaderSize;
|
|
HDC hMemDC;
|
|
HBITMAP hBitmap, hOldBitmap;
|
|
LPVOID lpBitmap, lpBitmap_Section;
|
|
DWORD dwBitmap;
|
|
|
|
{
|
|
HRSRC hResIcon;
|
|
DWORD dwSize;
|
|
LPBITMAPINFOHEADER lpResIcon;
|
|
|
|
hResIcon = LoadResource(hInst, FindResource(hInst,
|
|
MAKEINTRESOURCE(nIconID), RT_ICON));
|
|
|
|
if (!hResIcon) {
|
|
HideProgress(); // <== @E01
|
|
MessageBox(NULL, _TEXT("Load icon fail !"), _TEXT("Bug"), MB_OK | MB_SETFOREGROUND );
|
|
return (FALSE);
|
|
}
|
|
|
|
dwSize = SizeofResource(hInst, hResIcon);
|
|
|
|
uAddr = 0;
|
|
|
|
lpResIcon = LockResource(hResIcon);
|
|
|
|
if (!lpResIcon) {
|
|
goto UpdateIconFreeRes;
|
|
}
|
|
|
|
uAddr = SearchMem((LPBYTE)lpResIcon, dwSize, lpbMiniImeFileImage, uLen);
|
|
|
|
if (uAddr) {
|
|
DWORD nColors;
|
|
|
|
if (lpResIcon->biBitCount != 24) {
|
|
UINT i;
|
|
|
|
for (nColors = 1, i = 0; i < lpResIcon->biBitCount; i++) {
|
|
nColors *= 2;
|
|
}
|
|
} else {
|
|
// no RGBQUAD for 24 bit per pixel format
|
|
nColors = 0;
|
|
}
|
|
|
|
dwHeaderSize = lpResIcon->biSize + nColors * sizeof(RGBQUAD);
|
|
|
|
lpbmIconInfoHeader = (LPBITMAPINFOHEADER)GlobalAlloc(GMEM_FIXED,
|
|
dwHeaderSize);
|
|
|
|
if (lpbmIconInfoHeader) {
|
|
CopyMemory(lpbmIconInfoHeader, lpResIcon, dwHeaderSize);
|
|
lpbmIconInfoHeader->biHeight /= 2;
|
|
dwBitmap = (lpbmIconInfoHeader->biWidth + 7) / 8 *
|
|
lpbmIconInfoHeader->biHeight * lpResIcon->biBitCount;
|
|
} else {
|
|
uAddr = 0;
|
|
}
|
|
|
|
lpBitmap = GlobalAlloc(GMEM_FIXED, dwBitmap);
|
|
|
|
if (!lpBitmap) {
|
|
uAddr = 0;
|
|
}
|
|
}
|
|
|
|
UnlockResource(hResIcon);
|
|
UpdateIconFreeRes:
|
|
FreeResource(hResIcon);
|
|
|
|
if (uAddr == 0) {
|
|
return (FALSE);
|
|
}
|
|
}
|
|
|
|
{
|
|
HDC hDC;
|
|
|
|
// create a memory DC
|
|
hDC = GetDC(hWnd);
|
|
hMemDC = CreateCompatibleDC(hDC);
|
|
ReleaseDC(hWnd, hDC);
|
|
}
|
|
|
|
hBitmap = CreateDIBSection(hMemDC, (LPBITMAPINFO)lpbmIconInfoHeader,
|
|
DIB_RGB_COLORS, &lpBitmap_Section, NULL, 0);
|
|
|
|
hOldBitmap = SelectObject(hMemDC, hBitmap);
|
|
|
|
{
|
|
HFONT hOldFont;
|
|
LOGFONT lfFont;
|
|
RECT rcRect;
|
|
POINT ptOffset;
|
|
|
|
rcRect.left = rcRect.top = 0;
|
|
// biHeight - 1, biHeight is not including
|
|
rcRect.right = rcRect.bottom = lpbmIconInfoHeader->biHeight;
|
|
|
|
hOldFont = GetCurrentObject(hMemDC, OBJ_FONT);
|
|
GetObject(hOldFont, sizeof(lfFont), &lfFont);
|
|
if (lpbmIconInfoHeader->biHeight >= ENBOLD_ICONSIZE) {
|
|
lfFont.lfHeight = ((rcRect.bottom - rcRect.top) - 4 - 2) * (-1);
|
|
ptOffset.x = 4;
|
|
ptOffset.y = 3;
|
|
} else if (lpbmIconInfoHeader->biHeight >= 22) {
|
|
lfFont.lfHeight = ((rcRect.bottom - rcRect.top) - 4) * (-1);
|
|
ptOffset.x = 3;
|
|
ptOffset.y = 3;
|
|
} else if (lpbmIconInfoHeader->biHeight >= 18) {
|
|
lfFont.lfHeight = ((rcRect.bottom - rcRect.top) - 3) * (-1);
|
|
ptOffset.x = 3;
|
|
ptOffset.y = 3;
|
|
} else {
|
|
lfFont.lfHeight = ((rcRect.bottom - rcRect.top) - 4) * (-1);
|
|
ptOffset.x = 3;
|
|
ptOffset.y = 3;
|
|
}
|
|
|
|
lfFont.lfWidth = 0;
|
|
lfFont.lfWeight = 100;
|
|
lfFont.lfOutPrecision = OUT_TT_ONLY_PRECIS;
|
|
lfFont.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
|
|
lfFont.lfFaceName[0] = '\0';
|
|
LoadString(hInst, IDS_FONT_NAME, lfFont.lfFaceName,
|
|
sizeof(lfFont.lfFaceName) / sizeof(TCHAR));
|
|
hOldFont = SelectObject(hMemDC, CreateFontIndirect(&lfFont));
|
|
|
|
SetBkColor(hMemDC, RGB(0xC0, 0xC0, 0xC0)); // light gray
|
|
|
|
// write 1st DBCS to memory DC for shadow
|
|
SetTextColor(hMemDC, RGB(0xFF, 0xFF, 0xFF)); // white
|
|
ExtTextOut(hMemDC, rcRect.left + ptOffset.x, rcRect.top + ptOffset.y,
|
|
ETO_OPAQUE, &rcRect, szIme_Name, (cntChar == 2) ? 1 : 2, NULL);
|
|
|
|
// write 1st DBCS to memory DC
|
|
SetTextColor(hMemDC, RGB(0x00, 0x00, 0xFF)); // blue
|
|
SetBkMode(hMemDC, TRANSPARENT);
|
|
ptOffset.x -= 1;
|
|
ptOffset.y -= 1;
|
|
ExtTextOut(hMemDC, rcRect.left + ptOffset.x, rcRect.top + ptOffset.y,
|
|
ETO_CLIPPED, &rcRect, szIme_Name, (cntChar == 2) ? 1 : 2, NULL);
|
|
|
|
// write 1st DBCS to memory DC to enbold it
|
|
if (lpbmIconInfoHeader->biHeight > ENBOLD_ICONSIZE) {
|
|
ptOffset.x -= 1;
|
|
ExtTextOut(hMemDC,
|
|
rcRect.left + ptOffset.x, rcRect.top + ptOffset.y,
|
|
ETO_CLIPPED, &rcRect, szIme_Name, (cntChar == 2) ? 1 : 2, NULL);
|
|
}
|
|
|
|
SelectObject(hMemDC, GetStockObject(NULL_BRUSH));
|
|
SelectObject(hMemDC, GetStockObject(BLACK_PEN));
|
|
|
|
Rectangle(hMemDC, rcRect.left, rcRect.top,
|
|
rcRect.right, rcRect.bottom);
|
|
|
|
rcRect.right = rcRect.bottom = lpbmIconInfoHeader->biHeight - 1;
|
|
MoveToEx(hMemDC, rcRect.left, rcRect.top + 1, NULL);
|
|
LineTo(hMemDC, rcRect.left + 2, rcRect.top + 1);
|
|
|
|
MoveToEx(hMemDC, rcRect.right, rcRect.top + 1, NULL);
|
|
LineTo(hMemDC, rcRect.right - 2, rcRect.top + 1);
|
|
|
|
MoveToEx(hMemDC, rcRect.left, rcRect.bottom - 1, NULL);
|
|
LineTo(hMemDC, rcRect.left + 2, rcRect.bottom - 1);
|
|
|
|
MoveToEx(hMemDC, rcRect.right, rcRect.bottom - 1, NULL);
|
|
LineTo(hMemDC, rcRect.right - 2, rcRect.bottom - 1);
|
|
|
|
GetDIBits(hMemDC, hBitmap, 0, lpbmIconInfoHeader->biHeight, lpBitmap,
|
|
(LPBITMAPINFO)lpbmIconInfoHeader, DIB_RGB_COLORS);
|
|
|
|
CopyMemory(&lpbMiniImeFileImage[uAddr + dwHeaderSize], lpBitmap, dwBitmap);
|
|
}
|
|
|
|
DeleteObject(SelectObject(hMemDC, hOldBitmap));
|
|
DeleteObject(hMemDC);
|
|
GlobalFree((HGLOBAL)lpbmIconInfoHeader);
|
|
GlobalFree((HGLOBAL)lpBitmap);
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
BOOL Process_Icon(
|
|
HWND hWnd,
|
|
LPBYTE lpbMiniImeFileImage,
|
|
UINT uLen)
|
|
{
|
|
HRSRC hResIcon;
|
|
LPVOID lpResIcon;
|
|
int nIconID32, nIconID16, nIconID18, nIconID22;
|
|
|
|
// Get Icon from resource, use to find base IME Icon address
|
|
hResIcon = LoadResource(hInst, FindResource(hInst,
|
|
MAKEINTRESOURCE(IDIC_IME_ICON), RT_GROUP_ICON));
|
|
|
|
if ( hResIcon == NULL )
|
|
return FALSE;
|
|
|
|
lpResIcon = LockResource(hResIcon);
|
|
|
|
if ( lpResIcon == NULL )
|
|
{
|
|
FreeResource(hResIcon);
|
|
return FALSE;
|
|
}
|
|
|
|
nIconID32 = LookupIconIdFromDirectoryEx(lpResIcon, TRUE,
|
|
32, 32, LR_DEFAULTCOLOR);
|
|
|
|
nIconID16 = LookupIconIdFromDirectoryEx(lpResIcon, TRUE,
|
|
16, 16, LR_DEFAULTCOLOR);
|
|
|
|
nIconID18 = LookupIconIdFromDirectoryEx(lpResIcon, TRUE,
|
|
18, 18, LR_DEFAULTCOLOR);
|
|
|
|
nIconID22 = LookupIconIdFromDirectoryEx(lpResIcon, TRUE,
|
|
22, 22, LR_DEFAULTCOLOR);
|
|
|
|
UnlockResource(hResIcon);
|
|
FreeResource(hResIcon);
|
|
|
|
if (!UpdateMiniIMEIcon(hWnd, lpbMiniImeFileImage, uLen, nIconID32)) {
|
|
return (FALSE);
|
|
}
|
|
|
|
if (!UpdateMiniIMEIcon(hWnd, lpbMiniImeFileImage, uLen, nIconID16)) {
|
|
return (FALSE);
|
|
}
|
|
|
|
if (!UpdateMiniIMEIcon(hWnd, lpbMiniImeFileImage, uLen, nIconID18)) {
|
|
return (FALSE);
|
|
}
|
|
|
|
if (!UpdateMiniIMEIcon(hWnd, lpbMiniImeFileImage, uLen, nIconID22)) {
|
|
return (FALSE);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
BOOL Process_RT(HFILE hfFile, BYTE *szImeBuf, UINT Imelen, TCHAR *szPure_Name)
|
|
{
|
|
HGLOBAL hResData;
|
|
TCHAR szStr[MAX_CHAR_NUM+10];
|
|
TCHAR *szBuf;
|
|
UINT uAddr1,uAddr2;
|
|
UINT len,flen,i;
|
|
#ifdef UNICODE
|
|
BOOL bUniCode = TRUE;
|
|
TCHAR *buf;
|
|
#endif
|
|
LPVALIDCHAR lpValidChar;
|
|
|
|
// load valid char in choose/input state
|
|
hResData = LoadResource(hInst, FindResource(hInst,
|
|
MAKEINTRESOURCE(IDRC_VALIDCHAR), RT_RCDATA));
|
|
|
|
if ( hResData == NULL )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
lpValidChar = (LPVALIDCHAR)LockResource(hResData);
|
|
|
|
if ( lpValidChar == NULL )
|
|
{
|
|
FreeResource(hResData);
|
|
return FALSE;
|
|
}
|
|
|
|
*(LPVALIDCHAR)&Valid = *lpValidChar;
|
|
UnlockResource(hResData);
|
|
FreeResource(hResData);
|
|
|
|
uAddr1 = SearchMem((BYTE *)&Valid, sizeof(VALIDCHAR), szImeBuf, Imelen);
|
|
if(uAddr1 == 0)
|
|
{
|
|
ErrMsg(IDS_ERR_BASEIME, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
// IME table files
|
|
hResData = LoadResource(hInst, FindResource(hInst,
|
|
MAKEINTRESOURCE(IDRC_TABLEFILES), RT_RCDATA));
|
|
|
|
if ( hResData == NULL )
|
|
return FALSE;
|
|
|
|
*(LPTABLEFILES)&Table = *(LPTABLEFILES)LockResource(hResData);
|
|
UnlockResource(hResData);
|
|
FreeResource(hResData);
|
|
|
|
uAddr2 = SearchMem((BYTE *)&Table, sizeof(TABLEFILES), szImeBuf, Imelen);
|
|
if(uAddr2 == 0)
|
|
{
|
|
ErrMsg(IDS_ERR_BASEIME, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
// get file length
|
|
flen = _llseek(hfFile, 0L, 2);
|
|
|
|
// Allocate Memory
|
|
szBuf = (TCHAR *)GlobalAlloc(GMEM_FIXED, flen);
|
|
if(!szBuf)
|
|
{
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
_llseek(hfFile,0L,0); // Skip 'FF FE'
|
|
|
|
{
|
|
BYTE ubuf[3];
|
|
if(2 != _lread(hfFile, ubuf, 2))
|
|
{
|
|
GlobalFree((HGLOBAL)szBuf);
|
|
ErrIOMsg(IDS_ERR_FILEREAD, szTab_Name);
|
|
return FALSE;
|
|
}
|
|
|
|
if(ubuf[0] == 0xff && ubuf[1] == 0xfe) // UNICODE
|
|
flen -= 2;
|
|
else
|
|
{
|
|
_llseek(hfFile, 0L, 0);
|
|
bUniCode = 0;
|
|
}
|
|
|
|
}
|
|
#else
|
|
_llseek(hfFile,0L,0); // Move file pointer to begining
|
|
#endif
|
|
|
|
// Read file to memory
|
|
if(flen != _lread(hfFile, szBuf, flen))
|
|
{
|
|
GlobalFree((HGLOBAL)szBuf);
|
|
ErrIOMsg(IDS_ERR_FILEREAD, szTab_Name);
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
if(!bUniCode)
|
|
{
|
|
buf = (TCHAR *)GlobalAlloc(GMEM_FIXED, flen * 2);
|
|
if(!buf)
|
|
{
|
|
GlobalFree((HGLOBAL)szBuf);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
i = MultiByteToWideChar(950, MB_PRECOMPOSED, (BYTE *)szBuf, flen,
|
|
(LPTSTR)buf, flen);
|
|
GlobalFree((HGLOBAL)szBuf);
|
|
szBuf = buf;
|
|
flen = i * 2;
|
|
}
|
|
#endif
|
|
|
|
// Allocate global memory
|
|
hRadical = GlobalAlloc(GMEM_MOVEABLE, ALLOCBLOCK * sizeof(RADICALBUF));
|
|
if(!hRadical)
|
|
{
|
|
GlobalFree((HGLOBAL)szBuf);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
nRadicalBuffsize = ALLOCBLOCK;
|
|
iRadicalBuff = 0;
|
|
lpRadical = (LPRADICALBUF)GlobalLock(hRadical);
|
|
if(!lpRadical)
|
|
{
|
|
GlobalFree((HGLOBAL)szBuf);
|
|
GlobalFree(hRadical);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
hPhrase = GlobalAlloc(GMEM_MOVEABLE, ALLOCBLOCK * sizeof(PHRASEBUF));
|
|
if(!hPhrase)
|
|
{
|
|
GlobalFree((HGLOBAL)szBuf);
|
|
GlobalUnlock(hRadical);
|
|
GlobalFree(hRadical);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
nPhraseBuffsize = ALLOCBLOCK;
|
|
iPhraseBuff = 0;
|
|
lpPhrase = (LPPHRASEBUF)GlobalLock(hPhrase);
|
|
if(!lpPhrase)
|
|
{
|
|
GlobalFree((HGLOBAL)szBuf);
|
|
GlobalUnlock(hRadical);
|
|
GlobalFree(hRadical);
|
|
GlobalFree(hPhrase);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
len=0;
|
|
idxLine = 0;
|
|
for(i = 0; i < (flen/cntChar+1); i++)
|
|
{
|
|
if((szBuf[i] == 0x0d) || (szBuf[i] == 0x0a))
|
|
{
|
|
if(len != 0)
|
|
{
|
|
if(!Parse(szStr, len))
|
|
break;
|
|
len=0;
|
|
idxLine ++;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if((szBuf[i] == 0x1a) || (i == flen/cntChar))
|
|
{
|
|
if(len != 0)
|
|
{
|
|
if(!Parse(szStr, len))
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(len < MAX_CHAR_NUM)
|
|
szStr[len ++] = szBuf[i];
|
|
}
|
|
|
|
GlobalFree((HGLOBAL)szBuf);
|
|
|
|
if(!WritetoFile(szPure_Name))
|
|
{
|
|
GlobalUnlock(hRadical);
|
|
GlobalUnlock(hPhrase);
|
|
GlobalFree(hRadical);
|
|
GlobalFree(hPhrase);
|
|
return FALSE;
|
|
}
|
|
|
|
GlobalUnlock(hRadical);
|
|
GlobalUnlock(hPhrase);
|
|
GlobalFree(hRadical);
|
|
GlobalFree(hPhrase);
|
|
|
|
// Set Beep for candidates status
|
|
Valid.fwProperties1 = (WORD)(bCandBeep ? 0 : 1);
|
|
CopyMemory(&szImeBuf[uAddr1], &Valid, sizeof(VALIDCHAR));
|
|
CopyMemory(&szImeBuf[uAddr2], &Table, sizeof(TABLEFILES));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int __cdecl subComp(const void *Pointer1, const void *Pointer2)
|
|
{
|
|
LPRADICALBUF lpRadical1 = (LPRADICALBUF)Pointer1;
|
|
LPRADICALBUF lpRadical2 = (LPRADICALBUF)Pointer2;
|
|
WORD wWord1,wWord2;
|
|
UINT i;
|
|
|
|
for(i = 0; i < Valid.nMaxKey; i++)
|
|
{
|
|
wWord1 = Valid.wChar2SeqTbl[lpRadical1->szRadical[i] - 0x20];
|
|
wWord2 = Valid.wChar2SeqTbl[lpRadical2->szRadical[i] - 0x20];
|
|
if(wWord1 == wWord2)
|
|
continue;
|
|
|
|
if(wWord1 > wWord2)
|
|
return 1;
|
|
else
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
BOOL WritetoFile(
|
|
TCHAR *szPure_Name)
|
|
{
|
|
HFILE hTbl,hTblPtr,hTblCode;
|
|
HANDLE hKey;
|
|
UCHAR *szKey;
|
|
UCHAR szPtr[MAX_CHAR_NUM+10];
|
|
TCHAR szWindows[MAX_PATH];
|
|
TCHAR szFName[MAX_PATH];
|
|
TCHAR szTotal[MAX_CHAR_NUM];
|
|
UCHAR szPhrase[MAX_CHAR_NUM];
|
|
UINT len, i, j, k, l;
|
|
UINT nKey,nPtr,nBit,nByte;
|
|
WORD wlen,wTotalLen;
|
|
WORD wSeq;
|
|
WORD wWord;
|
|
DWORD dwRadical;
|
|
BOOL bPhrase;
|
|
UINT nAlloc;
|
|
#ifdef UNICODE
|
|
DWORD lPtrlen,lPrevlen;
|
|
UINT ii;
|
|
#else
|
|
WORD wPtrlen,wPrevlen;
|
|
#endif
|
|
|
|
|
|
|
|
// Get System directory
|
|
len = GetSystemDirectory((LPTSTR)szWindows, ARRAYSIZE(szWindows) - 1);
|
|
if (szWindows[len - 1] != '\\') { // consider C:\ ;
|
|
szWindows[len++] = '\\';
|
|
szWindows[len] = 0;
|
|
}
|
|
|
|
Valid.nMaxKey=szKey_Num_Str[0] - _TEXT('0');
|
|
j=(UINT)Valid.nSeqCode;
|
|
if(j < 1) {
|
|
ErrMsg(IDS_ERR_NORADICAL, 0);
|
|
return FALSE;
|
|
}
|
|
for(nBit=1; (j/=2) != 0; nBit++) ;
|
|
nByte=(nBit * Valid.nMaxKey + 7) / 8;
|
|
if(nByte > MAX_BYTE) {
|
|
TCHAR szErrStr[MAX_PATH];
|
|
TCHAR szShowMsg[MAX_PATH];
|
|
UINT nMaxKey;
|
|
|
|
nMaxKey=(MAX_BYTE*8)/nBit;
|
|
|
|
HideProgress();// <== @E01
|
|
|
|
LoadString(hInst, IDS_ERR_OVER_BITLEN, szErrStr, sizeof(szErrStr) / sizeof(TCHAR));
|
|
wsprintf(szShowMsg, szErrStr, Valid.nSeqCode, nMaxKey);
|
|
MessageBox(NULL, szShowMsg, NULL, MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND);
|
|
bOverMaxRadical=TRUE;
|
|
return FALSE;
|
|
}
|
|
qsort(lpRadical, iRadicalBuff, sizeof(RADICALBUF), subComp);
|
|
|
|
|
|
// Allocate Memory
|
|
nAlloc=ALLOCBLOCK*(nByte+sizeof(WORD));
|
|
hKey = GlobalAlloc(GMEM_MOVEABLE, nAlloc+100);
|
|
if(!hKey) {
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
szKey = GlobalLock(hKey);
|
|
if(!szKey) {
|
|
GlobalFree(hKey);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
nKey=nByte+sizeof(WORD);
|
|
ZeroMemory(szKey, nKey);
|
|
ZeroMemory(szPtr, nKey); //@D02A
|
|
nPtr=0;
|
|
bPhrase=FALSE;
|
|
for(i=0; i<iRadicalBuff; i++)
|
|
{
|
|
dwRadical=0;
|
|
for(j=0; j<Valid.nMaxKey; j++)
|
|
{
|
|
wSeq=Valid.wChar2SeqTbl[lpRadical[i].szRadical[j]-0x20];
|
|
// Check using undefined radical
|
|
if((wSeq == 0) && (lpRadical[i].szRadical[j] != _TEXT(' ')))
|
|
break;
|
|
dwRadical=(dwRadical << nBit)+wSeq;
|
|
}
|
|
|
|
if(j == Valid.nMaxKey)
|
|
{
|
|
wWord=lpRadical[i].wCode;
|
|
if(wWord != 0)
|
|
{
|
|
if(nKey == nAlloc)
|
|
{
|
|
HANDLE hTemp;
|
|
|
|
nAlloc += ALLOCBLOCK*(nByte+sizeof(WORD));
|
|
GlobalUnlock(hKey);
|
|
hTemp= GlobalReAlloc(hKey, nAlloc+100, GMEM_MOVEABLE);
|
|
if(hTemp == NULL)
|
|
{
|
|
GlobalFree(hKey);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
hKey=hTemp;
|
|
szKey=GlobalLock(hKey);
|
|
if(szKey == NULL)
|
|
{
|
|
GlobalFree(hKey);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
*((LPUNADWORD)&szKey[nKey])=dwRadical; // <== @D05
|
|
*((LPUNAWORD)&szKey[nKey+nByte])=wWord;// <== @D05
|
|
// *((DWORD *)&szKey[nKey])=dwRadical;
|
|
// *((WORD *)&szKey[nKey+nByte])=wWord;
|
|
nKey+=(nByte+sizeof(WORD));
|
|
}
|
|
|
|
wTotalLen=GetPhrase(i, szTotal);
|
|
if(wTotalLen == 0)
|
|
continue;
|
|
#ifdef UNICODE
|
|
ZeroMemory(szPhrase, MAX_CHAR_NUM);
|
|
wlen=0;
|
|
for(k = 0; k < wTotalLen; k++)
|
|
{
|
|
if(szTotal[k+1] != 1)
|
|
{
|
|
for(l = k; l < wTotalLen; l++)
|
|
{
|
|
*((TCHAR *)&szPhrase[wlen]) = szTotal[l];
|
|
wlen += 2;
|
|
if(szTotal[l] == 1)
|
|
break;
|
|
}
|
|
k = l;
|
|
}
|
|
else
|
|
{
|
|
if(nKey == nAlloc)
|
|
{
|
|
HANDLE hTemp;
|
|
|
|
nAlloc += ALLOCBLOCK*(nByte+sizeof(WORD));
|
|
GlobalUnlock(hKey);
|
|
hTemp= GlobalReAlloc(hKey, nAlloc+100, GMEM_MOVEABLE);
|
|
if(hTemp == NULL)
|
|
{
|
|
GlobalFree(hKey);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
hKey=hTemp;
|
|
szKey=GlobalLock(hKey);
|
|
if(szKey == NULL)
|
|
{
|
|
GlobalFree(hKey);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
// *((DWORD *)&szKey[nKey])=dwRadical;
|
|
*((LPUNADWORD)&szKey[nKey])=dwRadical; // <== @D05
|
|
//*((TCHAR *)&szKey[nKey+nByte]) = szTotal[k];
|
|
*((LPUNATCHAR)&szKey[nKey+nByte]) = szTotal[k]; // <== @D05
|
|
nKey += (nByte+sizeof(WORD));
|
|
if(szTotal[k+1] == 1) k ++;
|
|
}
|
|
}
|
|
#else
|
|
wlen=0;
|
|
for(k=0; k<wTotalLen; k += 2)
|
|
{
|
|
if(szTotal[k+1] & 0x80)
|
|
{
|
|
for(l=k; l<wTotalLen; l += 2)
|
|
{
|
|
szPhrase[wlen++] = szTotal[l];
|
|
szPhrase[wlen++] = szTotal[l+1];
|
|
if(!(szTotal[l+1] & 0x80))
|
|
break;
|
|
}
|
|
k = l;
|
|
}
|
|
else
|
|
{
|
|
if(nKey == nAlloc)
|
|
{
|
|
HANDLE hTemp;
|
|
|
|
nAlloc += ALLOCBLOCK*(nByte+sizeof(WORD));
|
|
GlobalUnlock(hKey);
|
|
hTemp= GlobalReAlloc(hKey, nAlloc+100, GMEM_MOVEABLE);
|
|
if(hTemp == NULL)
|
|
{
|
|
GlobalFree(hKey);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
hKey=hTemp;
|
|
szKey=GlobalLock(hKey);
|
|
if(szKey == NULL)
|
|
{
|
|
GlobalFree(hKey);
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
*((LPUNADWORD)&szKey[nKey])=dwRadical; // <== @D05
|
|
szKey[nKey+nByte] = szTotal[k];
|
|
szKey[nKey+nByte+1] = szTotal[k+1] | 0x80;
|
|
nKey += (nByte+sizeof(WORD));
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if(wlen == 0)
|
|
continue;
|
|
|
|
if(!bPhrase)
|
|
{
|
|
// Use first 5 characters of IME filename as table header name
|
|
len=lstrlen(szPure_Name);
|
|
if(len > 5)
|
|
len=5;
|
|
CopyMemory(Table.szTblFile[0], szPure_Name, len * cntChar);
|
|
Table.szTblFile[0][len]=0;
|
|
lstrcpy(Table.szTblFile[1], Table.szTblFile[0]);
|
|
lstrcpy(Table.szTblFile[2], Table.szTblFile[0]);
|
|
lstrcat(Table.szTblFile[0], _TEXT(".TBL"));
|
|
lstrcat(Table.szTblFile[1], _TEXT("PTR.TBL"));
|
|
lstrcat(Table.szTblFile[2], _TEXT("PHR.TBL"));
|
|
|
|
StringCchCopy(szFName, ARRAYSIZE(szFName), szWindows);
|
|
StringCchCat(szFName, ARRAYSIZE(szFName), Table.szTblFile[0]);
|
|
#ifdef UNICODE
|
|
{
|
|
char fname[MAX_PATH * 2];
|
|
int lenx = lstrlen(szFName);
|
|
WideCharToMultiByte(950, WC_COMPOSITECHECK, szFName, lenx,
|
|
(LPSTR)fname, lenx, NULL, NULL);
|
|
fname[lenx] = 0;
|
|
hTbl=_lcreat(fname, 0);
|
|
}
|
|
#else
|
|
hTbl=_lcreat(szFName, 0);
|
|
#endif
|
|
if(hTbl == -1)
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEOPEN, Table.szTblFile[0]);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
return FALSE;
|
|
}
|
|
|
|
StringCchCopy(szFName, ARRAYSIZE(szFName), szWindows);
|
|
StringCchCat(szFName, ARRAYSIZE(szFName), Table.szTblFile[1]);
|
|
|
|
#ifdef UNICODE
|
|
{
|
|
char fname[MAX_PATH * 2];
|
|
int lenx = lstrlen(szFName);
|
|
WideCharToMultiByte(950, WC_COMPOSITECHECK, szFName, lenx,
|
|
(LPSTR)fname, lenx, NULL, NULL);
|
|
fname[lenx] = 0;
|
|
hTblPtr = _lcreat(fname, 0);
|
|
}
|
|
#else
|
|
hTblPtr = _lcreat(szFName, 0);
|
|
#endif
|
|
if(hTblPtr == -1)
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEOPEN, Table.szTblFile[1]);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
return FALSE;
|
|
}
|
|
|
|
StringCchCopy(szFName, ARRAYSIZE(szFName), szWindows);
|
|
StringCchCat(szFName, ARRAYSIZE(szFName), Table.szTblFile[2]);
|
|
|
|
#ifdef UNICODE
|
|
{
|
|
char fname[MAX_PATH * 2];
|
|
int lenx = lstrlen(szFName);
|
|
WideCharToMultiByte(950, WC_COMPOSITECHECK, szFName, lenx,
|
|
(LPSTR)fname, lenx, NULL, NULL);
|
|
fname[lenx] = 0;
|
|
hTblCode = _lcreat(fname, 0);
|
|
}
|
|
#else
|
|
hTblCode = _lcreat(szFName, 0);
|
|
#endif
|
|
if(hTblCode == -1) {
|
|
ErrIOMsg(IDS_ERR_FILEOPEN, Table.szTblFile[2]);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
nPtr = nByte+sizeof(DWORD);
|
|
#else
|
|
nPtr = nByte+sizeof(WORD);
|
|
#endif
|
|
//ZeroMemory(szKey, nPtr*2);
|
|
ZeroMemory(szKey, nByte+sizeof(WORD) );
|
|
#ifdef UNICODE
|
|
lPtrlen=0;
|
|
lPrevlen=0;
|
|
#else
|
|
wPtrlen=0;
|
|
wPrevlen=0;
|
|
#endif
|
|
bPhrase=TRUE;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
CopyMemory(szTotal, szPhrase, wlen + cntChar);
|
|
|
|
ii = 0;
|
|
for(j = 0; j < (UINT)wlen / cntChar; j ++)
|
|
{
|
|
if(lPtrlen >= 0xfffffffd)
|
|
{
|
|
#else
|
|
for(j = 0; j < (UINT)wlen; j += 2)
|
|
{
|
|
if(wPtrlen >= 0xfffd)
|
|
{
|
|
#endif
|
|
ErrMsg(IDS_ERR_OVER_MAXLEN, 0);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
if(szTotal[j] != 1)
|
|
{
|
|
lPtrlen++;
|
|
// *((TCHAR *)&szPhrase[ii]) = szTotal[j];
|
|
*((LPUNATCHAR)&szPhrase[ii]) = szTotal[j]; // <== @D05
|
|
ii += 2;
|
|
continue;
|
|
}
|
|
#else
|
|
wPtrlen++;
|
|
if(*((LPUNAWORD)&szPhrase[j]) & END_PHRASE) // <== @D05
|
|
continue;
|
|
#endif
|
|
|
|
if(nPtr >= MAX_CHAR_NUM)
|
|
{
|
|
// Write file from key buffer
|
|
if(nPtr != _lwrite(hTblPtr, (BYTE *)szPtr, nPtr))
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[1]);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
return FALSE;
|
|
}
|
|
nPtr=0;
|
|
}
|
|
|
|
#ifndef UNICODE
|
|
*((LPUNAWORD)&szPhrase[j]) |= END_PHRASE; // <== @D05
|
|
*((LPUNADWORD)&szPtr[nPtr])=dwRadical; // <== @D05
|
|
*((LPUNAWORD)&szPtr[nPtr+nByte])=wPrevlen; // <== @D05
|
|
nPtr+=(nByte+sizeof(WORD));
|
|
wPrevlen=wPtrlen;
|
|
#else
|
|
*((LPUNADWORD)&szPtr[nPtr])=dwRadical; // <== @D05
|
|
*((LPUNADWORD)&szPtr[nPtr+nByte])=lPrevlen; // <== @D05
|
|
nPtr+=(nByte+sizeof(DWORD));
|
|
lPrevlen=lPtrlen;
|
|
#endif
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
wlen = ii / 2;
|
|
#endif
|
|
|
|
if((wlen * (UINT)cntChar) != _lwrite(hTblCode, szPhrase, wlen * cntChar))
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[2]);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bPhrase)
|
|
{
|
|
szPhrase[0] = (BYTE) 0xff;
|
|
szPhrase[1] = (BYTE) 0xff;
|
|
if(2 != _lwrite(hTblCode, (BYTE *)szPhrase, 2))
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[2]);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
return FALSE;
|
|
}
|
|
_lclose(hTblCode);
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(Table.szTblFile[0], szPure_Name);
|
|
lstrcat(Table.szTblFile[0], _TEXT(".TBL"));
|
|
StringCchCopy(szFName, ARRAYSIZE(szFName), szWindows);
|
|
StringCchCat(szFName, ARRAYSIZE(szFName), Table.szTblFile[0]);
|
|
#ifdef UNICODE
|
|
{
|
|
char fname[MAX_PATH * 2];
|
|
int lenx = lstrlen(szFName);
|
|
WideCharToMultiByte(950, WC_COMPOSITECHECK, szFName, lenx,
|
|
(LPSTR)fname, lenx, NULL, NULL);
|
|
fname[lenx] = 0;
|
|
hTbl = _lcreat(fname, 0);
|
|
}
|
|
#else
|
|
hTbl = _lcreat(szFName, 0);
|
|
#endif
|
|
|
|
if(hTbl == -1)
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEOPEN, Table.szTblFile[0]);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < nByte+sizeof(WORD); i++)
|
|
szKey[nKey++] = (BYTE) 0xff;
|
|
|
|
// Write file from key buffer
|
|
|
|
if(nKey != _lwrite(hTbl, szKey, nKey))
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[0]);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
return FALSE;
|
|
}
|
|
_lclose(hTbl);
|
|
GlobalUnlock(hKey);
|
|
GlobalFree(hKey);
|
|
|
|
if(bPhrase)
|
|
{
|
|
for(i = 0; i < nByte; i++)
|
|
szPtr[nPtr++] = (BYTE) 0xff;
|
|
#ifdef UNICODE
|
|
*((LPUNADWORD)&szPtr[nPtr]) = lPtrlen; // <== @D05
|
|
nPtr += 4;
|
|
#else
|
|
*((LPUNAWORD)&szPtr[nPtr]) = wPtrlen; // <== @D05
|
|
nPtr += 2;
|
|
#endif
|
|
// Write file from key buffer
|
|
if(nPtr != _lwrite(hTblPtr, (BYTE *)szPtr, nPtr))
|
|
{
|
|
ErrIOMsg(IDS_ERR_FILEWRITE, Table.szTblFile[1]);
|
|
return FALSE;
|
|
}
|
|
_lclose(hTblPtr);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
WORD GetPhrase(UINT iRadical, TCHAR *szPhrase)
|
|
{
|
|
LPPHRASEBUF Phrase;
|
|
WORD wLen=0;
|
|
UINT iAddr;
|
|
|
|
iAddr = lpRadical[iRadical].iFirst_Seg;
|
|
if(iAddr == NULL_SEG)
|
|
return 0;
|
|
|
|
Phrase=&lpPhrase[iAddr];
|
|
while(Phrase->iNext_Seg != NULL_SEG)
|
|
{
|
|
if((wLen+SEGMENT_SIZE) > MAX_CHAR_NUM )
|
|
{
|
|
CopyMemory(&szPhrase[wLen], Phrase->szPhrase, (MAX_CHAR_NUM-wLen) * cntChar);
|
|
wLen = MAX_CHAR_NUM;
|
|
szPhrase[wLen] = 0;
|
|
return wLen;
|
|
}
|
|
|
|
CopyMemory((char *)(szPhrase + wLen), Phrase->szPhrase, SEGMENT_SIZE * cntChar);
|
|
Phrase = &lpPhrase[Phrase->iNext_Seg];
|
|
wLen += SEGMENT_SIZE;
|
|
}
|
|
|
|
if((wLen+SEGMENT_SIZE) > MAX_CHAR_NUM )
|
|
{
|
|
CopyMemory(szPhrase + wLen, Phrase->szPhrase, (MAX_CHAR_NUM-wLen) * cntChar);
|
|
wLen = MAX_CHAR_NUM;
|
|
}
|
|
else
|
|
{
|
|
CopyMemory(szPhrase + wLen, Phrase->szPhrase, SEGMENT_SIZE * cntChar);
|
|
wLen += SEGMENT_SIZE;
|
|
}
|
|
|
|
szPhrase[wLen] = 0;
|
|
wLen = (WORD)lstrlen(szPhrase);
|
|
|
|
return wLen;
|
|
}
|
|
|
|
BOOL Parse(TCHAR *szStr, UINT len)
|
|
{
|
|
UINT i,j,k;
|
|
TCHAR szRadical[MAX_RADICAL];
|
|
|
|
// Skip blank
|
|
for(i=0; (i<len) && (szStr[i] == _TEXT(' ') || szStr[i] == _TEXT('\t')); i++) ;
|
|
if(i == len)
|
|
return TRUE;
|
|
|
|
j = len - 1;
|
|
while(szStr[j] == _TEXT(' ') || szStr[j] == _TEXT('\t'))
|
|
{
|
|
j --;
|
|
len --;
|
|
}
|
|
|
|
// Check Command Code 9/29/97 change logic
|
|
if(szStr[i] == _TEXT('/'))
|
|
{
|
|
// Check Radical Command
|
|
switch (szStr[i+1])
|
|
{
|
|
// Symbol
|
|
case _TEXT('s'):
|
|
case _TEXT('S'):
|
|
|
|
for(j=i+2; (j<len) && (szStr[j] == _TEXT(' ') || szStr[j] == _TEXT('\t')); j++) ;
|
|
if(j >= len)
|
|
return TRUE;
|
|
|
|
for(i=j+1; i<len; i++)
|
|
{
|
|
if(!PutRadical(szStr[j]++, *((LPUNAWORD)(&szStr[i])))) // <== @D05
|
|
return TRUE;
|
|
#ifndef UNICODE
|
|
i++;
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
// Interpret '/' literally
|
|
case _TEXT('/'):
|
|
i++;
|
|
goto GET_RADICAL;
|
|
|
|
// Reserve for future use
|
|
default:
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
GET_RADICAL:
|
|
// Get Radical
|
|
MyFillMemory(szRadical, MAX_RADICAL, _TEXT(' '));
|
|
|
|
k=0;
|
|
for(j=i; (j<len) && (k<MAX_RADICAL) && ((szStr[j] != _TEXT(' ')) && (szStr[j] != _TEXT('\t'))); j++)
|
|
{
|
|
// Make Uppercase
|
|
if((szStr[j] >= _TEXT('a')) && (szStr[j] <= _TEXT('z')))
|
|
szStr[j] -= ('a'-'A');
|
|
szRadical[k++] = szStr[j];
|
|
}
|
|
|
|
if(j == len)
|
|
return TRUE;
|
|
|
|
if(k==MAX_RADICAL)
|
|
{
|
|
// Skip radical of over length
|
|
for(i=j; (j<len) && (szStr[j] != _TEXT(' ')); j++) ;
|
|
if(i == len)
|
|
return TRUE;
|
|
j=i;
|
|
}
|
|
|
|
// Skip blank
|
|
for(i=j; (i<len) && (szStr[i] == _TEXT(' ') || szStr[i] == _TEXT('\t')); i++) ;
|
|
if(i == len)
|
|
return TRUE;
|
|
if(!PutPhrase(szRadical, &szStr[i], len-i))
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
UINT SearchMem(BYTE *szSrc, UINT nSrc, BYTE *szTag, UINT nTar)
|
|
{
|
|
UINT i,j;
|
|
|
|
for(i = 0; i < nTar; i ++)
|
|
{
|
|
for(j = 0; j < nSrc; j ++)
|
|
if(szSrc[j] != szTag[i+j])
|
|
break;
|
|
|
|
if(j == nSrc)
|
|
return(i);
|
|
}
|
|
|
|
return(0);
|
|
}
|
|
|
|
BOOL PutRadical(TCHAR cRadical, WORD wChinese)
|
|
{
|
|
UINT iAddr;
|
|
|
|
// Make Uppercase
|
|
if((cRadical >= _TEXT('a')) && (cRadical <= _TEXT('z')))
|
|
cRadical -= ('a' - 'A');
|
|
|
|
// Check Radical
|
|
if((cRadical < 0x20) || (cRadical > 0x5f))
|
|
return FALSE;
|
|
|
|
// Check DBCS
|
|
if(!is_DBCS(wChinese))
|
|
{
|
|
ErrMsg(IDS_ERR_SBCS, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
iAddr = cRadical - 0x20;
|
|
if(Valid.wChar2SeqTbl[iAddr] != 0)
|
|
return FALSE;
|
|
|
|
Valid.wChar2SeqTbl[iAddr] = (++Valid.nSeqCode);
|
|
Valid.wSeq2CompTbl[Valid.nSeqCode] = wChinese;
|
|
Valid.fChooseChar[iAddr/16] |= (1 << (iAddr % 16));
|
|
Valid.fCompChar[iAddr/16] |= (1 << (iAddr % 16));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL PutPhrase(TCHAR *szRadical, TCHAR *szPhrase, UINT len)
|
|
{
|
|
LPPHRASEBUF Phrase;
|
|
UINT iAddr,iRadical;
|
|
UINT iStart,i,j;
|
|
TCHAR szBuf[MAX_PATH];
|
|
UINT iBuflen;
|
|
|
|
#ifndef UNICODE // <== @E02
|
|
|
|
// Check DBCS
|
|
for(i = 0; i < len; i++)
|
|
{
|
|
if(szPhrase[i] == _TEXT(' '))
|
|
continue;
|
|
|
|
if(!is_DBCS(*((LPUNAWORD)(&szPhrase[i])))) // <== @D05
|
|
{
|
|
//ErrMsg(IDS_ERR_SBCS, 0);
|
|
|
|
TCHAR szErrStr[MAX_PATH];
|
|
TCHAR szStr1[MAX_PATH];
|
|
TCHAR szStr2[MAX_PATH];
|
|
LoadString(hInst, IDS_ERR_SBCS, szStr1, sizeof(szStr1) / sizeof(TCHAR));
|
|
StringCchPrintf(szErrStr, ARRAYSIZE(szErrStr), _TEXT("²Ä %d ¦æ : "), idxLine + 1);
|
|
CopyMemory(szStr2, szPhrase, len * cntChar);
|
|
szStr2[len] = 0;
|
|
StringCchCat(szErrStr, ARRAYSIZE(szErrStr), szStr2);
|
|
StringCchCat(szErrStr, ARRAYSIZE(szErrStr), _TEXT("\n"));
|
|
StringCchCat(szErrStr, ARRAYSIZE(szErrStr), szStr1);
|
|
if (MessageBox(NULL, szErrStr, NULL, MB_OKCANCEL | MB_ICONEXCLAMATION | MB_SETFOREGROUND)
|
|
== IDCANCEL)
|
|
return FALSE;
|
|
else
|
|
return TRUE; // ©¿²¤¤§
|
|
}
|
|
i++;
|
|
}
|
|
#endif // <== @E02
|
|
|
|
// Search Radical buffer
|
|
for(i = 0; i < iRadicalBuff; i++)
|
|
{
|
|
for(j = 0; j < MAX_RADICAL; j++)
|
|
if(lpRadical[i].szRadical[j] != szRadical[j])
|
|
break;
|
|
|
|
if(j == MAX_RADICAL)
|
|
break;
|
|
}
|
|
|
|
// Allocate new buffer if New Radical
|
|
if(i == iRadicalBuff)
|
|
{
|
|
if(iRadicalBuff+1 == nRadicalBuffsize)
|
|
if(!AllocRadical())
|
|
return FALSE;
|
|
|
|
CopyMemory(lpRadical[i].szRadical, szRadical, MAX_RADICAL * cntChar);
|
|
iRadicalBuff++;
|
|
lpRadical[i].iFirst_Seg = NULL_SEG;
|
|
lpRadical[i].wCode = 0;
|
|
}
|
|
|
|
// Search Starting address in Phrase table
|
|
iRadical = i;
|
|
iAddr = lpRadical[i].iFirst_Seg;
|
|
if(iAddr != NULL_SEG)
|
|
{
|
|
Phrase = &lpPhrase[iAddr];
|
|
while(Phrase->iNext_Seg != NULL_SEG)
|
|
Phrase=&lpPhrase[Phrase->iNext_Seg];
|
|
|
|
for(i = 0; i < SEGMENT_SIZE; i++)
|
|
if(Phrase->szPhrase[i] == 0)
|
|
break;
|
|
|
|
iStart = i;
|
|
}
|
|
|
|
// Put Phrase
|
|
iBuflen = 0;
|
|
for(i = 0; i < len; i++)
|
|
{
|
|
if(szPhrase[i] != _TEXT(' ') && (szPhrase[i] != _TEXT('\t')))
|
|
{
|
|
szBuf[iBuflen++] = szPhrase[i];
|
|
if((i+1) != len)
|
|
continue;
|
|
}
|
|
|
|
if(iBuflen == 0)
|
|
continue;
|
|
|
|
#ifdef UNICODE
|
|
if((iBuflen == 1) && (lpRadical[iRadical].wCode == 0))
|
|
{
|
|
lpRadical[iRadical].wCode = szBuf[0];
|
|
}
|
|
else
|
|
{
|
|
#else
|
|
if((iBuflen == 2) && (lpRadical[iRadical].wCode == 0))
|
|
{
|
|
lpRadical[iRadical].wCode = (((WORD)szBuf[0])<< 8)+
|
|
(WORD)szBuf[1];
|
|
}
|
|
else
|
|
{
|
|
szBuf[iBuflen-2] &= 0x7f;
|
|
#endif
|
|
// if(lpRadical[iRadical].wCode == 0)
|
|
// return FALSE;
|
|
|
|
if(iAddr == NULL_SEG)
|
|
{
|
|
if(iPhraseBuff + 1 == nPhraseBuffsize)
|
|
if(!AllocPhrase())
|
|
return FALSE;
|
|
|
|
lpRadical[iRadical].iFirst_Seg=iPhraseBuff;
|
|
iAddr=iPhraseBuff;
|
|
Phrase=&lpPhrase[iAddr];
|
|
ZeroMemory(Phrase->szPhrase, SEGMENT_SIZE * cntChar);
|
|
Phrase->iNext_Seg=NULL_SEG;
|
|
iPhraseBuff++;
|
|
iStart=0;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
for(j = 0; j < iBuflen; j ++)
|
|
#else
|
|
for(j = 0; j < iBuflen; j += 2)
|
|
#endif
|
|
{
|
|
if(iStart == SEGMENT_SIZE)
|
|
{
|
|
if(iPhraseBuff + 1 == nPhraseBuffsize)
|
|
if(!AllocPhrase())
|
|
return FALSE;
|
|
|
|
Phrase=&lpPhrase[iAddr];
|
|
|
|
while (Phrase->iNext_Seg != NULL_SEG)
|
|
Phrase=&lpPhrase[Phrase->iNext_Seg];
|
|
|
|
Phrase->iNext_Seg=iPhraseBuff;
|
|
Phrase=&lpPhrase[iPhraseBuff];
|
|
ZeroMemory(Phrase->szPhrase, SEGMENT_SIZE * cntChar);
|
|
Phrase->iNext_Seg=NULL_SEG;
|
|
iPhraseBuff++;
|
|
iStart=0;
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
*((LPUNAWORD)&Phrase->szPhrase[iStart ++]) = szBuf[j]; // <== @D05
|
|
#else
|
|
*((LPUNAWORD)&Phrase->szPhrase[iStart])= // <== @D05
|
|
(((WORD)szBuf[j])<< 8)+ (WORD)szBuf[j+1];
|
|
iStart += 2;
|
|
#endif
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
|
|
if(iStart == SEGMENT_SIZE)
|
|
{
|
|
if(iPhraseBuff + 1 == nPhraseBuffsize)
|
|
if(!AllocPhrase())
|
|
return FALSE;
|
|
|
|
Phrase=&lpPhrase[iAddr];
|
|
|
|
while (Phrase->iNext_Seg != NULL_SEG)
|
|
Phrase=&lpPhrase[Phrase->iNext_Seg];
|
|
|
|
Phrase->iNext_Seg=iPhraseBuff;
|
|
Phrase=&lpPhrase[iPhraseBuff];
|
|
ZeroMemory(Phrase->szPhrase, SEGMENT_SIZE * cntChar);
|
|
Phrase->iNext_Seg=NULL_SEG;
|
|
iPhraseBuff++;
|
|
iStart=0;
|
|
}
|
|
|
|
*((LPUNAWORD)&Phrase->szPhrase[iStart ++]) = 1; // <== @D05
|
|
#endif
|
|
}
|
|
|
|
iBuflen=0;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL AllocRadical()
|
|
{
|
|
HANDLE hTemp;
|
|
|
|
nRadicalBuffsize += ALLOCBLOCK;
|
|
GlobalUnlock(hRadical);
|
|
hTemp= GlobalReAlloc(hRadical, nRadicalBuffsize * sizeof(RADICALBUF),
|
|
GMEM_MOVEABLE);
|
|
if(hTemp == NULL)
|
|
{
|
|
nRadicalBuffsize -= ALLOCBLOCK;
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
hRadical=hTemp;
|
|
lpRadical=(LPRADICALBUF)GlobalLock(hRadical);
|
|
if(lpRadical == NULL)
|
|
{
|
|
nRadicalBuffsize -= ALLOCBLOCK;
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL AllocPhrase()
|
|
{
|
|
HANDLE hTemp;
|
|
|
|
nPhraseBuffsize += ALLOCBLOCK;
|
|
GlobalUnlock(hPhrase);
|
|
hTemp= GlobalReAlloc(hPhrase, nPhraseBuffsize * sizeof(PHRASEBUF),
|
|
GMEM_MOVEABLE);
|
|
|
|
if(hTemp == NULL)
|
|
{
|
|
nPhraseBuffsize -= ALLOCBLOCK;
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
hPhrase=hTemp;
|
|
lpPhrase=(LPPHRASEBUF)GlobalLock(hPhrase);
|
|
if(lpPhrase == NULL)
|
|
{
|
|
nPhraseBuffsize -= ALLOCBLOCK;
|
|
ErrMsg(IDS_ERR_MEMORY, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL is_DBCS(UINT wWord)
|
|
{
|
|
#ifdef UNICODE
|
|
if(wWord < 0x0080)
|
|
return FALSE;
|
|
#else
|
|
if((LOBYTE(wWord) < 0x81) || (LOBYTE(wWord) > 0xFE))
|
|
return FALSE;
|
|
if((HIBYTE(wWord) < 0x40) || (HIBYTE(wWord) > 0xFE))
|
|
return FALSE;
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
void ErrMsg(UINT iMsgID, UINT iTitle)
|
|
{
|
|
TCHAR szErrStr[MAX_PATH];
|
|
TCHAR szTitle[MAX_PATH];
|
|
|
|
HideProgress(); // <== @E01
|
|
|
|
LoadString(hInst, iTitle, szTitle, sizeof(szTitle) / sizeof(TCHAR));
|
|
LoadString(hInst, iMsgID, szErrStr, sizeof(szErrStr) / sizeof(TCHAR));
|
|
MessageBox(NULL, szErrStr, (iTitle) ? szTitle : NULL, MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_TASKMODAL);
|
|
|
|
ShowProgress();// <== @E01
|
|
}
|
|
|
|
void ErrIOMsg(UINT iMsgID, TCHAR *szFileName)
|
|
{
|
|
TCHAR szErrStr[MAX_PATH];
|
|
TCHAR szShowMsg[MAX_PATH];
|
|
|
|
HideProgress();// <== @E01
|
|
|
|
LoadString(hInst, iMsgID, szErrStr, sizeof(szErrStr) / sizeof(TCHAR));
|
|
wsprintf(szShowMsg, szErrStr, szFileName);
|
|
MessageBox(NULL, szShowMsg, NULL, MB_OK | MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_TASKMODAL);
|
|
|
|
ShowProgress();// <== @E01
|
|
}
|
|
|
|
void MyFillMemory(TCHAR *dst, DWORD cnt, TCHAR v)
|
|
{
|
|
#ifdef UNICODE
|
|
DWORD i;
|
|
for(i = 0; i < cnt; i ++)
|
|
dst[i] = v;
|
|
#else
|
|
FillMemory(dst, cnt, v);
|
|
#endif
|
|
}
|