⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hikerwbui.cpp

📁 自己用Markov模型做的一个整句物笔输入法的原型
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	//auto delete associated correct word
	if (bDelCorrWord)
	{
		DeleteCorrWord(pos);
		for (i = pos; i < wordnum; i++)
		{
			corrwordslen[i] = corrwordslen[i+1];
			corrwordslen[i+1] = 0;
		}
	}

	wordnum --;
}

static CString TransWords(int page)
{
	CString csWords, csiw;
	unsigned char lc = 0;
	unsigned char* pw = wordlist;
	int nw = selwordnum;

	if (nw <= 1)
	{
		csWords = CString("  ") + CString(pw);
		return csWords;
	}
	
	for (int n = 0; n < nw; pw++)
	{
		if (0 != *pw && 0 == lc)
		{
			if (n >= page*10 && n < (page+1)*10)
			{
				csiw.Format(" %1d ", (n+1)%10);
				csWords += csiw + CString(pw);
			}
			else if (n >= (page+1)*10)
			{
				break;
			}
			n++;
		}
		lc = *pw;
	}

	return csWords;
}

static void CorrSent()
{
	unsigned char *pcw;
	unsigned char cw[WORDLEN];
	
	int n = 0;
	for (int i = 0; n < corrwordnum; i++)
	{
		if (corrwordslen[i] != 0)
		{
			pcw = LocateCorrWord(i);
			memset(cw, 0, sizeof(cw));
			strncpy((char*)cw, (char*)pcw, corrwordslen[i]);
			DeleteWord(i, FALSE);
			InsertWord(cw, i, FALSE);
			n++;
		}
	}
}

static int GetKeyId(unsigned char c)
{
	int i;

	if (!ispunct(c))
	{
		for (i = 0; i < SOFTKEYBOARD_LEN; i+=2)
		{
			if (c == gKeyArr[1][i])
				return i/2;
		}
	}
	else
	{
		for (i = 0; i < SOFTKEYBOARD_LEN; i+=2)
		{
			if (c == gKeyArr[1][i])
				return i/2;
		}
		for (i = 0; i < SOFTKEYBOARD_LEN; i+=2)		//if in gKeyArr[1] not found, find in gKeyArr[0]
		{
			if (c == gKeyArr[0][i])
				return i/2;
		}
	}

	return -1;
}

//using for find a special key's corresponding code
static BOOL FindKeyCode(CString csKeyName, unsigned char* pcode)
{
	memset(codelist, 0, sizeof(codelist));
	if (GetCodes((unsigned char*)(const char*)csKeyName, codelist, selcodenum))
	{
		strcpy((char*)pcode, (char*)codelist);
		return TRUE;
	}

	return FALSE;
}

static CString GetChsPunc(unsigned char c)
{
	for (int i = 0; i < strlen((char*)gPunctuation); i++)
	{
		if (c == gPunctuation[i])
			break;
	}

	return CString(gChinsesPunc[2*i])+CString(gChinsesPunc[2*i+1]);
}

static void ShowFloatStaWnd()
{
	POINT pt;
	//HWND hWnd = GetFocus();

	Sleep(GetCaretBlinkTime()/4);	//???why, GetCaretPos may not return current caret position in time
	GetCaretPos(&pt);
	ClientToScreen(ghFocusWnd, &pt);
	
	CHikerWBStateWnd* staWnd;
	staWnd = (CHikerWBStateWnd*)CWnd::FromHandle(GetStaWndHandle());
	staWnd->ShowFloat(pt);
}

static int GetCurrLoc()
{
	int loc = 0;
	for (int i = 0; i <= currpos; i++)
		loc += wordslen[i];

	return loc;
}

static int GetAsc(int vk, BOOL bShiftDown)
{
	for (int i = 0; i < sizeof(gVKArr); i++)
	{
		if (gVKArr[i] == vk)
		{
			if (!bShiftDown)
				return gKeyArr[1][i*2];		//alphabetic or number
			else
				return gKeyArr[0][i*2];		//alphabetic or number
		}
	}
	
	return 0;
}

