⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ettcalib.cpp

📁 这是一个声波触摸屏驱动中的定位校准程序的源码. VC
💻 CPP
字号:
/*  Windows program. 校准屏幕 */
/*  修改历史
    2003。9。5 
	  更改 增加校准进程等待,以同步于主进程避免在之前画标记造成漏失
	2003。8。28 
	  在等待校准的过程中,改为直到校准完毕才退出,避免在“触摸时点击”
	模式下无法重复校准的错误

*/
#include <windows.h>
#include <winioctl.h>
#include "client.h"
#include "resource.h"

//常数定义
#define MAX_STRING 124
#define TEXT_WIDTH 100
#define TEXT_HEIGHT 50
#define FLAG_RADIUS 30
#define FLAG_SIZE 40
#define FLAG_PROP 4
#define FLAG_COLOR (RGB(0x10,0xef,0xef)) 
#define WM_ETTOUCH (WM_USER+1)
#define WM_ETESC (WM_USER+2)

// Global Variables:
HINSTANCE   hInst;  // The current instance
HANDLE      hthread;   //校准检测线程
DWORD       threadid;  //线程ID
TCHAR       szWindowClass[]="ETWO TOUCH Calibration";  // The name
TCHAR       szhelptext[]=" 压ESC键放弃屏幕校准 ";
HWND        hWnd;   // Handle to our window
HANDLE      hdev;     //设备指针
BOOL        frun,fcal,fend,ffir; //线程运行标志、校准成功标志、程序运行标志、第一次运行标志
_CALIBRATION_DATA set_cal;   //校准结果
//BYTE andbit[4*32]={0xff};
//BYTE xorbit[4*32]={0};

