Tim's profileAlwaysPhotosBlogListsMore Tools Help

Blog


    December 29

    netstat

    C:>netstat /?

    -a Displays all connections and listening ports. (Server-side connections are normally not shown).

    -e Displays Ethernet statistics. This may be combined with the -s option.

    -n Displays addresses and port numbers in numerical form.

    -p proto Shows connections for the protocol specified by proto; proto may be tcp or udp. If used with the -s option to display per-protocol statistics, proto may be tcp, udp, or ip.

    -r Displays the contents of the routing table.

    -s Displays per-protocol statistics. By default, statistics are shown for TCP, UDP and IP; the -p

    option may be used to specify a subset of the default.interval Redisplays selected statistics, pausing interval seconds between each display. Press CTRL+C to stop redisplaying statistics. If omitted, netstat will print the current configuration information once.

    Static global variable

    Global 變數被宣告成static之後會變成只有在該file才能使用該變數
     
    其他有關Static的小雜記
    -A static member function does not have a this pointer.
    The compiler does not allow the member access operation this-> in static member function because this member function has been declared as static, and therefore does not have a this pointer.
     
    -A static member function cannot be declared with the keywords virtual, const, volatile, or const volatile.
     
    -A static member function can access only the names of static members, enumerators, and nested types of the class in which it is declared. Suppose a static member function f() is a member of class X. The static member function f() cannot access the nonstatic members X or the nonstatic members of a base class of X.
    December 28

    PostMessage和SendMessage的不同

    SendMessage會直接送Message給指定的視窗而不經過訊息佇列,他會等到該視窗處裡完訊息回傳處裡的結果屬於sync call
     
    而PostMessage會把Message送給訊息佇列而且馬上return傳送成功或失敗屬於async call

    把CE上面的WMP叫到前景

    HWND hwnd=NULL;
     hwnd=FindWindow(_T("WMP for Mobile Devices"),_T("Windows Media"));
     if (hwnd != NULL){
      SetForegroundWindow(hwnd);
     }

    String 轉換 極簡版

    1、char*轉換成CString
    若將char*轉換成CString,除了直接賦值外,還可使用CString::Format進行。例如:

    CODE:
    char chArray[] = "This is a test";
    char * p = "This is a test";


    CODE:
    LPSTR p = "This is a test";
    或在已定義Unicode應的用程式中

    CODE:
    TCHAR * p = _T("This is a test");


    CODE:
    LPTSTR p = _T("This is a test");
    CString theString = chArray;
    theString.Format(_T("%s"), chArray);
    theString = p;
    2、CString轉換成char*

    若將CString類轉換成char*(LPSTR)類型,常常使用下列三種方法:

    方法一,使用強制轉換。例如:

    CODE:
    CString theString( "This is a test" );
    LPTSTR lpsz =(LPTSTR)(LPCTSTR)theString;
    方法二,使用strcpy。例如:

    CODE:
    CString theString( "This is a test" );
    LPTSTR lpsz = new TCHAR[theString.GetLength()+1];
    _tcscpy(lpsz, theString);
    需要說明的是,strcpy(或可移值Unicode/MBCS的_tcscpy)的第二個參數是 const wchar_t* (Unicode)或const char* (ANSI),系統編譯器將會自動對其進行轉換。

    方法三,使用CString::GetBuffer。例如:

    CODE:
    CString s(_T("This is a test "));
    LPTSTR p = s.GetBuffer();
    // 在這裏添加使用p的代碼
    if(p != NULL) *p = _T('\0');
    s.ReleaseBuffer();
    // 使用完後及時釋放,以便能使用其他的CString成員函數
    3、BSTR轉換成char*

    方法一,使用ConvertBSTRToString。例如:

    CODE:
    #include
    #pragma comment(lib, "comsupp.lib")
    int _tmain(int argc, _TCHAR* argv[])
    {
    BSTR bstrText = ::SysAllocString(L"Test");
    char* lpszText2 = _com_util::ConvertBSTRToString(bstrText);
    SysFreeString(bstrText); // 用完釋放
    delete[] lpszText2;
    return 0;
    }
    方法二,使用_bstr_t的賦值運算符重載。例如:

    CODE:
    _bstr_t b = bstrText;
    char* lpszText2 = b;
    4、char*轉換成BSTR

    方法一,使用SysAllocString等API函數。例如:

    CODE:
    BSTR bstrText = ::SysAllocString(L"Test");
    BSTR bstrText = ::SysAllocStringLen(L"Test",4);
    BSTR bstrText = ::SysAllocStringByteLen("Test",4);
    方法二,使用COleVariant或_variant_t。例如:

    CODE:
    //COleVariant strVar("This is a test");
    _variant_t strVar("This is a test");
    BSTR bstrText = strVar.bstrVal;
    方法三,使用_bstr_t,這是一種最簡單的方法。例如:

    CODE:
    BSTR bstrText = _bstr_t("This is a test");
    方法四,使用CComBSTR。例如:

    CODE:
    BSTR bstrText = CComBSTR("This is a test");


    CODE:
    CComBSTR bstr("This is a test");
    BSTR bstrText = bstr.m_str;
    方法五,使用ConvertStringToBSTR。例如:

    CODE:
    char* lpszText = "Test";
    BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);
    5、CString轉換成BSTR

    通常是通過使用CStringT::AllocSysString來實現。例如:

    CODE:
    CString str("This is a test");
    BSTR bstrText = str.AllocSysString();

    SysFreeString(bstrText); // 用完釋放
    6、BSTR轉換成CString

    一般可按下列方法進行:

    CODE:
    BSTR bstrText = ::SysAllocString(L"Test");
    CStringA str;
    str.Empty();
    str = bstrText;


    CODE:
    CStringA str(bstrText);
    7、ANSI、Unicode和寬字元之間的轉換
    方法一,使用MultiByteToWideChar將ANSI字元轉換成Unicode字元,使用WideCharToMultiByte將Unicode字元轉換成ANSI字元。

    方法二,使用“_T”將ANSI轉換成“一般”類型字串,使用“L”將ANSI轉換成Unicode,而在託管C++環境中還可使用S將ANSI字串轉換成String*物件。例如:

    CODE:
    TCHAR tstr[] = _T("this is a test");
    wchar_t wszStr[] = L"This is a test";
    String* str = S”This is a test”;
    方法三,使用ATL 7.0的轉換宏和類。ATL7.0在原有3.0基礎上完善和增加了許多字串轉換巨集以及提供相應的類,它具有如圖3所示的統一形式:

    其中,第一個C表示“class”,以便於ATL 3.0宏相區別,第二個C表示常量,2表示“to”,EX表示要開闢一定大小的緩衝。SourceType和DestinationType可以是A、T、W和OLE,其含義分別是ANSI、Unicode、“一般”類型和OLE字串。例如,CA2CT就是將ANSI轉換成一般類型的字串常量。下面是一些示例代碼:

    CODE:
    LPTSTR tstr= CA2TEX<16>("this is a test");
    LPCTSTR tcstr= CA2CT("this is a test");
    wchar_t wszStr[] = L"This is a test";
    char* chstr = CW2A(wszStr);

    結語
    幾乎所有的程式都要用到字串,而Visual C++.NET由於功能強大、應用廣泛,因而字串之間的轉換更為頻繁。本文幾乎涉及到目前的所有轉換方法。當然對於.NET框架來說,還可使用Convert和Text類進行不同資料類型以及字元編碼之間的相互轉換。

    http://140.118.175.207/Discuz/upload/viewthread.php?tid=39&extra=page%3D1

    [轉錄]CString,string,char*的综合比较(2)

    e)       增加

    作用

    char*

    string

    CString

    动态增加值

    strcat

    push

    append

    Append

    AppendChar

    AppendFormat

    f)      截取

    作用

    char*

    string

    CString

    得到部分值

    用下标操作

    substr

    Left

    Mid

    Right

    Truncate

    g)      移除

    作用

    char*

    string

    CString

    移除部份值

     

    remove

    Remove

    移除空白值

    RemoveBlanks

    注:此为ATL提供,非C函数

    remove_if

    Trim

    TrimLeft

    TrimRigth

    h)      转换大小写

    作用

    char*

    string

    CString

    转换大小写

    _strlwr

    _strupr

     

    MakeLower

    MakeUpper

    i)       与其他类型转换

    作用

    char*

    string

    CString

    转化为数字

    atoi

    atod

    atof

     

    Format

    转化为char*

     

    c_str

    GetBuffer

    GetBufferSetLength

    j)       格式化

    作用

    char*

    string

    CString

    格式化

    sprintf

     

    Format

    k)      得到长度

    作用

    char*

    string

    CString

    得到长度

    strlen

    length

    GetLength

    得到大小

     

    size

    GetAllocLength

    l)      判断为空

    作用

    char*

    string

    CString

    判断是否为空

    判断是否==NULL或者第一个字符是否是’\0’

    empty

    IsEmpty

    m)        重定义大小

    作用

    char*

    string

    CString

    重定义大小

    realloc

    new

    resize

    GetBufferSetLength

    n)        释放资源

    作用

    char*

    string

    CString

    释放

    free

    delete (delete[])

     

    ReleaseBuffer

    ReleaseBufferSetLength

    (五)  安全性

    CString > string > char*

    (六)  灵活性

    CString > string >char*

    (七)  可移植性

    char* = string > CString

    (九)  总结

    综上所述,我个人认为,在MFCATL中使用字符串尽量使用CString,毕竟都是微软的孩子,各方面都比其它更有优势,而在非微软平台上或对移植性要求较高的场合推荐使用string,标准模板库提供了那么强大的泛型算法,没必要再自己去造车轮。

    (十)  参考文献

    主要参考的是MSDN,就不一一列出了。

    [轉錄]CString,string,char*的综合比较

    (一)  概述

    stringCString均是字符串模板类,string为标准模板类(STL)定义的字符串类,已经纳入C++标准之中;

    CStringtypedef CStringT<TCHAR, StrTraitMFC<TCHAR>> CString)为Visual C++中最常用的字符串类,继承自CSimpleStringT类,主要应用在MFCATL编程中,主要数据类型有char(应用于ANSI)wchar_t(unicode)TCHAR(ANSIunicode均可)

    char*C编程中最常用的字符串指针,一般以’\0’为结束标志;

    (二)  构造

    ²        string是方便的,可以从几乎所有的字符串构造而来,包括CStringchar*

    ²        CString次之,可以从基本的一些字符串变量构造而来,包括char*等;

    ²        char*没有构造函数,仅可以赋值;

    ²        举例:

    char* psz = “joise”;

    CString cstr( psz );

    string str( cstr );

    (三)  运算符重载

    a)       operator=

    ²        string是最方便的,几乎可以直接用所有的字符串赋值,包括CStringchar*

    ²        CString次之,可以直接用些基本的字符串赋值,包括char*等;

    ²        char*只能由指针赋值,并且是极危险的操作,建议使用strcpy或者memcpy,而且char*在声明的时候如未赋初值建议先设为NULL,以避免野指针,令你抓狂;

    ²        举例:

    char *psz = NULL;

    psz = new char[10]; //当然,以上的直接写成char *psz = new char[10];也是一样

    memset( psz, 0, 10 );

    strcpy( psz, “joise” );

    CString cstr;

    cstr = psz;

    string str;

    str = psz;

    str = cstr;

    delete []psz;

    b)          operator+

    ²        stringCString差不多,可以直接与char*进行加法,但不可以相互使用+运算符,即string str = str + cstr是非法的,须转换成char*

    ²        char*没有+运算,只能使用strcat把两个指针连在一起;

    ²        举例:

    char* psz = “joise”;

    CString cstr = psz;

    cstr = cstr + psz;

    string str = psz;

    str = str + str + psz;

    strcat( psz, psz );

    strcat( psz, cstr );//合法

    strcat( psz, str );//非法,由此可见,CString可自动转换为const char*,而string不行

    c)      operator +=

    ²        string是最强大的,几乎可以与所有的字符串变量+=,包括CStringchar*

    ²        CString次之,可以与基本的一些字符串变量进行+=而来,包括char*等;

    ²        char*没有+=运算符,只能使用strcat把两个指针连在一起;

    d)      operator[]

    ²    CString最好,当越界时会抛出断言异常;

    ²    stringchar*下标越界结果未定义;

    ²        举例:

    char* psz = “joise”;

    CString cstr = psz;

    cout << cstr[8];

    string str = psz;

    cout << str[8];

    cout << psz[8];

    e)       operator== operator!=operator> operator< operator>= perator<=

    ²        CStringstring之间不可以进行比较,但均可以与char*进行比较,并且比较的是值,而不是地址;

           cout << ( psz == cstr );

           cout << ( psz == str );

           cout << ( str == psz );

           cout << ( cstr == psz );//以上代码返回均为1

    (四)  常用算法

    a)       查找

    作用

    char*

    string

    CString

    查找指定值

    strchr

    strstr

    strrstr

    strspn

    find

    Find

    第一个匹配的值

     

    fild_first_of

    FindOneOf

    从后面开始查找

     

     

    ReserveFind

    指定匹配方式

     

    find_if

     

    注:find_if中是把范围内的值挨个代入匹配函数直至返回true

    b)      比较

    作用

    char*

    string

    CString

    查找指定值(区分大小写)

    strcmp

    strncmp

    strcoll

    _strncoll

    operator<

    operator>

    operator<=

    operator>=

    operator==

    operator!=

    Collate

    Compare

    查找指定值(不区分大小写)

    _stricmp

    _strnicmp

    _stricoll

    _strnicoll

     

    CollateNoCase

    CompareNoCase

    注:返回值如果<0则前面的值小于后面的值,反之亦然

    c)      替换

    作用

    char*

    string

    CString

    查找指定值

    _strset

    _strnset

    replace

    replace_copy

    replace_copy_if

    replace_if

     

    Replace

    d)      插入

    作用

    char*

    string

    CString

    查找指定值

     

    insert

    Insert

     

    [轉錄]基本類型轉換整理

    int i = 100;
    long l = 2001;
    float f=300.2;
    double d=12345.119;
    char username[]="程佩君";
    char temp[200];
    char *buf;
    CString str;
    _variant_t v1;
    _bstr_t v2;

    一、其它数据类型转换为字符串

    • 短整型(int)
      itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制
      itoa(i,temp,2); ///按二进制方式转换
    • 长整型(long)
      ltoa(l,temp,10);
    • 浮点数(float,double)
      用fcvt可以完成转换,这是MSDN中的例子:
      int decimal, sign;
      char *buffer;
      double source = 3.1415926535;
      buffer = _fcvt( source, 7, &decimal, &sign );
      运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
      decimal表示小数点的位置,sign表示符号:0为正数,1为负数
    • CString变量
      str = "2008北京奥运";
      buf = (LPSTR)(LPCTSTR)str;
    • BSTR变量
      BSTR bstrValue = ::SysAllocString(L"程序员");
      char * buf = _com_util::ConvertBSTRToString(bstrValue);
      SysFreeString(bstrValue);
      AfxMessageBox(buf);
      delete(buf);
    • CComBSTR变量
      CComBSTR bstrVar("test");
      char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
      AfxMessageBox(buf);
      delete(buf);
    • _bstr_t变量
      _bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用
      _bstr_t bstrVar("test");
      const char *buf = bstrVar;///不要修改buf中的内容
      AfxMessageBox(buf);

    • 通用方法(针对非COM数据类型)
      用sprintf完成转换
      char  buffer[200];char  c = '1';int   i = 35;long  j = 1000;float f = 1.7320534f;sprintf( buffer, "%c",c);sprintf( buffer, "%d",i);sprintf( buffer, "%d",j);sprintf( buffer, "%f",f);

    二、字符串转换为其它数据类型
    strcpy(temp,"123");

    • 短整型(int)
      i = atoi(temp);
    • 长整型(long)
      l = atol(temp);
    • 浮点(double)
      d = atof(temp);
    • CString变量
      CString name = temp;
    • BSTR变量
      BSTR bstrValue = ::SysAllocString(L"程序员");
      ...///完成对bstrValue的使用
      SysFreeString(bstrValue);
    • CComBSTR变量
      CComBSTR类型变量可以直接赋值
      CComBSTR bstrVar1("test");
      CComBSTR bstrVar2(temp);
    • _bstr_t变量
      _bstr_t类型的变量可以直接赋值
      _bstr_t bstrVar1("test");
      _bstr_t bstrVar2(temp);

    三、其它数据类型转换到CString
    使用CString的成员函数Format来转换,例如:

    • 整数(int)
      str.Format("%d",i);
    • 浮点数(float)
      str.Format("%f",i);
    • 字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值
      str = username;
    • 对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。

    四、BSTR、_bstr_t与CComBSTR

    • CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
      char *转换到BSTR可以这样:
      BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
      SysFreeString(bstrValue);
      反之可以使用
      char *p=_com_util::ConvertBSTRToString(b);
      delete p;
      具体可以参考一,二段落里的具体说明。

      CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。
      特别是_bstr_t,建议大家使用它。

    五、VARIANT 、_variant_t 与 COleVariant

    • VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。
      对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:
      VARIANT va;
      int a=2001;
      va.vt=VT_I4;///指明整型数据
      va.lVal=a; ///赋值

      对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:

      Byte bVal; // VT_UI1.
      Short iVal; // VT_I2.
      long lVal; // VT_I4.
      float fltVal; // VT_R4.
      double dblVal; // VT_R8.
      VARIANT_BOOL boolVal; // VT_BOOL.
      SCODE scode; // VT_ERROR.
      CY cyVal; // VT_CY.
      DATE date; // VT_DATE.
      BSTR bstrVal; // VT_BSTR.
      DECIMAL FAR* pdecVal // VT_BYREF|VT_DECIMAL.
      IUnknown FAR* punkVal; // VT_UNKNOWN.
      IDispatch FAR* pdispVal; // VT_DISPATCH.
      SAFEARRAY FAR* parray; // VT_ARRAY|*.
      Byte FAR* pbVal; // VT_BYREF|VT_UI1.
      short FAR* piVal; // VT_BYREF|VT_I2.
      long FAR* plVal; // VT_BYREF|VT_I4.
      float FAR* pfltVal; // VT_BYREF|VT_R4.
      double FAR* pdblVal; // VT_BYREF|VT_R8.
      VARIANT_BOOL FAR* pboolVal; // VT_BYREF|VT_BOOL.
      SCODE FAR* pscode; // VT_BYREF|VT_ERROR.
      CY FAR* pcyVal; // VT_BYREF|VT_CY.
      DATE FAR* pdate; // VT_BYREF|VT_DATE.
      BSTR FAR* pbstrVal; // VT_BYREF|VT_BSTR.
      IUnknown FAR* FAR* ppunkVal; // VT_BYREF|VT_UNKNOWN.
      IDispatch FAR* FAR* ppdispVal; // VT_BYREF|VT_DISPATCH.
      SAFEARRAY FAR* FAR* pparray; // VT_ARRAY|*.
      VARIANT FAR* pvarVal; // VT_BYREF|VT_VARIANT.
      void FAR* byref; // Generic ByRef.
      char cVal; // VT_I1.
      unsigned short uiVal; // VT_UI2.
      unsigned long ulVal; // VT_UI4.
      int intVal; // VT_INT.
      unsigned int uintVal; // VT_UINT.
      char FAR * pcVal; // VT_BYREF|VT_I1.
      unsigned short FAR * puiVal; // VT_BYREF|VT_UI2.
      unsigned long FAR * pulVal; // VT_BYREF|VT_UI4.
      int FAR * pintVal; // VT_BYREF|VT_INT.
      unsigned int FAR * puintVal; //VT_BYREF|VT_UINT.

    • _variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
      使用时需加上#include <comdef.h>
      例如:
      long l=222;
      ing i=100;
      _variant_t lVal(l);
      lVal = (long)i;

    • COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:
      COleVariant v3 = "字符串", v4 = (long)1999;
      CString str =(BSTR)v3.pbstrVal;
      long i = v4.lVal;

    六、其它一些COM数据类型

    • 根据ProgID得到CLSID
      HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);
      CLSID clsid;
      CLSIDFromProgID( L"MAPI.Folder",&clsid);
    • 根据CLSID得到ProgID
      WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID);
      例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID
      LPOLESTR pProgID = 0;
      ProgIDFromCLSID( CLSID_IApplication,&pProgID);
      ...///可以使用pProgID
      CoTaskMemFree(pProgID);//不要忘记释放

    七、ANSI与Unicode
    Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。

    • 将ANSI转换到Unicode
      (1)通过L这个宏来实现,例如: CLSIDFromProgID( L"MAPI.Folder",&clsid);
      (2)通过MultiByteToWideChar函数实现转换,例如:
      char *szProgID = "MAPI.Folder";
      WCHAR szWideProgID[128];
      CLSID clsid;
      long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));
      szWideProgID[lLen] = '\0';
      (3)通过A2W宏来实现,例如:
      USES_CONVERSION;
      CLSIDFromProgID( A2W(szProgID),&clsid);
    • 将Unicode转换到ANSI
      (1)使用WideCharToMultiByte,例如:
      // 假设已经有了一个Unicode 串 wszSomeString...
      char szANSIString [MAX_PATH];
      WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL );
      (2)使用W2A宏来实现,例如:
      USES_CONVERSION;
      pTemp=W2A(wszSomeString);

    八、其它

    • 对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:
      LPARAM lParam;
      WORD loValue = LOWORD(lParam);///取低16位
      WORD hiValue = HIWORD(lParam);///取高16位

    • 对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:
      WORD wValue;
      BYTE loValue = LOBYTE(wValue);///取低8位
      BYTE hiValue = HIBYTE(wValue);///取高8位

    • 两个16位数据(WORD)合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)
      LONG MAKELONG( WORD wLow, WORD wHigh );
      WPARAM MAKEWPARAM( WORD wLow, WORD wHigh );
      LPARAM MAKELPARAM( WORD wLow, WORD wHigh );
      LRESULT MAKELRESULT( WORD wLow, WORD wHigh );

    • 两个8位的数据(BYTE)合成16位的数据(WORD)
      WORD MAKEWORD( BYTE bLow, BYTE bHigh );

    • 从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值
      COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );
      例如COLORREF bkcolor = RGB(0x22,0x98,0x34);

    • 从COLORREF类型的颜色值得到RGB三个颜色值
      BYTE Red = GetRValue(bkcolor); ///得到红颜色
      BYTE Green = GetGValue(bkcolor); ///得到绿颜色
      BYTE Blue = GetBValue(bkcolor); ///得到兰颜色

    九、注意事项
    假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )

     

     

    http://blog.csdn.net/visiond/archive/2002/02/07/3949.aspx

    December 26

    [轉錄]#pragma once的缺點

    The programmer must rely on the compiler to handle #pragma once correctly. If the compiler makes a mistake, for example by failing to recognize that two symbolic links with different names point to the same file, then the compilation will fail. Compilers with #pragma once-related bugs included LCC-Win32 as of 2004 [2][3] and GCC as of 1998.[4] As of 2005, the GCC documentation lists #pragma once as an "obsolete" feature.[5]

    And, it is not recognized by all preprocessors, so you cannot rely on it in a portable program.

    December 21

    [轉錄]手機簡史

     
    --
     
    首先是1G. 2G. 3G的這個G字,其實就是Generation,也就是世代的意思,所以3G很多人可能會誤以為有三個G開頭的字(類似我們今天稱呼triple W or I triple E),但其實真的就只是3rd Generation的意思,怎麼樣?單純到有點出乎你的意料吧?

    簡單來說,從1G進步到2G,主要的改變是從類比訊號轉為數位訊號,在1G通訊標準時期,最著名的規格是AMPS (Advanced Mobile Phone System),早期的黑金剛即屬此種規格下的產品,其實Advanced指的進階,只是比一般的室內電話更進步一點,所以就跟室內電話一樣,AMPS也是類比的語音傳輸,而AMPS所採用的處理技術為FDMA (Frequency Division Multiple Access,分頻多工存取)。

    後來2G則進步到數位訊號,其中的規格並不只有一種,所採用的技術也可以粗淺的分為TDMA與CDMA兩種。歐洲、台灣等地所使用的GSM (Global System For Mobile Communication)與日本採用的PDC (Personal Digital Cellular)都屬於TDMA(Time Division Multiple Access,分時多工存取)的技術,而美國則由Qualcomm公司發展出一套嶄新的傳輸標準CDMA (Code Division Multiple Access,分碼多工存取),此時的CDMA其實仍然屬於2G的範圍,後來則被通稱為所謂的窄頻CDMA (narrow-band CDMA),以便於跟3G的新一代CDMA技術做區別。

    至於3G與2G的差異,最主要的地方在於資料傳輸的速度,換句話說也就是頻寬的增加。3G的通訊標準不一而足,但主要都是從CDMA技術為藍圖而發展出來的,最著名的包括了W-CDMA (Wide-band CDMA)、CDMA 2000、以及大陸積極推動的TDS-CDMA。這些都只是資料傳輸技術的不同。

    至於FOMA (Freedom Of Multimedia Access),本身並不是一種技術,而是日本NTT DoCoMo所推出的3G行動上網服務,這也是全球第一個真正商業運行的3G服務,FOMA本身採用W-CDMA的技術,基地台設備則由Ericsson提供。所以拿FOMA來跟W-CDMA、CDMA 2000或是TDMA來比是有概念化上的缺失,就好像拿橘子跟椅子比一樣,而日本第二大系統業者KDDI所推動的3G服務,則是以CDMA 2000為架構。

    而所謂的WAP與GPRS,其實兩者之間也無法真正被拿來作比較,這也是目前很多很多人的一個誤解,以為GPRS是拿來與WAP相提並論的。WAP (Wireless Application Protocol,無線應用協定)是一種通訊協定,就好像internet上用的是HTTP一樣,而在WAP協定下所使用的程式語言則為WML (Wireless Mark-Up Language),這也相對於一般internet所使用的HTML。

    而在介紹GPRS以前,我們應該要對幾個概念正名一下(這可不是什麼台灣正名運動的正名),一般我們說的WAP手機,其實應該是指WAP Over Circuit-Switched Data,或是簡單一點說成WAP Over GSM Circuit也行,但我們所說的GPRS手機上網,其實是屬於WAP Over Packet-Switched Data,或是WAP Over GPRS。從這邊我們可以看出來,GPRS相對的概念其實並不是WAP,而應該是傳統GSM線路的傳輸方式。

    GPRS (General Packet Radio Service,通用封包無線傳輸服務),根本上的技術是從之前GSM線路傳輸的9.6Kbps,改用封包傳輸的技術,分開傳送、同步處理,使得傳輸速度得以大幅度提升,理論上可以達到100Kbps,但目前實作出來的速度約略是在40~50Kbps左右(依所利用到的Time Slot而定)。至於為什麼GSM線路傳輸的速度只有9.6Kbps而不是96Kbps,這可真的是一個大哉問了,我只能說,一開始GSM規格在制定的時候,一個時槽(Time Slot)所劃分的頻寬扣掉容錯碼後就只剩9.6Kbps(因為一開始GSM仍然是拿來講電話的,當初誰會想到要用這玩意上網?),而GPRS技術則可以一次利用單一頻率中全部的八個時槽來傳輸資料,至於傳送的方式則是拆開成封包同步傳輸,後端再把封包組裝起來形成原始的資料(想像成WinRAR或是Love Machine的多個壓縮檔就能理解了),但這邊又有一個技術要跟GPRS釐清不同的地方,那就是所謂的HSCSD (High Speed Circuit Switched Data Service),HSCSD與GPRS類似的地方是都能同時使用超過一個的時槽進行資料傳輸,但相異的地方在於HSCSD仍然是採用傳統GSM的線路傳輸技術而非GPRS的封包傳送,所以如果覺得GPRS上網太貴的人,不妨去看看新加坡HSCSD服務的費率吧,包管你看了以後不寒而慄。至於把GPRS稱作2.5G,其實是一個有些投機取巧的做法,因為真的要探究邏輯性思考的話(沒辦法,進研究所以後一天到晚在那邊討論邏輯思考,弄的我都有點神經質),顯然2.5G是一個有很大問題的名詞,因為Generation這個字的意思本身就是無法被分割的,就好像考試的成績,第一名後面就是第二名,沒有什麼2.5名這種東西,既然有2.5名那他就是第三名!會拿2.5G來稱呼GPRS,無非是因為GPRS大幅度提升了GSM系統架構下資料傳輸的速度,可是這個速度又還沒達到3G的要求,只好給它硬塞一個2.5G的名詞,至於2.7G,那就更Kuso了,為什麼是2.7不是2.8呢?其實我也不知道,相信搞出這個名詞的人也不知道。