• <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>

            笑看風(fēng)云淡

            寵辱不驚,看庭前花開(kāi)花落;去留無(wú)意,望天空云卷云舒
            posts - 96, comments - 48, trackbacks - 0, articles - 0
              C++博客 :: 首頁(yè) :: 新隨筆 ::  :: 聚合  :: 管理

            第一章 不能免俗的“Hello, World!”

            在這一章里,就像所有的入門(mén)級(jí)教程一樣,我也將不能免俗地以一個(gè)“Hello, World!”程序開(kāi)始我的教程。然后,我將逐步深入,向你介紹這個(gè)ATL版本程序中所有必要的信息。此外,我還將介紹一些Win32中你可能不知道的東西,包括WinMain的_t兼容以及如何在MessageBox中加入自己的圖標(biāo)等等。

            接近,接近,再接近……

            可以說(shuō),所有“Hello, World!”程序的內(nèi)容不外乎都是以十分有限的幾行代碼向當(dāng)前的目標(biāo)屏幕環(huán)境上輸出一個(gè)字符串“Hello, World!”。這個(gè)程序通常具有以下幾個(gè)特點(diǎn):

            1. 排除印刷錯(cuò)誤的可能性,幾乎所有的初學(xué)者都可以照葫蘆畫(huà)瓢地獨(dú)立書(shū)寫(xiě)、編譯并運(yùn)行這個(gè)程序。
            2. 這個(gè)程序可以體現(xiàn)出當(dāng)前語(yǔ)言環(huán)境的典型配置方式。
            3. 這個(gè)程序中具有當(dāng)前語(yǔ)言特定的程序入口點(diǎn)。
            4. 這個(gè)程序中含有一條當(dāng)前環(huán)境典型的輸出語(yǔ)句(通常也是最簡(jiǎn)單、最常用的),由這條語(yǔ)句來(lái)輸出“Hello, World!”字符串。
            5. 從這個(gè)程序可以很清楚的了解當(dāng)前語(yǔ)言環(huán)境下程序運(yùn)行的典型流程。
            6. 這個(gè)程序可能還會(huì)表現(xiàn)當(dāng)前語(yǔ)言的一些其它特點(diǎn)。

            那么,首先讓我以最簡(jiǎn)單的C語(yǔ)言版“Hello, World!”開(kāi)始吧:

            #include <stdio.h>

            int main()
            {
                printf( "Hello, World!n" );
                return 0;
            }

            雖然是不到10行的代碼,但它仍然五臟俱全。現(xiàn)在,就由我將它和上述的特點(diǎn)對(duì)號(hào)入座吧。也就是說(shuō),這個(gè)程序能體現(xiàn)出C程序設(shè)計(jì)的以下特點(diǎn):

            1. C語(yǔ)言的程序以main函數(shù)作為程序入口點(diǎn)。
            2. printf是C中用來(lái)輸出字符串的代碼。
            3. 函數(shù)是C語(yǔ)言程序的基本單位,它通常由返回值、函數(shù)名、參數(shù)列表、函數(shù)體、return組成。
            4. 調(diào)用函數(shù)的時(shí)候要include相應(yīng)的頭文件。
            5. n是C語(yǔ)言中的轉(zhuǎn)義字符,代表?yè)Q行符。

            接下來(lái),我們來(lái)看一看Win32版的“Hello, World!”:

            #include <windows.h>

            int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
            {
                MessageBox( NULL, TEXT("Hello, World!"), TEXT("Hello"), 0 );
                return 0;
            }

            這個(gè)程序告訴你了以下幾件事:

            1. 所有Win32下的C程序都需要包含windows.h頭文件。
            2. Win32下的程序是以WinMain作為程序入口點(diǎn)的,而不是main。
            3. Win32下最常用輸出信息的方法是MessageBox。
            4. WINAPI是Win32 API函數(shù)的調(diào)用約定,也就是__stdcall。
            5. HINSTANCE、LPSTR都是Win32自定義的數(shù)據(jù)類(lèi)型,分別表示應(yīng)用程序?qū)嵗浔鸵钥兆址Y(jié)尾的ANSI字符串指針。
            6. TEXT宏用于在源代碼一級(jí)保證ANSI/Unicode字符串的兼容。

            如果你對(duì)以上的幾個(gè)知識(shí)點(diǎn)仍然有些許迷茫,請(qǐng)參考Charles Petzold的《Programming Windows》(中譯《Windows程序設(shè)計(jì)》)的第一章。這段代碼就是幾乎原封不動(dòng)地搬過(guò)來(lái)的。不過(guò),我在編寫(xiě)這段代碼的時(shí)候,通常會(huì)這么寫(xiě):

            #include <windows.h>
            #include <tchar.h>

            int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
            {
                MessageBox( NULL, _T("Hello, World!"), _T("Hello"), 0 );
                return 0;
            }

            是的,有幾個(gè)地方有些不一樣,我對(duì)它們的解釋是:

            1. tchar.h中包含了對(duì)C runtime library中ANSI/Unicode字符串的源代碼級(jí)兼容。
            2. _tWinMain提供了對(duì)命令行參數(shù)lpCmdLine的ANSI/Unicode源碼級(jí)兼容。
            3. _T宏亦包含在tchar.h之中,它的作用和TEXT宏一樣,但它比TEXT宏更加短小,因此可以節(jié)省編碼的時(shí)間。

            現(xiàn)在我可以告訴你,隨著我們的步步接近,接下來(lái)ATL版的“Hello, World!”程序就要出現(xiàn)在我們的眼前了。那么,就讓我們來(lái)看看這個(gè)猶抱琵琶半遮面的家伙吧。(請(qǐng)注意,雖然這是一個(gè)ATL版本的程序,但是你仍然需要建立一個(gè)Win32 Application的工程,而不是用ATL/COM Wizard。)

            //////////////////////////////////////////////////////////////////////////
            // ATL的GUI程序設(shè)計(jì)配套源代碼
            // 第一章 不能免俗的“Hello, World!”
            // 工程名稱(chēng):HelloWorld
            // 作者:李馬
            // http://www.titilima.cn
            //////////////////////////////////////////////////////////////////////////

            #include <atlbase.h>
            CComModule _Module;

            int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
            {
                _Module.Init( NULL, hInstance );
                MessageBox( NULL, _T("Hello, World!"), _T("Hello"), 0 );
                _Module.Term();
                return 0;
            }

            也許有些陌生了,不過(guò)所幸它并無(wú)太多的變化——畢竟整個(gè)代碼段就沒(méi)有多長(zhǎng)。好了,這一節(jié)的內(nèi)容就到這里,希望李馬的這種漸近的方法沒(méi)讓大家覺(jué)得一切來(lái)得太突然。大家可以喝口水先,然后做個(gè)深呼吸再,因?yàn)榻酉聛?lái)我們就要開(kāi)始接觸真正的ATL程序了。

            “不過(guò)如此”

            說(shuō)句題外話(huà)先。許是我太狂妄,又許是我太幼稚,總之我在上大學(xué)以來(lái),越來(lái)越喜歡說(shuō)“不過(guò)如此”這句話(huà)。譬如上了大學(xué)以后,沒(méi)過(guò)倆月我就覺(jué)得大學(xué)“不過(guò)如此”;學(xué)會(huì)喝酒之后,就又會(huì)覺(jué)得喝酒“不過(guò)如此”;到了北京以后,又覺(jué)得北京“不過(guò)如此”;參觀(guān)了某著名軟件公司之后,又覺(jué)得它“不過(guò)如此”……書(shū)歸正傳話(huà)歸正題,不知道你第一眼看過(guò)ATL版本的“Hello, World!”之后會(huì)不會(huì)同樣有這樣一種感覺(jué)?——自然,我希望是這樣的。

            那么,在了解ATL之前,就讓我們先來(lái)目測(cè)一下這個(gè)“Hello, World!”吧。也許,你會(huì)從上面的代碼猜到以下內(nèi)容:

            1. atlbase.h大概其應(yīng)該是ATL程序需要包含的頭文件。
            2. CComModule,從類(lèi)名稱(chēng)看應(yīng)該是一個(gè)模塊類(lèi)。_Module是這個(gè)模塊類(lèi)的實(shí)例。
            3. WinMain沒(méi)變。
            4. CComModule::Init應(yīng)該是對(duì)模塊進(jìn)行初始化,這個(gè)方法應(yīng)該是在程序初始化的時(shí)候調(diào)用。
            5. CComModule::Term應(yīng)該是對(duì)模塊進(jìn)行結(jié)束處理,這個(gè)方法應(yīng)該是在程序結(jié)束之前調(diào)用。
            6. WinMain的最后仍然是以return結(jié)尾。

            好,是不是“不過(guò)如此”呢?沒(méi)錯(cuò)!

            大抵如此

            到此為止,希望你的猜想能夠讓你對(duì)ATL的恐懼感(如果有的話(huà))一掃而光。那么,現(xiàn)在李馬來(lái)為你補(bǔ)充上幾點(diǎn):

            atlbase.h在用ATL進(jìn)行GUI程序設(shè)計(jì)的時(shí)候,就如同SDK中的windows.h一樣重要。對(duì)于GUI程序設(shè)計(jì)的部分,這個(gè)文件中主要有這么幾個(gè)值得關(guān)注的地方:

            1. Win32程序設(shè)計(jì)必備的頭文件,諸如windows.h、tchar.h等。
            2. CComModule的定義。對(duì)于GUI程序設(shè)計(jì),我們可以將它簡(jiǎn)單地看作對(duì)HINSTANCE的一個(gè)封裝。
            3. 一些簡(jiǎn)單的工具類(lèi)。(請(qǐng)?jiān)徫也荒茉谶@里提供給你它們具體的名字,因?yàn)锳TL 3.0和ATL 7.0是不一樣的。VC 6.0附帶的是ATL 3.0,它的atlbase.h中主要提供了一些COM的智能指針和字符串,如CComPtr、CComBSTR等;而VS2003中的ATL 7.0中則附帶了一些更有趣的類(lèi),比如CRegKey、CHandle等。)

            下面接著說(shuō)CComModule。相信你可以從它的類(lèi)名稱(chēng)中看出來(lái),這個(gè)類(lèi)主要用來(lái)管理COM的各種信息。如果你深入到ATL的源代碼之中,你可能會(huì)為它的眾多成員與方法感覺(jué)到迷惑。其實(shí)在進(jìn)行GUI程序設(shè)計(jì)的時(shí)候,你只需要關(guān)心以下這些內(nèi)容:

            1. HRESULT CComModule::Init( _ATL_OBJMAP_ENTRY* p, HINSTANCE h, const GUID* plibid = NULL );
              進(jìn)行模塊的初始化,第一個(gè)參數(shù)取NULL,第二個(gè)參數(shù)取應(yīng)用程序的實(shí)例句柄,也就是WinMain中傳入的hInstance。
            2. void CComModule::Term();
              進(jìn)行模塊的卸載,在程序結(jié)束時(shí)調(diào)用。
            3. HINSTANCE CComModule::GetModuleInstance();
              獲取應(yīng)用程序?qū)嵗浔鶦ComModule::m_hInst。
            4. HINSTANCE CComModule::GetResourceInstance();
              獲取資源模塊句柄CComModule::m_hInstResource,這個(gè)值在默認(rèn)情況下是和CComModule::m_hInst一致的。如果你程序的所有資源位于一個(gè)DLL之中,那么你可以在初始化應(yīng)用程序中將CComModule::m_hInstResource成員賦值為這個(gè)DLL的模塊句柄。

            接著說(shuō)CComModule的實(shí)例_Module。可以說(shuō),這個(gè)全局變量貫穿于A(yíng)TL整個(gè)框架的始終,無(wú)論你是使用它編寫(xiě)COM組件還是GUI程序。譬如,你可能不止一次地需要使用模塊的實(shí)例句柄(LoadIcon、LoadCursor),那么你只需要這樣調(diào)用:

            extern CComModule _Module;
            HICON hIcon = ::LoadIcon( _Module.GetResourceInstance(), MAKEINTRESOURCE( IDI_YOURICON ) );

            好了,那么現(xiàn)在我們可以充分展示一下這個(gè)模塊類(lèi)的具體使用了。在此,我僅僅將我先前的“Hello, World!”作了一番擴(kuò)展,如下:

            //////////////////////////////////////////////////////////////////////////
            // ATL的GUI程序設(shè)計(jì)配套源代碼
            // 第一章 不能免俗的“Hello, World!”
            // 工程名稱(chēng):HelloWorldEx
            // 作者:李馬
            // http://www.titilima.cn
            //////////////////////////////////////////////////////////////////////////

            #include <atlbase.h>
            CComModule _Module;

            int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
            {
                _Module.Init( NULL, hInstance );
                _Module.m_hInstResource = LoadLibrary( _T("shell32.dll") );

                MSGBOXPARAMS mbp;
                ZeroMemory( &mbp, sizeof( mbp ) );
                mbp.cbSize       = sizeof( mbp );
                mbp.dwLanguageId = GetSystemDefaultLangID();
                mbp.dwStyle      = MB_USERICON;
                mbp.hInstance    = _Module.GetResourceInstance();
                mbp.lpszCaption  = _T("Hello");
                mbp.lpszIcon     = MAKEINTRESOURCE( 44 );
                mbp.lpszText     = _T("Hello, World!");
                MessageBoxIndirect( &mbp );

                FreeLibrary( _Module.m_hInstResource );
                _Module.m_hInstResource = NULL;
                _Module.Term();
                return 0;
            }

            這個(gè)程序運(yùn)行起來(lái)是這個(gè)樣子:

            如你所見(jiàn),在這里我使用了來(lái)自應(yīng)用程序之外的資源,也就是對(duì)CComModule::GetModuleInstance進(jìn)行了特殊處理。WTL就是對(duì)CComModule這個(gè)類(lèi)進(jìn)行了繼承處理而派生出了CAppModule類(lèi),使之成為了更適合應(yīng)用程序使用的模塊類(lèi)。有興趣的朋友可以參看WTL附帶的atlapp.h文件,我這里就不多說(shuō)了。

            “貌合神離”

            字典上對(duì)這個(gè)詞的解釋是:“表面上很親密而實(shí)際上懷有二心”。在此,我將它用在A(yíng)TL 3.0與7.0上,用來(lái)表示它們倆“用法兼容而實(shí)現(xiàn)迥異”的既有事實(shí)。不過(guò),對(duì)于GUI程序設(shè)計(jì)而言,你并不需要深入了解這方面的內(nèi)容。因此我這里列舉的,也只是與GUI有關(guān)的部分。

            • ATL 3.0之中,CComModule直接繼承自_ATL_MODULE;而ATL 7.0之中,CComModule則經(jīng)歷了一串的繼承鏈。
            • 相比之下,ATL 7.0中的CComModule更有COM的味道,譬如它的ModuleInstance、ResourceInstance都可以作為COM組件的property,使用get、put來(lái)處理。

            當(dāng)然,ATL畢竟是一個(gè)為開(kāi)發(fā)COM組件而構(gòu)建的Framework,所以ATL 7.0中的atlbase.h之中還包含了更多有關(guān)COM開(kāi)發(fā)的工具類(lèi)。這些內(nèi)容與本書(shū)無(wú)關(guān),而且李馬也自認(rèn)現(xiàn)在尚無(wú)能力來(lái)解說(shuō)這些內(nèi)容,所以一并從略了就。


            只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            久久久久国产精品嫩草影院| 精品久久久久久99人妻| 狠狠人妻久久久久久综合蜜桃| 久久精品中文騷妇女内射| 中文字幕乱码人妻无码久久 | 日韩va亚洲va欧美va久久| 久久精品国产精品国产精品污 | 久久久艹| 久久久精品波多野结衣| 久久精品国产国产精品四凭| 久久97久久97精品免视看| 久久高清一级毛片| 色婷婷综合久久久久中文字幕 | 久久久久亚洲AV无码专区桃色| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 国产毛片欧美毛片久久久| 伊人久久精品无码av一区| 色欲av伊人久久大香线蕉影院| 亚洲国产精品一区二区久久hs| 日韩精品久久久久久免费| 狠狠久久亚洲欧美专区| 久久九色综合九色99伊人| 久久久久久久91精品免费观看| 亚洲AV无码久久| 91亚洲国产成人久久精品| 久久久久久无码国产精品中文字幕| 天天综合久久一二三区| 人妻无码αv中文字幕久久 | 久久se精品一区精品二区| 久久精品三级视频| 人妻丰满AV无码久久不卡 | 久久人爽人人爽人人片AV| 91久久精品无码一区二区毛片| 97香蕉久久夜色精品国产| 国产精品久久波多野结衣| 欧美大战日韩91综合一区婷婷久久青草| 精品人妻伦九区久久AAA片69| 亚洲国产精品久久久久久| 亚洲va久久久噜噜噜久久男同| 91久久精品无码一区二区毛片| 午夜天堂av天堂久久久|