|
Windows Mobile触摸屏(Touch Panel)截获
为了做全屏手写功能,需要把鼠标的事件全部截获过来,研究了一个星期左右,发现有三种方法可以实现。而且对每种方法已经写了测试代码。根据三种方法效果的好坏排序:
1. 用英文手写识别(TRNSCRBR)Touch的拦截代码,这种方法实现是上上策,这个是微软为手写专门在Touch 驱动中加的。
2. 自己写一个伪Touch驱动,让GWES加载这个Touch驱动,在你的Touch驱动中再调用原来的驱动。
2. 编写伪Touch驱动。
这个方法跟上面的方法其实是一个方法,只是微软来写和我们自己的区别。微软写的太复杂了,搞得我没有搞定上面的方法。可能是微软为了更好的扩展和其他应用吧。但是我们只给自己的应用用的话,那就很简单了。看代码吧
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch ( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls((HMODULE) hModule);
g_hInstTouch = LoadLibrary(TOUCH_DLL);
break;
case DLL_PROCESS_DETACH:
if(NULL != g_hInstTouch)
FreeLibrary(g_hInstTouch);
break;
}
return TRUE;
}
在DllMain中,把Touch.dll Load进来。我们只要看TouchPanelEnable和自己的一个callback函数。
// 原始Callback
PFN_TOUCH_PANEL_CALLBACK pfnOrgTouchPanelCallback = NULL;
HWND g_sipWnd = NULL;
HWND g_hwWnd = NULL;
#define HW_CLASSNAME L"CeSipEng"
INT xSaved = 0;
INT ySaved = 0;
int iMinX = 4;
int iMinY = 4;
BOOL hwTouchPanelCallback(
TOUCH_PANEL_SAMPLE_FLAGS Flags,
INT X,
INT Y
)
{
if(NULL == g_sipWnd)
{
g_sipWnd = FindWindow(L"SipWndClass", NULL);
}
g_hwWnd = GetWindow(g_sipWnd, GW_CHILD);
if(IsWindowVisible(g_hwWnd))
{
TCHAR szClassName[32];
GetClassName(g_hwWnd, szClassName, 32);
if(wcsicmp(szClassName, HW_CLASSNAME) == 0)
{
// down
if(Flags == (TouchSampleDownFlag | TouchSampleIsCalibratedFlag | TouchSampleValidFlag))
{
SendMessage(g_hwWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(X,Y));
}
// mouse
else if(Flags == (TouchSampleDownFlag | TouchSamplePreviousDownFlag | TouchSampleIsCalibratedFlag |
TouchSampleValidFlag) &&
xSaved - X > iMinX || X - xSaved > iMinX &&
ySaved - Y > iMinY || Y - ySaved > iMinY)
{
SendMessage(g_hwWnd, WM_MOUSEMOVE, 0, MAKELPARAM(X,Y));
}
// up
else if(Flags ==(TouchSampleIsCalibratedFlag |
TouchSampleValidFlag | TouchSamplePreviousDownFlag))
{
SendMessage(g_hwWnd, WM_LBUTTONUP, 0, MAKELPARAM(X,Y));
}
xSaved = X;
ySaved = Y;
return TRUE;
}
Else
// 发送给系统
return pfnOrgTouchPanelCallback(Flags, X,Y);
}
//发送给系统
return pfnOrgTouchPanelCallback(Flags, X,Y);
}
BOOL
TouchPanelEnable(
PFN_TOUCH_PANEL_CALLBACK pfnCallback
)
{
if(g_hInstTouch)
{
if (NULL == pfnTouchPanelEnable)
{
pfnTouchPanelEnable = (PFN_TOUCH_PANEL_ENABLE)GetProcAddress(g_hInstTouch,
TEXT("TouchPanelEnable"));
}
// 保存原来的Callback
pfnOrgTouchPanelCallback = pfnCallback;
// 传入自己的Callback
return pfnTouchPanelEnable(hwTouchPanelCallback);
}
return FALSE;
}
其他的函数跟TouchPanelEnable一样的形式,就是GetProcAddress一下,然后再Call一下。
差点忘记,把自己的写的注册到系统,让GWES.exe调用。
[HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\TOUCH]
“DriverName”=”MyTouch.dll”
我把伪Touch的代码放到了MyTouch中
请问做个此方面的朋友,此方法是否可行
|
|