国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
WinCE下常用但缺少的功能函數(shù)(UuidCreate、ini文件操作)
 
2007.7.1 18:12 作者:peng
 

最近兩周,在做一個項目的移植,大部分時間是比較幸運的,大部分的API都被支持,多是一些VS2005語法要求更為嚴格后的一些常見錯誤,另外就是CE對完成例程的不支持,改為Select模型也就可以了,再就是ARM CPU平臺下常見的內(nèi)存對齊問題和據(jù)說也是常見的模板的兼容性問題。總的來說還是比較幸運的。
 
在此中間有兩個小的問題,一個是WinCE下沒有Ini文件的操作API,再就是沒有UuidCreate函數(shù)創(chuàng)建通用的GUID。這兩個問題都是比較普通常見的操作,于是開始我沒有太重視,以為隨便一搜索網(wǎng)上就會有一堆的現(xiàn)成代碼可用,因為太普通了。但事實證明我是錯誤的,至少ini操作比較完善的工具函數(shù)我就沒有找到合適的,GUID的創(chuàng)建倒是有個C#的版本,但C版本也沒有見到,后來想,可能是目前做手機開發(fā)的資源和人還是較少吧。
 
后來就不得不放棄自己懶惰的想法了,沒辦法,既然沒有就自己實現(xiàn)了。實際上我還是傾向于使用現(xiàn)成代碼的,因為代碼雖然簡單不多,但自己寫的話測試和調(diào)試還是有些費事,要保證可靠性還可能要考慮到一些自己可能會有些地方考慮不到,綜合別人的代碼可以彌補這些不足?,F(xiàn)在我花了些時間實現(xiàn),并基本詳細測試過了,所以也就拿出來共享一下,以讓后面用到的人能夠比我現(xiàn)在能省事些,畢竟一直以來大都是從互聯(lián)網(wǎng)拿,自己給予的太少,如果都和我這樣,估計就比較可怕了,也該拿出些東西來了,否則心里老是不安。
 
首先是創(chuàng)建GUID,這個主要的一點是盡可能和WinAPI的特性保持一致,否則可能會有重復的風險,這是一個難點,所以主要是要參考Rfc和MSDN,代碼如下:
 
//------------------------------------------------------------------------------
//  Win CE下生成Guid的文件:由于Win CE下不支持UuidCreate函數(shù),因此創(chuàng)建Uuid需要
//  自己實現(xiàn),僅僅用隨機數(shù)的方式不能保證同其它系統(tǒng)(PC)下的兼容性。從MSDN上找到
//  了Guid的實現(xiàn)算法,據(jù)文檔中描述,算法保持了同PC下的基本一致性。    
//  
//  參考:http://msdn2.microsoft.com/en-us/library/aa446557.aspx
// 
//------------------------------------------------------------------------------
#pragma once
#include <wincrypt.h>
class PocketGuid
{
private:
    // One to three bits of the clock sequence section are used to define the variant, or layout,
    // of the GUID. Windows and the PocketGuid class generate variant type 2 GUIDs.
    enum GuidVariant
    {
        ReservedNCS = 0x00,
        Standard = 0x02,
        ReservedMicrosoft = 0x06,
        ReservedFuture = 0x07
    };
    // The upper four bits of the timestamp section contain the GUID's version that specifies the content of
    // each section. Before Windows 2000, the CoCreateGuid function generated version 1 GUIDs. With Windows 2000,
    // Microsoft switched to version 4 GUIDs, since embedding the MAC address was viewed as a security risk.
    // The PocketGuid class also generates version 4 GUIDs.
    enum GuidVersion
    {
        TimeBased = 0x01,
        Reserved = 0x02,
        NameBased = 0x03,
        Random = 0x04
    };
    class Const
    {
        // number of bytes in guid
    public:
        static const int ByteArraySize = 16;
 
