在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的值。

  1. HINSTANCE  hinstance = LoadLibrary(_T("touch.dll"));
  2.  
  3. BOOL (*pTouchPanelGetDeviceCaps)(INT iIndex, LPVOID lpOutput);
  4. pTouchPanelGetDeviceCaps = (BOOL(*)(INT iIndex, LPVOID lpOutput))GetProcAddress(hinstance, _T("TouchPanelGetDeviceCaps"));
  5.  
  6. TPDC_CALIBRATION_POINT_COUNT point_count;
  7.  
  8. if (pTouchPanelGetDeviceCaps != NULL)
  9. {
  10.     (*pTouchPanelGetDeviceCaps)(TPDC_CALIBRATION_POINT_COUNT_ID, &point_count);
  11. }

2、这样子,在point_count.cCalibrationPoints里就包含了校准所需要的点数,一般来说,都是5个点,四个角每个角一个,屏幕中央一个。然后再调用TouchPanelGetDeviceCaps(),但给予不同的参数TPDC_CALIBRATION_POINT_ID,把液晶屏真实的大小传入TPDC_CALIBRATION_POINT结构中,用一个循环来处理这5个点。

  1. for (int i = 0; i < point_count.cCalibrationPoints; i++)
  2. {
  3.     TPDC_CALIBRATION_POINT point;
  4.     point.PointNumber = i;
  5.     point.cDisplayWidth = 240;
  6.     point.cDisplayHeight = 320;
  7.     if (pTouchPanelGetDeviceCaps != NULL)
  8.     {
  9.         (*pTouchPanelGetDeviceCaps)(TPDC_CALIBRATION_POINT_ID, &point);
  10.     }
  11.     ......
  12. }

3、这样,5次的结果中,point.CalibrationX和point.CalibrationY分别为(120,160)(24,32)(24,288)(216,288)(216,32),这5个坐标也就是系统根据液晶屏大小计算得出的要效准的点的坐标。这时应该根据系统计算得出的点的坐标,在液晶屏相应的位置画上标记,让用户去点击,获得用户点击的触摸屏坐标,循环5次,把5次的结果存入数组中,以供将来设置使用。

  1. BOOL (*pTouchPanelReadCalibrationPoint)(INT* pRawX, INT* pRawY);
  2. pTouchPanelReadCalibrationPoint = (BOOL(*)(INT* pRawX, INT* pRawY))GetProcAddress(hinstance, _T("TouchPanelReadCalibrationPoint"));
  3.  
  4. INT x = 0, y = 0;
  5. if (pTouchPanelReadCalibrationPoint != NULL)
  6. {
  7.     (*pTouchPanelReadCalibrationPoint)(&x, &y)
  8. }

4、最后,调用TouchPanelSetCalibration,设置数据并启用。

  1. INT32 ScreenX[5]
  2. INT32 ScreenY[5]
  3. INT32 TouchX[5]
  4. INT32 TouchY[5]
  5. BOOL (*pTouchPanelSetCalibration)(INT32 cCalibrationPoints, INT32* pScreenXBuffer, INT32* pScreenYBuffer, INT32* pUncalXBuffer, INT32* pUncalYBuffer);
  6. pTouchPanelSetCalibration = (BOOL(*)(INT32 cCalibrationPoints, INT32* pScreenXBuffer, INT32* pScreenYBuffer, INT32* pUncalXBuffer, INT32* pUncalYBuffer))GetProcAddress(hinstance, _T("TouchPanelSetCalibration"));
  7.  
  8. if (pTouchPanelSetCalibration != NULL)
  9. {
  10.     (*pTouchPanelSetCalibration)(5, ScreenX, ScreenY, TouchX, TouchY)
  11. }

5、这样就能完成校验了。TouchPanelSetCalibration()会根据那些坐标数组校验,合法的话就返回TRUE。

上面的是实验思路和代码片断,具体代码我正在调试中,貌似问题不少,调通后再对思路和代码进行修正吧,=.= ,真是一个累人的工作。。。

读过这篇日志的读者同时也读了:

相关日志:

4 条评论 »

  1. zouhaiyuan 于 2007-11-13 @ 16:15:41 留言

    TouchPanelReadCalibrationPoint这个函数怎么总是返回FALSE,并且获得的x,y也一直是0,请问这该如何做???

  2. lollipop 于 2007-11-14 @ 00:41:06 留言

    我到现在也没调通这个。PB里面也没有相关的代码。。。

  3. 俺踏月色而来 于 2007-12-17 @ 11:47:17 留言

    屏幕校正这个问题搞定了吗?我的要求比较低,直接用系统校正之后,把注册表导出来,
    现在想问问有什么办法直接用一个程序把注册表中的数据生效呢?这样可以不用每次启动都去校正一次。
    MAIL我:AndrewWang@sina.com,谢谢

  4. 匿名 于 2008-05-07 @ 10:15:49 留言

    请问:触摸屏校准这个问题你搞定了吗?调通没有?我现在刚开始做这个,想请教几个问题。QQ:120226320

RSS 为此帖反馈评论 · 反向跟踪 网站

留条评论