| C++ 언어를 권장하지 않는 이유 | 
|---|
| 
                                                C++ 언어는 개발 생산성 저하로 인해 Windows CE에서는 사용을 권장하지 않습니다.(SmartX사용 환경과 비교시 개발 소요 시간이 10배 이상 증가할 수 있습니다.) 또한, 개발 환경 구축 문제로 인해 개발 지원 자체가 안되는 경우도 있습니다. 따라서 C# 또는Basic 언어에서 SmartX New Framework를 사용하여 개발하실 것을 권장하고 있습니다.  | 
                                          
                                          
 본 자료는
      1. 프로그램 동작 전 준비사항(설치환경 및 필요 설치파일)
      2. ADOCE RunTime 설치하기
      3. CADOCE.cpp의 ADOCE Class 관련 설명 및 사용법
      4. 프로그램 핵심 소스
      순서로 진행합니다.
 본 자료는 ADO(ActiveX Data Object)CE를 활용하여 C++에서 Database를 접근하기 위한 환경구성에 대하여 설명하는 자료입니다. 
    IEC-Series는 기본적으로 ADO.NET을 내장하고 있어 .NET Compact Framework기반에서 Database 접근을 바로 할 수 있습니다. 그렇지만 C++(API/MFC)환경에서 지원 가능한 ADOCE가 기본적으로 포함되어 있지 않아 관련된 파일을 설치하셔야 합니다. 
    본문에서 설명되는 내용은 HNS의 IEC-Series에서 ADOCE를 연동하기 위한 방법을 설명합니다. 
IEC-Series에 따라 개발 툴과 필요한 설치파일 및 DB 파일이 다르므로 다음 표를 참고바랍니다
| IEC266-Series | IEC667-Series | IEC1000-Series | |
|---|---|---|---|
| 개발툴 | Visual Studio 2005/2008 | Visual Studio 2008 | |
| 설치파일명 | HNS_ADO_Setup.exe | HNS_ADO_Setup 1000 6.0.exe HNS_ADO_Setup 1000 7.0.exe  | 
      |
| Sample DB File | emp.sdf(36Kb), 3.1 Version | emp.sdf(40Kb) 3.5 Version | |
| SQL Connection()  부분 차이점  | 
        [중요] m_ADOCE.SQLConnection(L"Provider =Microsoft.SQLSERVER.MOBILE.OLEDB.3.0; Data source=\\Flash Disk\\emp.sdf");  | 
        [중요] m_ADOCE.SQLConnection(L"Provider =Microsoft.SQLSERVER.CE.OLEDB.3.5; Data source=\\Flash Disk\\emp.sdf");  | 
      |
| IEC266 | IEC667 | IEC1000 | |
|---|---|---|---|
| 개발툴 | Visual Studio 2005/2008 | Visual Studio 2008 | |
| 설치파일명 | HNS_ADO_Setup.exe | HNS_ADO_Setup 1000 6.0.exe HNS_ADO_Setup 1000 7.0.exe  | 
      |
| Sample DB File | emp.sdf(36Kb), 3.1 Version | emp.sdf(40Kb) 3.5 Version | |
| SQL Connection()  부분 차이점  | 
        [중요] m_ADOCE.SQLConnection(L"Provider =Microsoft.SQLSERVER.MOBILE.OLEDB.3.0; Data source=\\Flash Disk\\emp.sdf");  | 
        [중요] m_ADOCE.SQLConnection(L"Provider =Microsoft.SQLSERVER.CE.OLEDB.3.5; Data source=\\Flash Disk\\emp.sdf");  | 
      |
2. ADOCE RunTime 설치하기
-  [STEP-1] 본 문서의 첨부파일을 다운로드 하시기 바랍니다.
 -  [STEP-2] ActiveSync 연결하여 HNS_ADO_Setup.exe 파일을 IEC-Series 장치에 복사합니다. (복사는 임의의 폴더에 하시면 됩니다.) 
복사 후 장치에서 파일을 실행하시기 바랍니다. IEC266/667-Series는 HNS_ADO_Setup.exe 파일을 복사하여 실행하고 IEC1000-Series는 HNS_ADO_1000_Setup.exe 파일을 복사하여 실행합니다.
  -  [STEP-3] 복사된 HNS_ADO_Setup.exe 파일을 IEC-Series에서 실행하여, Setup Start를 클릭한 후,설치경로 설정없이 "OK" 버튼을 클릭합니다. 
        
  -  [STEP-4] 설치 완료 메시지가 화면이 출력되면, 정상적으로 설치 완료
