How to seek CEDB Database in wince5 with CEDB_SEEK_VALUEFIRSTEQUAL Parameter?

I need to seek a Database which I build in wince 5.0's "cemail.vol" volume Database file. It's  the CEDB so I have to use the CEDB's winapi.

My develop&test entironment is vs2005 vc8 + CF .NET 2.0(not yet install sp1) + WM5 PPC SDK + CHS WM5 pocket PC.


At first, I used CeCreateDatabaseEx() create my database in cemail.vol with one sort column. Code like that:

Code Snippet
#define PKEY_ID                   MAKELONG(CEVT_UI4,1)
#define PKEY_PHONENUM    MAKELONG(CEVT_LPWSTR,2)
#define PKEY_VALUE            MAKELONG(CEVT_LPWSTR,3)

CEGUID m_ceguidDB;
CEDBASEINFO m_MyDB;
HANDLE dbMyDB = NULL;
CEOID  oidDb = 0;

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    int ret;
    CREATE_INVALIDGUID(&m_ceguidDB);
    ...
    if (!CeMountDBVol(&m_ceguidDB, L"cemail.vol", OPEN_EXISTING ))
    {       
        DWORD dwErr = GetLastError();
        CeUnmountDBVol(&m_ceguidDB);
        return false;
    }
    else
    {
        memset(&m_MyDB, 0, sizeof(m_MyDB));
        m_MyDB.dwDbaseType = 0;
        m_MyDB.dwFlags = CEDB_VALIDNAME | CEDB_NOCOMPRESS;
        m_MyDB.wNumSortOrder = 1;
        m_MyDB.rgSortSpecs[0].propid = PKEY_ID;
        m_MyDB.rgSortSpecs[0].dwFlags = CEDB_SORT_NONNULL;
        wcscpy(m_MyDB.szDbaseName,L"MyDB");
        CeCreateDatabaseEx(&m_ceguidDB,&m_MyDB);
        ret = GetLastError();
    }
}

 



Then I write a function to add 2 record for testing seek:

Code Snippet
BOOL AddRecord()
{
    CEPROPVAL *pProps;
    dbMyDB = CeOpenDatabaseEx(&m_ceguidDB, &oidDb, L"MyDB", NULL, CEDB_AUTOINCREMENT, NULL);
    if (dbMyDB == 0)
        return false;
    pProps = new CEPROPVAL[3];
    memset(pProps,0,sizeof(pProps));
    pProps->propid = PKEY_ID;
    pProps->wFlags = 0;
    pProps->wLenData = 0;
    pProps->val.ulVal = 1;
    pProps++;
    memset(pProps,0,sizeof(pProps));
    pProps->propid = PKEY_TYPE;
    pProps->wFlags = 0;
    pProps->wLenData = 0;
    pProps->val.lpwstr = L"11";
    pProps++;
    memset(pProps,0,sizeof(pProps));
    pProps->propid = PKEY_VALUE;
    pProps->wFlags = 0;
    pProps->wLenData = 0;
    pProps->val.lpwstr = L"111111";
    pProps = pProps - 2;
    oidDb = CeWriteRecordProps(dbMyDB, 0, 3, pProps);
    if (oidDb == 0)
    {
        CloseHandle(dbMyDB);
        return false;
    }
    memset(pProps,0,sizeof(pProps));
    pProps->propid = PKEY_ID;
    pProps->wFlags = 0;
    pProps->wLenData = 0;
    pProps->val.ulVal = 2;
    pProps++;
    memset(pProps,0,sizeof(pProps));
    pProps->propid = PKEY_TYPE;
    pProps->wFlags = 0;
    pProps->wLenData = 0;
    pProps->val.lpwstr = L"22";
    pProps++;
    memset(pProps,0,sizeof(pProps));
    pProps->propid = PKEY_VALUE;
    pProps->wFlags = 0;
    pProps->wLenData = 0;
    pProps->val.lpwstr = L"222222";
    pProps = pProps - 2;
    oidDb = CeWriteRecordProps(dbMyDB, 0, 3, pProps);
    if (oidDb == 0)
    {
         CloseHandle(dbMyDB);
         return false;
    }
    return true;
}

 



Now I can seek the DB like that:

Code Snippet
BOOL TestSeek()
{
    WORD wProp;
    PBYTE pBuff = NULL;
    DWORD dwRecSize;
    DWORD dwSize = 0;
    CEOID m_ceoid=0;
    CEOID tempOid = 0;
    PCEPROPVAL pProp = new CEPROPVAL;
    pProp->propid = PKEY_ID;
    pProp->wFlags = 0;
    pProp->wLenData = 0;
    pProp->val.ulVal = 1;
    dbMyDB = CeOpenDatabaseEx(&m_ceguidDB, &m_ceoid,  L"MyDB", NULL, 0, NULL);
    //dbMyDB = CeOpenDatabaseEx(&m_ceguidDB, &m_ceoid, L"MyDB", PKEY_ID, 0, NULL);
    ret= GetLastError();
    if (dbMyDB == 0)
         return false;
    else
    {
         tempOid = CeSeekDatabase(dbMyDB,         EDB_SEEK_BEGINNING,0,NULL);
        //tempOid = CeSeekDatabase(dbMyDB, CEDB_SEEK_VALUEFIRSTEQUAL,         DWORD)&pProp, &dwSize);
        ret = GetLastError();
        if (tempOid != 0)
        {
            tempOid = CeReadRecordPropsdbMyDB, CEDB_ALLOWREALLOC, &wProp, NULL, &(LPBYTE)pBuff, &dwRecSize);
            pProp = (PCEPROPVAL)pBuff;
            for (int i=0;i<WPROP;I++)
            {
                if (pProp->propid == PKEY_VALUE)
                {
                    //do something here
                    return true;
                }
                pProp++;
            }
        }
    }
    return false;
}

 