  // multiplex variant info
  static const int VariantByte = 8;
  static const int VariantByteMask = 0x3f;
  static const int VariantByteShift = 6;
  // multiplex version info
  static const int VersionByte = 7;
  static const int VersionByteMask = 0x0f;
  static const int VersionByteShift = 4;
    };
public:
    static HRESULT CreateGuid (GUID & guid)
    {
        HCRYPTPROV hCryptProv = NULL;
        HRESULT hr = S_OK;
 
        // holds random bits for guid
        BYTE  * bits = new BYTE[Const::ByteArraySize];
        if (bits == NULL)
        {
            hr = E_OUTOFMEMORY;
            goto ExitHere;
        }
        // get crypto provider handle
        if (!CryptAcquireContext (&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
        {
            hr = HRESULT_FROM_WIN32 (GetLastError ());
            goto ExitHere;
        }
        // generate a 128 bit (16 byte) cryptographically random number
        if (!CryptGenRandom (hCryptProv, Const::ByteArraySize, bits))
        {
            hr = HRESULT_FROM_WIN32 (GetLastError ());
            goto ExitHere;
        }
        // set the variant
        bits[Const::VariantByte] &= Const::VariantByteMask;
        bits[Const::VariantByte] |= ((int)Standard << Const::VariantByteShift);
        // set the version
        bits[Const::VersionByte] &= Const::VersionByteMask;
        bits[Const::VersionByte] |= ((int)Random << Const::VersionByteShift);       
       
        memcpy (&guid, bits, sizeof (GUID));
  
    ExitHere:
        if (hCryptProv != NULL)
            CryptReleaseContext (hCryptProv, 0);
        if (bits != NULL)
            delete [] bits;
  return hr;
    };
};

 

ini文件操作相關(guān)函數(shù),根據(jù)我的需要,只實現(xiàn)了4個,代碼如下:

 

#ifdef UNDER_CE

//=======================================================================================================
//
//   WinCE下不支持ini文件操作的API,根據(jù)MSDN的幫助和Win32下測試的API的特性,模擬實現(xiàn)。測試發(fā)現(xiàn)API在不同
//   系統(tǒng)下的特性不完全一致,但區(qū)別不大,這里實現(xiàn)的是大部分XP系統(tǒng)下的特性
//  
//=======================================================================================================

#define GetPrivateProfileSectionNames   GetMyProfileSectionNames
#define GetPrivateProfileSection GetMyProfileSection
#define WritePrivateProfileString WriteMyProfileString
#define GetPrivateProfileString GetMyProfileString

BOOL WriteMyProfileString (LPCTSTR section, LPCTSTR keyName, LPCTSTR value, LPCTSTR filePath)
{
    CIniFile iniFile;
    CString str = _T ("");

    CString strSection = section;
    CString strKeyName = keyName;
    CString strValue = value;

    if (!iniFile.Open (filePath, CFile::modeRead | CFile::modeCreate | CFile::modeNoTruncate))
        return FALSE;

    CStringArray strArray;
    while (iniFile.ReadLine (str))
    {
        strArray.Add (str);
    }
    iniFile.Close ();

    BOOL foundKey = FALSE;
    BOOL addValue = FALSE;
    for (int i = 0; i < strArray.GetSize (); i++)
    {
        str = strArray[i];
        str = str.TrimLeft ().TrimRight ();
        if (str.GetAt (0) == ',' || str.GetAt (0) == '#')
            continue;

        if (!foundKey)
        {
            if (str.GetAt (0) == '[' && str.Right (str.GetLength () - 1).TrimLeft ().Find (strSection) == 0)
            {
                foundKey = TRUE;
                if (keyName == NULL)
                {
                    strArray.RemoveAt (i);
                    i --;
                }
            }
        }
        else
        {
            // enter new key's area
            if (str.GetAt (0) == '[')
            {
                if (keyName != NULL)
                {
                    strArray.InsertAt (i, strKeyName + _T ("=") + strValue + _T ("\r"));
                    addValue = TRUE;
                }
                break;
            }
            else if (keyName == NULL)
            {
                strArray.RemoveAt (i);
                i --;
            }
            else if (str.Find (strKeyName) == 0)
            {
                CString rightValue = str.Right (str.GetLength () - strKeyName.GetLength ()).TrimLeft ();
                if (rightValue.Find (_T ("=")) == 0)
                {
                    if (value != NULL)
                    {
                        strArray[i] = strKeyName + _T ("=") + strValue + _T ("\r");
                        addValue = TRUE;
                    }
                    else
                    {
                        strArray.RemoveAt (i);
                    }
                    break;
                }
            }
        }
    }
   
    if (!addValue && keyName != NULL && value != NULL)
    {
        if (!foundKey)
            strArray.Add (_T ("[") + strSection + _T ("]") + _T ("\r"));
        strArray.Add (strKeyName + _T ("=") + strValue + _T ("\r"));
    }

    if (!iniFile.Open (filePath, CFile::modeCreate | CFile::modeWrite))
        return FALSE;

    for (int i = 0; i < strArray.GetSize (); i++)
    {
        iniFile.WriteString (strArray[i]);
    }
    iniFile.Close ();
 
    return TRUE;
}

void GetMyProfileString (LPCTSTR  section, LPCTSTR keyName, LPCTSTR defaultStr, CString & returnedStr, LPCTSTR fileName)
{
    CString strSection = section;
    CString strKeyName = keyName;
    returnedStr = defaultStr;
   
    if (strSection == _T ("") || strKeyName == _T (""))
        return;

    CIniFile iniFile;
    CString str = _T ("");

    if (!iniFile.Open (fileName, CFile::modeRead))
        return;

    BOOL foundKey = FALSE;
    while (iniFile.ReadLine (str))
    {
        str = str.Trim ();
        if (str.GetAt (0) == ',' || str.GetAt (0) == '#')
            continue;

        if (!foundKey)
        {
            if (str.GetAt (0) == '[' && str.Right (str.GetLength () - 1).TrimLeft ().Find (strSection) == 0)
                foundKey = TRUE;
        }
        else
        {
            // enter new key's area
            if (str.GetAt (0) == '[')
            {
                foundKey = FALSE;
                break;
            }           
            else if (str.Find (strKeyName) == 0)
            {
                CString rightValue = str.Right (str.GetLength () - strKeyName.GetLength ()).TrimLeft ();
                if (rightValue.Find (_T ("=")) == 0)
                {
                    returnedStr = rightValue.Right (rightValue.GetLength () - 1).Trim ();
                    break;
                }
            }
        }
    }
    iniFile.Close ();
}


DWORD GetMyProfileString (LPCTSTR  section, LPCTSTR keyName, LPCTSTR defaultStr, LPTSTR returnedString, DWORD size, LPCTSTR filePath)
{
    if (returnedString == NULL || size == 0)
        return 0;

    if (size == 1)
    {
        returnedString[0] = '\0';
        return 0;
    }

    CString str = _T ("");
    GetMyProfileString (section, keyName, defaultStr, str, filePath);

    DWORD available = size - 1;

    if (available < (DWORD)str.GetLength ())
        str = str.Left (available);

    wcscpy_s (returnedString, size, str.GetBuffer ());
    int allocSize = str.GetLength (); 

    returnedString[allocSize + 1] = '\0';
    return allocSize;
}

DWORD GetMyProfileSectionNames (LPTSTR returnBuffer, DWORD size,  LPCTSTR fileName)
{   
    if (returnBuffer == NULL || size == 0)
        return 0;
    if (size <= 2)
    {
        returnBuffer[0] = '\0';
        return 0;
    }

    CIniFile iniFile;
    if (!iniFile.Open (fileName, CFile::modeRead))
    {
        returnBuffer[0] = '\0';
        return 0;
    }

    CString str = _T ("");
    DWORD allocSize = 0;
    DWORD available = size - 1;
    while (iniFile.ReadLine (str) && available > 1)
    {
        str = str.Trim ();
        if (str.GetAt (0) == ',' || str.GetAt (0) == '#')
            continue;

        if (str.GetAt (0) == '[')
        {
            CString section = str.Right (str.GetLength () - 1).Trim ();
            int pos = section.Find (_T ("]"));
            if (pos >= 0)
                section = section.Left (pos).Trim ();

            if (available < (DWORD)section.GetLength ())
                section = section.Left (available - 1);

            wcscpy_s (returnBuffer + allocSize, size - allocSize, section.GetBuffer ());
            int curAlloc = section.GetLength () + 1; 
            allocSize += curAlloc; 
            ASSERT (available >= (DWORD)curAlloc);
            available -= curAlloc;
        }
    }             
    returnBuffer[allocSize] = '\0';
    return allocSize > 1 ? allocSize -1 : 0;
}

DWORD GetMyProfileSection (LPCTSTR section, LPTSTR returnedString, DWORD size, LPCTSTR fileName)
{
    if (returnedString == NULL || size == 0 || section == NULL)
        return 0;

    if (size <= 2)
    {
        returnedString[0] = '\0';
        return 0;
    }

    CIniFile iniFile;
    if (!iniFile.Open (fileName, CFile::modeRead))
    {
        returnedString[0] = '\0';
        return 0;
    }
    CString strSection = section;

    CString str = _T ("");
    DWORD allocSize = 0;
    DWORD available = size - 1;
    BOOL  foundKey = FALSE;
    while (iniFile.ReadLine (str) && available > 1)
    {
        str = str.Trim ();
        if (str.GetAt (0) == ',' || str.GetAt (0) == '#')
            continue;

        if (!foundKey)
        {
            if (str.GetAt (0) == '[' && str.Right (str.GetLength () - 1).TrimLeft ().Find (strSection) == 0)
                foundKey = TRUE;
        }
        else
        {
            // enter new key's area
            if (str.GetAt (0) == '[')
            {
                foundKey = FALSE;
                break;
            }    

            CString entry = _T ("");
            int pos = str.Find (_T ("="));
            if (pos >= 0)
            {
                CString left = str.Left (pos).Trim ();
                CString right = str.Right (str.GetLength () - pos - 1).Trim ();
                entry = left + _T ("=") + right;
            }
            else
            {
                entry = str;
            }

            if (available < (DWORD)entry.GetLength ())
                entry = entry.Left (available - 1);

            wcscpy_s (returnedString + allocSize, size - allocSize, entry.GetBuffer ());
            int curAlloc = entry.GetLength () + 1; 
            allocSize += curAlloc; 
            ASSERT (available >= (DWORD)curAlloc);
            available -= curAlloc;
        }
    }             
    returnedString[allocSize] = '\0';
    return allocSize > 1 ? allocSize -1 : 0;
}

//=======================================================================================================
#endif   //UNDER_CE

 

 

這里用到了讀文件的函數(shù),每次讀一行,開始使用了CStdioFile的ReadString,PC下已經(jīng)測試通過了,但真正到了手機上發(fā)現(xiàn)受騙了,呵呵,手機上的ReadString的特性變了,具體可以查看MFC中的源碼,粗略讀了一下它的代碼,似乎CE下ReadString的特性是:如果文件大小不足128,則全部讀出,否則只讀一行;也就是可能超過一行,所以不符合需求了。于是簡單的自己寫了一個能支持真正讀一行的類:

 

 


#ifdef UNDER_CE
class CIniFile : public CStdioFile
{
public:
    CIniFile() {}
    ~CIniFile() {}

    BOOL ReadLine (CString& rString)
    {
        ASSERT_VALID(this);

        ULONGLONG nStartPosition = CFile::GetPosition();
        bool fEndOfFile = false;

        rString = _T("");    // empty string without deallocating
        const int nMaxSize = 128;
        LPTSTR lpsz = rString.GetBuffer(nMaxSize);
        int nLen = 0;
        for (;;)
        {
            // Reading is not buffered, just let the internal OS buffer handle it.
            UINT nRead = CFile::Read(
             reinterpret_cast<void*>(lpsz),
             (nMaxSize)*sizeof(*lpsz) // convert from characters to bytes
             );

            nRead /= sizeof(*lpsz); // convert from bytes to characters

            if(nRead != nMaxSize)
            {
                // reached end of file, terminate the string here.
                fEndOfFile = true;
                //nLen = nRead;
                //break;
            }

            // check for end of line character
            for(nLen = 0 ; nLen < static_cast<int>(nRead) && lpsz[nLen] != '\n' ; ++nLen)
                ;

            if(lpsz[nLen]=='\n')
            {
                // nLen is correct location of end of line, which should be replaced with a null terminator
                fEndOfFile = false;
                break;
            }

            if (fEndOfFile)
            {
                nLen = nRead;
                break;
            }

            rString.ReleaseBuffer();

            nLen = rString.GetLength();
            lpsz = rString.GetBuffer(nMaxSize + nLen) + nLen;
        }

        lpsz[nLen] = '\0';
        rString.ReleaseBuffer();

        nLen = rString.GetLength();

        // Reset the file pointer to the position immediately after the end of line character
        if(!fEndOfFile)
        {
            CFile::Seek(nStartPosition + (nLen + 1) * sizeof(TCHAR), begin);
        }
        return nLen != 0;
    }
};
#endif

 

你可以通過這個鏈接引用該篇文章:http://hrybird.bokee.com/viewdiary.16230696.html

 (#)
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
CString to BYTE array
CStdioFile.ReadString讀取中文產(chǎn)生亂碼解決方法
VC:CString用法整理(轉(zhuǎn)載)
CString截取字符串全攻略&CString::Find()函數(shù)(轉(zhuǎn)載)
【整理】Dword、LPSTR、LPWSTR、LPCSTR、LPCWSTR、LPTSTR、...
轉(zhuǎn)載:MFC文件操作,很全面
更多類似文章 >>
生活服務(wù)
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服