주의설치가 완료되면 Flash Disk\ADODB 폴더가 생성됩니다. IEC-Series 바탕화면의 Registry Save를 클릭하여 시스템의 변경사항을 저장한 다음 IEC-Series를 재부팅 해줍니다. Flash Disk\ADODB 폴더 내부 파일을 삭제하면 안됩니다.
 
3. CADOCE.CPP의 ADOCE Class 관련 설명 및 사용법
시리얼(Serial) 통신에 관련된 모든 기능을 담당하는 CSerialPort 클래스로서 세부 내용은 다음과 같이 이루어져 있습니다. 예제소스의 CSerialPort.cpp 파일 참고
|  // COM을 초기화 // COINIT_MULTITHREADED는 COM을 여러 개 작동시키기 위함 BOOL CADOCE::SQLInit() {  HRESULT hr; 
          hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if(FAILED(hr)) return FALSE; return TRUE; }  | 
      |
|---|---|
| (반환값) BOOL : COM 초기화 성공인 경우 True 리턴. COM 초기화 실패하는 경우 False 리턴 | 
|  // SQLConnection의 인자 bstrCon은 SQL을 연결하기 위한 ADOCE의 데이터 베이스 연결 문자열 BOOL CADOCE::SQLConnection(BSTR bstrCon) {  HRESULT hr; 
          }// COM 객체의 결과를 받기위한 hr hr = CoCreateInstance( CLSID_ADOCEConnection, NULL, CLSCTX_INPROC_SERVER, IID_IADOCEConnection, (LPVOID*) &m_adoceCon); // CoCreateInstance 실패 if(FAILED(hr)) return FALSE; // m_adoceCon이 NULL인 경우 if(!m_adoceCon) return FALSE; // SQLConnection 함수 호출 시 넘겨받은 bstrCon을 데이터베이스 연결 문자열로 호출한다 hr = m_adoceCon->Open( bstrCon, NULL, NULL, adOpenUnspecified); // 만약 연결이 제대로 되면 호출 시 넘겨 받은 bstrCon에서 지정하는 DB와 연결됨 if(FAILED(hr)) return FALSE; return TRUE;  | 
      |
|---|---|
|  (인자) BSTR bstrCon : SQLConnection 함수를 호출할 경우 호출하는 쪽에서 넣어줄  ‘데이터베이스 연결 문자열’ (반환 값) BOOL : OPEN Connect 성공인 경우 True 리턴. OPEN Connect 실패하는 경우 False 리턴  | 
      
|  // 쿼리를 실행하는 기능 // adCmdText : SQL 쿼리 문장. adCmdTable : 테이블 이름 // adCmdStoreProc : 저장 프로시저. adCmdUnknown : 다양한 방법 BOOL CADOCE::SQLExecute(BSTR bstrCmd) {  HRESULT hr; 
          }// 넘겨받은 쿼리를 Execute를 통해 처리. 결과는 IADOCERecordset 형태로 반환 hr = m_adoceCon->Execute(bstrCmd, NULL,adCmdText, &m_adoceRec); if(FAILED(hr)) return FALSE; if(!m_adoceRec) return FALSE; return TRUE;  | 
      |
|---|---|
|  (인자) BSTR bstrCmd :  SQLExecute 함수를 호출할 경우 실행할 SQL쿼리 (반환값) BOOL : 쿼리 Execute 성공인 경우 True 리턴. 쿼리 Execute 실패하는 경우 False 리턴  | 
      
|  // 현재 쿼리의 결과로 처리된 데이터가 담긴 IADOCERecordset으로부터 한줄의 레코드를  // 가져오는 기능을 수행. 가져온 데이터는 IADOCEFields 형태의 전역 변수에 들어가면서 IADOCEFields 형태로 반환하게 구성 IADOCEFields* CADOCE::GetFields() {  m_adoceRec → get_Fields(&m_adoceFields); 
          } return m_adoceFields;  | 
      |
|---|---|
|  (반환값) IADOCEFields m_adoceFields : IADOCERecordset으로부터 가져온 한줄의 데이터 | 
      
|  // GetFields 함수로부터 사용자가 원하는 위치의 필드를 가져오게 합니다.  // 가져온 데이터는IADOCEField 형태의 전역변수에 들어가면서 IADOCEField 형태로 반환 IADOCEField* CADOCE::GetField(int iField) {  GetFields() → get_Item(_variant_t((long)iField), &m_adoceField); 
          } return m_adoceField;  | 
      |
