在WinCE下调用校准触摸屏的API和源代码(2)
注意:以下内容仅为思路草稿,调试中,尚未完成,仅供参考。
今天的调试结果,这个方法有较大问题,在完成校验执行FreeLibrary(hinstance)后,OS失去了TouchPanel的控制。于是想参考CoreDll.dll里的TouchCalibrate()的实现,为了找这段代码我特意装了Platform Builder,却发现该死的微软只给了这个API的声明,实现部分的源代码根本木有,网上放狗搜也木有找到,真是要崩溃了!!!
在在WinCE下调用校准触摸屏的API和源代码(1)中的主要问题是怎样调用API来进行校准操作,这个问题解决后,接下来要解决的是怎样取得校准所得到的数据,以及下次开机时直接使用这些数据而不必再次校准。为了完成这个任务,我准备先分析触摸屏的驱动程序touch.dll文件导出的API,以及其实现。在我所用的MX21_MP SDK里,touch.def的EXPORT部分是这样的:
EXPORTS
STDAPI(TouchPanelGetDeviceCaps,8);
STDAPI(TouchPanelEnable,4);
STDAPI(TouchPanelDisable,0);
STDAPI(TouchPanelSetMode,8);
STDAPI(TouchPanelReadCalibrationPoint, 8);
STDAPI(TouchPanelReadCalibrationAbort, 0);
STDAPI(TouchPanelSetCalibration, 20);
STDAPI(TouchPanelCalibrateAPoint, 16);
STDAPI(TouchPanelPowerHandler, 4);
; @CESYSGEN IF WCESHELLFE_MODULES_TRANSCRIBER || SHELLW_MODULES_CGRTOUCH
TouchReset
TouchRegisterWindow
TouchUnregisterWindow
TouchSetValue
TouchGetValue
TouchCreateEvent
TouchGetFocusWnd
TouchGetLastTouchFocusWnd
TouchGetQueuePtr
; @CESYSGEN ENDIF
思路是这样的:
1、定义一个TPDC_CALIBRATION_POINT_COUNT类型(该类型定义在tchddi.h中)的变量point_count,通过调用TouchPanelGetDeviceCaps来得到point_count的值。
- HINSTANCE hinstance = LoadLibrary(_T("touch.dll"));
- BOOL (*pTouchPanelGetDeviceCaps)(INT iIndex, LPVOID lpOutput);
- pTouchPanelGetDeviceCaps = (BOOL(*)(INT iIndex, LPVOID lpOutput))GetProcAddress(hinstance, _T("TouchPanelGetDeviceCaps"));
- TPDC_CALIBRATION_POINT_COUNT point_count;
- if (pTouchPanelGetDeviceCaps != NULL)
- {
- (*pTouchPanelGetDeviceCaps)(TPDC_CALIBRATION_POINT_COUNT_ID, &point_count);
- }
2、这样子,在point_count.cCalibrationPoints里就包含了校准所需要的点数,一般来说,都是5个点,四个角每个角一个,屏幕中央一个。然后再调用TouchPanelGetDeviceCaps(),但给予不同的参数TPDC_CALIBRATION_POINT_ID,把液晶屏真实的大小传入TPDC_CALIBRATION_POINT结构中,用一个循环来处理这5个点。
- for (int i = 0; i < point_count.cCalibrationPoints; i++)
- {
- TPDC_CALIBRATION_POINT point;
- point.PointNumber = i;
- point.cDisplayWidth = 240;
- point.cDisplayHeight = 320;
- if (pTouchPanelGetDeviceCaps != NULL)
- {
- (*pTouchPanelGetDeviceCaps)(TPDC_CALIBRATION_POINT_ID, &point);
- }
- ......
- }
3、这样,5次的结果中,point.CalibrationX和point.CalibrationY分别为(120,160)(24,32)(24,288)(216,288)(216,32),这5个坐标也就是系统根据液晶屏大小计算得出的要效准的点的坐标。这时应该根据系统计算得出的点的坐标,在液晶屏相应的位置画上标记,让用户去点击,获得用户点击的触摸屏坐标,循环5次,把5次的结果存入数组中,以供将来设置使用。
- BOOL (*pTouchPanelReadCalibrationPoint)(INT* pRawX, INT* pRawY);
- pTouchPanelReadCalibrationPoint = (BOOL(*)(INT* pRawX, INT* pRawY))GetProcAddress(hinstance, _T("TouchPanelReadCalibrationPoint"));
- INT x = 0, y = 0;
- if (pTouchPanelReadCalibrationPoint != NULL)
- {
- (*pTouchPanelReadCalibrationPoint)(&x, &y);
- }
4、最后,调用TouchPanelSetCalibration,设置数据并启用。
- INT32 ScreenX[5];
- INT32 ScreenY[5];
- INT32 TouchX[5];
- INT32 TouchY[5];
- BOOL (*pTouchPanelSetCalibration)(INT32 cCalibrationPoints, INT32* pScreenXBuffer, INT32* pScreenYBuffer, INT32* pUncalXBuffer, INT32* pUncalYBuffer);
- pTouchPanelSetCalibration = (BOOL(*)(INT32 cCalibrationPoints, INT32* pScreenXBuffer, INT32* pScreenYBuffer, INT32* pUncalXBuffer, INT32* pUncalYBuffer))GetProcAddress(hinstance, _T("TouchPanelSetCalibration"));
- if (pTouchPanelSetCalibration != NULL)
- {
- (*pTouchPanelSetCalibration)(5, ScreenX, ScreenY, TouchX, TouchY);
- }
5、这样就能完成校验了。TouchPanelSetCalibration()会根据那些坐标数组校验,合法的话就返回TRUE。
上面的是实验思路和代码片断,具体代码我正在调试中,貌似问题不少,调通后再对思路和代码进行修正吧,=.= ,真是一个累人的工作。。。


zouhaiyuan 于 2007-11-13 @ 16:15:41 留言 :
TouchPanelReadCalibrationPoint这个函数怎么总是返回FALSE,并且获得的x,y也一直是0,请问这该如何做???
lollipop 于 2007-11-14 @ 00:41:06 留言 :
我到现在也没调通这个。PB里面也没有相关的代码。。。
俺踏月色而来 于 2007-12-17 @ 11:47:17 留言 :
屏幕校正这个问题搞定了吗?我的要求比较低,直接用系统校正之后,把注册表导出来,
现在想问问有什么办法直接用一个程序把注册表中的数据生效呢?这样可以不用每次启动都去校正一次。
MAIL我:AndrewWang@sina.com,谢谢
匿名 于 2008-05-07 @ 10:15:49 留言 :
请问:触摸屏校准这个问题你搞定了吗?调通没有?我现在刚开始做这个,想请教几个问题。QQ:120226320