When I use CeOpenDatabaseEx(&m_ceguidDB, &m_ceoid,  L"MyDB", NULL, 0, NULL), it returns the first record correctly.But when I use CeOpenDatabaseEx(&m_ceguidDB, &m_ceoid, L"MyDB", PKEY_ID, 0, NULL), the handle "dbMyDB" is 0xffffffff, the result of GetLastError() after CeOpenDatabaseEx() is 0x00000057 and CeSeekDatabase(dbMyDB, CEDB_SEEK_VALUEFIRSTEQUAL, (DWORD)&pProp, &dwSize) returns 0 always.


I try to search with Google, see many people ask with the same question but nobody get a correct answer. At last I find something in MSDN: CeOpenDatabaseEx (CEDB) is obsolete. Applications should call CeOpenDatabaseEx2 instead.

So I think CeOpenDatabaseEx()(CEDB) with CEDB_SEEK_VALUEFIRSTEQUAL Parameter is abandoned and always return 0 in WM5. Then I try to use CeOpenDatabaseEx2()(CEDB). Also I noticed I have to use the function CeOpenDatabaseEx2()(CEDB) to open the database first. So I modified the TestSeek() function like that:

Code Snippet
BOOL TestSeek()
{
    WORD wProp;
    PBYTE pBuff = NULL;
    DWORD dwRecSize;
    DWORD dwSize = 0;
    CEOID m_ceoid=0;
    CEOID tempOid = 0;
    SORTORDERSPECEX sortkey;
    sortkey.wVersion = 1;
    sortkey.wNumProps = 1;
    sortkey.wKeyFlags = 0;
    sortkey.rgPropID[0] = PKEY_ID;
    sortkey.rgdwFlags[0] = CEDB_SORT_NONNULL;
    PCEPROPVAL pProp = new CEPROPVAL;
    pProp->propid = PKEY_ID;
    pProp->wFlags = 0;
    pProp->wLenData = 0;
    pProp->val.ulVal = 1;
    dbMyDB = CeOpenDatabaseEx2(&m_ceguidDB, &m_ceoid, L"MyDB", &sortkey, 0, NULL);
    ret= GetLastError();
    if (dbMyDB == 0)
        return false;
    else
    {
        tempOid = CeSeekDatabaseEx(dbMyDB, CEDB_SEEK_VALUEFIRSTEQUAL, (DWORD)&pProp, 1, &dwSize);
        ret = GetLastError();
        if (tempOid != 0)
        {
            tempOid = CeReadRecordPropsdbMyDB, CEDB_ALLOWREALLOC, &wProp, NULL, &(LPBYTE)pBuff, &dwRecSize);
            pProp = (PCEPROPVAL)pBuff;
            for (int i=0;i<WPROP;I++)&NBSP;
            {
                if (pProp->propid == PKEY_VALUE)
                {
                    //do something here
                    return true;
                }
                pProp++;
            }
        }
    }
    return false;
}

 



Unluckly the result is the same, the handle "dbMyDB" is 0xffffffff, the result of GetLastError() after CeOpenDatabaseEx2() is 0x00000057 and CeSeekDatabaseEx(dbMyDB, CEDB_SEEK_VALUEFIRSTEQUAL, (DWORD)&pProp, 1, &dwSize) returns 0.


So maybe it is the last chance for me to approach the goal. I should use CeCreateDatabaseEx2() to create database at the beginning. After every inch search from Google&MSDN, I write the code behind:

Code Snippet
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    int ret;
    CREATE_INVALIDGUID(&m_ceguidDB);
    ...
    if (!CeMountDBVol(&m_ceguidDB, L"cemail.vol", OPEN_EXISTING ))
    {       
        DWORD dwErr = GetLastError();
        CeUnmountDBVol(&m_ceguidDB);
        return false;
    }
    else
    {
        CEDBASEINFOEX dbinfo; 
        ZeroMemory(&dbinfo, sizeof(CEDBASEINFOEX)); 
        dbinfo.wVersion = 1; 
        wcscpy(dbinfo.szDbaseName, L"MyDB"); 
        dbinfo.dwFlags = CEDB_VALIDCREATE; 
        dbinfo.wNumSortOrder = 1; 
        dbinfo.rgSortSpecs[0].wVersion = 1; 
        dbinfo.rgSortSpecs[0].wNumProps = 1; 
        dbinfo.rgSortSpecs[0].wKeyFlags = 0; 
        dbinfo.rgSortSpecs[0].rgPropID[0] = MAKELONG(CEVT_I4, 1); 
        dbinfo.rgSortSpecs[0].rgdwFlags[0] = CEDB_SORT_NONNULL; 
        CeCreateDatabaseEx2(&m_ceguidDB, &dbinfo); 
        ret = GetLastError();
    }
}

 


The code pass the compile&build&run perfectly. But fateful error is: It can not create the database in fact. GetLastError() returns 0x00000057 always. I check the "windbase.h" for the last time, and find something different with MSDN. It is the definition of SORTORDERSPECEX. In CEDB it should has 5 properties, instead of EDB, it has 6 properties. But in "windbase.h" just have one define with 6 properties. Maybe that's the reason why I failed to create CEDB database with SORTORDERSPECEX property?


Finally I tried all the ways I can think out, now I admitted my defeat. Does anybody know how to seek CEDB database use with CEDB_SEEK_VALUEFIRSTEQUAL Parameter? If you known it exactly and may post the correct code, I will be great thanks for your kindness. And I think many developer will also thank for your help.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值