Пример #1
0
inline void handleCandidatesClosed(HWND hwnd) {
	if(!hwnd||hwnd!=candidateIMEWindow) return;
	/* Obtain IME context */
	HIMC imc = ImmGetContext(hwnd);
	if (!imc) {
		candidateIMEWindow=0;
		nvdaControllerInternal_inputCandidateListUpdate(L"",-1,L"");
		return;
	}
	DWORD count = 0;
	DWORD len = ImmGetCandidateListCountW(imc, &count);
	ImmReleaseContext(hwnd, imc);
	if (!count) {
		candidateIMEWindow=0;
		nvdaControllerInternal_inputCandidateListUpdate(L"",-1,L"");
	}
}
Пример #2
0
static bool handleCandidates(HWND hwnd) {
	/* Obtain IME context */
	HIMC imc = ImmGetContext(hwnd);
	if (!imc)  return false;

	/* Make sure there is at least one candidate list */
	DWORD count = 0;
	DWORD len = ImmGetCandidateListCountW(imc, &count);
	if (!count) {
		ImmReleaseContext(hwnd, imc);
		return false;
	}
	candidateIMEWindow=hwnd;
	/* Read first candidate list */
	CANDIDATELIST* list = (CANDIDATELIST*)malloc(len);
	ImmGetCandidateList(imc, 0, list, len);
	ImmReleaseContext(hwnd, imc);

	/* Determine candidates currently being shown */
	DWORD pageEnd = list->dwPageStart + list->dwPageSize;
	DWORD selection=list->dwSelection-list->dwPageStart;
	if (list->dwPageSize == 0) {
		pageEnd = list->dwCount;
	} else if (pageEnd > list->dwCount) {
		pageEnd = list->dwCount;
	}

	/* Concatenate currently shown candidates into a string */
	WCHAR* cand_str = (WCHAR*)malloc(len);
	WCHAR* ptr = cand_str;
	for (DWORD n = list->dwPageStart, count = 0;  n < pageEnd;  ++n) {
		DWORD offset = list->dwOffset[n];
		WCHAR* cand = (WCHAR*)(((char*)list) + offset);
		size_t clen = wcslen(cand);
		if (!clen)  continue;
		CopyMemory(ptr, cand, (clen + 1) * sizeof(WCHAR));
		if ((n + 1) < pageEnd)  ptr[clen] = '\n';
		ptr += (clen + 1);
		++count;
	}
	HKL kbd_layout = GetKeyboardLayout(0);
	WCHAR filename[MAX_PATH + 1]={0};
	ImmGetIMEFileNameW(kbd_layout, filename, MAX_PATH);
	if(cand_str&&wcslen(cand_str)>0) {
		nvdaControllerInternal_inputCandidateListUpdate(cand_str,selection,filename);
	}
	/* Clean up */
	free(cand_str);
	free(list);
	return (count > 0);
}
Пример #3
0
static LRESULT handleIMEWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
	switch (message) {
		case WM_IME_NOTIFY:
			if(!hasValidIMEContext(hwnd)) return 0;
			switch (wParam) {
				case IMN_SETOPENSTATUS:
					handleOpenStatus(hwnd);
					break;
				case IMN_OPENCANDIDATE:
				case IMN_CHANGECANDIDATE:
					PostMessage(hwnd,wm_candidateChange,0,0);
					break;

				case IMN_CLOSECANDIDATE:
					nvdaControllerInternal_inputCandidateListUpdate(L"",-1,L"");
					break;

				case IMN_SETCONVERSIONMODE:
					PostMessage(hwnd,wm_handleIMEConversionModeUpdate,0,0);
					break;

				case IMN_PRIVATE:
					// Needed in XP to support EasyDots IME
					if (!isUIElementMgrSafe || !isTSFThread(true))
						handleReadingStringUpdate(hwnd);
					break;
			}
			break;

		case WM_IME_COMPOSITION:
			if(!hasValidIMEContext(hwnd)) return 0;
			curIMEWindow=hwnd;
			if(!isTSFThread(true)) {\
				if(lParam&GCS_COMPSTR||lParam&GCS_CURSORPOS) {
					handleComposition(hwnd, wParam, lParam);
				}
			}
			break;

		case WM_IME_ENDCOMPOSITION:
			if(!hasValidIMEContext(hwnd)) return 0;
			if(curIMEWindow==hwnd) {
				if(handleEndComposition(hwnd, wParam, lParam)) {
					//Disable further typed character notifications produced by TSF
					typedCharacter_window=NULL;
				}
				curIMEWindow=NULL;
			}
			break;

		case WM_ACTIVATE:
		case WM_SETFOCUS:
			if(!hasValidIMEContext(hwnd)) return 0;
			handleIMEConversionModeUpdate(hwnd,false);
			if(!isTSFThread(true)) {
				if (hwnd != GetFocus())  break;
				handleComposition(hwnd, wParam, lParam);
				handleCandidates(hwnd);
			}
			break;
		default:
			break;
	}
	return 0;
}