BOOL HookKeyHandle(WPARAM wParam, LPARAM lParam)
{
	unsigned short c = 0;			//!must be initialized with 0
	BYTE lpKeyboardState[256];
	int codelen = strlen((char*)code);
	int cslen = strlen((char*)codestr);
	int wslen = 0;
	unsigned char codeback[CODELEN];//temporary variable
	unsigned char corrword[WORDLEN];
	//int codenum = 0;
	CString csWords;

	CHikerWBStateWnd* staWnd;
	staWnd = (CHikerWBStateWnd*)CWnd::FromHandle(GetStaWndHandle());
	
	CMakeWordDlg newWordWnd;
	//newWordWnd.Create(IDD_DIALOG_MAKEWORD, NULL);

	BOOL bCapsLock = (GetKeyState(VK_CAPITAL) << 15);
	BOOL bShiftDown = (GetKeyState(VK_SHIFT) >> 15);
	BOOL bCtrlDown = ((GetKeyState(VK_CONTROL) >> 15) != 0);
	BOOL iSoftKeyboard = 0;

	if (lParam > 0 || lParam < -200)		//05.11.10 hard keyborad
	{
		GetKeyboardState(lpKeyboardState);
		ToAscii(wParam, (lParam&0x00FF0000)>>16, lpKeyboardState, &c, 0);	//the second parameter seems no use.
		iSoftKeyboard = (!gbChsSta && gbSBCSta), 10, 0;
	}
	else		//from soft keyboard
	{
		bShiftDown = (lParam<=-100)?TRUE:FALSE;
		iSoftKeyboard = (lParam<=-100) ? -(lParam+100) : -lParam;
		c = GetAsc(wParam, bShiftDown);
	}

	//process keyin
	if (gbChsSta && iSoftKeyboard <= 0 &&
			((isalpha(c) && !bCapsLock && !bShiftDown && !bCtrlDown) /*lower case letter*/
			|| !gbTmpPy && 32 == c && codelen < giMaxCodeLen && codelen > 0))	//or space
	{//key in chinses character
		giLastKey = wParam;

//		if (gbFloatStaWnd && !staWnd->IsWindowVisible())		//show floating state window
//		{
//			ShowFloatStaWnd();
//		}

		if (strlen((char*)wordstr) >= SENTLEN-6)
		{
			MessageBeep(/*MB_ICONASTERISK*/0xFFFFFFFF);
			return TRUE;
		}

		if (!gbTmpPy)
		{
			if (codelen >= giMaxCodeLen || code[codelen-1] == 32 || 0 == codelen)					//new code
			{
				memset(code, 0, sizeof(code));
				codelen = 0;
				currpos++;
			}
			code[codelen++] = c;
			lastpos = currpos;

			//show code
//			staWnd->SetCode((LPCSTR)code, FALSE);
			if (codelen < giMaxCodeLen && code[codelen-1] != 32)		//code is not full, return
			{

				//get select words(by prior)
				memset(wordlist, 0, sizeof(wordlist));
				GetWords(code, codestr, currpos, wordlist, selwordnum);
				giPageNo = 0;
				csWords = TransWords(giPageNo);
				//show select words
//				staWnd->SetWord((LPCSTR)csWords, giPageNo, selwordnum);
//				staWnd->SetSent((LPCSTR)wordstr, wordslen, wordnum, currpos);

				return TRUE;
			}

			//--insert code into code stream
			InsertCode(code, currpos);		//don't clear the code
			memset(corrword, 0, sizeof(corrword));
			InsertCorrWord(corrword, currpos);		//insert an empty correct word

			//translate the code stream to word stream
			strcpy((char*)lastwordstr, (char*)wordstr);
			memset(wordstr, 0, sizeof(wordstr));
			if (!Translate(codestr, wordstr, codenum, wordnum,	codeslen, wordslen))
				strcpy((char*)wordstr, (char*)lastwordstr);

			//get select words again(by post)
			memset(wordlist, 0, sizeof(wordlist));
			GetWords(code, codestr, currpos, wordlist, selwordnum);
			giPageNo = 0;
			csWords = TransWords(giPageNo);
			//show select words
//			staWnd->SetWord((LPCSTR)csWords, giPageNo, selwordnum);


			//display translated word stream
			CorrSent();
//			if (codenum > 0)
//				staWnd->SetSent((LPCSTR)wordstr, wordslen, wordnum, currpos);
		}
		else	//temporary pinyin
		{
			code[codelen++] = c;
			lastpos = currpos;

			//show code
//			staWnd->SetCode((LPCSTR)code, FALSE);

			memset(wordlist, 0, sizeof(wordlist));
			PYGetWords(code, wordlist, selwordnum);
			giPageNo = 0;
			csWords = TransWords(giPageNo);
			//show select words
//			staWnd->SetWord((LPCSTR)csWords, giPageNo, selwordnum);
		}
	}
	else if (gbChsSta && !bShiftDown && iSoftKeyboard <= 0  
			&& (selwordnum > 1)
			&& (48 <= c && c <= 57 || 32 == c && gbTmpPy)
			&& (((selwordnum%10 == 0 || ((giPageNo+1)*10 <= selwordnum)) && c-48 >= 0 && c-48 <= 9)
			|| (selwordnum%10 != 0 && ((giPageNo+1)*10 > selwordnum) && c-48 >= 1 && c-48 <= selwordnum%10)
			|| 32 == c && gbTmpPy))
	{
		giLastKey = wParam;

		if (selwordnum <= 0)		//duplicate space character
			return TRUE;

		if (c == 32)				//temporary pinyin
			c = 49;

		if (c == 48)				//note c is and unsigned short
			c = 9;
		else
			c -= 49;

		c = giPageNo*10+c;

		memset(corrword, 0, sizeof(corrword));
		GetWordSel(wordlist, c, corrword);

		if (0 == strlen((char*)corrword))
			return TRUE;

		if (gbTmpPy)
		{
			FindCodeByWord(corrword, code);
			InsertCode(code, currpos);
			InsertCorrWord(corrword, currpos);
			gbTmpPy = FALSE;

			staWnd->SetCode((LPCSTR)code);

			memset(wordlist, 0, sizeof(wordlist));
			GetWords(code, codestr, currpos, wordlist, selwordnum);
			giPageNo = 0;
			csWords = TransWords(giPageNo);
			//show select words
			staWnd->SetWord((LPCSTR)csWords, giPageNo, selwordnum);
		}
		else if (codelen < giMaxCodeLen && code[codelen-1] != 32)		//not full code
		{
			code[codelen] = 32;
			InsertCode(code, currpos);
			InsertCorrWord(corrword, currpos);
		}
		else
		{
			DeleteCode(currpos);
			DeleteCorrWord(currpos);
			InsertCode(code, currpos);
			InsertCorrWord(corrword, currpos);
		}

		//translate
		strcpy((char*)lastwordstr, (char*)wordstr);
		memset(wordstr, 0, sizeof(wordstr));
		if (!Translate(codestr, wordstr, codenum, wordnum,	codeslen, wordslen))
			strcpy((char*)wordstr, (char*)lastwordstr);

		//updat word stream by correct word stream
		CorrSent();
		if (codenum > 0)
			staWnd->SetSent((LPCSTR)wordstr, wordslen, wordnum, currpos);
	}
	else if ((8 == wParam || 46 == wParam) && (cslen > 0 || codelen > 0))	//backspace & del key
	{
		if (lastpos >= 0 && lastpos == currpos && wParam == 8)			//only the last code can be deleted letter by letter
		{
			memset(codeback, 0, sizeof(codeback));
			GetCode(currpos, codeback);		
			if (0 == strcmp((char*)codeback, (char*)code))	//first delete the code
			{
				DeleteCode(currpos);
				DeleteWord(currpos, TRUE);
//					DeleteCorrWord(currpos);
			}

			if (codelen > 0)		//delete last letter of the code using backspace key
			{
				//delete last letter 
				if (32 == code[strlen((char*)code)-1])	//lastcode has no space, but codestr may has!
				{
					code[strlen((char*)code)-1] = 0;
					code[strlen((char*)code)-1] = 0;
				}
				else
				{
					code[strlen((char*)code)-1] = 0;
				}

				//if code is empty
				if (0 == strlen((char*)code))
				{
					//if (8 == wParam)	//backspace key
						currpos--;
//					else		//del key
//					{
//						if (currpos >= wordnum-1)
//							currpos --;
//					}

					GetCode(currpos, code);
					gbTmpPy = FALSE;
					staWnd->SetCode((LPCSTR)code);
				}
				else
					staWnd->SetCode((LPCSTR)code, FALSE);
			}
		}
		else
		{
			if (currpos < 0 && wParam == 8)
				return TRUE;

			//delete last input word
//				DeleteCorrWord(currpos);
			if (8 == wParam)	//backspace key
			{
				DeleteCode(currpos);
				DeleteWord(currpos, TRUE);
				currpos --;
			}
			else
			{
				//if (currpos <= wordnum -1)
				currpos ++;
				DeleteCode(currpos);
				DeleteWord(currpos, TRUE);
				if (currpos >= 0)
					currpos --;
			}
			GetCode(currpos, code);
			staWnd->SetCode((LPCSTR)code);
		}

		//get the code's corresponding words
		memset(wordlist, 0, sizeof(wordlist));
		if (gbTmpPy)
			PYGetWords(code, wordlist, selwordnum);	
		else
			GetWords(code, codestr, currpos, wordlist, selwordnum);
		giPageNo = 0;
		CString csWords = TransWords(giPageNo);

		staWnd->SetSent((LPCSTR)wordstr, wordslen, wordnum, currpos);
		staWnd->SetWord((LPCSTR)csWords, giPageNo, selwordnum);

		codelen = strlen((char*)code);
		cslen = strlen((char*)codestr);
		if (cslen == 0 && codelen == 0)
			Clean();			//hide the window

		giLastKey = wParam;
	}
	else if (!gbTmpPy && cslen > 0 && (VK_LEFT == wParam || VK_RIGHT == wParam || VK_HOME == wParam || VK_END == wParam))
	{
		if (currpos >= 0 && codelen < giMaxCodeLen && code[codelen-1] != 32 && giLastKey != 27)		//current code is not full and last key is not Esc
			return TRUE;
		
		switch(wParam) 
		{
		case VK_LEFT:
			if (currpos >= 0)
				currpos --;
			break;
		case VK_RIGHT:
			if (currpos < codenum-1)
				currpos ++;
			break;
		case VK_HOME:
			currpos = -1;
			break;
		case VK_END:
			currpos = codenum - 1;
			break;
		default:
			break;
		}
		
		lastpos = -1;
		GetCode(currpos, code);
		//get the code's corresponding words
		memset(wordlist, 0, sizeof(wordlist));
		GetWords(code, codestr, currpos, wordlist, selwordnum);	
		giPageNo = 0;
		CString csWords = TransWords(giPageNo);

		staWnd->SetCode((LPCSTR)code);
		staWnd->SetWord((LPCSTR)csWords, giPageNo, selwordnum);
		staWnd->SetSent((LPCSTR)wordstr, wordslen, wordnum, currpos);

		giLastKey = wParam;
	}
	else if (selwordnum > 0 && (33 == wParam || 34 == wParam))		//pageup and pagedown key
	{
		if (33 == wParam && giPageNo > 0)
			giPageNo--;
		else if (34 == wParam && (giPageNo+1)*10 < selwordnum)
			giPageNo++;

		CString csWords = TransWords(giPageNo);
		staWnd->SetWord((LPCSTR)csWords, giPageNo, selwordnum);
	}
	else if (cslen > 0 && 13 == wParam)	//enter key
	{
		memset(code, 0, sizeof(code));
		memset(wordstr, 0, sizeof(wordstr));
		Translate(codestr, wordstr, codenum, wordnum, codeslen, wordslen);
		CorrSent();

		if (ghFocusWnd && ghFocusWnd != AfxGetMainWnd()->GetSafeHwnd())
		{
			if (codenum > 0)
			{
				staWnd->SetCode((LPCSTR)code);
				staWnd->SetSent((LPCSTR)wordstr, wordslen, wordnum, currpos);
				PostSent();
				Train(codestr, wordstr, wordslen);
			}
			Clean();
		}
		else
		{
			//Beep(0xFF, 80);
			MessageBeep(/*MB_ICONASTERISK*/0xFFFFFFFF);
		}

		gbTmpPy = FALSE;
		giLastKey = wParam;
	}
	else if (16 == wParam)	//shift; soft keyboard shift key can't send message
	{
		if (16 == giLastKey && !bShiftDown)		//! only shift key can genereate two continuous WM_HOOKKEY message!, See Keyprocedure func.
		{
			gbChsSta = !gbChsSta;
			gbChsPctSta = gbChsSta;
			staWnd->SetChsSta(gbChsSta);
			staWnd->SetChsPct(gbChsPctSta);
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -