You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1109 lines
36 KiB
1109 lines
36 KiB
#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
|