// Declare functions
DWORD   WINAPI ThreadProcess1(LPVOID );    //线程运行函数
ATOM    RegisterWindowClass(HINSTANCE hInstance);
BOOL    InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
void    DrawFlag(HWND,int,int);            //定位标志绘制函数
void    WriteRegKey(void);                 //注册表写入函数

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	MSG msg;

	RegisterWindowClass(hInstance);
	hInst = hInstance;
	ffir=true;
	frun=false;


	// Initialize application
	if (!InitInstance (hInstance, nCmdShow))  return FALSE;
	
	// Main message loop:
	fcal=FALSE;
	hdev=CreateFile("\\\\.\\ettouch",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	{
		char s[100000];
		unsigned long	status,n;
		status = ReadFile (hdev, s, 5000, &n, 0);
		status++;
	}
	if (!(hdev==INVALID_HANDLE_VALUE))  { //设备指针
		HDC hdct;
		hdct=GetDC(hWnd);
//		frun=false;
		fend=TRUE;
        while (fend)  {
			ShowCursor(FALSE);   
			hthread=CreateThread(NULL,0,ThreadProcess1,hdct,NULL,&threadid);  //生成校准线程
			if (hthread!=NULL)  {
				while (GetMessage(&msg, NULL, 0, 0))  {
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				SuspendThread(hthread);
				CloseHandle(hthread);
			} else {
				MessageBox(hWnd,"系统错误!资源不足",NULL,MB_OK);  //线程无法生成
				fend=FALSE;
			}
		}
        CloseHandle(hdev);
		ReleaseDC(hWnd,hdct);
        return msg.wParam;
    }
	return (MessageBox(hWnd,"驱动程序没有加载!",NULL,MB_OK));  //打开设备失败
}
//  Register the window class.
//
ATOM RegisterWindowClass(HINSTANCE hInstance) {   //注册窗口
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style       = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = (WNDPROC)WndProc;
	wcex.cbClsExtra  = 0;
	wcex.cbWndExtra  = 0;
	wcex.hInstance   = hInstance;
    wcex.hIcon       = LoadIcon(hInstance,(LPCTSTR)IDI_ASTERISK);
	wcex.hIcon       = LoadIcon(hInstance,(LPCTSTR)IDI_ICON1);
	wcex.hCursor       = LoadCursor(NULL,  IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW);//+1);
	wcex.lpszMenuName  = NULL; //(LPCSTR)IDC_SECOND;
	wcex.lpszClassName = szWindowClass;
	wcex.hIconSm       = NULL; //LoadIcon(wcex.hInstance,(LPCTSTR)IDI_SMALLICON);
	return (RegisterClassEx(&wcex));
}
//  Create the main window
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){
	hWnd = CreateWindow(//WS_EX_DLGMODALFRAME,
                       szWindowClass, NULL, //szTitle,
                       WS_MAXIMIZE | WS_POPUP,//WS_OVERLAPPEDWINDOW,
                       CW_USEDEFAULT,0,CW_USEDEFAULT,0,NULL,NULL,hInstance, NULL);
	if (!hWnd)	return FALSE;

	ShowWindow(hWnd, SW_MAXIMIZE);
	UpdateWindow(hWnd);
	return TRUE;
}
//  Message processor.
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
	DWORD	BytesReturned;
	int wmId;//, wmEvent;
	switch (message)  {
	case WM_DESTROY:
		if (fcal)	{    //calibrate success
			WriteRegKey();
		}
		PostQuitMessage(0);
		break;
	case WM_KEYUP:
		wmId=LOWORD(wParam);
		if (wmId==VK_ESCAPE)	{  //escape键退出
			TerminateThread(hthread,0xFFFFFFFF);
			ShowCursor(TRUE);
			fcal=FALSE;
			fend=FALSE;
			PostMessage(hWnd,WM_DESTROY,0,0);  
			DestroyWindow(hWnd);
		}
		break;
	case WM_ETTOUCH:
		ShowCursor(TRUE);
		if (MessageBox(hWnd," 鼠标是否正确随指尖移动? y/n","确认",MB_YESNO)==IDYES) {
//			TerminateThread(hthread,0xFFFFFFFF);
			fcal=TRUE;
			fend=FALSE;
			frun=FALSE;
			PostMessage(hWnd,WM_DESTROY,0,0);
		} else {	//未得到确认则恢复原有的数据
			ShowCursor(FALSE);
			fcal=FALSE;
			DeviceIoControl(hdev,IOCTL_ETTOUCH_UPDATE_SETTING,NULL,0,NULL,0,&BytesReturned,NULL);
			frun=TRUE;
		}
		break;
	case WM_PAINT:	{
		RECT rclient,rc;
		PAINTSTRUCT ps;
		HDC hdc;
		int bkmode;

		hdc=GetDC(hWnd);
		BeginPaint(hWnd,&ps);
		GetClientRect(hWnd,&rclient);  //获取屏幕尺寸
		rc.top=rclient.bottom/2-100;
		rc.bottom=rclient.bottom/2+100;
		rc.left=rclient.right/2-300;
		rc.right=rclient.right/2+300;
		bkmode=SetBkMode(hdc,TRANSPARENT);

		//写说明文本
		DrawText(hdc,szhelptext,sizeof(szhelptext)-1,&rc,DT_CENTER | DT_VCENTER);
		SetBkMode(hdc,bkmode);
		EndPaint(hWnd,&ps);
		ReleaseDC(hWnd,hdc);
		if (ffir) {    //第一次处理paint消息时启动校准进程
			frun=true;
			ffir=false;
		}
		break;
	}

	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

void DrawFlag(HWND hwnd,int x,int y)	 //绘制校准标志
{
    HPEN hpen,holdpen;
	int noldmode;
	HDC hdc;

	hdc=GetDC(hwnd);
	hpen=CreatePen(PS_SOLID,2,FLAG_COLOR);
	holdpen=(HPEN)SelectObject(hdc,hpen);
	noldmode=SetROP2(hdc,R2_XORPEN);      //异或写入,方便擦除
	Arc(hdc,x-FLAG_RADIUS+10,y-FLAG_RADIUS+10,x+FLAG_RADIUS-10,y+FLAG_RADIUS-10,x-FLAG_RADIUS+10,y-FLAG_RADIUS+10,x-FLAG_RADIUS+10,y-FLAG_RADIUS+10);
	Arc(hdc,x-FLAG_RADIUS,   y-FLAG_RADIUS,   x+FLAG_RADIUS,   y+FLAG_RADIUS,   x-FLAG_RADIUS,   y-FLAG_RADIUS,   x-FLAG_RADIUS,   y-FLAG_RADIUS   );
	MoveToEx(hdc,x-FLAG_SIZE,y,NULL);
	LineTo(hdc,x+FLAG_SIZE,y);
	MoveToEx(hdc,x,y-FLAG_SIZE,NULL);
	LineTo(hdc,x,y+FLAG_SIZE);
	SetROP2(hdc,noldmode);
	SelectObject(hdc,holdpen);
	DeleteObject(hpen);
	ReleaseDC(hwnd,hdc);
}

void WriteRegKey()	{//注册表写入
	HKEY hkey;
	TCHAR path[] = "System\\CurrentControlSet\\Services\\ETTouch\\Parameters";

	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,path,NULL,KEY_SET_VALUE,&hkey)==ERROR_SUCCESS)  {
		RegSetValueEx(hkey,"XHigh",NULL,REG_DWORD,(unsigned char*)(&set_cal.nBorderRight),4);
		RegSetValueEx(hkey,"XLow",NULL,REG_DWORD,(unsigned char*)(&set_cal.nBorderLeft),4);
		RegSetValueEx(hkey,"YHigh",NULL,REG_DWORD,(unsigned char*)(&set_cal.nBorderBottom),4);
		RegSetValueEx(hkey,"YLow",NULL,REG_DWORD,(unsigned char*)(&set_cal.nBorderTop),4);
		RegSetValueEx(hkey,"XOffset",NULL,REG_DWORD,(unsigned char*)(&set_cal.nXOffset),4);
		RegSetValueEx(hkey,"YOffset",NULL,REG_DWORD,(unsigned char*)(&set_cal.nYOffset),4);

		RegCloseKey(hkey);
	} else 
		MessageBox(hWnd,"无法打开注册表中的相关子键!",NULL,MB_OK);
}

DWORD WINAPI ThreadProcess1(LPVOID param)	{//校准处理线程
	RECT	rclient;
	DWORD	BytesReturned;
	int		xleft,xright,ytop,ybottom,x,y,xhigh,xlow,yhigh,ylow;//,fcur;
	_CALIBRATE_DATA	cal_info;

	while (!frun) {   Sleep(100);    }      //等待主进程通知            
	GetClientRect(hWnd,&rclient);  //获取屏幕尺寸 
	while(frun )	{
		x=rclient.right/4;
		y=rclient.bottom/4;
		DrawFlag(hWnd,x,y);          //绘制第一点标记
		DeviceIoControl(hdev,IOCTL_ETTOUCH_RESET_CALINFO,NULL,0,NULL,0,&BytesReturned,NULL);  //设置驱动为待校准
		cal_info.Cal_State=CALIBRATE_NOTREADY;

		while ((cal_info.Cal_State!=CALIBRATE_READY))  {
			//读取第一点原始数据
			DeviceIoControl(hdev,IOCTL_ETTOUCH_GET_CALINFO,NULL,0,&cal_info,sizeof(_CALIBRATE_DATA),&BytesReturned,NULL);
			Sleep(50);
		}
		xleft=cal_info.TouchX;
		ytop=cal_info.TouchY;
		DrawFlag(hWnd,x,y);	//擦除第一点
		x=x*(4-1);			// right*3/4
		y=y*(4-1);			// bottom*3/4
		DrawFlag(hWnd,x,y);	//绘制第二点
		DeviceIoControl(hdev,IOCTL_ETTOUCH_RESET_CALINFO,NULL,0,NULL,0,&BytesReturned,NULL);
		cal_info.Cal_State=CALIBRATE_NOTREADY;
		while ((cal_info.Cal_State!=CALIBRATE_READY))  {
			DeviceIoControl(hdev,IOCTL_ETTOUCH_GET_CALINFO,NULL,0,&cal_info,sizeof(_CALIBRATE_DATA),&BytesReturned,NULL);
			Sleep(50);
		}
		xright=cal_info.TouchX;
		ybottom=cal_info.TouchY;
		DrawFlag(hWnd,x,y);			//擦除第二点

		//计算新的数据边界
		set_cal.nBorderLeft	  = rclient.left;
		set_cal.nBorderRight  = rclient.right;
		set_cal.nBorderTop	  = rclient.top;
		set_cal.nBorderBottom = rclient.bottom;

		xhigh=xright+(xright-xleft)/2;
		xlow=xleft-(xright-xleft)/2;
		if (xlow<=0) xlow=0;       //检查原始数据的有效性
		if (xhigh>2048) xhigh=2048;
		yhigh=ybottom+(ybottom-ytop)/2;
		ylow=ytop-(ybottom-ytop)/2;
		if (ylow<=0) ylow=0;
		if (yhigh>2048) yhigh=2048;
		set_cal.nBorderLeft=xlow;  //计算新的数据边界
		set_cal.nBorderRight=xhigh;
		set_cal.nBorderTop=ylow;
		set_cal.nBorderBottom=yhigh;
		set_cal.nXOffset=0;
		set_cal.nYOffset=0;

		//启用新的边界数据
		DeviceIoControl(hdev,IOCTL_ETTOUCH_UPDATE_CAL,&set_cal,sizeof(_CALIBRATION_DATA),NULL,0,&BytesReturned,NULL);
		frun=false;
		PostMessage(hWnd,WM_ETTOUCH,0,0);  //发出校准结束信号
		while (!frun)  {  Sleep(100);  }   //等待主进程重新启动
		//{ if (frun) break;  } ;
	}
	return 1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -