윈도 임베디드 CE 시스템 개발



Stop! 윈도 임베디드 CE 시스템 개발!-9
GPS 디바이스 드라이버의 개발


이번 호에는 윈도 임베디드 CE 6.0에서 새롭게 추가된 GPS 드라이버와 윈도 임베디드 CE 6.0 R3에서 소개된 터치 및 제스쳐 기능의 사용에 대하여 살펴 보고자 한다. 터치 및 제스터의 기능은 응용 프로그램에서 터치의 다양한 효과를 이용하여 사용자 인터페이스 및 동작 효과를 구성하는데 유용한 기능을 제공할 것이다.

글: 라영호/ ratharn@naver.com

연재순서

01회. 윈도우 임베디드 시스템 테스팅
02회. 부트로더를 통한 개발 준비  
03회. 빌드이야기
04회. 윈도우 임베디드 CE 6.0 커널 이야기 
05회. 디바이스 드라이버 개발
06회. 윈도우 임베디드 시스템 디버깅
07회. 디스플레이 디바이스 드라이버, 윈도우 임베디드 시스템, 3D의 세계로…
08회. 플래시 메모리를 저장 장치로
09회. GPS 디바이스 드라이버의 개발
10회. 선 없는 세상으로
1 1회. 멀티미디어 세상속으로 -Ⅰ
12회. 멀티미디어 세상속으로 -Ⅱ

 

필 / 자 / 소 / 개

필자는 윈도우 모바일 관련 스마트폰 개발과 윈도우CE 관련 장치를 개발하고 있다. 개인적으로 운영하고 있는 윈도우CE에 관한 블로그(www.embeddedce.com)를 통해 윈도우CE 개발에 대한 다양한 생각과 방법론을 함께 생각해 보고자 노력 중이다. 아울러 윈도우CE의 포팅 뿐만 아니라 개발에서부터 최종 제품이 나오기까지 거쳐야 할 다양한 테스트 및 신뢰성 문제에도 관심을 가지고 있다.

GPS 디바이스 드라이버

GPS 디바이스 드라이버는 사실 크게 문제가 된 적이 없다. 시리얼 포트를 통해 NMEA 형식으로 전달된 GPS 정보를 분석하여 위치 정보를 파악하고 사용하면 되는 것이 GPS 드라이버다. 여기에 GPS 모듈에 대한 전원을 관리하고 GPS 모듈의 펌웨어 업데이트 기능을 제공하면 대부분 GPS 드라이버로써의 역할을 다 하는 것이다.
하지만 GPS 장치가 윈도 모바일이나 윈도 임베디드 CE 장치의 일반적으로 탑재되는 장치로 자리 잡고 응용 프로그램에서 보다 효율적으로 이용할 수 있게 하는 방법이 요구 되었다. 이러한 요구 사항을 통해 나온 드라이버가 GPS 드라이버다. 흔히 GPSID(GPS Intermediate Driver)라는 이름으로 불린다. GPS 드라이버는 윈도 모바일 스마트폰 시스템에서 먼저 사용이 되었고 윈도 임베디드 CE 6.0에 새로운 드라이버 컴포넌트로 탑재가 되었다. GPSID의 역할을 살펴보면 다음과 같다.

·응용 프로그램에서 GPS 장치에 관한 표준 API 제공
·GPS 데이터의 분석 및 위치 좌표 산출을 GPSID에서 통합하여 처리함.
·여러 응용 프로그램에서 GPS 정보를 동시에 사용할 수 있도록 기능 제공
·위치 정보 처리에 관한 표준 프레임 워크를 제공
·다양한 GPS 장치를 통합적으로 관리할 수 있도록 기능 제공


그림 1은 GPS 드라이버의 구조를 간략히 설명하는 그림이다. GPS 드라이버는 여러 GPS 하드웨어로부터 GPS 정보를 받을 수 있는 구조로 구성되었다. 또한 파일 형태로 GPS 정보를 읽어 들어 처리하거나 저장할 수 있도록 되어 있다.
GPS의 정보를 분석하기 위한 NMEA 파서가 존재하며 이 NMEA 파서가 GPS 하드웨어로부터 전달된 GPS 정보인 NMEA 정보를 분석하여 사용할 수 있게 한다. 여러 응용 프로그램에서 GPS 정보를 이용할 수 있도록 API 레이어가 존재한다.
그림 2와 같이 플랫폼 빌더에는 GPS 드라이버를 사용할 수 있도록 여러 가지 GPS 드라이버 관련 컴포넌트들이 포함되어 있다.

