• <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 - 58,  comments - 75,  trackbacks - 0
            WTL中的窗口消息的映射和自定義窗口消息映射

            窗口消息的映射是通過宏MESSAGE_HANDLER完成的。
            MESSAGE_HANDLER( 消息ID,消息處理函數 )。
            自定義的消息也是通過這個宏來映射的

            添加窗口消息函數后的對話框的定義如下
            #include < atlapp.h >
            #include "resource.h"

            const int WM_MY_MESSAGE = WM_USER+1; //自定義消息ID

            class CMainDialog : public CDialogImpl< CMainDialog >
            {
            public:
                enum { IDD = IDD_MAINDLG };

            public:
                BEGIN_MSG_MAP( CMainDialog )
                    MESSAGE_HANDLER( WM_INITDIALOG, OnInitDialog ) //系統的窗口消息映射,窗口初始化消息
                    MESSAGE_HANDLER( WM_MY_MESSAGE, OnMyMessage ) //自定義消息的映射
                    COMMAND_ID_HANDLER( IDOK, OnOk ) //控件消息的映射
                    COMMAND_ID_HANDLER( IDCANCEL, OnCancel )
                    COMMAND_ID_HANDLER( IDC_SENDMESSAGE_BUTTON, OnSendMyMessage ) //用來發送自定義消息的按鈕消息映射
                END_MSG_MAP()

            public:
                //窗口初始化消息映射函數,這是個窗口系統消息
                LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
                {
                    // center the dialog on the screen
                    CenterWindow();

                    return TRUE;
                }

                LRESULT OnOk( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled )
                {
                    EndDialog( wID );
                    return 0;
                }

                LRESULT OnCancel( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled )
                {
                    EndDialog( wID );
                    return 0;
                }

                //發送自定義消息
                LRESULT OnSendMyMessage( WORD wNotfyCode, WORD wID, HWND hWndCtl, BOOL &bHandled )
                {
                    //ATL::CWindow的SendMessage的調用
                    SendMessage( WM_MY_MESSAGE );
                    return 0;
                }

                //處理自定義消息
                LRESULT OnMyMessage( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
                {
                    //ATL::CWindow的MessageBox的調用
                    MessageBox( "This is MyMessage Handle" ); //彈出個對話框
                    return 0;
                }
            };
            posted @ 2007-05-09 11:59 walkspeed 閱讀(1041) | 評論 (0)編輯 收藏
            WTL創建對話框。
            要用到頭文件 atlapp.h

            對話框的定義如下
            #include < atlapp.h >
            class CMainDialog : public CDialogImpl< CMainDialog >
            {
                //用戶代碼
            }

            CDialogImpl類是WTL中的模式對話框的基類。他利用了奇異自遞歸模板技術,來獲得繼承類的實際行為。
            有了定義我們要給這個對話框一個窗口資源。很簡單,只要代碼中定義一個IDD的枚舉量就可以了。
            枚舉量的值為窗口資源的ID。對話框的定義代碼演化為如下
            #include < atlapp.h >
            class CMainDialog : public CDialogImpl< CMainDialog >
            {
            public:
                enum { IDD=IDD_MAINDLG };//一定要在public域,否則沒辦法訪問,編譯時報錯
                //用戶代碼
            }

            就這樣進行編譯,編譯器會報錯,說CMainDialog是個抽象類,不能實例化。
            其原因是ProessWindowMessage函數是個抽象地。
            我們是不是要手動添加這個函數呢?可以。但對于編寫代碼來說并不方便。
            這里要用到ATL中的消息映射宏了。
            BEGIN_MSG_MAP( 類名 )
            END_MSG_MAP()
            有了這兩個宏對后,就自動的添加了ProessWindowMessage函數了,而且添加消息映射的函數也方便。
            現在對話框的定義代碼演化為如下了
            #include < atlapp.h >
            class CMainDialog : public CDialogImpl< CMainDialog >
            {
            public:
                enum { IDD=IDD_MAINDLG };//一定要在public域,否則沒辦法訪問,編譯時報錯
                
            public:
                BEGIN_MSG_MAP( CMainDialog )
                END_MSG_MAP()
                //用戶代碼
            }

            有了以上代碼,對話框就可以顯現在屏幕上了。但是這個對話框沒有辦法推出,應為沒有一個消息映射函數。
            接不到推出的消息。
            我們有添加兩個消息映射,分別對應界面上的OK按鈕和Cancel按鈕。這兩個是button控件,我們用控件的消息映射
            COMMAND_ID_HANDLER( ID, Fun )。
            添加消息映射后的對話框類定義如下
            #include < atlapp.h >
            class CMainDialog : public CDialogImpl< CMainDialog >
            {
            public:
                enum { IDD=IDD_MAINDLG };//一定要在public域,否則沒辦法訪問,編譯時報錯
               
            public:
                BEGIN_MSG_MAP( CMainDialog )
                    COMMAND_ID_HANDLER( IDOK, OnOk )
                    COMMAND_ID_HANDLER( IDCANCEL, OnCancel )
                END_MSG_MAP()
               
            public:
                LRESULT OnOk( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled )
                {
                    EndDialog( wID );//推出對話框
                    return 0;
                }

                LRESULT OnCancel( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL &bHandled )
                {
                    EndDialog( wID );//推出對話框
                    return 0;
                }
                //用戶代碼
            };

            posted @ 2007-05-09 11:18 walkspeed 閱讀(1362) | 評論 (0)編輯 收藏
            程序的進入函數不是C/C++的進入函數main,而是微軟的進入函數winMain。其形式如下
            int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
            {
                //用戶代碼
                ...............
                return 0;
            }

            WTL是在ATL的基礎上發展起來的,要用到ATL中的模塊類CComModule,所以要初始化COM庫。
            初始化COM庫調用CoInitialize,卸載COM庫調用CoUninitialize。程序形式如下
            #include < atlbase.h >

            int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
            {
                CoInitialize( NULL );//用于應用程序
                //用戶代碼
                ...............
               
                CoUninitialize();
                return 0;
            }

            WTL的應用程序部分的代碼封裝在了CAppModule中。要定義一個CAppModule的全局變量,保證在程序啟動前就被構造好
            CAppModule是繼承的ATL中的CComModule類。程序形式演變成如下
            #include < atlbase.h >
            #include < atlapp.h > //WTL要用到的

            int WINAPI _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nShowCmd )
            {
                CoInitialize( NULL );//用于應用程序
                 _Module.Init( NULL, hInstance );//初始化一個應用程序
                //用戶代碼
                ...............
                _Module.Term();//銷毀
                CoUninitialize();
                return 0;
            }
            posted @ 2007-05-09 10:42 walkspeed 閱讀(858) | 評論 (0)編輯 收藏
                C++標準庫中的文件流類提供的各種操作中沒有直接獲得正在操作的文件的大小的函數。要獲得文件大小得轉個彎,用如下的方法
                假設我們有了一個已經打開的文件對象ifile。
                先將文件內的位置指針移到文件尾
                ifile.seekg( 0, ios::end );
                再讀取當前位置,這就是文件的大小了。
                long filelength = ifile.tellg();

            posted @ 2007-05-02 17:04 walkspeed 閱讀(1075) | 評論 (0)編輯 收藏
            通過文件流讀取數據
            ifstream類代表讀文件對象,所有的讀操作都在這個類中。

            read成員函數,用來讀取數據到指定的buf中。
            這個成員函數來至basic_istream類。
            函數原型(來直MSDN文檔)
            basic_istream& read( char_type *_Str, streamsize _Count );
            _Str   字符指針
            _Count 要讀取的字符數量

            get成員函數,用來讀取一個或多個字符
            這個成員函數來至basic_istream類。
            函數原型(來直MSDN文檔)
            int_type get( ); 讀取一個字符,不過是作為int類型返回
            basic_istream& get( char_type& _Ch ); 讀取一個字符
            basic_istream& get( char_type *_Str, streamsize _Count ); 讀取指定數量的字符
            basic_istream& get( char_type *_Str, streamsize _Count, char_type _Delim ); 讀取指定數量的字符,但與到與_Delim相同的字符就停止
            basic_istream& get( basic_streambuf<Elem, Tr> *_Strbuf );
            basic_istream& get( basic_streambuf<Elem, Tr> *_Strbuf, char_type _Delim );

            peek成員函數,用來返回下一個字符,當不從istream的buf中移出
            這個成員函數來至basic_istreamlei。
            函數原型(來至MSDN文檔)
            int_type peek( );

            getline成員函數,用來讀取一行數據
            這個成員函數來至basic_istream類
            函數原型(來至MSDN文檔)
            basic_istream& getline( char_type *_Str, streamsize _Count );
            basic_istream& getline( char_type *_Str, streamsize _Count, char_type _Delim );

            readsome成員函數,用于讀取指定數量的數據到buf中
            這個函數來至basic_istream類。
            函數原型(來至MSDN文檔)
            streamsize readsome( char_type *_Str, streamsize _Count );

            >>運算符重載
            對C++基本類型進行了重載操作。可以直接讀取這些數據。但會跳過控制字符。
            用戶可以擴展這個運算符操作的類型。
            這個讀取是有類型的。


            posted @ 2007-05-02 16:57 walkspeed 閱讀(3437) | 評論 (1)編輯 收藏
            C++ STL中的對文件操作的類
            ifstream 用于讀文件
            ofstream 用于寫文件
            fstream  用于讀寫文件

            打開文件
            可以在夠高文件流對象時直接打開
            ifstream ifile( 文件名 )
            ofstream ofile( 文件名 )
            fstream  file( 文件名 )

            也可以用open行為
            ifstream ifile
            ifile.open( 文件名 )
            ofstream ofile
            ofile.open( 文件名 )
            fstream file
            file.open( 文件名 )

            關閉文件
            文件對象銷毀時自動關閉文件。
            也可用close關閉文件。
            ifile.close()
            ofile.close()
            file.close()

            文件大開放式標致
            這寫標致定義在iso_base類中。分別如下
            in     打開,用于讀取(這是ifstream的缺省模式)
            out    打開,用于改寫(這是ofstream的缺省模式)
            app    寫入是始終添加與尾端
            ate    打開文件之后令讀寫位置移至文件尾端
            trunc  將先前的文件內容移除
            binary 二進制方式打開
            這些標致和或在一起。
            這些標致作為對象構造或open行為的第二個參數,來定義文件打開分方式。

            隨機存儲
            用于讀文件的隨機存儲
            tellg()     返回讀取的位置
            seekg( pos )  從當前位置移動pos個位子(絕對移送)
            seekg( offset, rpos )  以rpos位置開始移動offset個位置(相對移動)

            用于寫文件的隨機存儲
            tellp()       返回寫入的位置
            seekp( pos )  從當前位置移動pos個位子(絕對移送)
            seekp( offset, rpos )  以rpos位置開始移動offset個位置(相對移動)

            讀數據
            利用read行為
            ifstream ifile
            ifile.read(buf,length)

            寫數據
            利用write行為
            ofstream ofile
            ofile.write(buf,length)  
            posted @ 2007-05-02 13:31 walkspeed 閱讀(1563) | 評論 (0)編輯 收藏
                   Signal會安優先級的不同來調用不同組的slot。這樣要求signal能根據不同的優先級來管理slot組。典型的實現方法是用std::map。將其定義為如下形式std::map< int, slot >。由于每個優先級下可能有一組slot,所以要將這一組slot組織到一起管理,在boost signal中使用std::list來管理,其可能的形式大體如下std::list< slot >。這樣就要修改剛才定義的map了,修改后的map可能的定義如下std::map< int, std::list< slot > >

                  在實際的boost signal中并沒有直接的存儲slotboost signal庫中有個slot類),而是存儲了functionboost function類的對象)對象。而且為了方便控制signalfunction之間的聯系,引入了connection類,用來表示signalfunction之間的聯系。Connection的對象當然和一個function放在了一起。這樣boost signal提供了一個connection_slot_pair類來存儲一個functionconnection對。這樣在boost signal中一個slot組的實際定義如下std::list< connection_slot_pair >。并且被重定義為group_list類型(typedef std::list<connection_slot_pair> group_list)。相應的在boost signalmap的實際定義如下std::map<stored_group, group_list, compare_type>,并且被重定義為slot_container_typetypedef std::map<stored_group, group_list, compare_type> slot_container_type)。將以上的這些東西組織到一個類中,以便于管理。這個類就是named_slot_mapSignal中真正用來管理slot的管理器。

                     Named_slot_map的類數據成員如下定義(boost源碼中的一部分,數據成員部分)

             

            class BOOST_SIGNALS_DECL named_slot_map

            {

            public:

            typedef named_slot_map_iterator iterator;//named_slot_map容器的迭代器

            private:

            typedef std::list<connection_slot_pair> group_list;//function connection對組類型

            typedef std::map<stored_group, group_list, compare_type> slot_container_type;//容器類型

            typedef slot_container_type::iterator group_iterator;//容器迭代器類型

            typedef slot_container_type::const_iterator const_group_iterator;

             

            slot_container_type groups;//定義一個用來管理function connection組的容器對象

            group_iterator back;//容器的迭代器對象

            };

             

                     Named_slot_map也是一個容器。Stl的容器為了外界方便訪問容器內數據單元,提供了迭代器。Named_slot_map也有自己的迭代器。這個迭代器就是named_slot_map_iterator類。Named_slot_map提供了以下方法來獲得迭代器iterator begin()iterator end()Begin方法提供首迭代器,end方法提供尾迭代器。向容器中插入數據用insert。清除某個數據用而而然erase,清空容器中的所有數據用clear

            posted @ 2007-04-25 15:18 walkspeed 閱讀(1501) | 評論 (1)編輯 收藏
              敏捷開發中提倡依賴關系倒置,即1依賴接口而非具體類,2使用接口的對象定義接口。
              boost signal中的signal的模板參數是個函數類型。可以將其看成一個接口。signal對象依賴這個接口,而且是有signal定義的。具體類去實現鎮魂歌接口(即實現這個函數類型)
              signal和slot框架組成了一個observer模式的實現。signal是出版者,slot是訂閱者
            posted @ 2007-04-24 19:36 walkspeed 閱讀(429) | 評論 (0)編輯 收藏

              本以為slot就是被signal存儲并管理的slot。但是通過解讀boost的源代碼發現這個類并沒有被signal直接管理,而僅僅用來構造了下connection。沒有發現其他的用途。如果這樣,那為何不直接在signal的connect中直接進行connection的構造呢。
              signal的connect函數沒有直接接收function對象,而是接收的slot<>對象,而slot<>對象用來接收function。這個function看來未必一定是個函數對象了。可以是個原始函數或類函數了。 這個猜測要證實了才能確定。即便如此,這個類的作用是有限的。不過關于那個tackeable的用法還沒有完全高清楚,可能那是這個類存在的理由,也許以后會有什么的發展。但現在確實看不出什么大的用途。
              奇怪于為何在signal中的slot管理器,不去直接管理slot<>的實例,而是管理connection和function的pair。

              個人覺得在slot<>中的最有用處的函數。
            void slot_base::create_connection()
            {
             basic_connection* con = new basic_connection();

             {
              con->signal = static_cast<void*>(this);
              con->signal_data = 0;
              con->blocked_ = false ;
              con->signal_disconnect = &bound_object_destructed;
             }
             
             data->watch_bound_objects.reset(con);

             scoped_connection safe_connection(data->watch_bound_objects);

             for(std::vector<const trackable*>::iterator i = data->bound_objects.begin();
              i != data->bound_objects.end(); ++i)
             {
              BOOST_SIGNALS_NAMESPACE::detail::bound_object binding;
              (*i)->signal_connected(data->watch_bound_objects, binding);

              BOOST_SIGNALS_NAMESPACE::detail::auto_disconnect_bound_object disconnector(binding);

              con->bound_objects.push_back(binding);
              disconnector.release();
             }

             safe_connection.release();
             data->watch_bound_objects.set_controlling(true);
            }

            posted @ 2007-04-23 16:57 walkspeed 閱讀(856) | 評論 (2)編輯 收藏
                    類的數據成員的布局是按某種順序的,有一個相對與類的頭位子的偏移量,這個偏移量的計算方法如下:
                 
                    (size_t)&(((classname*)0)->members)

                    classname 是一個類名,members是類中任何一個數據成員的名字。0在這里是一個地址,這是一個保留地址,它不能作為左值,但可以作為右值,去提取其中的對象。
                    在0地址位,構造了一個classname的結構布局。

                    在使用中去每次寫這個表達式還是很麻煩的。可以用個宏將其包起來,如下

                    #difine offsetof( ClassName, MemberName ) (size_t)&(((classname*)0)->members)

                    其實這個宏在windows和linux平臺下都以提供了。
            posted @ 2007-04-08 10:54 walkspeed 閱讀(1068) | 評論 (0)編輯 收藏
            僅列出標題
            共6頁: 1 2 3 4 5 6 

            <2007年4月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            常用鏈接

            留言簿(4)

            隨筆分類(64)

            隨筆檔案(58)

            文章分類(3)

            文章檔案(3)

            相冊

            收藏夾(9)

            C++零碎

            好友

            搜索

            •  

            積分與排名

            • 積分 - 161397
            • 排名 - 163

            最新評論

            閱讀排行榜

            評論排行榜

            四虎亚洲国产成人久久精品| 久久精品一本到99热免费| 国产精品久久久久乳精品爆 | 欧美国产成人久久精品| 久久久99精品成人片中文字幕| 亚洲日本va午夜中文字幕久久| 亚洲精品高清一二区久久| 久久久久亚洲AV无码网站| 久久久久国产一级毛片高清板| 色天使久久综合网天天| 久久亚洲精品视频| 久久精品国产亚洲AV蜜臀色欲| 久久久久久久尹人综合网亚洲| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久不射电影网| 一本一本久久a久久精品综合麻豆| MM131亚洲国产美女久久| 日韩美女18网站久久精品| 国产精品久久久久久久久| 久久久亚洲AV波多野结衣| 精品久久久久久无码国产| 99久久人妻无码精品系列| 99久久精品免费看国产一区二区三区| 狠狠色丁香婷综合久久| 日韩久久久久久中文人妻| 国产精品亚洲综合久久 | 精品国产日韩久久亚洲| 久久91精品综合国产首页| 嫩草影院久久国产精品| 国产成人久久激情91| 精品久久无码中文字幕| 亚洲AV日韩AV天堂久久| 亚洲AV日韩精品久久久久久| 亚洲一区精品伊人久久伊人| 亚洲国产成人精品久久久国产成人一区二区三区综 | 亚洲精品美女久久久久99小说 | 久久成人小视频| 99久久精品免费看国产一区二区三区| 亚洲国产精品综合久久网络| 久久影院久久香蕉国产线看观看| 久久国产影院|