|---|---|
|  (인자) int iField : 지정한 위치의 필드 (반환값) IADOCEField m_adoceField : 사용자가 원하는 위치의 필드  | 
      
|  // 가져온 한 줄의 레코드에 몇 개의 필드가 있는지 확인하는 기능 LONG CADOCE::GetFieldCount() {  LONG lFieldCount; 
          }GetFields() → get_Count(&lFieldCount); return lFieldCount;  | 
      |
|---|---|
|  (반환값) LONG lFieldCount : 레코드 집합의 필드 개수 | 
      
|  // 지정한 위치의 필드명을 반환하는 기능 LPCWSTR CADOCE::GetFieldName(int iField) {  IADOCEField * pField = GetField(iField); 
          } if(!pField) {  return NULL; 
            }BSTR strFieldName; pField → get_Name(&strFieldName); return strFieldName;  | 
      |
|---|---|
|  (인자) int iField : 필드에서 지정한 위치 (반환값) BSTR strFieldName : 필드로부터 가져온 이름  | 
      
|  // 지정한 위치의 필드로부터 데이터를 반환하는 기능 VARIANT CADOCE::GetFieldValue(int iField) {  VARIANT value; 
          } VariantInit(&value); IADOCEField * pField = GetField(iField); if(!pField) {  return _variant_t((long)0); 
            }pField → get_Value(&value); return value;  | 
      |
|---|---|
|  (인자) int iField : 필드에서 지정한 위치 (반환값) VARIANT value : 필드로부터 가져온 데이터  | 
      
|  // GetFieldValue 함수로부터 반환받은 데이터를 문자열로 변환하는 기능 LPCWSTR CADOCE::GetFieldValueString(int iField) {  VARIANT value = GetFieldValue(iField); 
          } VARIANT valueString; VariantInit(&valueString); if(value.vt == VT_BSTR) {  valueString = value; 
            }else {  VariantChangeType(&valueString, &value, 0, VT_BSTR); 
            }return valueString.bstrVal;  | 
      |
|---|---|
|  (인자) int iField : 필드에서 지정한 위치 (반환값) VARIANT valueString.bstrVal : 반환되는 데이터  | 
      
|  // Recordset을 첫번째 레코드로 이동 BOOL CADOCE::MoveFirst() {  if(!m_adoceRec) 
          }{  return FALSE; 
            }HRESULT hr = m_adoceRec->MoveFirst(); return (!FAILED(hr));  | 
      |
|---|---|
| (반환값) BOOL : 데이터가 없으면 FALSE, 데이터가 있으면 TRUE | 
|  // Recordset을 다음 레코드로 이동 BOOL CADOCE::MoveNext() {  if(!m_adoceRec) 
          }{  return FALSE; 
            }HRESULT hr = m_adoceRec → MoveNext(); return (!FAILED(hr));  | 
      |
|---|---|
| (반환값) BOOL : 데이터가 없으면 FALSE, 데이터가 있으면 TRUE | 
|  // 더 이상 읽을 데이터가 없는지 확인하는 기능을 수행. 다른 레코드를 계속 이동시킬 경우 더 이상 이동시킬 데이터가 없는지 확인하는 수단으로 사용 BOOL CADOCE::IsEOF() {  if(!m_adoceRec) 
          } {  return FALSE; 
            }VARIANT_BOOL fValue; HRESULT hr = m_adoceRec → get_EOF(&fValue); return (fValue == VARIANT_TRUE);  | 
      |
|---|---|
| (반환값) BOOL : True는 이동시킬 데이터가 있음. False는 이동시킬 데이터가 없음 | 
|  // Release하고 Close함으로 데이터 베이스로부터 사용 중지됨 void CADOCE::SQLClose() {  if(m_adoceCon) 
          } {  m_adoceCon->Release(); 
            }m_adoceCon → Close(); m_adoceCon = NULL; if(m_adoceRec) {  m_adoceRec->Release(); 
            }m_adoceRec → Close(); m_adoceRec = NULL;  | 
      |
|---|---|
| - | 
|  // COM 사용 해제 void CADOCE::SQLUnInit() {  CoUninitialize(); 
          }  | 
      |
|---|---|
| (반환값) 없음 | 


  
								
        