·GPS Intermediate Driver - GPS 드라이버 소스
·Location Framework Core - GPS 관련 서비스 관리 프레임 워크
·Location Framework GPS Plugin - GPS 하드웨어 관리 모듈
·Location Framework Simulation Plugins - GPS 관련 하드웨어 없이 GPS기능을 테스트 해 볼 수 있게 하는 모듈
·Location Framework Wifi Plugin - 무선 인터넷(WIFI)를 통하여 위치 정보를 이용하기 위한 모듈 등으로 구성되어 있다.

GPS 데이터의 이용

응용 프로그램에서 GPS 정보를 이용하기 위해서는 다음과 같은 함수를 통해 GPS 정보를 얻게 된다. GPS 정보에 대해서 NMEA 정보를 분석하고 산출해 내는 것이 아니라 최종 정보 형태로 GPS 정보를 얻을 수 있기 때문에 GPS 정보를 이용한 응용 프로그램 개발에 있어 보다 용이하게 접근할 수 있는 장점을 제공해 준다.
표 1에서와 같이 GPS 드라이버를 통하여 GPS 장치의 위치 정보를 얻기 위해서는 시리얼 드라이버를 열어 GPS 데이터를 일일이 분석해야 하는 수고 없이 쉽게 함수를 통해 이용할 수 있게 한다. 물론 GPS 디바이스 드라이버를 사용하더라도 기존처럼 GPS에서 출력되는 GPS 정보를 이용할 수 있는 방법은 동시에 제공된다.

표 1. GPS관련 함수

GPS 드라이버 및 로케이션 프레임워크를 통해 전달되는 GPS 정보는 다음 표 2와 같은 구조체를 통해 위치 정보가 전달이 된다.

 


typedef struct _GPS_POSITION {
 DWORD dwVersion; // GPSID client 버전
 DWORD dwSize; // sizeof(_GPS_POSITION)
 DWORD dwValidFields;

 DWORD dwFlags;

 //** 시간 정보
 SYSTEMTIME stUTCTime;  //  UTC GPS 시간
 //** Position heading related
 double dblLatitude;             // 위도
 double dblLongitude;            // 경도
 float  flSpeed;                 // 속도
 float  flHeading;              // 방향
 double dblMagneticVariation;  
 float  flAltitudeWRTSeaLevel;
 float  flAltitudeWRTEllipsoid;

 //정확도
 GPS_FIX_QUALITY FixQuality;
 GPS_FIX_TYPE FixType;
 GPS_FIX_SELECTION SelectionType;    
 float flPositionDilutionOfPrecision;  
 float flHorizontalDilutionOfPrecision;
 float flVerticalDilutionOfPrecision;

 //** Satellite information
 DWORD dwSatelliteCount
 DWORD rgdwSatellitesUsedPRNs[GPS_MAX_SATELLITES
 DWORD dwSatellitesInView;                       
 DWORD rgdwSatellitesInViewPRNs[GPS_MAX_SATELLITES];
 DWORD rgdwSatellitesInViewElevation[GPS_MAX_SATELLITES
 DWORD rgdwSatellitesInViewAzimuth[GPS_MAX_SATELLITES];
 DWORD rgdwSatellitesInViewSignalToNoiseRatio[GPS_ MAX_SATELLITES];
} GPS_POSITION, *PGPS_POSITION;

표 2. GPS 정보 구조체

 

GPSID 드라이버는 플랫폼 빌더의 PublicCommon OakDriversGPSID라는 디렉토리에 위치하며 GPSID 드라이버 및 프레임워크에 대한 모든 소스가 제공된다.
표 3은 GPS로 부터 전달된 NMEA 데이터를 각 형식에 맞추어 파싱하는 소스로 현재 GPSID 드라이버에서는 GGA, RMC, GSA, GSV, GLL 형태의 충 6가지 데이터 형식을 분석하고 이용할 수 있게 한다. 좀 더 자세한 내용은 해당 소스를 참고하기 바란다.

 

BOOL CGPSParser::ParseSentence(BYTE *pbSentence, DWORD dwLen) {
 DEBUGCHK(dwLen >= 2);
 DEBUGCHK(pbSentence[0] == cSentenceStart);
 DEBUGCHK(pbSentence[dwLen-2] == cCR);
 DEBUGCHK(pbSentence[dwLen-1] == cLF);
 DEBUGCHK(g_pGPSLock->IsLocked());

 // 중략

 if (! VerifyChecksumIfPresent(pbSentence,dwLen)) // NMEA 데이터의 checksum 검사
  return FALSE;
        // 중략

    CHAR *szSentenceID = szTalkerID ccTalkerLen;
 CHAR *szData       = szSentenceID ccSentenceIDLen;

 if (szData[0] != ′,′) {
  DEBUGMSG(ZONE_PARSE,(L"GPS: Sentence does not have an opening ′,′ following sentenceIDrn"));
  return FALSE;
 }

 CNMEAString nmeaString(szData1);

 DEBUGMSG(ZONE_PARSE,(L"GPS: Received sentence with SentenceID=<%.3S>.rn",szSentenceID));

 //
 // NMEA 데이터에 대한 분석
 //
 if (0 == strncmp(szSentenceID,cszGGA,ccSentenceIDLen))  // GGA 형식
  return ParseGGA(&nmeaString);
 else if (0 == strncmp(szSentenceID,cszRMC,ccSentenceIDLen)) // RMC 형식
  return ParseRMC(&nmeaString);
 else if (0 == strncmp(szSentenceID,cszGSA,ccSentenceIDLen))  // GSA 형식
  return ParseGSA(&nmeaString);
 else if (0 == strncmp(szSentenceID,cszGSV,ccSentenceIDLen)) // GSV 형식
  return ParseGSV(&nmeaString);
 else if (0 == strncmp(szSentenceID,cszGLL,ccSentenceIDLen)) // GLL 형식
  return ParseGLL(&nmeaString);  
 DEBUGMSG(ZONE_PARSE,(L"GPS: Sentence is not of a format that we can parse.  SentenceID=<%.3S>rn",szSentenceID));
  return FALSE;
}
표 3. GPS 드라이버 소스 일부분

GPSID 드라이버를 구성하고 있는 소스를 간략히 살펴보면 다음과 같다.

·GPSAPI.cpp - GPSOpenDevice() 함수와 같은 함수 호출 시 IPC를 통해 통신을 하고 GPSID 관련 동작을 하도록 한다.
·GPSCore.cpp - GPSID 드라이버의 메인 소스다. 내부의 GPSWorkerThread()를 통해 GPS와 통신을 하고 처리를 한다.
·GPSDriver.cpp - GPSID 드라이버의 추상화 레이어.·GPSHandle.cpp - API/프로세서에 대한 핸들 관리를 한다.
·GPSIntrf.cpp - xxx_Init/xxx_IOControl과 같은 디바이스 드라이버 인터페이스 기능을 처리한다.
·GPSMultiplexer.cpp - 가상 시리얼/GPSID에 대한 다중 엑세스를 할 수 있도록 관리한다.
·GPSParse.cpp - GPS에서부터 받은NMEA 정보를 파싱하고 해석하는 역할을 한다.
·GPString.cpp - GPS NMEA 데이터에 대한 각각의 필드 정보를 관리한다.

GPS 정보 얻기

GPSID 드라이버를 통해 GPS 정보를 얻는 방식은 GPS에 관련된 쓰레드를 생성하여 GPS 위치정보에 관련된 이벤트가 발생했을 때 GPS 정보를 얻는 이벤트 방식을 기본적으로 사용한다.
표 4는 GPS 정보 읽는 응용 프로그램의 예를 보여주며 GPS 위치정보 이벤트가 발생했을 때 GPSGetPosition() 함수를 사용하여 현재 위치를 알아내는 소스이다.


DWORD WINAPI CGPSController::GPSThreadProc(__opt LPVOID lpParameter)
{
  DWORD dwRet = 0;
 GPS_POSITION gps_Position = {0};
 GPS_DEVICE gps_Device = {0};
 HANDLE gpsHandles[GPS_CONTROLLER_EVENT_COUNT] = {s_hNewLocationData,
         s_hDeviceStateChange,
         s_hExitThread
         };
     // 중략
    do
    {
  dwRet = WaitForMultipleObjects(GPS_CONTROLLER_ EVENT_COUNT,
              gpsHandles,
              FALSE,
              INFINITE);
  if (dwRet == WAIT_OBJECT_0) // GPS 정보가 업데이트 되었음
        {
  dwRet = GPSGetPosition(s_hGPS_Device, &gps_Position, MAX_AGE, 0);
             if (ERROR_SUCCESS != dwRet)
             {
                  continue;
             }
             else
             {
                  s_pGPSSink->SetGPSPosition(gps_Position);
             }
        }
        else if (dwRet == WAIT_OBJECT_0 1)
        {
                  dwRet = GPSGetDeviceState(&gps_Device);                                    if (ERROR_SUCCESS != dwRet)
                  {
                   continue;
                  }
                  else
                  {
                   s_pGPSSink->SetGPSDeviceInfo(gps_Device);
                  }          }
 // 중략
표 4. GPS 정보 얻기 소스


GPS 폴링 드라이버

지금까지는 이벤트 방식의 GPS 드라이버에 대해 살펴봤다. 이벤트 방식은 Thread를 구성하여 항상 이벤트가 발생에 대응하도록 응용 프로그램을 구성해야 한다는 단점이 있다. 이러한 단점을 개선하고자 GPS 드라이버를 폴링 방식으로 접근할 수 있도록 하는 방법을 별도로 제공한다. 이 방법은 폴링 드라이버이며 다음 표 6와 같이 폴링 드라이버로 구현한 GPS 드라이버를 표 5와 같이 등록하여 사용할 수 있게 한다.

 


[HKEY_LOCAL_MACHINESystemCurrentControlSetGPS Intermediate DriverDriversPoll]
"InterfaceType" = "Poll"
"CommPort" = "GPP0:"
[HKEY_LOCAL_MACHINEServicesGPSPollService]
 "Dll"="PollService"
    "Order"=dword:15
 "Keep"=dword:1
 "Index"=dword:0
 "Prefix"="GPP"

표 5. GPS 폴링 드라이버 레지스터리

 


#include
#include
#include
#include

DWORD g_dwServiceState = SERVICE_STATE_ON;

// 중략

extern "C" DWORD GPP_Init (DWORD dwData) {
 return TRUE;
}

extern "C" DWORD GPP_Open (DWORD dwData, DWORD dwAccess, DWORD dwShareMode) {
 return TRUE;
}

extern "C" BOOL GPP_IOControl(DWORD dwData, DWORD dwCode, PBYTE pBufIn,
  DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
                               PDWORD pdwActualOut)
{
 DWORD dwError = ERROR_INVALID_PARAMETER;

switch (dwCode) {
case IOCTL_SERVICE_START:
 g_dwServiceState = SERVICE_STATE_ON;
break;

case IOCTL_SERVICE_STOP:
g_dwServiceState = SERVICE_STATE_OFF;
 break;   

case IOCTL_SERVICE_STATUS:
*(DWORD *)pBufOut = g_dwServiceState;
*pdwActualOut = sizeof(DWORD);
break;
case IOCTL_GPS_DRIVER_GET_LOCATION_V1: // GPS 위치 정보 전달
if (g_dwServiceState == SERVICE_STATE_ON) {

ASSERT((pBufOut != NULL) && (dwLenOut == sizeof(GPS_POSITION)));
gpsData.dblLatitude  = 0.04;  // 가상 위도 정보, 실제 GPS 정보를 여기에 기록
gpsData.dblLongitude -= 0.05;
memcpy(pBufOut,&gpsData,sizeof(gpsData));
*pdwActualOut = sizeof(gpsData);
}
else {
SetLastError(ERROR_SERVICE_NOT_ACTIVE);
return FALSE;
}
break;

default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
break;
}

return TRUE;
}
extern "C" BOOL WINAPI DllEntry( HANDLE hInstDll, DWORD fdwReason,
                  LPVOID lpvReserved) {
return TRUE;
}
표 6. GPS 폴링 드라이버 소스


터치 및 제스처

윈도우 임베디드 CE 6.0 R3에 탑재된 터치 및 제스처 엔진은 작은 LCD 화면에서 터치를 통하여 인터넷 환경을 효율적으로 이용할 수 있도록 만들어졌다. 물론 멀티터치와 같은 혁신적인 기술이 개발되어 단순터치를 이용한 제스처 효과는 좀 식상한 작업으로 보일 것이다.
하지만 아직까지는 멀티터치를 널리 사용할 수 없기 때문에 현재 터치 방식에서 최대한의 효과를 볼 수 있는 형태로 나왔다고 볼 수 있다. 앞으로 멀티 터치가 지원될 것으로 예상되는 윈도우 임베디드 CE 7.0에서 본격적으로 터치나 제스처의 강점을 볼 수 있을 것으로 예상한다.
새롭게 추가된 제스처는 팬(Pan)과 플릭(Flick)이라는 제스처가 추가되었다. 팬 제스처의 경우 사용자가 터치한 상태에서 화면을 전후좌우로 이동하는 제스처를 의미하고 플릭 제스처의 경우 터치 화면을 잡고 던지는 듯한 제스처를 인식할 수 있다. 이러한 제스처는 물리 엔진이라고 불리는 "Physics Engine.dll"과 연계하여 터치를 했을 때 실제 화면이 자연스럽게 패닝이 되게 하거나 플릭 제스처에 의해 화면의 스크롤이 자연스럽게 동작할 수 있게 할 수 있다.


그림 3. 제스처의 내부 동작 구조


그림 3은 윈도우 임베디드 CE 6.0 R3에서 변경된 제스처 처리 내부 구조에 대해 설명하고 있다.
기존에 터치를 담당하고 있던 "Touch.dll"과 응용 프로그램 사이에서 터치 후 어떠한 식으로 움직임을 처리할 것인가를 담당하는 "GestureAnimation.lib", 제스처를 인식하는 "TouchGesture.lib", 터치와 제스처에 대해 화면의 움직임을 처리하는 물리 엔진인 "PhysicsEngine.dll" 등의 요소가 터치 및 제스처를 처리하는 컴포넌트로 포함되었다.

실버라이트, Win32 제스처

윈도우임베디드 CE 6.0 R3에 제스처 엔진이 포함되어 있지만 윈도우임베디드 CE 6.0용 응용 프로그램에서 손쉽게 사용해 프로그램을 할 수 있어야 의미가 있을 것이다.
우선 개발하는 윈도우CE 운영체제에 터치와 제스처 기능을 포함시키기 위해서는 다음과 같은 시스템 생성 변수를 추가하여 해당 컴포넌트가 포함되도록 한다.

· SYSGEN_TOUCHGESTURE - 터치 제스처가 지원 되도록 구성
· SYSGEN_GESTUREANIMATION - 제스처에 따른 동작 애니메이션이 되도록 구성

위 시스템 생성 변수(SYSGEN 변수라고 함)를 추가하면 윈도 임베디드 CE 운영체제에서 터치 및 제스처에 관한 동작을 운영체제 자체에서 지원할 수 있는 기능이 생긴다. 따라서 기존은 파일 탐색기와 같은 프로그램에서도 사용자의 제스처에 따라 부드러운 스크롤이 되는 것을 확인할 수 있을 것이다. 위 시스템 생성 변수를 추가하면 기존에 사용하던 Win32 컨트롤이나 실버라이트 컨트롤 중 WS_HSCROLL이나 WS_ VSCROLL 속성으로 만들어진 윈도우나 컨트롤에 대해서는 특별한 이벤트 처리 없이도 터치 및 제스처에 반응하게 할 수 있다. 하지만 그 이외의 컨트롤에 대해서는 제스처 이벤트에 반응할 수 있도록 구성해야 한다. 기존의 컨트롤에서도 SetWindowsAutoGesture(hWnd, LpAudoGestureInfo) 함수에 의해 터치 제스처에 반응을 제어할 수 있다.

· 팬 제스처 메시지
· GID_PAN : 제스처 메시지
· GID_END : 제스처 종료를 통보함

· 플릭 제스처 메시지
· GID_SCROLL

그림 4. 응용 프로그램에서 제스처 이벤트 처리

제스처 메시지의 처리

그림 4는 응용 프로그램에서 실제로 제스처 이벤트가 어떻게 발생하고 처리하는지 보여주는 테스트 프로그램이다. 제스처 메시지는 기존 터치나 키와 같은 윈도우이벤트 메시지로 앞에서 설명한 GID_ 형태의 메시지로 전달된다.
표 7은 실제 응용 프로그램에서 터치 및 제스처에 관한 이벤트를 처리하게 해 주는 프로그램의 소스이다. WM_GES TURE라는 새로운 윈도우메시지를 통해 제스처 이벤트가 전달이 되고 이 메시지의 세부 인자를 통해 어떠한 제스처인지 판단할 수 있게 구성되어 있다.


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch (message)
 {
  case WM_CREATE:
                          // 생략
  EnableGestures(hWnd, TGF_GID_ALL,TGF_SCOPE_ PROCESS);
  // 제스처를 인식하게 시킨다.
  break;

  case WM_SIZE:
                          // 중략
                          break;

  case WM_GESTURE:
                          if (wParam == GID_BEGIN)
                                  //제스처 시작 이벤트 메시지
                          if (wParam <= GID_LAST)
                                 // 제스처 종료 이벤트 메시지
                          {
                                  SetCapture(hWnd);
                                  DisplayGestureInfo((HGESTUREINFO)lParam);
                                  ReleaseCapture();
   }
                          CloseGestureInfoHandle((HGESTUREINFO)lParam);
                          return 1;

  case WM_DESTROY:
                       // 중략
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}
표 7. 제스처 메시지 처리 소스 예제


물리 엔진(Physics Engine)

물리 엔진은 말 그대로 터치 제스처에 대한 동작의 반응을 어떻게 하면 실제와 같이 움직일 것인가에 중점을 두고 있는 부분이라고 생각하면 된다. 터치나 제스처에서 객체를 터치에 경계면으로 던질때 실제 물건처럼 튕겨져 나가고 하는 등의 움직임을 처리해 주는 엔진이라고 생각하면 된다.
물리 엔진에 대한 초기화는 PHYSICSENGINEINIT라는 구조체를 통해 설정하게 된다. 표 8는 물리 엔진에 대한 초기 처리 및 동작을 처리하는 프로그램 예제이다. 물리 엔진은 화면의 X축, Y축 각각에 대해 조정이 가능하다. 또한 어떠한 식으로 속도가 변할 것인가, 경계면을 만났을 때 어떻게 반응할 것인가에 대해 지정할 수 있다.


표 8. 물리 엔진의 경계 조건


peInit.cbSize = sizeof(PHYSICSENGINEINIT);
peInit.dwInitialAngle =  4096; // 각도를 지정한다.
peInit.lInitialVelocity = 100; // 속도를 지정한다. 속도의 단위는 픽셀/초당
peInit.dwEngineType = 0;
peInit.dwFlags = 0;
peInit.bXAxisMovementMode =
                       PHYSICSENGINE_MOVEMENT_MODE_DECELERATE;
peInit.bYAxisMovementMode =
                       PHYSICSENGINE_MOVEMENT_MODE_DECELERATE;
  peInit.bXAxisBoundaryMode =
                       PHYSICSENGINE_BOUNDARY_MODE_NONE;
  peInit.bYAxisBoundaryMode =
                       PHYSICSENGINE_BOUNDARY_MODE_NONE;
  peInit.sizeView.cx = bmp.bmWidth;
  peInit.sizeView.cy = bmp.bmHeight;
  peInit.sizeItem.cx = peInit.sizeItem.cy = 1;

// 물리 엔진에 대한 동작 명령
                        case ID_ACTION_STARTMOTION:
                                if (hPhysEng == NULL)
                                {
                                        peInit.ptInitialPosition = posInitial;
                                        peInit.rcBoundary = rectAnimation;
 if(SUCCEEDED(CreatePhysicsEngine(&peInit, &hPhysEng)))
                SetTimer(hWnd, 1, 20, NULL);
                                }
                                break;
표 9. 물리엔진에 대한 설정 및 동작 지정 소스


사용자 제스처 등록
사용자 제스처 등록은 팬이나 플릭과 같은 운영체제가 제공하는 기본 제스처 이외에 사용자가 제스처를 추가 할 수 있게 하는 기능이다.
터치스크린 위에서 다양한 제스처를 사용할 수 있게 함으로써 좀 더 사용자가 터치를 이용해 편리하게 사용할 수 있도록 하는 기능이다.


[HKLM System GWE Recognizers RecognizerName]
  "Dll" = "RecognizerName.DLL"
  "Index" = DWORD:1
  "Order" = DWORD:0
표 10. 사용자 제스처 인식기 등록 레지스터리 항목

사용자 제스처 처리는 다음과 같이 DLL 형태의 사용자 제스처 인식기를 윈도 임베디드 CE 6.0 운영체제에 포함시키고 해당 DLL이 제스처를 처리할 수 있도록 먼저 구성을 해야 한다.
사용자 제스처 인식기는 RegisterGesture( ) 함수와 Reco gnizeGesture( ) 두 함수를 이용해 처리를 하게 된다. 사용자 제스처 인식기의 기본 골격은 표 11에서 확인할 수 있다.

extern "C" HRESULT APIENTRY RecognizeGesture(PCCETOUCHI NPUT pInputs, UINT cInputs)
{
 HRESULT hr = E_PENDING;

 for (UINT c = 0; c < cInputs c)
    {
  if (pInputs[c].dwFlags & TOUCHEVENTF_DOWN)
              HandleTouchDown(pInputs[c].x, pInputs[c].y);
         else if (pInputs[c].dwFlags & TOUCHEVENTF_UP)
              HandleTouchUp(pInputs[c].x, pInputs[c].y);
         else if (pInputs[c].dwFlags & TOUCHEVENTF_MOVE)
              HandleTouchMove(pInputs[c].x, pInputs[c].y);
    }
 return HRESULT;
}



void HandleTouchUp(UINT x, UINT y)
{
 …
     Gesture(hwnd, pGestureInfo, pExtraArguments);
    …
}
표 11. 사용자 제스처 인식기 소스의 일부분

끝으로

지금까지 윈도 임베디드 CE 6.0의 GPS 디바이스 드라이버와 R3에서 새롭게 추가된 터치 및 제스처 기능에 대해 살펴봤다. 윈도 임베디드 CE 6.0에 대한 소식보다는 앞으로 나올 윈도 임베디드 CE 7.0 버전 즉, 윈도 임베디드 컴팩트 버전이 더 기다려지는 시기이다.
안드로이드 운영체제 및 여러 임베디드 운영체제들이 시장 형성을 위해 각축을 벌이고 있는 만큼 새로운 7.0 버전이 어떻게 나올 것인가는 앞으로의 운영체제 향방을 가르는 중요한 이벤트라고 할 수 있다. 올해 한해 임베디드 시스템 운영체제의 미래를 예측해보며 새롭게 시작한 2010년의 두 번째 달을 맞이하고자 한다.
회원가입 후 이용바랍니다.
개의 댓글
0 / 400
댓글 정렬
BEST댓글
BEST 댓글 답글과 추천수를 합산하여 자동으로 노출됩니다.
댓글삭제
삭제한 댓글은 다시 복구할 수 없습니다.
그래도 삭제하시겠습니까?
댓글수정
댓글 수정은 작성 후 1분내에만 가능합니다.
/ 400
내 댓글 모음
저작권자 © 테크월드뉴스 무단전재 및 재배포 금지