16,472
社区成员
发帖
与我相关
我的任务
分享
/************************************************************************
*
* CharHandler - WM_CHAR handler
*
************************************************************************/
void CharHandler( HWND hWnd, UINT wParam )
{
unsigned char ch = (unsigned char)wParam;
//
// Because DBCS characters are usually generated by IMEs (as two
// PostMessages), if a lead byte comes in, the trail byte should
// arrive very soon after. We wait here for the trail byte and
// store them into the text buffer together.
if ( IsDBCSLeadByte( ch ) ) {
//
// Wait an arbitrary amount of time for the trail byte to
// arrive. If it doesn't, then discard the lead byte.
//
// This could happen if the IME screwed up. Or, more likely,
// the user generated the lead byte through ALT-numpad.
//
MSG msg;
int i = 10;
while (!PeekMessage((LPMSG)&msg, hWnd, WM_CHAR, WM_CHAR, PM_REMOVE)) {
if ( --i == 0 )
return;
Yield();
}
StoreDBCSChar( hWnd, (WORD)(((unsigned)(msg.wParam)<<8) | (unsigned)ch ));
} else {
switch( ch )
{
case '\r':
case '\t':
case '\b':
//
// Throw away. Already handled at WM_KEYDOWN time.
//
break;
default:
StoreChar( hWnd, ch );
break;
}
}
}
/************************************************************************
*
* IsDBCSTrailByte - returns TRUE if the given byte is a DBCS trail byte
*
* The algorithm searchs backward in the string, to some
* known character boundary, counting consecutive bytes
* in the lead byte range. An odd number indicates the
* current byte is part of a two byte character code.
*
* INPUT: PCHAR - pointer to a preceding known character boundary.
* PCHAR - pointer to the character to test.
*
* OUTPUT:BOOL - indicating truth of p==trailbyte.
*
************************************************************************/
BOOL IsDBCSTrailByte( char *base, char *p )
{
int lbc = 0; // lead byte count
assert(base <= p);
while ( p > base ) {
if ( !IsDBCSLeadByte(*(--p)) )
break;
lbc++;
}
return (lbc & 1);
}
/************************************************************************
*
* StoreChar - Stores one SBCS character into text buffer and advances
* cursor
*
************************************************************************/
void StoreChar( HWND hWnd, BYTE ch )
{
int i;
HDC hdc;
//
// If insert mode, move rest of line to the right by one
//
if ( fInsertMode ) {
for ( i = LASTCOL; i > xPos; i-- )
textbuf[yPos][i] = textbuf[yPos][i-1];
//
// If the row ends on a lead byte, blank it out
// To do this we must first traverse the string
// starting from a known character boundry until
// we reach the last column. If the last column
// is a character boundry then the last character
// is either a single byte or a lead byte
//
for ( i = xPos+1; i < LASTCOL; ) {
if ( IsDBCSLeadByte( textbuf[yPos][i] ) )
i++;
i++;
}
if (i==LASTCOL)
if ( IsDBCSLeadByte( textbuf[yPos][LASTCOL] ) )
textbuf[yPos][LASTCOL] = ' ';
} else { // overtype mode
if ( IsDBCSLeadByte( textbuf[yPos][xPos] ) )
//
// Blank out trail byte
//
textbuf[yPos][xPos+1] = ' ';
//
// or shift line left on character and blank last column
//
// for ( i = xPos+1; i < LASTCOL; i++ )
// textbuf[yPos][i] = textbuf[yPos][i+1];
// textbuf[yPos][LASTCOL] = ' ';
}
//
// Store input character at current caret position
//
textbuf[yPos][xPos] = ch;
//
// Display input character.
//
hdc = GetDC( hWnd );
HideCaret( hWnd );
TextOut( hdc, xPos*cxMetrics, yPos*cyMetrics,
&(textbuf[yPos][xPos]), MAXCOL-xPos );
ShowCaret( hWnd );
ReleaseDC( hWnd, hdc );
SendMessage( hWnd, WM_KEYDOWN, VK_RIGHT, 1L );
}