|
|
#include "hwxobj.h"
#include "memmgr.h"
#include "resource.h"
#include "hwxfe.h"
#include "dbg.h"
#include "cmnhdr.h"
#ifdef UNDER_CE // Windows CE Stub for unsupported APIs
#include "stub_ce.h"
#endif // UNDER_CE
#ifdef FE_JAPANESE
// for character comment
BOOL FGetFarEastInfo(HWXRESULTPRI *pResult, DWORD *pdwID, LPIMEFAREASTINFO *ppInfo); #endif
// implementation of CHwxMB
CHwxMB::CHwxMB(CHwxInkWindow * pInk,HINSTANCE hInst):CHwxObject(hInst) { m_pInk = pInk; m_pCHwxThreadMB = NULL; m_pCHwxStroke = NULL; m_hMBWnd = NULL; // m_hInstance = hInst;
SetRect(&m_clipRect,0,0,0,0); m_ptClient.x = m_ptClient.y = 0; #ifdef FE_CHINESE_SIMPLIFIED
m_CurrentMask = m_lastMaskSent = ALC_CHS_EXTENDED; #else
m_CurrentMask = m_lastMaskSent = ALC_JPN_EXTENDED; #endif
m_lastCharSent = INVALID_CHAR; memset(m_Context, '\0', sizeof(m_Context)); m_bHiPri = FALSE; if ( pInk ) m_boxSize = (USHORT)pInk->GetMBHeight(); else m_boxSize = PadWnd_Height;
m_bDown = FALSE; m_bRightClick = FALSE; m_bNoInk = TRUE; m_cLogicalBox = 0; m_curBox = TOTALLOGICALBOX; m_iBoxPrev = TOTALLOGICALBOX; m_hdcMouse = NULL;
m_hCursor = LoadCursor(NULL,IDC_ARROW); m_bResize = FALSE; m_firstX = 0;
m_bTimerStarted = FALSE; m_timeoutValue = 0; m_pImeStringCandidate = NULL; m_pImeStringCandidateInfo = NULL; m_bErase = FALSE; } CHwxMB::~CHwxMB() { m_pInk = NULL; // m_hInstance = NULL;
if ( m_hMBWnd ) { DestroyWindow(m_hMBWnd); m_hMBWnd = NULL; } if ( m_pCHwxThreadMB ) { delete m_pCHwxThreadMB; m_pCHwxThreadMB = NULL; } if ( m_pCHwxStroke ) { delete m_pCHwxStroke; m_pCHwxStroke = NULL; } if ( m_pImeStringCandidate ) { MemFree((void *)m_pImeStringCandidate); m_pImeStringCandidate = NULL; } if ( m_pImeStringCandidateInfo ) { MemFree((void *)m_pImeStringCandidateInfo); m_pImeStringCandidateInfo = NULL; } }
BOOL CHwxMB::Initialize(TCHAR * pClsName) { BOOL bRet = CHwxObject::Initialize(pClsName); if ( bRet ) { WNDCLASS wndClass; wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = MBWndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = sizeof(void *); wndClass.hInstance = m_hInstance; wndClass.hIcon = 0; wndClass.hCursor = LoadCursor(NULL,MAKEINTRESOURCE(32631)); #ifndef UNDER_CE
wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE+1); #else // UNDER_CE
wndClass.hbrBackground = GetSysColorBrush(COLOR_3DFACE); #endif // UNDER_CE
wndClass.lpszMenuName = NULL; wndClass.lpszClassName = TEXT("WPad");
RegisterClass(&wndClass);
int tmpSize = sizeof(IMESTRINGCANDIDATE) + MB_NUM_CANDIDATES * sizeof(LPWSTR); m_pImeStringCandidate = (LPIMESTRINGCANDIDATE)MemAlloc(tmpSize); if ( !m_pImeStringCandidate ) { return FALSE; } tmpSize = sizeof(IMESTRINGCANDIDATEINFO) + MB_NUM_CANDIDATES * sizeof(LPWSTR); m_pImeStringCandidateInfo = (LPIMESTRINGCANDIDATEINFO)MemAlloc(tmpSize); if ( !m_pImeStringCandidateInfo ) { return FALSE; } m_pCHwxThreadMB = new CHwxThreadMB(this,m_boxSize); if ( !m_pCHwxThreadMB ) { MemFree((void *)m_pImeStringCandidate); m_pImeStringCandidate = NULL; MemFree((void *)m_pImeStringCandidateInfo); m_pImeStringCandidateInfo = NULL; return FALSE; } m_pCHwxStroke = new CHwxStroke(TRUE,32); if ( !m_pCHwxStroke ) { MemFree((void *)m_pImeStringCandidate); m_pImeStringCandidate = NULL; MemFree((void *)m_pImeStringCandidateInfo); m_pImeStringCandidateInfo = NULL; delete m_pCHwxThreadMB; m_pCHwxThreadMB = NULL; return FALSE; }
bRet = m_pCHwxThreadMB->Initialize(TEXT("CHwxThreadMB")); if ( !bRet ) { MemFree((void *)m_pImeStringCandidate); m_pImeStringCandidate = NULL; MemFree((void *)m_pImeStringCandidateInfo); m_pImeStringCandidateInfo = NULL; delete m_pCHwxThreadMB; m_pCHwxThreadMB = NULL; delete m_pCHwxStroke; m_pCHwxStroke = NULL; return FALSE; } bRet = m_pCHwxStroke->Initialize(TEXT("CHwxStrokeMB")); if ( !bRet ) { MemFree((void *)m_pImeStringCandidate); m_pImeStringCandidate = NULL; MemFree((void *)m_pImeStringCandidateInfo); m_pImeStringCandidateInfo = NULL; delete m_pCHwxThreadMB; m_pCHwxThreadMB = NULL; delete m_pCHwxStroke; m_pCHwxStroke = NULL; return FALSE; } } return bRet; }
BOOL CHwxMB::CreateUI(HWND hwnd) { m_hMBWnd = CreateWindowEx( 0, TEXT("WPad"), TEXT(""), WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)IDC_MBINPUT, //980706:for #1624. for "?" help
m_hInstance, this); if( !m_hMBWnd ) { return FALSE; } return TRUE; }
void CHwxMB::HandlePaint(HWND hwnd) { int x, i; RECT rc; HBRUSH hbr, hbrOld; int mbWidth = m_pInk->GetMBWidth(); int mbHeight = m_pInk->GetMBHeight(); int numBoxes = m_pInk->GetMBBoxNumber();
// Erase the whole thing first
//
PAINTSTRUCT ps; BeginPaint(hwnd, &ps);
if ( ps.fErase ) { rc.left = rc.top = 0; rc.right = mbWidth; rc.bottom = Box_Border; #ifndef UNDER_CE
FillRect(ps.hdc,&rc,(HBRUSH)(COLOR_3DFACE+1)); #else // UNDER_CE
FillRect(ps.hdc,&rc,GetSysColorBrush(COLOR_3DFACE)); #endif // UNDER_CE
rc.left = 0; rc.top = mbHeight - Box_Border; rc.right = mbWidth; rc.bottom = mbHeight; #ifndef UNDER_CE
FillRect(ps.hdc,&rc,(HBRUSH)(COLOR_3DFACE+1)); #else // UNDER_CE
FillRect(ps.hdc,&rc,GetSysColorBrush(COLOR_3DFACE)); #endif // UNDER_CE
x = 0; for ( i = 0; i < numBoxes; i++) { rc.left = x; rc.top = Box_Border; rc.right = rc.left + Box_Border; rc.bottom = mbHeight - Box_Border; #ifndef UNDER_CE
FillRect(ps.hdc,&rc,(HBRUSH)(COLOR_3DFACE+1)); #else // UNDER_CE
FillRect(ps.hdc,&rc,GetSysColorBrush(COLOR_3DFACE)); #endif // UNDER_CE
rc.left = x + m_boxSize - Box_Border; rc.top = Box_Border; rc.right = rc.left + Box_Border; rc.bottom = mbHeight - Box_Border; #ifndef UNDER_CE
FillRect(ps.hdc,&rc,(HBRUSH)(COLOR_3DFACE+1)); #else // UNDER_CE
FillRect(ps.hdc,&rc,GetSysColorBrush(COLOR_3DFACE)); #endif // UNDER_CE
x += m_boxSize; } }
// Draw all the boxes.
//
//----------------------------------------------------------------
//980803:ToshiaK merge with PRC
//use COLOR_WINDOW instead of WHITE_BRUSH
//----------------------------------------------------------------
hbr = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW)); hbrOld = (HBRUSH)::SelectObject(ps.hdc, hbr); x = 0; for (i=0; i < numBoxes; i++) { Rectangle(ps.hdc, x+Box_Border, Box_Border, x+m_boxSize-Box_Border, m_boxSize-Box_Border); rc.top = Box_Border; rc.left= x+Box_Border; rc.right=x+m_boxSize-Box_Border; rc.bottom=m_boxSize-Box_Border; DrawEdge(ps.hdc,&rc,EDGE_SUNKEN,BF_RECT); m_pInk->DrawHwxGuide(ps.hdc,&rc); x += m_boxSize; } m_iBoxPrev = TOTALLOGICALBOX;
//
// Redraw the current character.
//
m_pCHwxStroke->DrawStroke(ps.hdc,0,TRUE); ::SelectObject(ps.hdc, hbrOld); ::DeleteObject(hbr); //980803:ToshiaK.PRC merge
EndPaint(hwnd, &ps); }
BOOL CHwxMB::IsInInkBox(PPOINT ppt) { int iBox = ppt->x / m_boxSize; POINT pt = *ppt; RECT rc; rc.left = iBox*m_boxSize + Box_Border; rc.top = Box_Border; rc.right = rc.left + m_boxSize - 2*Box_Border; rc.bottom = m_boxSize - Box_Border; return PtInRect(&rc,pt); }
BOOL CHwxMB::IsPointInResizeBox(PPOINT ppt) {
int iBox = (ppt->x-1) / m_boxSize; int numBox = m_pInk->GetMBBoxNumber(); if ( numBox == ( iBox + 1) ) return FALSE; POINT pt = *ppt; RECT rc; rc.left = (iBox+1)*m_boxSize - Box_Border; rc.top = Box_Border + 2; rc.right = rc.left + 2*Box_Border; rc.bottom = m_boxSize - Box_Border - 2; return PtInRect(&rc,pt); }
void CHwxMB::recognize(void) { PostThreadMessage(m_pCHwxThreadMB->GetID() , THRDMSG_RECOGNIZE, (WPARAM)m_cLogicalBox, (LONG) 0); m_cLogicalBox = 0; }
void CHwxMB::SetLogicalBox(int iBox) { if (iBox != m_curBox) // Are we in a new box ?
{ //
// We need to blow away the strokes we saved for redrawing the screen
//
m_pCHwxStroke->DeleteAllStroke(); if (iBox == TOTALLOGICALBOX) // If the new box is TOTALLOGICALBOX we need to recognize everything.
{ recognize(); } else { m_cLogicalBox++; } } }
void CHwxMB::SetContext() { if (m_lastMaskSent != m_CurrentMask) { PostThreadMessage(m_pCHwxThreadMB->GetID(), THRDMSG_SETMASK, (WPARAM) m_CurrentMask, 0);
m_lastMaskSent = m_CurrentMask; } WCHAR wch = 0x0000; memset(m_Context, '\0', sizeof(m_Context)); if ( S_OK == ((m_pInk->GetAppletPtr())->GetIImePad())->Request(m_pInk->GetAppletPtr(),IMEPADREQ_GETCOMPOSITIONSTRING,(WPARAM)m_Context,100) && (wch = findLastContext()) ) { if (m_lastCharSent != wch ) {
PostThreadMessage(m_pCHwxThreadMB->GetID(), THRDMSG_SETCONTEXT, (WPARAM)wch, 0);
m_lastCharSent = wch; } } else { if (m_lastCharSent != INVALID_CHAR) { PostThreadMessage(m_pCHwxThreadMB->GetID(), THRDMSG_SETCONTEXT, (WPARAM) INVALID_CHAR, 0);
m_lastCharSent = INVALID_CHAR; } } }
void CHwxMB::DrawMBInkBox(HDC hdc, WORD iBox) { RECT rc; HBRUSH hbr = ::CreateSolidBrush(::GetSysColor(COLOR_WINDOW)); HBRUSH hbrOld = (HBRUSH)SelectObject(hdc, hbr); PatBlt(hdc, (m_boxSize * iBox) + Box_Border, Box_Border, m_boxSize-Box_Border*2, m_boxSize-Box_Border*2, PATCOPY); rc.left = (m_boxSize * iBox) + Box_Border; rc.top = Box_Border; rc.right = m_boxSize * (1 + iBox) - Box_Border; rc.bottom = m_boxSize - Box_Border; DrawEdge(hdc,&rc,EDGE_SUNKEN,BF_RECT); m_pInk->DrawHwxGuide(hdc,&rc); SelectObject(hdc, hbrOld); ::DeleteObject(hbr); }
BOOL CHwxMB::HandleMouseEvent(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) { POINT pt; POINT ptTmp; int x,y; int iBox,len; //----------------------------------------------------------------
//Satori #2763.
//must cast (short) first.
//pt.x = (unsigned short)LOWORD(lp);
//pt.y = (unsigned short)HIWORD(lp);
//----------------------------------------------------------------
pt.x = (LONG)(short)LOWORD(lp); pt.y = (LONG)(short)HIWORD(lp);
#ifdef UNDER_CE // LBUTTON + ALT key handling
//Standard way for RBUTTON handling is combination w/ LBUTTON + ALT key
if(msg == WM_LBUTTONDOWN){ if(GetAsyncKeyState(VK_MENU)) msg = WM_RBUTTONDOWN; } else if(msg == WM_LBUTTONUP){ if(GetAsyncKeyState(VK_MENU)) msg = WM_RBUTTONUP; } #endif // UNDER_CE
switch (msg) { case WM_LBUTTONDBLCLK: case WM_LBUTTONDOWN: { // Pump up our thread priority by 1 level
if ( !m_bDown && IsInInkBox(&pt) && !m_bResize ) { if ( m_bRightClick ) return TRUE; if (!m_bHiPri) { SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL); m_bHiPri = TRUE; }
if (m_bTimerStarted) { KillTimer(hwnd, TIMER_ID); m_bTimerStarted = FALSE; }
SetCapture(hwnd);
m_bDown = TRUE;
// Now possibly sending the previous ink to the recognizer
// and closing any open alt-lists.
iBox = pt.x / m_boxSize; SetLogicalBox(iBox); m_bErase = FALSE;
// Setup the clipRect and region for the DC if it's
// not already set up.
if (m_hdcMouse == NULL) { m_hdcMouse = GetDC(hwnd); }
if (iBox != m_curBox) { m_clipRect.left = iBox*m_boxSize + Box_Border; m_clipRect.top = Box_Border; m_clipRect.right = m_clipRect.left + m_boxSize - 2*Box_Border; m_clipRect.bottom = m_boxSize - Box_Border;
// adjust clip rectangle to have ink staying in the box
//990602:for KOTAE #818
m_clipRect.left += 2; m_clipRect.top += 2; m_clipRect.right -= 2; m_clipRect.bottom -= 2;
#if 0 //OLD code
m_clipRect.left += 1; m_clipRect.top += 1; m_clipRect.right -= 1; m_clipRect.bottom -= 1; #endif
}
if (pt.x < m_clipRect.left) { pt.x = m_clipRect.left; } else if (pt.x >= m_clipRect.right) { pt.x = m_clipRect.right - 1; }
if (pt.y < m_clipRect.top) { pt.y = m_clipRect.top ; } else if (pt.y >= m_clipRect.bottom) { pt.y = m_clipRect.bottom - 1; }
// Get the offset to the window so we can convert the
// screen points to window points without doing a call on each one.
if ( m_pCHwxStroke->AddPoint(pt) ) { m_ptClient.x = m_ptClient.y = 0; ScreenToClient(hwnd, &(m_ptClient));
// Save away the current and previous box info.
m_iBoxPrev = m_curBox; m_curBox = (USHORT)iBox;
return TRUE; } else return FALSE; } else if (IsPointInResizeBox(&pt)) { if ( !m_bResize ) { SetCapture(hwnd); m_bResize = TRUE; m_firstX = pt.x; ptTmp = pt; ClientToScreen(hwnd,&ptTmp); SetCursorPos(ptTmp.x,ptTmp.y); if ( GetStrokeCount() ) { HandleUserMessage(hwnd,MB_WM_ERASE,0,0); } } return TRUE; } break; }
case WM_LBUTTONUP: { if (m_bDown) { m_bDown = FALSE; x = (short)pt.x; y = (short)pt.y;
if (x < m_clipRect.left) { pt.x = m_clipRect.left; } else if (x >= m_clipRect.right) { pt.x = m_clipRect.right - 1; }
if (y < m_clipRect.top) { pt.y = m_clipRect.top; } else if (y >= m_clipRect.bottom) { pt.y = m_clipRect.bottom - 1; } m_pCHwxStroke->AddPoint(pt);
ReleaseCapture();
m_pCHwxStroke->AddBoxStroke(m_cLogicalBox-1,m_curBox,m_boxSize);
if (m_bNoInk) { m_bNoInk = FALSE;
//
// First Stroke in the box is done, set the context info now.
//
SetContext(); }
//
// Send the Recognizer stroke off.
//
PSTROKE pstRecog = m_pCHwxStroke->CopyCurrentStroke(); if ( pstRecog ) //----------------------------------------------------------------
//00/07/03: Hail pointed out.
//for Win64. (LPARAM) is better than LONG_PTR.
//LONG_PTR is not defined in VC6(only Platform SDK)
//----------------------------------------------------------------
PostThreadMessage(m_pCHwxThreadMB->GetID(), THRDMSG_ADDINK, (WPARAM)m_boxSize, (LPARAM)pstRecog); //
// Erase the old ink, we have a tiny slice of time before the next
// stroke can begin.
//
if ((m_curBox != m_iBoxPrev) && (m_iBoxPrev != TOTALLOGICALBOX)) { DrawMBInkBox(m_hdcMouse, m_iBoxPrev); m_iBoxPrev = TOTALLOGICALBOX; }
// Now start timer
//
// If timeout value is 0, it means no timeout. Don't
// start timer
if( m_timeoutValue ) { SetTimer(hwnd, TIMER_ID, m_timeoutValue, NULL); m_bTimerStarted = TRUE; }
return TRUE; } else if (IsPointInResizeBox(&pt)) { if ( m_bResize ) { len = pt.x - m_firstX; iBox = (m_firstX-4) / m_boxSize; m_boxSize += (USHORT)len; m_boxSize = (USHORT)(m_boxSize > INKBOXSIZE_MIN ? m_boxSize : INKBOXSIZE_MIN); m_pInk->SetMBHeight(m_boxSize); ptTmp.x = (iBox + 1) * m_boxSize; ptTmp.y = pt.y; ClientToScreen(hwnd,&ptTmp); SetCursorPos(ptTmp.x,ptTmp.y); m_firstX = (iBox+1) * m_boxSize; m_pInk->ChangeIMEPADSize(FALSE); m_pInk->ChangeLayout(FALSE); ReleaseCapture(); m_bResize = FALSE; UpdateWindow(GetParent(m_pInk->GetInkWindow())); UpdateWindow(m_pInk->GetInkWindow()); return TRUE; } } else { if ( m_bResize ) { if ( hwnd == GetCapture() ) ReleaseCapture(); m_hCursor = LoadCursor(NULL,IDC_ARROW); SetCursor(m_hCursor); m_bResize = FALSE; } } break; }
case WM_MOUSEMOVE: { //char szbuf[256];
//wsprintf(szbuf, "WM_MOUSEMOVE pt.x [%d] pt.y[%d]\n", pt.x, pt.y);
//OutputDebugString(szbuf);
} if (m_bDown && !m_bResize) { //UINT cbPt = 1;
x = (short)pt.x; y = (short)pt.y; if ( x < m_clipRect.left) { pt.x = m_clipRect.left; } else if ( x >= m_clipRect.right ) { pt.x = m_clipRect.right - 1; }
if ( y < m_clipRect.top ) { pt.y = m_clipRect.top; } else if ( y >= m_clipRect.bottom ) { pt.y = m_clipRect.bottom - 1; } if ( m_pCHwxStroke->AddPoint(pt) ) { m_pCHwxStroke->DrawStroke(m_hdcMouse,2,FALSE); } return TRUE; } else if ( hwnd == GetCapture() || IsPointInResizeBox(&pt)) { //990602:KOTAE #245.
//If mouse move is too fast, back ground is NOT repainted.
//So, This is little bit hack but work well.
//This sleep change context switch and remove too much WM_MOUSEMOVE message.
#if 1
static DWORD g_dwTick; DWORD dwTick = ::GetTickCount(); if(dwTick - g_dwTick < 20) { return TRUE; } g_dwTick = dwTick; #endif
HCURSOR hCur = LoadCursor(NULL,IDC_SIZEWE); #ifndef UNDER_CE // CE specific
m_hCursor = SetCursor(hCur); #else // UNDER_CE
SetCursor(hCur); #endif // UNDER_CE
if ( m_bResize ) { Dbg(("Resizing Multibox \n")); //990621:KOTAE #1229
pt.x = (short)pt.x; if(pt.x < 0) { return TRUE; }
iBox = (m_firstX-4) / m_boxSize; len = pt.x - m_firstX; m_boxSize += (USHORT)len;
Dbg(("=>new m_boxSize %d\n", m_boxSize)); //wsprintf(szbuf, "new m_boxSize [%d]\n", m_boxSize);
//OutputDebugString(szbuf);
//----------------------------------------------------------------
//980821:ToshiaKCheck max size of m_boxSize,
//To prevent resize boxsize inifinitly.
//----------------------------------------------------------------
INT cxScreen = ::GetSystemMetrics(SM_CXFULLSCREEN)/2; INT cyScreen = ::GetSystemMetrics(SM_CYFULLSCREEN)/2; if(m_boxSize >= INKBOXSIZE_MIN) { if(m_boxSize >= cxScreen || m_boxSize >= cyScreen) { m_boxSize = (USHORT)(cxScreen < cyScreen ? cxScreen : cyScreen); } } else { m_boxSize = INKBOXSIZE_MIN; } //----------------------------------------------------------------
//Old code
//----------------------------------------------------------------
//m_boxSize = m_boxSize > INKBOXSIZE_MIN ? m_boxSize : INKBOXSIZE_MIN ;
m_pInk->SetMBHeight( m_boxSize ); ptTmp.x = (iBox+1) * m_boxSize; ptTmp.y = pt.y; ClientToScreen(hwnd,&ptTmp); SetCursorPos(ptTmp.x,ptTmp.y); m_pInk->ChangeIMEPADSize(FALSE); m_pInk->ChangeLayout(FALSE); UpdateWindow(GetParent(m_pInk->GetInkWindow())); UpdateWindow(m_pInk->GetInkWindow()); //990602:KOTAE #245.
::InvalidateRect(m_pInk->GetInkWindow(), NULL, TRUE); m_firstX = (iBox+1) * m_boxSize; } return TRUE; } else { if ( !m_bResize ) { m_hCursor = LoadCursor(NULL,IDC_ARROW); // SATORI #164
SetCursor(m_hCursor); } return TRUE; } break; case WM_RBUTTONDOWN: { if ( IsInInkBox(&pt) ) { m_bRightClick = TRUE; return TRUE; } } break; case WM_RBUTTONUP: { // 980408:kwada - IME98A #304
// No popup menu when left button is down.
if(m_bDown) { m_bRightClick = FALSE; break; }
if ( IsInInkBox(&pt) ) { HMENU hMenu; HMENU hMenuTrackPopup; //----------------------------------------------------------------
//fixed MSKK #5035.Need to load specified language's menu resource
//BUGBUG::hMenu = LoadMenu (m_hInstance, MAKEINTRESOURCE(IDR_MB));
//----------------------------------------------------------------
hMenu = CHwxFE::GetMenu(m_hInstance, MAKEINTRESOURCE(IDR_MB)); if (!hMenu) { m_bRightClick = FALSE; return FALSE; } hMenuTrackPopup = GetSubMenu (hMenu, 0); ClientToScreen(m_hMBWnd,&pt); #ifndef UNDER_CE // Windows CE does not support TPM_LEFTBUTTON on TrackPopupMenu
TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0,m_hMBWnd, NULL); #else // UNDER_CE
TrackPopupMenu (hMenuTrackPopup, TPM_LEFTALIGN, pt.x, pt.y, 0,m_hMBWnd, NULL); #endif // UNDER_CE
DestroyMenu (hMenu); m_bRightClick = FALSE; return TRUE; } } break; default: break; } return FALSE; Unref(wp); }
LRESULT CHwxMB::HandleUserMessage(HWND hwnd, UINT iMsg,WPARAM wp,LPARAM lp) { LRESULT lRet = 0;
switch (iMsg) { //
// We sometimes don't get a WM_LBUTTONUP message due to the system
// design. We need to simulate one here if we think we are in a
// down state or risk flaky behaviour. The hwxpad assumes we will
// get one and may leak resources if we don't.
//
case MB_WM_ERASE: case MB_WM_DETERMINE: { //
// In either case, do the recognition, for erase then send a
// backspace key through.
//
if (m_cLogicalBox) { // TOTALLOGICALBOX represents invalid box number, force it to recognize
// the ink in the current box.
if (m_hdcMouse == NULL) { m_hdcMouse = GetDC(hwnd); }
DrawMBInkBox(m_hdcMouse, m_curBox); SetLogicalBox(TOTALLOGICALBOX); lRet = 1; m_bErase = FALSE; if (iMsg == MB_WM_ERASE) { //
// Send a backspace key in to erase the last garbage character.
//
// PostThreadMessage(m_pCHwxThreadMB->GetID(), THRDMSG_CHAR, VK_BACK, 0);
m_bErase = TRUE; } } m_bNoInk = TRUE; // We have no more ink for sure now.
//
// In either case erase/time-out/recog-button we no longer have
// a current box, or a need for a DC or a need to be HighPriority.
//
if (m_hdcMouse) { ReleaseDC(hwnd, m_hdcMouse); m_hdcMouse = NULL; }
m_curBox = TOTALLOGICALBOX; // There's no more ink, init state again.
if (m_bHiPri) { SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_NORMAL); m_bHiPri = FALSE; } break; } case MB_WM_COPYINK: m_pInk->CopyInkFromMBToCAC(* m_pCHwxStroke,m_clipRect.left-Box_Border,0); break; case MB_WM_HWXCHAR: { HWXRESULTPRI * pResult = (HWXRESULTPRI *)wp; HWXRESULTPRI * pPrev = pResult; while ( pResult ) { if ( m_bErase && NULL == pResult->pNext ) { // delete the last node
MemFree((void *)pResult); break; } if ( pResult->cbCount ) { #ifndef FE_JAPANESE
for ( short i = 0; i < pResult->cbCount; i++) { m_StringCandidate[i][0] = pResult->chCandidate[i]; m_StringCandidate[i][1] = 0x0000; m_pImeStringCandidate->lpwstr[i] = m_StringCandidate[i]; } m_pImeStringCandidate->uCount = pResult->cbCount; (m_pInk->GetAppletPtr())->SendHwxStringCandidate(m_pImeStringCandidate); #else
DWORD dwFarEastid; LPIMEFAREASTINFO lpFarEastInfo = NULL;
if (FGetFarEastInfo( pResult, &dwFarEastid, &lpFarEastInfo )) { for ( short i = 0; i < pResult->cbCount; i++) { m_StringCandidate[i][0] = pResult->chCandidate[i]; m_StringCandidate[i][1] = 0x0000; m_pImeStringCandidateInfo->lpwstr[i] = m_StringCandidate[i]; } m_pImeStringCandidateInfo->dwFarEastId = dwFarEastid; m_pImeStringCandidateInfo->lpFarEastInfo = lpFarEastInfo; m_pImeStringCandidateInfo->fInfoMask = INFOMASK_NONE; m_pImeStringCandidateInfo->iSelIndex = 0; m_pImeStringCandidateInfo->uCount = pResult->cbCount; (m_pInk->GetAppletPtr())->SendHwxStringCandidateInfo(m_pImeStringCandidateInfo);
if (lpFarEastInfo) MemFree(lpFarEastInfo); } else { for ( short i = 0; i < pResult->cbCount; i++) { m_StringCandidate[i][0] = pResult->chCandidate[i]; m_StringCandidate[i][1] = 0x0000; m_pImeStringCandidate->lpwstr[i] = m_StringCandidate[i]; } m_pImeStringCandidate->uCount = pResult->cbCount; (m_pInk->GetAppletPtr())->SendHwxStringCandidate(m_pImeStringCandidate); } #endif
} pResult = pResult->pNext; pPrev->pNext = NULL; MemFree((void *)pPrev); pPrev = pResult; } break; } // case MB_WM_COMCHAR:
// ((m_pInk->GetAppletPtr())->GetIImePad())->Request(m_pInk->GetAppletPtr(),IMEPADREQ_SENDCONTROL,IMEPADCTRL_CARETBACKSPACE,0);
// break;
default: break; } return lRet; Unref(lp); }
LRESULT CHwxMB::HandleCommand(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) { UINT uCode =(UINT)LOWORD(wp); switch ( uCode ) { case IDM_MBRECOG: return HandleUserMessage(hwnd,MB_WM_DETERMINE,0,0); case IDM_MBDELETE: return HandleUserMessage(hwnd,MB_WM_ERASE,0,0); case IDM_MBPROP: // This is a hack fix. I think we should use Request().
//((m_pInk->GetAppletPtr())->GetIImePad())->Request(m_pInk->GetAppletPtr(),
// IMEPADREQ_CONFIGSELF,0,0);
// IDM_CONFIGAPPLET == 0x7009
if(m_pInk && m_pInk->GetAppletPtr() && m_pInk->GetAppletPtr()->GetIImePad()) { ((m_pInk->GetAppletPtr())->GetIImePad())->Request(m_pInk->GetAppletPtr(), IMEPADREQ_POSTMODALNOTIFY, IMEPN_CONFIG, 0); } //PostMessage(GetParent(GetParent(hwnd)), WM_COMMAND,0x7009,NULL);
return 0; default: break; } return DefWindowProc(hwnd, msg, wp, lp); }
//----------------------------------------------------------------
//990618:ToshiaK for KOTAE #1329
//----------------------------------------------------------------
void CHwxMB::OnSettingChange(UINT msg, WPARAM wp,LPARAM lp) { #ifndef UNDER_CE // Unsupported.
if(wp == SPI_SETNONCLIENTMETRICS) { if(m_pCHwxStroke) { m_pCHwxStroke->ResetPen(); } } #else // UNDER_CE
if(m_pCHwxStroke) { m_pCHwxStroke->ResetPen(); } #endif // UNDER_CE
UNREFERENCED_PARAMETER(msg); UNREFERENCED_PARAMETER(lp); }
void CHwxMB::SetBoxSize(WORD w) { m_boxSize = w; }
WCHAR CHwxMB::findLastContext() { WCHAR prev,curr; prev = curr = 0x0000; for(int i = 0; i < sizeof(m_Context)/sizeof(WCHAR); i++) { if ( curr = m_Context[i] ) { prev = curr; } else { return prev; } } return prev; }
#ifdef FE_JAPANESE
// for character comment
#include "..\..\imeknl\iconvert\chcomnt.h"
BOOL FGetFarEastInfo(HWXRESULTPRI *pResult, DWORD *pdwID, LPIMEFAREASTINFO *ppInfo) { // count char number
INT i; INT len; WCHAR *wszComment; for ( i = len = 0; i < pResult->cbCount; i++) { wszComment = WSZGetCharComment(pResult->chCandidate[i], COMMENTCLIENT_HW); if (wszComment) len += lstrlenW(wszComment); len++; // for NULL
}
if ((*ppInfo = (LPIMEFAREASTINFO)MemAlloc(sizeof(IMEFAREASTINFO)+len*sizeof(WCHAR)))==NULL) return FALSE; *pdwID = FEID_JAPANESE; (*ppInfo)->dwSize = sizeof(IMEFAREASTINFO)+len*sizeof(WCHAR); (*ppInfo)->dwType = IMEFAREASTINFO_TYPE_COMMENT;
INT ip; WCHAR *wszBuf;
ip = 0; wszBuf = (WCHAR*)((*ppInfo)->dwData);
for ( i = 0; i < pResult->cbCount; i++) { wszComment = WSZGetCharComment(pResult->chCandidate[i], COMMENTCLIENT_HW); if (wszComment) { memcpy( wszBuf+ip, wszComment, (lstrlenW(wszComment)+1)*sizeof(WCHAR)); ip += lstrlenW(wszComment)+1; } else { wszBuf[ip++] = 0; } } return TRUE; } #endif
|