• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            春暖花開
            雪化了,花開了,春天來了
            posts - 149,comments - 125,trackbacks - 0

            為什么Microsoft code sample傾向使用ZeroMemory而不是{0}?

            這是最近看的一片短文的title,當時就很好奇。
            經常查閱MSDN的程序員都會有這個印象,微軟code sample中常見的是ZeroMemory,而不是語言提供的“{0}”清零功能(不過,我一直也沒有問個why)。c++語法中聲明對數組或純結構(struct),可以使用例如SPerson sTest = {0}; 來將所有成員置0.

            那篇文章的解釋是,Microsoft使用ZeroMemory會更clear,因為“= {0}” 這樣的語法有些生僻,不是所有人都可以一下子明白。

            實際上,兩者還是有一些區別。
            其一,ZeroMemory會將結構所有字節置0,而={0}只會將成員置0,其中padding字節不變。

            其二,但一個struct有構造函數或虛函數時,ZeroMemory可以,而={0}會編譯不過。顯然,后者起到了一些保護作用,因為對一個有虛函數的對象使用ZeroMemory時,會將其虛函數的指針置0,這是非常危險的,因為調用虛函數時,程序顯然會crash。參看如下代碼:

            struct SPerson
            {
                
            //SPerson(){    }
                char c;
                
            float s;
            }
            ;

            class CTestVirtual
            {
            public:
                CTestVirtual()
                
            {
                }


                
            virtual int Draw()
                
            {
                    
            return 10;
                }


                
            int a;
            }
            ;

            void Test() 
            {
                
            char sztmp[20];
                ZeroMemory(sztmp, 
            sizeof(sztmp));

                SPerson sTest 
            = {0};
                
            int i = sizeof(SPerson);

                
            //CTestVirtual otv = {0};    //Compire error
                CTestVirtual tv;
                ZeroMemory(
            &tv, sizeof(tv));
                tv.Draw();        
            //As it is an object, don't use the virtual function pointer, so don't crash.
                CTestVirtual *pTv = &tv;
                pTv
            ->Draw();    //Crash!!!
            }

            因此,在windows平臺下,對于數組或純結構使用ZeroMemory是安全的,對于class,則使用構造函數,不要調用ZeroMemory。如果有跨平臺要求,使用={0}則可以減少一些工作。
            posted @ 2008-12-20 15:04 Sandy 閱讀(699) | 評論 (1)編輯 收藏
            原諒我無知,對LPTSTR不是很熟悉,盡管用了半年的WIN32,今天才想起思考LPTSTR這個變量.

            例如:
            LPTSTR lpStr = _T("Hello");
            int len1 = wcslen(lpStr); // 值為5
            int len2 = sizeof(lpStr); // 值為4

            原來是這樣的啊,今天我終于弄明白了!

            lpStr 是一個指針,它的用法應該與指針同.

            犯了一個很低級的錯誤.記錄下來.
            posted @ 2008-12-19 21:10 Sandy 閱讀(2185) | 評論 (0)編輯 收藏

            LoadString的一些小用法中, 談到了對LoadString的一點用法,萬連文指出這個方法解決不夠徹底,聽取了他的意見,我參考了一下vc的CString的LoadString的寫法.
            具體在VC98\MFC\SRC\WINSTR.CPP這個文件中,我也貼出來一部分:

            #ifdef _UNICODE
            #define CHAR_FUDGE 1    // one TCHAR unused is good enough
            #else
            #define CHAR_FUDGE 2    // two BYTES unused for case of DBC last char
            #endif

            BOOL CString::LoadString(UINT nID)
            {
                
            // try fixed buffer first (to avoid wasting space in the heap)
                TCHAR szTemp[256];
                
            int nLen = AfxLoadString(nID, szTemp, _countof(szTemp));
                
            if (_countof(szTemp) - nLen > CHAR_FUDGE)
                
            {
                    
            *this = szTemp;
                    
            return nLen > 0;
                }


                
            // try buffer size of 512, then larger size until entire string is retrieved
                int nSize = 256;
                
            do
                
            {
                    nSize 
            += 256;
                    nLen 
            = AfxLoadString(nID, GetBuffer(nSize-1), nSize);
                }
             while (nSize - nLen <= CHAR_FUDGE);
                ReleaseBuffer();

                
            return nLen > 0;
            }


            #ifndef _AFXDLL
            int AFXAPI AfxLoadString(UINT nID, LPTSTR lpszBuf, UINT nMaxBuf)
            {
                ASSERT(AfxIsValidAddress(lpszBuf, nMaxBuf
            *sizeof(TCHAR)));
            #ifdef _DEBUG
                
            // LoadString without annoying warning from the Debug kernel if the
                
            //  segment containing the string is not present
                if (::FindResource(AfxGetResourceHandle(),
                   MAKEINTRESOURCE((nID
            >>4)+1), RT_STRING) == NULL)
                
            {
                    lpszBuf[
            0= '\0';
                    
            return 0// not found
                }

            #endif //_DEBUG
                
            int nLen = ::LoadString(AfxGetResourceHandle(), nID, lpszBuf, nMaxBuf);
                
            if (nLen == 0)
                    lpszBuf[
            0= '\0';
                
            return nLen;
            }

            #endif

            這段代碼寫的挺精妙的.
            posted @ 2008-12-18 19:35 Sandy 閱讀(3877) | 評論 (1)編輯 收藏
            今天在做東西的時候,用LoadString遇到了一些問題.可能大家日后也會用到,分享一下.

            LoadString 從資源載入字符串,我們一般這么用。
            舉個例子:
            TCHAR str[20];
            LoadString(hInstance, IDS_STR, str, 20);

            如果我們的字符串的長度不知道,或許它會變化的話,我們怎么來獲得資源ID對應的字符串呢?這就要用到
            LoadString的另一種用法,我們可以這樣用
            LPCTSTR lpcStr = (LPCTSTR)LoadString(hInstance, IDS_STR, NULL, 0);

            感覺上沒有什么問題?。?br>
            但是實際應用中又出現問題了,讀出的字符串沒有截斷處理,它包含了下一個ID包含的字符串或者更多。

            怎么辦?在MSDN中,LoadString已經清楚地指出
            lpBuffer is set to NULL, the return value is a pointer to the requested string. The caller should cast the return value to an LPCTSTR. This pointer points directly to the resource, so the string is read-only. The length of the string, not including any terminating null character, can be found in the word preceding the string.

            同時它也給出了解決辦法:
            To use the lpBuffer pointer, the n flag must be set with the resource compiler, RC.
            Note   String resources are not null-terminated by default. When lpBuffer is set to NULL, verify whether the string resource represented by the pointer returned by LoadString is null-terminated, and if necessary, append a terminating null character to the resource before using it in your application.

            一開始我沒有太明白the n flag must be set with the resource compiler, RC.的含義,很迷惑,不知道如何解決。但是在網上尋找方法的時候,發現這么一篇文章
            http://lak4cyut.blogspot.com/2008/08/wm-api-loadstring.htmlWM API : LoadString() 另一種使用方式),我才徹底明白過來。

            我使用的是VS2005,在project->properties->Resource->Command Line中添加一個 “-n”,即可。

            在運行程序,正常顯示了。

            大家如遇相同問題,可以試試這個方法。
            posted @ 2008-12-17 20:07 Sandy 閱讀(6643) | 評論 (8)編輯 收藏
             

            最近做的很多事情都涉及快捷方式,所以整理一下。

            快捷方式的格式

            數字#路徑 參數

            數字,我不太清楚這個是代表什么含義,也沒有看到確切的說法,有人說是#后的ACSII字符的數量,

            路徑,有相對路徑,也有絕對路徑。如果路徑中包含空格的話,一定要用雙引號括起來,否則會產生錯誤, 把空格以后的內容當成參數了吧,這是我認為的。

            參數,有多種吧,我還沒有查資料,等查到了再補充。

            舉個例子:

            39#"\Windows\Camera.exe"

            這是手機的程序中相機的快捷方式。顯然39不是#后的字符的數量。

            路徑有時會是一些縮寫,微軟自己的程序會這么寫,如手機中的圖片和視頻,其內容為22#:MSPIMG

            :MSPIMG是什么意思呢?路徑,又是指代什么呢?通過查閱資料,發現它對應注冊表HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Shell\\Rai中的:MSPIMG,其中“1對應的值為pimg.exe。

            快捷方式的創建

            快捷方式的創建可以通過SHCreateShortcut這個函數來創建,其原型如下:

            DWORD WINAPI SHCreateShortcut(

              LPTSTR szShortcut,

            LPTSTR szTarget

            );

            例如:

            SHCreateShortcut( _T("\\My Documents\\Windows Media Player.lnk"), _T("\\Windows\\Ceplayer.exe"));

            快捷方式路徑的獲取

            快捷方式的目標路徑獲取,可以通過SHGetShortcutTarget來獲取。其原型如下:

            BOOL SHGetShortcutTarget(

                      LPTSTR szShortcut,

             LPTSTR szTarget,

             int cbMax

            );

            例如:

            TCHAR str[MAX_PATH];

            SHGetShortcutTarget(_T("\\My Documents\\Windows Media Player.lnk"), str, MAX_PATH);

            posted @ 2008-12-14 23:10 Sandy 閱讀(568) | 評論 (0)編輯 收藏
             

            最近在看代碼,寫代碼的人很喜歡用回調函數和函數指針。一直覺得回調函數和函數指針挺神秘的,所以查了一些資料,來與大家一起來分享。

            什么是回調函數

            簡而言之,回調函數就是一個通過函數指針調用的函數。如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用為調用它所指向的函數時,我們就說這是回調函數。

            為什么要使用回調函數

               因為使用回調函數可以把調用者和被調用者分開,調用者不關心誰是被調用者,所有它需知道的,只是存在一個具有某種特定原型、某些限制條件(如返回值為int)的被調用函數?;卣{函數就好像是一個中斷處理函數,系統在符合你設定的條件時自動調用。

            如何使用回調函數

             使用回調函數,我們需要做三件事:

            • 聲明
            • 定義
            • 設置觸發條件:在你的函數種把你的回調函數名稱轉化為地址作為一個參數,以便于系統調用。

            聲明和定義時應注意,回調函數由系統調用,所以可以認為它屬于windows系統,不要把它當作你的某個類的成員函數。

            回調函數是一個程序員不能顯示調用的函數,通過將回調函數的地址傳給調用者從而實現調用?;卣{函數是十分必要的,在我們想通過一個統一接口實現不同的內容,這時回調函數非常合適。

            函數指針的聲明

            對回調函數有了一個初步的了解,下面我們來說一下函數指針。因為要實現回調,必須首先定義函數指針。

            void (*) ()

            左邊圓括弧中的星號是函數指針聲明的關鍵。另外兩個元素是函數的返回類型(void)和右邊圓括弧中的入口參數

            為函數指針聲明類型定義:

            Typedef void(* pfv)()

            pfv 是一個函數指針,它指向的函數沒有輸入參數,返回類型為voie。使用這個類型定義名稱可以隱藏負責的函數指針語法。

            void (*p)();

            void func()

            {

            ……

            }

            p = func;

            p的賦值可以不同,但一定要是函數的指針,并且參數和返回類型相同。

            例如:

            現學現賣的一個小例子

            #include <iostream>
            using namespace std;

            typedef 
            void (*PF)();
            void func()
            {
              cout 
            << "func" << endl;
            }


            void caller( PF pf)
            {
              pf();
            }


            int main()
            {
              PF p 
            = func;
              caller(p);

              system(
            "pause");

              
            return 0;
            }


            調用約定

            visual c++中,可以在函數類型前加_cdecl,_stdcall或者_pascal來表示調用規范(默認為_cdecl)。調用規范影響編譯器產生的給定函數名,參數傳遞的順序,堆棧清理責任以及參數傳遞機制。

            不過,在win32的程序中,我見得比較多的是CALLBACK,這個宏定義在windef.h中,

            #define CALLBACK    __stdcall

            它約定了函數在它們返回到調用者之前,都會從堆棧中移除掉參數。

             

            摘自:

            回調函數

            http://hi.baidu.com/spidermanzy/blog/item/b25b00956469c6097bf48016.html

            回調函數以及鉤子函數的概念

            http://zq2007.blog.hexun.com/9068988_d.html

            聲明函數指針并實現回調

            http://www.vckbase.com/document/viewdoc/?id=195

            posted @ 2008-12-07 16:56 Sandy 閱讀(13215) | 評論 (7)編輯 收藏
             

            昨天,125,即農歷十一月初八,我見證了別人訂婚的溫馨和浪漫,心里也暖暖的有一股溫馨的沖動。

            先簡單介紹一下這兩位吧,一位是即將成為成功男士的man,已經拿到了一家非常知名企業的offer,一位是小巧可愛的心理老師,兩位也將在今年年末,步入婚姻的殿堂。令人流口水的羨慕。

            一百朵玫瑰花,伴著香水百合,代表白頭偕老,男生的“你愿意嫁給我么?”,女生激動的淚水洋溢著幸福。我們當時總共10人,除去這對,其他的是四對情侶,心里都有這么一點溫馨的沖動。

            幸福的時候是這么幸福,回憶過去的點滴,你會覺得男生也會這么細心,女生竟是這么體貼,幸福……

            我們這一對,也走了很長的路,算算有五年多了,還在愛情長跑的路上,我們對愛很堅定,看著這么幸福的一對,我們也有所沖動。但是一切還沒有完全定下來,目前還在上學。

            只能將心中的沖動埋藏在心,待某一時刻,期待我們也能帶給別人溫馨的沖動吧。

            祝福這幸福的一對,百年好合,甜甜美美,也希望我們手牽著手,走到幸福的終點。

            幸福……真好!
            posted @ 2008-12-06 10:11 Sandy 閱讀(175) | 評論 (0)編輯 收藏
             
            SHGetSpecialFolderPath

            作用:

            獲取特定文件夾路徑

            原型:

            BOOL SHGetSpecialFolderPath(

                     HWND hwndOwner,

                     LPTSTR lpszPath,

                     int nFolder,

                     BOOL fCreate

            );

            示例:

                獲得自啟動文件夾的路徑

                TCHAR filePath[MAX_PATH];

                ::SHGetSpecialFolderPath(NULL, filePath, CSIDL_STARTUP, FALSE);

            以下是nFolder值的對應情況

            獲取值的機器為多普達838

            CSIDL_STARTMENU —— \Windows\“開始”菜單

            CSIDL_STARTUP —— \Windows\StartUp

            CSIDL_WINDOWS —— \Windows

            CSIDL_RECENT ——

            CSIDL_PROGRAMS —— \Windows\“開始”菜單\程序

            CSIDL_PROGRAM_FILES —— \Program Files

            CSIDL_PERSONAL —— \My Documents

            CSIDL_MYVIDEO ——

            CSIDL_MYPICTURES —— \My Documents\我的圖片

            CSIDL_MYMUSIC —— \My Documents\我的音樂

            CSIDL_FONTS —— \Windows\Fonts

            CSIDL_FAVORITES —— \Windows\Favorites

            CSIDL_DESKTOPDIRECTORY ——

            CSIDL_DESKTOP —— \My Documents

            CSIDL_APPDATA —— \Application Data

            posted @ 2008-12-05 16:35 Sandy 閱讀(3866) | 評論 (0)編輯 收藏
                 摘要: 今天在網上看到的.最近在弄瀏覽器,對其方法要熟悉一些.貼出來,以備查詢. IWebBrowser2 Interface http://msdn.microsoft.com/en-us/library/aa752127(VS.85).aspx AddressBar ...  閱讀全文
            posted @ 2008-12-03 13:34 Sandy 閱讀(2751) | 評論 (0)編輯 收藏
             

                   向大家SHOW一下,我自己畫的圓餅圖。
                                  

                     呵呵,自我感覺不錯。

                     原理很簡單,是通過畫多邊形,并填充不同的顏色來實現的。

                     實際上,這個圖是通過以下幾個圖拼成的。
                                    

                       這下大家清楚了很多了吧。

             

                      這個圖的關鍵在于弧上的各點的坐標如何得到?這個圓餅的最上面的那個圖形其實是一個橢圓。我們可以利用一個橢圓上點的計算公式來求的弧上點的坐標。
                                    

                  長軸為a,短軸為b, 軸心為(x0, y0)那么橢圓上的某點坐標(x, y)

                   x = x0 + a * cos(θ);

                   y= y0 + b * sin(θ) ;

                  通過這種方法計算弧上各點后,將弧平移,如下圖:
                                               

                   這樣我們就可以計算出柱面下半部分的弧線坐標了。

             

                   呵呵,這樣就簡單多了吧。

            posted @ 2008-12-02 22:51 Sandy 閱讀(2918) | 評論 (5)編輯 收藏
            僅列出標題
            共15頁: First 7 8 9 10 11 12 13 14 15 
            国内精品久久久久影院亚洲| 999久久久免费精品国产| 伊人久久大香线蕉精品| 97精品伊人久久久大香线蕉 | 99久久综合狠狠综合久久| 人妻精品久久久久中文字幕69 | 久久99精品国产麻豆宅宅| 国产精品成人99久久久久| 老司机午夜网站国内精品久久久久久久久 | 天天综合久久久网| 伊人久久大香线蕉综合5g| 人妻丰满AV无码久久不卡| 99久久精品国产一区二区蜜芽| 日韩亚洲国产综合久久久| 99久久er这里只有精品18| 91性高湖久久久久| 久久天天躁狠狠躁夜夜网站| 999久久久国产精品| 一本久久a久久精品亚洲| 精品久久久久久国产三级| 久久九九精品99国产精品| 婷婷久久综合九色综合绿巨人 | 久久久久亚洲AV无码专区网站| 亚洲欧洲日产国码无码久久99| 91秦先生久久久久久久| 久久精品国产99久久无毒不卡| 思思久久精品在热线热| 精品国产91久久久久久久a| 久久久精品国产sm调教网站| 中文字幕无码久久久| 久久天天躁狠狠躁夜夜2020 | 久久狠狠爱亚洲综合影院| 国产精品狼人久久久久影院| 99久久精品日本一区二区免费| 精品熟女少妇AV免费久久| 久久人人爽人人爽人人片AV东京热| 久久久精品久久久久久 | 18岁日韩内射颜射午夜久久成人 | 国产精品美女久久久久网| 久久精品国产亚洲av影院| 久久亚洲私人国产精品vA|