📄 chnconv_dll.cpp
字号:
// chnconv_dll.cpp
#include <windows.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include "msc.h"
#include "cjkctype.h"
#include "cnvchar.h"
#include "codepage.h"
#include "gaiji.h"
#include "nls.h"
#include "res.h"
#include "storechr.h"
#include "stream.h"
#include "stringex.h"
#include "conv_err.h"
#include "chnconv.h"
#include "chnconv_cp.h"
#include "chnconv_dll.h"
#include "fontname.h"
#include "unicode.h"
#include "uninorm.h"
#include "unij2f.h"
#include "unif2j.h"
#include "conv_tbl.h"
#include "hkscs.h"
// for debug
#define DEBUG_MEMORY 0
static int nOsCodePage ; // OS偺僐乕僪儁乕僕
static volatile int IsAborted ;
static unsigned long nTlsIndex ;
static CRITICAL_SECTION LoadUser32Section ;
#define PEEK_MESSAGE_CONUT_MASK 0xFF
#define CP_DEFINE_CODEPAGE 0x0000FFFF // 僐乕僪儁乕僕偺掕媊
#define CP_DEFINE_PSEUDOCODE 0x00FF0000 // 媅帡拞崙岅偺掕媊
#define CP_DEFINE_OPTIONAL 0x0F000000 // 斏懱帤偺掕媊側偳
#define CP_DEFINE_FONT 0xF0000000 // 帤懱掕媊
#define CP_CHINESE_HZ ( CP_CHINESE_SIMPLIFIED + 0x100000 ) // old
#define CP_FANTI 0x08000000
#define CP_JAPANESE_CW_FANTI ( CP_JAPANESE_CW + CP_FANTI )
#define CP_JAPANESE_CWN_FANTI ( CP_JAPANESE_CWN + CP_FANTI )
#define CP_JAPANESE_NHP ( CP_JAPANESE_NH + 0x1000000 )
#define CP_JAPANESE_NH3P ( CP_JAPANESE_NH + 0x2000000 )
#define CP_GOTHIC 0x10000000
#if CP_JAPANESE_NHP & CP_FANTI || CP_JAPANESE_NH3P & CP_FANTI
#error Error: Codepage definition illegal 1
#endif
// RTF偺僼僅儞僩柤夝庍偱偺傒巊梡
#define CP_CHINESE_TRADITIONAL_HK ( CP_CHINESE_TRADITIONAL + 0x1000000 )
#if CP_CHINESE_TRADITIONAL_HK & CP_DEFINE_PSEUDOCODE || CP_CHINESE_TRADITIONAL_HK & CP_FANTI
#error Error: Codepage definition illegal 2
#endif
int InitChnconvData ( CHNCONVDATA *pData, int nSrcCodePage, int nDstCodePage, const CHNCONVEXINFO *pInfo ) ;
int InitConversionMode ( CHNCONVDATA *pData ) ;
int AllocWritingData ( CHNCONVDATA *pData, const CHNCONVEXINFO *pInfo ) ;
int FreeWritingData ( CHNCONVDATA *pData ) ;
int DoChnconv ( CHNCONVDATA *pData ) ;
int WriteFileStart ( CHNCONVDATA *pData ) ;
int WriteFileEnd ( CHNCONVDATA *pData ) ;
int GetCharSize ( int nCodePage ) ;
////////////////////////////////////////////
// CHNCONV.DLL 偺 LOAD 偍傛傃 FREE //
////////////////////////////////////////////
int WINAPI DllMain ( HINSTANCE hInst, unsigned long dwReason, void *pReserved ) {
if ( dwReason == DLL_PROCESS_ATTACH ) {
// LastError 梡偺僀儞僨僢僋僗傪妋曐
if ( ( nTlsIndex = TlsAlloc () ) == (unsigned long) -1 ) return FALSE ;
__try {
InitializeCriticalSection ( & LoadUser32Section ) ;
}
__except ( EXCEPTION_EXECUTE_HANDLER ) { return FALSE ; }
// 曄悢傪弶婜壔
nOsCodePage = GetACP () ;
// 儕僜乕僗偺僀儞僗僞儞僗傪弶婜壔
SetResourceInstance ( hInst ) ;
if ( DEBUG_MEMORY ) {
MessageBoxA ( NULL, "Debug Version", "CHNCONV.DLL", MB_OK ) ;
}
}
if ( dwReason == DLL_PROCESS_DETACH ) {
DeleteCriticalSection ( & LoadUser32Section ) ;
TlsFree ( nTlsIndex ) ;
}
return TRUE ;
}
////////////////////////////////////////////
// CHNCONV乮ANSI斉乯 //
////////////////////////////////////////////
// 惉岟偟偨偲偒偼 CONV_SUCCESS 傪曉偡
// 幐攕偟偨偲偒偼 CONV_ERROR_UNKNOWN 埲忋偺掕悢傪曉偡
int WINAPI ChnconvExA ( const char *szSrcFileName, const char *szDstFileName, int nSrcCodePage, int nDstCodePage, const CHNCONVEXINFO *pInfo ) {
int nError = CONV_ERROR_PARAM ;
IsAborted = 0 ;
if ( ! pInfo || pInfo->cbSize == sizeof(CHNCONVEXINFO) ) {
CHNCONVDATA Data = { 0 } ;
__try {
// 僨乕僞偺弶婜壔
if ( InitChnconvData ( & Data, nSrcCodePage, nDstCodePage, pInfo ) ) { nError = CONV_ERROR_PARAM ; goto CAUGHT_ERROR ; }
if ( AllocWritingData ( & Data, pInfo ) ) { nError = CONV_ERROR_MEMORY ; goto CAUGHT_ERROR ; }
if ( InitConversionMode ( & Data ) ) { nError = CONV_ERROR_CODEPAGE ; goto CAUGHT_ERROR ; }
// 擖椡僗僩儕乕儉傪奐偔
if ( ! ( Data.dwReserved & ( RESERVEDMODE_ONLY_START | RESERVEDMODE_ONLY_END ) ) ) {
Data.StreamIn = OpenFileStreamForReadingA ( szSrcFileName ) ;
if ( Data.StreamIn == NULL ) { nError = CONV_ERROR_READ ; goto CAUGHT_ERROR ; }
}
// 弌椡僗僩儕乕儉傪奐偔
Data.StreamOut = OpenFileStreamForWritingA ( szDstFileName ) ;
if ( Data.StreamOut == NULL ) { nError = CONV_ERROR_WRITE ; goto CAUGHT_ERROR ; }
// 幚峴
if ( Data.dwReserved & ( RESERVEDMODE_ONLY_START | RESERVEDMODE_ONLY_END ) ) {
if ( Data.dwReserved & RESERVEDMODE_ONLY_START ) nError = WriteFileStart ( & Data ) ;
else if ( Data.dwReserved & RESERVEDMODE_ONLY_END ) nError = WriteFileEnd ( & Data ) ;
}
else {
nError = DoChnconv ( & Data ) ;
}
CAUGHT_ERROR :;
}
__except ( EXCEPTION_EXECUTE_HANDLER ) { nError = CONV_ERROR_UNKNOWN ; }
// 僗僩儕乕儉傪暵偠傞
if ( Data.StreamIn && CloseStream ( Data.StreamIn, NULL ) && ! nError ) nError = CONV_ERROR_READ ;
if ( Data.StreamOut && CloseStream ( Data.StreamOut, NULL ) && ! nError ) nError = CONV_ERROR_WRITE ;
// 儊儌儕乕偺夝曻
FreeWritingData ( & Data ) ;
}
SetChnconvLastError ( nError ) ;
return nError ;
}
////////////////////////////////////////////
// CHNCONV乮UNICODE斉乯 //
////////////////////////////////////////////
// 惉岟偟偨偲偒偼 CONV_SUCCESS 傪曉偡
// 幐攕偟偨偲偒偼 CONV_ERROR_UNKNOWN 埲忋偺掕悢傪曉偡
int WINAPI ChnconvExW ( const wchar_t *szSrcFileName, const wchar_t *szDstFileName, int nSrcCodePage, int nDstCodePage, const CHNCONVEXINFO *pInfo ) {
int nError = CONV_ERROR_PARAM ;
IsAborted = 0 ;
if ( ! pInfo || pInfo->cbSize == sizeof(CHNCONVEXINFO) ) {
CHNCONVDATA Data = { 0 } ;
__try {
// 僨乕僞偺弶婜壔
if ( InitChnconvData ( & Data, nSrcCodePage, nDstCodePage, pInfo ) ) { nError = CONV_ERROR_PARAM ; goto CAUGHT_ERROR ; }
if ( AllocWritingData ( & Data, pInfo ) ) { nError = CONV_ERROR_MEMORY ; goto CAUGHT_ERROR ; }
if ( InitConversionMode ( & Data ) ) { nError = CONV_ERROR_CODEPAGE ; goto CAUGHT_ERROR ; }
// 擖椡僗僩儕乕儉傪奐偔
if ( ! ( Data.dwReserved & ( RESERVEDMODE_ONLY_START | RESERVEDMODE_ONLY_END ) ) ) {
Data.StreamIn = OpenFileStreamForReadingW ( szSrcFileName ) ;
if ( Data.StreamIn == NULL ) { nError = CONV_ERROR_READ ; goto CAUGHT_ERROR ; }
}
// 弌椡僗僩儕乕儉傪奐偔
Data.StreamOut = OpenFileStreamForWritingW ( szDstFileName ) ;
if ( Data.StreamOut == NULL ) { nError = CONV_ERROR_WRITE ; goto CAUGHT_ERROR ; }
// 幚峴
if ( Data.dwReserved & ( RESERVEDMODE_ONLY_START | RESERVEDMODE_ONLY_END ) ) {
if ( Data.dwReserved & RESERVEDMODE_ONLY_START ) nError = WriteFileStart ( & Data ) ;
else if ( Data.dwReserved & RESERVEDMODE_ONLY_END ) nError = WriteFileEnd ( & Data ) ;
}
else {
nError = DoChnconv ( & Data ) ;
}
CAUGHT_ERROR :;
}
__except ( EXCEPTION_EXECUTE_HANDLER ) { nError = CONV_ERROR_UNKNOWN ; }
// 僗僩儕乕儉傪暵偠傞
if ( Data.StreamIn && CloseStream ( Data.StreamIn, NULL ) && ! nError ) nError = CONV_ERROR_READ ;
if ( Data.StreamOut && CloseStream ( Data.StreamOut, NULL ) && ! nError ) nError = CONV_ERROR_WRITE ;
// 儊儌儕乕偺夝曻
FreeWritingData ( & Data ) ;
}
SetChnconvLastError ( nError ) ;
return nError ;
}
////////////////////////////////////////////
// CHNCONV for STRING //
////////////////////////////////////////////
// 惉岟偟偨偲偒偼 CONV_SUCCESS 傪曉偡
// 幐攕偟偨偲偒偼 CONV_ERROR_UNKNOWN 埲忋偺掕悢傪曉偡
intptr_t WINAPI ChnconvStringEx ( const char *szSrcBuffer, char *szDstBuffer, int nSrcCodePage, int nDstCodePage, const CHNCONVEXINFO *pInfo, size_t nMaxLen ) {
int nError = CONV_ERROR_PARAM ;
IsAborted = 0 ;
size_t nResultLen ;
if ( ! pInfo || pInfo->cbSize == sizeof(CHNCONVEXINFO) ) {
CHNCONVDATA Data = { 0 } ;
__try {
// 僨乕僞偺弶婜壔
if ( InitChnconvData ( & Data, nSrcCodePage, nDstCodePage, pInfo ) ) { nError = CONV_ERROR_PARAM ; goto CAUGHT_ERROR ; }
if ( AllocWritingData ( & Data, pInfo ) ) { nError = CONV_ERROR_MEMORY ; goto CAUGHT_ERROR ; }
if ( InitConversionMode ( & Data ) ) { nError = CONV_ERROR_CODEPAGE ; goto CAUGHT_ERROR ; }
// 擖椡僗僩儕乕儉傪奐偔
if ( ! ( Data.dwReserved & ( RESERVEDMODE_ONLY_START | RESERVEDMODE_ONLY_END ) ) ) {
Data.StreamIn = OpenStringStreamForReading ( szSrcBuffer, -1, GetCharSize ( nSrcCodePage ) ) ;
if ( Data.StreamIn == NULL ) { nError = CONV_ERROR_READ ; goto CAUGHT_ERROR ; }
}
// 弌椡僗僩儕乕儉傪奐偔
Data.StreamOut = OpenStringStreamForWriting ( szDstBuffer, nMaxLen, GetCharSize ( nDstCodePage ) ) ;
if ( Data.StreamOut == NULL ) { nError = CONV_ERROR_WRITE ; goto CAUGHT_ERROR ; }
// 幚峴
if ( Data.dwReserved & ( RESERVEDMODE_ONLY_START | RESERVEDMODE_ONLY_END ) ) {
if ( Data.dwReserved & RESERVEDMODE_ONLY_START ) nError = WriteFileStart ( & Data ) ;
else if ( Data.dwReserved & RESERVEDMODE_ONLY_END ) nError = WriteFileEnd ( & Data ) ;
}
else {
nError = DoChnconv ( & Data ) ;
}
CAUGHT_ERROR :;
}
__except ( EXCEPTION_EXECUTE_HANDLER ) { nError = CONV_ERROR_UNKNOWN ; }
// 僗僩儕乕儉傪暵偠傞
if ( Data.StreamIn && CloseStream ( Data.StreamIn, NULL ) && ! nError ) nError = CONV_ERROR_READ ;
if ( Data.StreamOut && CloseStream ( Data.StreamOut, & nResultLen ) && ! nError ) nError = CONV_ERROR_WRITE ;
// 儊儌儕乕偺夝曻
FreeWritingData ( & Data ) ;
}
SetChnconvLastError ( nError ) ;
if ( nError ) return -1 ;
return nResultLen ;
}
////////////////////////////////////////////
// 僼傽僀儖偺敾暿 //
////////////////////////////////////////////
int CompareFileStart ( STREAM *Stream, const char *szString ) ;
int ChnconvTxt ( CHNCONVDATA *pData ) ;
int ChnconvRtf ( CHNCONVDATA *pData ) ;
int Tm2rtfTxt ( CHNCONVDATA *pData ) ;
int Tm2rtfTec ( CHNCONVDATA *pData ) ;
int Fwen2rtf ( CHNCONVDATA *pData ) ;
int DoChnconv ( CHNCONVDATA *pData ) {
int nError ;
if ( pData->nSrcCodePage == CP_JAPANESE_FW ) return Fwen2rtf ( pData ) ;
if ( pData->nSrcCodePage == CP_JAPANESE_TM ) {
int IsTec = 0 ;
if ( pData->dwConversionMode & CONVMODE_CONVERT_TXT ) IsTec = 0 ;
else if ( pData->dwConversionMode & CONVMODE_CONVERT_RTF ) IsTec = 1 ;
else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -