HRESULT CCandidateList::_StartCandidateList(TfClientId tfClientId, ITfDocumentMgr *pDocumentMgr, ITfContext *pContextDocument, TfEditCookie ec, ITfRange *pRangeComposition){ TfEditCookie ecTmp; HRESULT hr = E_FAIL; BOOL fClipped; // clear the previous candidate list. // only one candidate window is supported. _EndCandidateList(); // create a new context on the document manager object for // the candidate ui. if (FAILED(pDocumentMgr->CreateContext(tfClientId, 0, NULL, &_pContextCandidateWindow, &ecTmp))) return E_FAIL; // push the new context. if (FAILED(pDocumentMgr->Push(_pContextCandidateWindow))) goto Exit; _pDocumentMgr = pDocumentMgr; _pDocumentMgr->AddRef(); _pContextDocument = pContextDocument; _pContextDocument->AddRef(); _pRangeComposition = pRangeComposition; _pRangeComposition->AddRef(); // advise ITfContextKeyEventSink to the new context. if (FAILED(_AdviseContextKeyEventSink())) goto Exit; // advise ITfTextLayoutSink to the document context. if (FAILED(_AdviseTextLayoutSink())) goto Exit; //ÉêÇ뻺³åÇø int cchMax = 10; wchar_t *pchText = new wchar_t[cchMax]; //»ñµÃÊäÈë×Ö·û ULONG pcch = 0; if(_pRangeComposition->GetText(ec, NULL, pchText, cchMax, &pcch) == S_OK){ pchText[pcch] = 0; } //²éѯºòÑ¡×Ö if(!CandidateTree->ForwardTo(pchText[pcch - 1])){ _pRangeComposition->Collapse(ec, TF_ANCHOR_END); _pTextService->_TerminateComposition(ec, _pContextDocument); }else{ CCandidateTree::Node *node = CandidateTree->GetCurrent(); if(node != NULL){ //ÏÔʾ/ÊäÈëºòÑ¡×Ö if(node->IsEnd()){ _InputDefaultCandidate(ec); // create an instance of CCandidateWindow class. }else if(_pCandidateWindow = new CCandidateWindow()){ RECT rc; ITfContextView *pContextView; // get an active view of the document context. if (FAILED(pContextDocument->GetActiveView(&pContextView))) goto Exit; // get text extent for the range of the composition. if (FAILED(pContextView->GetTextExt(ec, pRangeComposition, &rc, &fClipped))) goto Exit; pContextView->Release(); // create the dummy candidate window if (!_pCandidateWindow->_Create()) goto Exit; _pCandidateWindow->_Move(rc.left, rc.bottom); _pCandidateWindow->_Show(); hr = S_OK; } } } //ÊÍ·Å»º³åÇø delete[] pchText; Exit: if (FAILED(hr)) { _EndCandidateList(); } return hr; }
BOOL CInputModeWindow::_Create(CTextService *pTextService, ITfContext *pContext, BOOL bCandidateWindow, HWND hWnd) { POINT pt = {0, 0}; if(pContext != nullptr) { _pContext = pContext; _pContext->AddRef(); if(_AdviseTextLayoutSink() != S_OK) { return FALSE; } } if(!bCandidateWindow && _pContext == nullptr) { return FALSE; } _pTextService = pTextService; _pTextService->AddRef(); _bCandidateWindow = bCandidateWindow; if(_bCandidateWindow) { _hwndParent = hWnd; } else { ITfContextView *pContextView; if(_pContext->GetActiveView(&pContextView) == S_OK) { if(FAILED(pContextView->GetWnd(&_hwndParent)) || _hwndParent == nullptr) { _hwndParent = GetFocus(); } SafeRelease(&pContextView); } } _hwnd = CreateWindowExW(WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_NOACTIVATE, InputModeWindowClass, L"", WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, _hwndParent, nullptr, g_hInst, this); if(_hwnd == nullptr) { return FALSE; } HDC hdc = GetDC(nullptr); _size = MulDiv(16, GetDeviceCaps(hdc, LOGPIXELSY), 96); ReleaseDC(nullptr, hdc); if(_bCandidateWindow) { RECT r; GetClientRect(_hwndParent, &r); pt.x = r.left; pt.y = r.bottom; ClientToScreen(_hwndParent, &pt); } SetWindowPos(_hwnd, HWND_TOPMOST, pt.x, pt.y + IM_MERGIN_Y, _size + IM_MERGIN_X * 2, _size + IM_MERGIN_Y * 2, SWP_NOACTIVATE); return TRUE; }
HRESULT CCandidateList::_StartCandidateList(TfClientId tfClientId, ITfDocumentMgr *pDocumentMgr, ITfContext *pContext, TfEditCookie ec, ITfRange *pRange, BOOL reg, BOOL comp) { HRESULT hr = E_FAIL; TfEditCookie ecTextStore; ITfContextView *pContextView; HWND hwnd = NULL; _EndCandidateList(); if(pDocumentMgr->CreateContext(tfClientId, 0, NULL, &_pContextCandidateWindow, &ecTextStore) != S_OK) { return E_FAIL; } if(pDocumentMgr->Push(_pContextCandidateWindow) != S_OK) { goto exit; } _pDocumentMgr = pDocumentMgr; _pDocumentMgr->AddRef(); _pContextDocument = pContext; _pContextDocument->AddRef(); _pRangeComposition = pRange; _pRangeComposition->AddRef(); _ec = ec; _comp = comp; if(_AdviseContextKeyEventSink() != S_OK) { goto exit; } if(_AdviseTextLayoutSink() != S_OK) { goto exit; } try { _pCandidateWindow = new CCandidateWindow(_pTextService, this); if(pContext->GetActiveView(&pContextView) == S_OK) { if(!_pTextService->_UILessMode && _pCandidateWindow->_CanShowUIElement()) { if(FAILED(pContextView->GetWnd(&hwnd)) || hwnd == NULL) { hwnd = GetFocus(); } } SafeRelease(&pContextView); } if(!_pCandidateWindow->_Create(hwnd, NULL, 0, 0, reg, comp)) { goto exit; } HRESULT hrSession = E_FAIL; try { CCandidateWindowEditSession *pEditSession = new CCandidateWindowEditSession(_pTextService, _pContextDocument, _pRangeComposition, _pCandidateWindow); // Asynchronous pContext->RequestEditSession(ec, pEditSession, TF_ES_ASYNC | TF_ES_READWRITE, &hrSession); SafeRelease(&pEditSession); } catch(...) { } if(hrSession != TF_S_ASYNC) { hr = E_FAIL; goto exit; } hr = S_OK; } catch(...) { } exit: if(hr != S_OK) { _EndCandidateList(); } return hr; }