⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbcsedit.c

📁 windows环境下的一套汉字处理引擎,可以对汉字进行相应的处理
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************
    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 + -