bool CRAPIContacts :: Read()
{
    // RAPI 핸들용
    HRESULT hr;
    // DB 검색용
    CEOID    m_ContactsCEOID;
    HANDLE    m_ContactsHDB;
    // DB 파일 핸들 얻기 처리용
    HANDLE    hEnum;
    CEOID    enumCeoid;
    CEOIDINFO oidInfo;
    // DB 내의 데이터 레코드 처리용
    DWORD    dwRecSize = 0;
    WORD    wProps = 0;
    PBYTE    pRecordvar = NULL;
    // DB 레코드 위치 관리용
    CEOID    oid = 0;
    DWORD    dwIndex = 0;
    int        iRecIndex = 0;
    try
    {
        //
        // RAPI 초기화 하기 (내부에서 연결도 하더라)
        //
        hr = CeRapiInit();
        if (hr != ERROR_SUCCESS)
            throw "RAPI 초기화 에러";
        //
        // PDA 내부의 Database 를 검색하여 Contacts Database 의 핸들을 얻자꾸나
        //
        m_ContactsCEOID = NULL;
        hEnum = CeFindFirstDatabase(0);
        while(enumCeoid = CeFindNextDatabase( hEnum))
        {
            CString strDBName;
            // DB 명을 얻어서 ANSI STR 로 바꾼 후에
            CeOidGetInfo(enumCeoid, &oidInfo);
            strDBName = oidInfo.infDatabase.szDbaseName;
            // Contacts Database 이름이면 연락처 DB 이니..
            if (int Pos = strDBName.Find("Contacts Database") >= 0)
            {
                m_ContactsCEOID = enumCeoid;
                break;
            }
        }
        //
        // 연락처 DB 를 검색하지 못하였다면 실패
        //
        if (!m_ContactsCEOID)
            throw "연락처 DB 검색 실패";
        //
        // 연락처 DB 를 열자꾸나
        //
        HWND m_hWnd = NULL;
        m_ContactsHDB = CeOpenDatabase (&m_ContactsCEOID, NULL, 0,  CEDB_AUTOINCREMENT, m_hWnd);
        if( m_ContactsHDB == INVALID_HANDLE_VALUE )
            throw "DB 연결 실패";
        //
        // 첫 위치로 이동
        //
        iRecIndex = 0;
        oid = CeSeekDatabase (m_ContactsHDB, CEDB_SEEK_BEGINNING, iRecIndex, &dwIndex);
        if(GetLastError() != ERROR_SUCCESS)
            throw "위치 이동 실패";
        //
        // 첫번째 Row 를 가져오자~
        //
        oid = CeReadRecordProps (m_ContactsHDB, CEDB_ALLOWREALLOC, &wProps, NULL, &(LPBYTE )pRecordvar, &dwRecSize);
        if( oid == ERROR_INSUFFICIENT_BUFFER )
            throw "첫 데이터 읽기 실패";
        //
        // 뺑뺑이를 돌려
        //
        CONTACTITEM ContactItem;
        while (oid != 0 )
        {
            ZeroMemory(&ContactItem, sizeof(CONTACTITEM));
            //
            // 데이터 분석 시작
            //
            PCEPROPVAL pRecord = (PCEPROPVAL)pRecordvar;
            WORD    iPropId;
            int        iPropDataType;
            for( int i = 0; i < wProps; i++ )
            <FONT COLOR=#0000FF>{
                CString Str = "";
                iPropId = HIWORD(pRecord[i].propid );
                iPropDataType = LOWORD(pRecord[i].propid );
                //
                // 매크로로 CASE 를 처리하다. 같은 문장이 많아
                //
#define CASECONTACTITEM(v, Out)    \\
    case v:    \\
    Str = pRecord[i].val.lpwstr;    \\
    if (Str != "") \\
    strncpy((char *)&Out, (LPCTSTR)Str, sizeof(Out)); \\
                break;
                switch (iPropId)
                {
                    CASECONTACTITEM(0x3A06,    ContactItem.FirstName);
                    CASECONTACTITEM(0x3A1C,    ContactItem.MobilePhoneNumber);
                    CASECONTACTITEM(0x4083,    ContactItem.EMail1);
                    CASECONTACTITEM(0x3A11,    ContactItem.LastName);
                    CASECONTACTITEM(0x3a17,    ContactItem.JobTitle);
                    CASECONTACTITEM(0x3a16,    ContactItem.CompanyName);
                    CASECONTACTITEM(0x3A18,    ContactItem.DepartmentName);
                    CASECONTACTITEM(0x3A08,    ContactItem.FirstName);
                    CASECONTACTITEM(0x3A09,    ContactItem.HomeTelephoneNumber);
                    CASECONTACTITEM(0x3A05,    ContactItem.ContactsSuffix);
                }
            }
            OnProgress(Sender, &ContactItem, iRecIndex, 10);
            //
            // 다음 Row 를 요청
            //
            oid = CeReadRecordProps (m_ContactsHDB, CEDB_ALLOWREALLOC, &wProps, NULL, &(LPBYTE )pRecordvar, &dwRecSize);
            //OutputDebugString("   \\n");
            iRecIndex++;
        }
        //
        // 닫자
        //
        CeCloseHandle(m_ContactsHDB);
        CeRapiUninit();
        return true;
    }
    //
    // 캐치~ 아웃~
    //
    catch (...)
    {
        // 열린 DB 가 있으면 닫자
        if (m_ContactsHDB)
            CloseHandle(m_ContactsHDB);
        // RAPI UnInit
        CeRapiUninit();
        return false;
    }
} |