漫談WinCE的手寫(xiě)識(shí)別技術(shù)(二)
{
goto END;
}
//Get the character from recognizer
if(HWXGETRESULTS(m_hrc,iCount,0,1,phwxResults) == FALSE)
{
goto END;
}
//Set the character to the stored buffer
for(i = 0; i iNum; i++)
{
if(i == 0)
{
if(phwxResults[i].rgChar[0] != 0)
{
pWchar[iGetNum ++] = phwxResults[i].rgChar[0];
}
else
{
break;
}
}
else
{
//The indxBox member also store the character
if(phwxResults[i].indxBox != 0)
{
pWchar[iGetNum ++] = phwxResults[i].indxBox ;
}
else
{
break;
}
if(phwxResults[i].rgChar[0] != 0)
{
pWchar[iGetNum ++] = phwxResults[i].rgChar[0];
}
else
{
break;
}
}
}
END:
if(phwxResults != NULL)
{
delete [] phwxResults;
}
return iGetNum;
}
//Descriptiong:
// Input the stroke
//Parameter:
// lpPnt: [in] Pointer to the stroke POINT
// iCount: [in] The count of the lpPnt
// scale: [in] The scale base of lpPnt
BOOL CRecognizer::InputStroke(POINT *lpPnt, int iCount, ScaleType scale)
{
BOOL bRes = FALSE;
int i = 0;
POINT *pt;
pt = new POINT[iCount];
if(pt == NULL)
{
goto END;
}
for(i = 0; i iCount; i++)
{
pt[i] = lpPnt[i];
if(scale == SCALE_APPWND)
{
//Convert to the screen scale
pt[i].x *= 4;
pt[i].y *= 4;
MapWindowPoints(m_hWndRecog, HWND_DESKTOP, pt[i], 1);
}
}
//Input stroke
bRes = HWXINPUT(m_hrc,pt,iCount,0);
if(bRes == FALSE)
{
goto END;
}
bRes = TRUE;
END:
if(pt != NULL)
{
delete [] pt;
}
return bRes;
}
不知道大家看到這段代碼有什么感覺(jué),反正我是挺高興的,因?yàn)樽屛覐姆爆嵉淖R(shí)別過(guò)程中脫離出來(lái).
關(guān)于代碼,也許最讓人疑惑的可能是這兩個(gè)宏:RECOGNIZE_FUNCTION_FROM_DLL,RECOGNIZE_FUNCTION_FROM_LIB.
顧名思義,RECOGNIZE_FUNCTION_FROM_DLL表明識(shí)別函數(shù)調(diào)用是來(lái)源于動(dòng)態(tài)鏈接庫(kù)(DLL),同理,RECOGNIZE_FUNCTION_FROM_LIB則是編譯的時(shí)候鏈接到lib庫(kù).為什么需要定義這兩個(gè)宏呢?因?yàn)樵跇?biāo)準(zhǔn)的SDK下,如果直接包含recog.h后調(diào)用相關(guān)識(shí)別函數(shù),是會(huì)報(bào)link錯(cuò)誤.因?yàn)闃?biāo)準(zhǔn)的SDK是不包含任何手寫(xiě)識(shí)別組件的.從調(diào)試的便利性來(lái)說(shuō),這時(shí)候如果只拷貝識(shí)別庫(kù)到模擬器就可以順利測(cè)試程序,絕對(duì)比重新定制一個(gè)包含手寫(xiě)識(shí)別引擎的系統(tǒng)要來(lái)得方便.
在示例代碼中,因?yàn)槭亲R(shí)別繁體中文,所以包含的動(dòng)態(tài)鏈接庫(kù)為:hwxcht.dll.如果需要識(shí)別其它文字,則只要更改該動(dòng)態(tài)鏈接庫(kù)名稱(chēng)即可.當(dāng)然,還要更改DEFAULT_ALC宏,這個(gè)宏定義了識(shí)別的范圍.
因?yàn)槭纠a中的識(shí)別函數(shù)全部是宏定義,具體意義根據(jù)函數(shù)的來(lái)源而不同,所以RECOGNIZE_FUNCTION_FROM_DLL和RECOGNIZE_FUNCTION_FROM_LIB同一時(shí)間只能定義一個(gè).如果兩個(gè)都定義,毫無(wú)疑問(wèn),出錯(cuò)!^_^
最后,用偽代碼做范例說(shuō)明如何使用該封裝類(lèi),以此做本章結(jié)尾:
CRecognizer recog;
Rect rcWnd;
/*rcWnd 獲取應(yīng)用窗口hWnd的大小*/
//初始化
//直接賦值窗口坐標(biāo),函數(shù)體內(nèi)部會(huì)根據(jù)標(biāo)志直接轉(zhuǎn)換為屏幕坐標(biāo)
recog.Initialize(hWnd,rcWnd,SCALE_APPWND);
評(píng)論