RAM-based Registy方式下触摸信息保存和重置一种思路

来源:互联网 发布:云计算工程师 编辑:程序博客网 时间:2024/06/01 10:09

在此种方式下,因为注册表信息重启后就没有了,所以相应的触摸校准信息也会丢失并恢复到出厂值。对于保存可以由应用在校准后读出来保存到外部文件,这个容易实现。不过对于重置,因为触摸信息是由gwes加载并生效的,因此就算应用从文件中读取并设置注册表也没有效果。对于触摸校准gwes会调用一个TouchCalibrateUI_Done来使校准有效,但是它不对应用开放,在网上找到了一个思路觉得可行,只是没有验证。
CalibrUi.lib作为gwes的一部分,在sysgen时被组装进gwes.exe;修改calibrui.cpp,在其中加入判断代码,如果应用程序调用TouchCalibrate()进行校正之前设置了一个指定名字的事件,则calibrui.lib不再重新校正,而是直接从注册表中恢复校正数据,否则进行再次校正;具体修改为:在函数TouchCalibrateUI_DrawMainScreen中加入判断,如果不需要重新校正就直接返回;在函数TouchCalibrateUI_HandleUserInputMessage中加入判断,如果不需要重新校正则调用TouchCalibrateRestoreFromRegistry()和TouchCalibrationAbort(),然后返回;这样,注册表中的校正数据就会被gwes重新读取,应用程序在这之前可以从文件中读取校正数据到注册表中,从而实现触摸屏校正数据的文件形式保存
引用自:http://xiaoxiongwinnie.blogbus.com/logs/30161249.html

==========================================================
又找到了另外一种实现思路

第一步,定义自定义触摸屏校准值保存的注册表位置

#define PSCAL_REGPATH L"SOFTWARE\\ANYCOMPAY\\TOUCH"
#define CALDATA_REGVAL L"CalibrationData"


第二步,在D:\WINCE600\PLATFORM\FreeScale51\COMMON\SRC\SOC\COMMON_FSL_V2\TOUCH\.\tchmain.c中添加如下函数,从指定位置读取五个样点的位置

static ULONG
GetPsTouchCalData(int* iUncalX,int* iUncalY)
{
HKEY hKey;
BOOL bReadOk=FALSE;
WCHAR tcCalData[64]=L"524,523 796,244 796,808 252,809 258,233";

if(ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE, PSCAL_REGPATH, 0,KEY_READ, &hKey))
{
DWORD dwLen = sizeof(tcCalData);
if(ERROR_SUCCESS==RegQueryValueEx(hKey, CALDATA_REGVAL, NULL, NULL, (LPBYTE)tcCalData, &dwLen))
{
   bReadOk = TRUE;
}
RegCloseKey(hKey);
}
if(bReadOk)
{
//524,523 796,244 796,808 252,809 258,233
swscanf(tcCalData,L"%d,%d %d,%d %d,%d %d,%d %d,%d",(iUncalX+0),(iUncalY+0),(iUncalX+1),(iUncalY+1),
   (iUncalX+2),(iUncalY+2) ,(iUncalX+3),(iUncalY+3),(iUncalX+4),(iUncalY+4));
}
return bReadOk;
}

第三步,在D:\WINCE600\PLATFORM\FreeScale51\COMMON\SRC\SOC\COMMON_FSL_V2\TOUCH\.\tchmain.c中添加如下线程函数,等待事件,执行应用自定义触摸屏校准值

#define POT_NUM 5
static ULONG
TouchApplyRegistryData(
    PVOID   Reserved //@parm Reserved, not used.
    )
{
BOOL bStop=FALSE;
//五个点分别为中,左上,左下,右下,右上
//实例屏幕尺寸为800*640
int iScreenX[POT_NUM] = {400,160,160,640,640};//(1/2 1/5 1/5 4/5 4/5)*width
int iScreenY[POT_NUM] = {240,96,384,384,96}; //(1/2 1/5 4/5 4/5 1/5)*higth
int iUncalX[POT_NUM] = {0};
int iUncalY[POT_NUM] = {0};
HANDLE hSetApplyEvent = CreateEvent( NULL, FALSE,FALSE, L"APPLY_CAL_REGISTRY");
UNREFERENCED_PARAMETER(Reserved);
RETAILMSG(TRUE,(L"Go into TouchApplyRegistryData ...............................\r\n"));
while(!bStop)
{
WaitForSingleObject( hSetApplyEvent, INFINITE);
if(GetPsTouchCalData(iUncalX,iUncalY))
{
   TouchPanelSetCalibration(POT_NUM,iScreenX,iScreenY,iUncalX,iUncalY);
   RETAILMSG(TRUE,(L"TouchApplyRegistryData call Finished ...............................\r\n"));
}
}
CloseHandle(hSetApplyEvent);
ExitThread(1);
    return ( TRUE );
}

如何确定取样点屏幕的坐标位置,在TouchPanelReadCalibrationPoint中最后打印RETAILMSG(TRUE,(L"TouchPanelReadCalibrationPoint : %d %d\r\n",*pRawX,*pRawY));
即可知道校准时系统取了那几个样点及其具体屏幕坐标,也就是TouchPanelSetCalibration函数的第二个和第三个参数,我得出的结论是,五个点的时候规律为:

X:(1/2 1/5 1/5 4/5 4/5)*width
Y:(1/2 1/5 4/5 4/5 1/5)*higth

第四步,在D:\WINCE600\PLATFORM\FreeScale51\COMMON\SRC\SOC\COMMON_FSL_V2\TOUCH\.\tchmain.c中TouchPanelEnable函数中添加如下代码,启动第三部中的线程
hSetApplyThread = CreateThread( NULL, 0, TouchApplyRegistryData, 0, 0, NULL);

第五步,在应用程序调用TouchCalibrate 后,将系统默认保存的cal值(HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\TOUCH)复制到自定义保存的位置(PSCAL_REGPATH)
   并将"SOFTWARE\\ANYCOMPAY"下的注册表全部保存到SD或Flash,存储为abc.reg.

第六步,系统每次起来后将abc.reg导入到系统注册表中,并发送”"APPLY_CAL_REGISTRY"“event到touch驱动,触发驱动更新自定义cal值

引用自:http://hi.baidu.com/cqit2001/blog/item/d0a547fc1a64a78db801a062.html