📄 dbcsedit.c
字号:
/**************************************************************************
Name:
DBCSEdit.c
Description:
Make the Edit Control to be DBCS enbale
Date:
1993 Oct. - 1993 Dec.
Created By:
Wang Zhidong
Last Modify:
Ma Hongfei, 1993 Dec.
Version:
1.10
Comments:
?????????????????????
**************************************************************************/
#include <windows.h>
#include <mate.h>
#define SWAPLONG(l) MAKELONG(HIWORD(l),LOWORD(l))
int bMouseDown=0;
FARPROC fpOldEditProc = NULL;
FARPROC fpOldWordBreakProc = NULL;
BOOL bErrorFlag = FALSE;
BOOL bSetFlag = FALSE;
char szClass[8];
extern HANDLE hInst;
extern int bCWinVer;
extern char szEdit[];
extern char szNoEnter[];
extern char szNewEditer[];
BOOL IsBeforeHanzi (HWND, int );
BOOL IsBetweenHanzi (HWND);
BOOL IsStartBetweenHanzi ( HWND );
BOOL IsAfterHanzi (HWND, int );
DWORD GetWordPos (HWND);
// added by Ma: 12/04/93
void CalculateLine ( FARPROC, HWND, long, long, RECT FAR * );
BOOL CheckLine ( FARPROC, HWND, long );
int WINAPI WordBreakProc (LPSTR, short, short, WORD);
// *************************************************************************************
// Function Name : DWORD GetWordPos ( HWND hWnd )
// Parameter:
// HWND hWnd: Handle of edit control window
// Return Value:
// selected area of word
// Function:
// To get selected area of word which current caret position pointed
// *************************************************************************************
DWORD GetWordPos ( HWND hWnd )
{
HANDLE hBuf;
LPSTR lpBuf;
UINT nLineNum, nLineLength, nLineStartCharPos;
long lPosition;
// Get Current Selected area Position
lPosition = CallWindowProc ( fpOldEditProc, hWnd, EM_GETSEL, 0, 0L);
if ( LOWORD ( lPosition ) != HIWORD ( lPosition ))
return lPosition; // if selected area exist, only return it
/* The following is to check position of selected area is after one hanzi or not */
nLineNum = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEFROMCHAR, LOWORD ( lPosition ), 0L );
nLineStartCharPos = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEINDEX, nLineNum, 0L);
nLineLength = CallWindowProc ( fpOldEditProc, hWnd, EM_LINELENGTH, nLineStartCharPos, 0L );
// if selected position is out of line, only return it
if ( LOWORD ( lPosition ) > nLineStartCharPos + nLineLength ) return lPosition;
// Alloc Buffer for EM_GETLINE
if (( hBuf = LocalAlloc ( LHND, nLineLength+2 )) == NULL )
{
bErrorFlag = TRUE;
return lPosition;
}
if (( lpBuf = LocalLock ( hBuf )) == NULL )
{
bErrorFlag = TRUE;
LocalFree ( hBuf );
return lPosition;
}
// read from Edit Buffer
* ( int FAR * ) lpBuf = nLineLength;
CallWindowProc (fpOldEditProc, hWnd, EM_GETLINE, nLineNum, ( DWORD ) lpBuf );
// check if position is at not last hanzi
if ( LOWORD ( lPosition ) <= nLineStartCharPos + nLineLength - 2
&& AnsiNext ( lpBuf + LOWORD ( lPosition ) - nLineStartCharPos ) == lpBuf + LOWORD ( lPosition ) - nLineStartCharPos + 2 )
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return lPosition + 0x20000;
}
// check if position is at end of last hanzi
if ( LOWORD ( lPosition ) == nLineStartCharPos + nLineLength
&& AnsiPrev ( lpBuf, lpBuf + LOWORD ( lPosition ) - nLineStartCharPos ) == lpBuf + LOWORD ( lPosition ) - nLineStartCharPos - 2 )
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return lPosition - 2;
}
// check for english word end pos
while ( HIWORD ( lPosition ) < nLineStartCharPos + nLineLength )
{
char cTmpCh = * ( lpBuf + HIWORD ( lPosition ) - nLineStartCharPos );
if ( cTmpCh == ' ' || cTmpCh == '\t' || cTmpCh == '\r' || cTmpCh == '\n' || IsDBCSLeadByte ( cTmpCh ) )
break;
lPosition += 0x10000;
}
// check for english word start pos
while ( LOWORD ( lPosition ) >= nLineStartCharPos )
{
char cTmpCh = * ( lpBuf + LOWORD ( lPosition ) - nLineStartCharPos );
if ( cTmpCh == ' ' || cTmpCh == '\t' || cTmpCh == '\r' || cTmpCh == '\n' || IsDBCSLeadByte ( cTmpCh ) )
break;
lPosition --;
}
// Free all alloc memory
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return lPosition + 1;
}
// *************************************************************************************
// Function Name : BOOL IsBeforeHanzi ( HWND hWnd, int Direction )
// Parameter:
// HWND hWnd: Handle of edit control window
// int Direction :
// > 0 : Check End position of selected area is before one hanzi or not ?
// == 0 : Check current position is before one hanzi or not ? ( no selected area )
// < 0 : Check Start position of selected area is before one hanzi or not ?
// Return Value:
// TRUE : yes
// FALSE : not
// Function:
// To Check current position or position of selected area is before one hanzi or not ?
// *************************************************************************************
BOOL IsBeforeHanzi ( HWND hWnd, int Direction )
{
HANDLE hBuf;
LPSTR lpBuf;
UINT nLineNum, nLineLength, nLineStartCharPos;
long lPosition;
// Get Current Selected area Position
lPosition = CallWindowProc ( fpOldEditProc, hWnd, EM_GETSEL, 0, 0L);
if ( ! Direction && LOWORD ( lPosition ) != HIWORD ( lPosition ))
return FALSE;
if ( Direction > 0 ) // Process End position of selected area
lPosition = SWAPLONG ( lPosition );
// else process start position of selected area
/* The following is to check position of selected area is after one hanzi or not */
nLineNum = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEFROMCHAR, LOWORD ( lPosition ), 0L );
nLineStartCharPos = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEINDEX, nLineNum, 0L);
nLineLength = CallWindowProc ( fpOldEditProc, hWnd, EM_LINELENGTH, nLineStartCharPos, 0L );
// Alloc Buffer for EM_GETLINE
if (( hBuf = LocalAlloc ( LHND, nLineLength+2 )) == NULL )
{
bErrorFlag = TRUE;
return FALSE;
}
if (( lpBuf = LocalLock ( hBuf )) == NULL )
{
bErrorFlag = TRUE;
LocalFree ( hBuf );
return FALSE;
}
// read from Edit Buffer
* ( int FAR * ) lpBuf = nLineLength;
CallWindowProc (fpOldEditProc, hWnd, EM_GETLINE, nLineNum, ( DWORD ) lpBuf );
// check
if ( AnsiNext ( lpBuf + LOWORD ( lPosition ) - nLineStartCharPos ) == lpBuf + LOWORD ( lPosition ) - nLineStartCharPos + 2 )
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return TRUE; // it is between two part of one hanzi
}
else
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return FALSE;
}
}
// *************************************************************************************
// Function Name : BOOL IsBetweenHanzi ( HWND hWnd )
// Parameter:
// HWND hWnd: Handle of edit control window
// Return Value:
// TRUE : yes
// FALSE : not
// Function:
// To Check current position or position of selected area is between one hanzi or not ?
// *************************************************************************************
BOOL IsBetweenHanzi ( HWND hWnd )
{
HANDLE hBuf;
LPSTR lpBuf;
UINT nLineNum, nLineLength, nLineStartCharPos;
long lPosition;
// Get Current Selected area Position
lPosition = CallWindowProc ( fpOldEditProc, hWnd, EM_GETSEL, 0, 0L);
/* The following is to check start position of selected area is between two part of one hanzi or not */
nLineNum = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEFROMCHAR, LOWORD ( lPosition ), 0L );
nLineStartCharPos = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEINDEX, nLineNum, 0L);
nLineLength = CallWindowProc ( fpOldEditProc, hWnd, EM_LINELENGTH, nLineStartCharPos, 0L );
// Start Position is not between in two part of one hanzi
if ( LOWORD ( lPosition ) >= nLineStartCharPos + nLineLength )
return FALSE;
// Alloc Buffer for EM_GETLINE
if (( hBuf = LocalAlloc ( LHND, nLineLength+2 )) == NULL )
{
bErrorFlag = TRUE;
return FALSE;
}
if (( lpBuf = LocalLock ( hBuf )) == NULL )
{
bErrorFlag = TRUE;
LocalFree ( hBuf );
return FALSE;
}
// read from Edit Buffer
* ( int FAR * ) lpBuf = nLineLength;
CallWindowProc (fpOldEditProc, hWnd, EM_GETLINE, nLineNum, ( DWORD ) lpBuf );
// check
if ( AnsiNext (AnsiPrev (lpBuf, lpBuf + LOWORD ( lPosition ) - nLineStartCharPos )) != lpBuf + LOWORD ( lPosition ) - nLineStartCharPos )
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return TRUE; // it is between two part of one hanzi
}
if ( LOWORD ( lPosition ) == HIWORD ( lPosition ))
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return FALSE; // no, it isn't between two part of one hanzi
}
// Unlock it
LocalUnlock ( hBuf );
LocalFree ( hBuf );
/* Check for end position of selected area is between two part of one hanzi or not */
nLineNum = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEFROMCHAR, HIWORD ( lPosition ), 0L );
nLineStartCharPos = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEINDEX, nLineNum, 0L);
nLineLength = CallWindowProc ( fpOldEditProc, hWnd, EM_LINELENGTH, nLineStartCharPos, 0L );
// Alloc Buffer for EM_GETLINE
if (( hBuf = LocalAlloc ( LHND, nLineLength+2 )) == NULL )
{
bErrorFlag = TRUE;
return FALSE;
}
if (( lpBuf = LocalLock ( hBuf )) == NULL )
{
bErrorFlag = TRUE;
LocalFree ( hBuf );
return FALSE;
}
// read from Edit Buffer
* ( int FAR * ) lpBuf = nLineLength;
CallWindowProc (fpOldEditProc, hWnd, EM_GETLINE, nLineNum, ( DWORD ) lpBuf );
// check
if ( AnsiNext ( AnsiPrev ( lpBuf, lpBuf + HIWORD ( lPosition ) - nLineStartCharPos )) == lpBuf + HIWORD ( lPosition ) - nLineStartCharPos )
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return FALSE;
}
else
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return TRUE;
}
}
// *************************************************************************************
// Function Name : BOOL IsStartBetweenHanzi ( HWND hWnd )
// Parameter:
// HWND hWnd: Handle of edit control window
// int Direction :
// Return Value:
// TRUE : yes
// FALSE : not
// Function:
// To Check start position of selected area is between one hanzi or not ?
// *************************************************************************************
BOOL IsStartBetweenHanzi ( HWND hWnd )
{
HANDLE hBuf;
LPSTR lpBuf;
UINT nLineNum, nLineLength, nLineStartCharPos;
long lPosition;
// Get Current Selected area Position
lPosition = CallWindowProc ( fpOldEditProc, hWnd, EM_GETSEL, 0, 0L);
/* The following is to check start position of selected area is between two part of one hanzi or not */
nLineNum = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEFROMCHAR, LOWORD ( lPosition ), 0L );
nLineStartCharPos = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEINDEX, nLineNum, 0L);
nLineLength = CallWindowProc ( fpOldEditProc, hWnd, EM_LINELENGTH, nLineStartCharPos, 0L );
// Start Position is not between in two part of one hanzi
if ( LOWORD ( lPosition ) >= nLineStartCharPos + nLineLength )
return FALSE;
// Alloc Buffer for EM_GETLINE
if (( hBuf = LocalAlloc ( LHND, nLineLength+2 )) == NULL )
{
bErrorFlag = TRUE;
return FALSE;
}
if (( lpBuf = LocalLock ( hBuf )) == NULL )
{
bErrorFlag = TRUE;
LocalFree ( hBuf );
return FALSE;
}
// read from Edit Buffer
* ( int FAR * ) lpBuf = nLineLength;
CallWindowProc (fpOldEditProc, hWnd, EM_GETLINE, nLineNum, ( DWORD ) lpBuf );
// check
if ( AnsiNext (AnsiPrev (lpBuf, lpBuf + LOWORD ( lPosition ) - nLineStartCharPos )) != lpBuf + LOWORD ( lPosition ) - nLineStartCharPos )
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return TRUE; // it is between two part of one hanzi
}
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return FALSE; // no, it isn't between two part of one hanzi
}
// *************************************************************************************
// Function Name : BOOL IsAfterHanzi ( HWND hWnd, int Direction )
// Parameter:
// HWND hWnd: Handle of edit control window
// int Direction :
// > 0 : Check End position of selected area is after one hanzi or not ?
// == 0 : Check current position is after one hanzi or not ? ( no selected area )
// < 0 : Check Start position of selected area is after one hanzi or not ?
// Return Value:
// TRUE : yes
// FALSE : not
// Function:
// To Check current position or position of selected area is after one hanzi or not ?
// *************************************************************************************
BOOL IsAfterHanzi( HWND hWnd, int Direction )
{
HANDLE hBuf;
LPSTR lpBuf;
UINT nLineNum, nLineLength, nLineStartCharPos;
long lPosition;
// Get Current Selected area Position
lPosition = CallWindowProc ( fpOldEditProc, hWnd, EM_GETSEL, 0, 0L);
if ( ! Direction && LOWORD ( lPosition ) != HIWORD ( lPosition ))
return FALSE;
if ( Direction > 0 ) // Process End position of selected area
lPosition = SWAPLONG ( lPosition );
// else process start position of selected area
/* The following is to check position of selected area is after one hanzi or not */
nLineNum = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEFROMCHAR, LOWORD ( lPosition ), 0L );
nLineStartCharPos = CallWindowProc ( fpOldEditProc, hWnd, EM_LINEINDEX, nLineNum, 0L);
nLineLength = CallWindowProc ( fpOldEditProc, hWnd, EM_LINELENGTH, nLineStartCharPos, 0L );
// Alloc Buffer for EM_GETLINE
if (( hBuf = LocalAlloc ( LHND, nLineLength+2 )) == NULL )
{
bErrorFlag = TRUE;
return FALSE;
}
if (( lpBuf = LocalLock ( hBuf )) == NULL )
{
bErrorFlag = TRUE;
LocalFree ( hBuf );
return FALSE;
}
// read from Edit Buffer
* ( int FAR * ) lpBuf = nLineLength;
CallWindowProc (fpOldEditProc, hWnd, EM_GETLINE, nLineNum, ( DWORD ) lpBuf );
// check
if ( AnsiPrev (lpBuf, lpBuf + LOWORD ( lPosition ) - nLineStartCharPos ) == lpBuf + LOWORD ( lPosition ) - nLineStartCharPos - 2 )
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return TRUE; // it is between two part of one hanzi
}
else
{
LocalUnlock ( hBuf );
LocalFree ( hBuf );
return FALSE;
}
}
long WINAPI EditProc ( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
static int xMousePos, xLastPos;
long ldat;
// POINT pts;
// MSG msg;
HDC hDC;
NPTEXTMETRIC ptm;
switch(message){
case WM_CREATE:
// added by MA: 12/03/93
{
HANDLE hMem;
hMem = GlobalAlloc ( GHND, 100 );
SetProp ( hWnd, szNoEnter, hMem );
}
PostMessage (hWnd, EM_SETWORDBREAKPROC, NULL,
(LPARAM)(FARPROC)WordBreakProc);
// (DWORD)lpprocWordBreak);
break;
case WM_DESTROY:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -