青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Creative Commons License
本Blog采用 知識(shí)共享署名-非商業(yè)性使用-禁止演繹 3.0 Unported許可協(xié)議 進(jìn)行許可。 —— Fox <游戲人生>

游戲人生

游戲人生 != ( 人生 == 游戲 )
站點(diǎn)遷移至:http://www.yulefox.com。請(qǐng)訂閱本博的朋友將RSS修改為http://feeds.feedburner.com/yulefox
posts - 62, comments - 508, trackbacks - 0, articles - 7

項(xiàng)目中使用了消息通信機(jī)制,因?yàn)橄㈩愋头浅6啵鄳?yīng)的,處理消息的地方代碼也非常多。

自然而然想到MFC中的消息映射:

創(chuàng)建一個(gè)缺省MFC框架程序的解決方案Test,在Test.h中看到以下內(nèi)容:

class Ctest_mfcApp : public CWinApp
{
public:
    Ctest_mfcApp();

// 重寫
public:
    virtual BOOL InitInstance();

// 實(shí)現(xiàn)
    afx_msg void OnAppAbout();
    DECLARE_MESSAGE_MAP()
};

 

其中,最緊要的就是DECLARE_MESSAGE_MAP()這個(gè)宏,相關(guān)內(nèi)容展開(kāi)如下:

struct AFX_MSGMAP_ENTRY
{
    UINT nMessage;   // windows message
    UINT nCode;      // control code or WM_NOTIFY code
    UINT nID;        // control ID (or 0 for windows messages)
    UINT nLastID;    // used for entries specifying a range of control id's
    UINT_PTR nSig;   // signature type (action) or pointer to message #
    AFX_PMSG pfn;    // routine to call (or special value)
};

struct AFX_MSGMAP
{
    const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
    const AFX_MSGMAP_ENTRY* lpEntries;
};

#define DECLARE_MESSAGE_MAP() \
protected: \
    static const AFX_MSGMAP* PASCAL GetThisMessageMap(); \
    virtual const AFX_MSGMAP* GetMessageMap() const; \

其中AFX_PMSG不再解析下去,我們認(rèn)為這是一個(gè)指向特定消息對(duì)應(yīng)的實(shí)現(xiàn)函數(shù)的函數(shù)指針,這幾個(gè)宏的作用可簡(jiǎn)單理解成為Test這個(gè)項(xiàng)目定義了一個(gè)靜態(tài)的消息映射表。當(dāng)消息到來(lái)時(shí),從消息隊(duì)列中彈出消息并分發(fā)到具有入口實(shí)現(xiàn)的上層CWnd派生窗口。用戶只需要注冊(cè)消息,實(shí)現(xiàn)消息入口函數(shù)就夠了,這在MFC中一般放在.cpp文件頭部。Test.cpp中頭部有以下內(nèi)容:

BEGIN_MESSAGE_MAP(CTest, CWinApp)
    ON_COMMAND(ID_APP_ABOUT, &CTest::OnAppAbout)
    // 基于文件的標(biāo)準(zhǔn)文檔命令
    ON_COMMAND(ID_FILE_NEW, &CWinApp::OnFileNew)
    ON_COMMAND(ID_FILE_OPEN, &CWinApp::OnFileOpen)
    // 標(biāo)準(zhǔn)打印設(shè)置命令
    ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()

這里是為消息枚舉值與消息實(shí)現(xiàn)函數(shù)建立映射,其中涉及到的宏的展開(kāi)如下:

#define ON_COMMAND(id, memberFxn) \
    { WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSigCmd_v, \
        static_cast<AFX_PMSG> (memberFxn) },

#define BEGIN_MESSAGE_MAP(theClass, baseClass) \
    PTM_WARNING_DISABLE \
    const AFX_MSGMAP* theClass::GetMessageMap() const \
        { return GetThisMessageMap(); } \
    const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap() \
    { \
        typedef theClass ThisClass;                           \
        typedef baseClass TheBaseClass;                       \
        static const AFX_MSGMAP_ENTRY _messageEntries[] =  \
        {

#define END_MESSAGE_MAP() \
        {0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 } \
    }; \
        static const AFX_MSGMAP messageMap = \
        { &TheBaseClass::GetThisMessageMap, &_messageEntries[0] }; \
        return &messageMap; \
    }                                  \
    PTM_WARNING_RESTORE

按照上述思路得到的相似代碼如下:

// Test.h
typedef void (* funCall)(void*);        // 消息執(zhí)行函數(shù)類型

struct tagMsgEntry                      // 消息入口結(jié)構(gòu)
{
    int            nMsgType;            // 消息類型
    funCall        MsgRun;              // 消息執(zhí)行函數(shù)
};

struct tagMsgMap                        // 消息映射表結(jié)構(gòu)
{
    const tagMsgMap* (__stdcall* funGetBaseMsgMap)();
    const tagMsgEntry* pMsgEntries;     // 消息入口集
};

class CMessage
{
    // ...
protected:
    static const tagMsgMap* __stdcall GetThisMsgMap();
    virtual const tagMsgMap* GetMsgMap() const;
};

// Test.cpp
const tagMsgMap* CMessage::GetMsgMap() const
{
    return GetThisMsgMap();
}

const tagMsgMap* __stdcall CMessage::GetThisMsgMap()
{
    static const tagMsgEntry MsgEntries[] =
    {
        { MSG_SOME_ONE, SomeOneFunc },
        { MSG_SOME_TWO, SomeTwoFunc },
        { MSG_NULL, NULL }
    };
    static const tagMsgMap msgMap =
    {
        &CBaseMessage::GetThisMsgMap,    // 父類消息映射表
        &MsgEntries[0]
    };
    return &msgMap;
}

int CMessage::MsgProc(int nMsgType)
{
    switch( nMsgType )
    {
    case MSG_SOME_ONE:
        {

        }
        break;
    }
    return CBaseMessage::MsgProc(nMsgType);
}

這種處理的優(yōu)點(diǎn)在于,子類沒(méi)有定義的消息實(shí)現(xiàn)接口,可以使用父類接口實(shí)現(xiàn)。不過(guò)在現(xiàn)在的消息處理中,我們一般不需要由基類來(lái)完成,因此可以不依賴基類接口,使用宏可以使代碼看上去更加簡(jiǎn)潔。

___________________________________________________________

簡(jiǎn)化版本的消息映射采用以下方式,簡(jiǎn)單清晰:

// Test.h
#define REG_MSG_FUNC(nMsgType, MsgFunc) \
    CMessge::RegisterCallFunc(nMsgType, MsgFunc); \

typedef void (* function)(void*);

typedef std::map<int, function> MSG_MAP;
typedef MSG_MAP::const_iterator MSG_CITR;

class CMessage
{
    // ...
public:
    static const MSG_MAP& GetMsgMap();
    static void RegisterCallFunc(int nMsgType, void(* Func)(void *))
    {
        s_MsgMap[nMsgType] = Func;
    }

    int CMessage::Run(int nMsgType)                // 消息公用執(zhí)行函數(shù)
    {
        MSG_ITR itr = s_MsgMap.find(nMsgType);
        if( s_MsgMap.end() != itr )
        {
            itr->second(this);
        }
    }

protected:
    static MSG_MAP            s_MsgMap;            // 消息映射表
};

// UserTest.cpp -- 用戶在使用時(shí)對(duì)自己關(guān)心的消息予以注冊(cè), 入口函數(shù)予以實(shí)現(xiàn)即可
REG_MSG_FUNC(MSG_SOME_ONE, SomeOneFunc)

void SomeOneFunc(CBaseMessage *pMsg)
{
    return;
}

___________________________________________________________

最近忙的焦頭爛額,正好寫到消息,稍微整理一下,提供些許借鑒。

Feedback

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)[未登錄](méi)  回復(fù)  更多評(píng)論   

2008-09-30 12:32 by cppexplore
頂一下
前幾天我也剛寫了一個(gè),用在線程消息的處理中,我的消息類型做數(shù)組下標(biāo)了,直接定位取處理函數(shù),這都是無(wú)關(guān)緊要的細(xì)節(jié)。關(guān)鍵在ON_COMMAND宏的展現(xiàn)方式,我的處理線程消息,名字起做ON_MESSAGE
整體思路基本都是一樣的,呵呵。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2008-10-10 08:50 by Condor
對(duì)于成員函數(shù)這個(gè)寫法應(yīng)該沒(méi)用了。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2008-10-10 10:23 by Fox
@Condor
你說(shuō)的這個(gè)問(wèn)題我也考慮了,既然被提到,可以查看新一篇:http://www.shnenglu.com/Fox/archive/2008/10/10/63625.html

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 02:30 by OwnWaterloo
@cppexplore
【消息類型做數(shù)組下標(biāo)了,直接定位取處理函數(shù),這都是無(wú)關(guān)緊要的細(xì)節(jié)。】
這恰恰是最重要的細(xì)節(jié) …… 這樣做得不償失……



# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 02:35 by OwnWaterloo
@cppexplore
我再說(shuō)明白一點(diǎn):
既然【用消息類型做數(shù)組下標(biāo),直接定位處理函數(shù)】,為什么不直接使用虛函數(shù)?

你的方案是為了消息路由而消息路由,沒(méi)能理解采用消息路由的”苦衷“——如果采用更容易理解的虛函數(shù)來(lái)實(shí)現(xiàn),虛表將占用比較多的資源,不得已而采用消息路由。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)[未登錄](méi)  回復(fù)  更多評(píng)論   

2009-02-18 12:00 by cppexplore
@OwnWaterloo
歡迎來(lái)我blog討論:http://www.shnenglu.com/CppExplore 這篇http://www.shnenglu.com/CppExplore/archive/2008/11/07/66216.html下。查表是本質(zhì),為什么要使用虛函數(shù)?更容易理解?MFC的消息映射展現(xiàn)方式很難理解嗎? 虛函數(shù)更容易擴(kuò)展嗎? 說(shuō)到虛函數(shù)占用較多資源而導(dǎo)致不得已采用消息路由,我不能認(rèn)同,這個(gè)因素在整個(gè)系統(tǒng)中的開(kāi)銷你有沒(méi)有量化過(guò)?比如 因?yàn)椴捎盟鼘?dǎo)致并發(fā)數(shù)下降了多少多少之類?歡迎來(lái)我blog討論。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 16:29 by OwnWaterloo
@cppexplore

1. 時(shí)間消耗

時(shí)間消耗自然不用說(shuō),是你的實(shí)現(xiàn)最得意的部分,o(1)。
同樣,虛函數(shù)也是o(1)。

2. 空間消耗

假設(shè)你總共有N個(gè)消息,你仔細(xì)看看你的實(shí)現(xiàn):
是不是每個(gè)(要處理消息的)類有一個(gè)長(zhǎng)度會(huì)N的函數(shù)表,
空間大小至少是N×sizeof(void*);
每個(gè)對(duì)象有一個(gè)指向(或間接指向)該表的指針,
空間大小至少是sizeof(void*)。

虛函數(shù)的經(jīng)典實(shí)現(xiàn)的空間消耗也是one class one vtbl, one object one vptr,和你的實(shí)現(xiàn)還是相同的。


這就回答了你一個(gè)問(wèn)題:
【我不能認(rèn)同,這個(gè)因素在整個(gè)系統(tǒng)中的開(kāi)銷你有沒(méi)有量化過(guò)?比如 因?yàn)椴捎盟鼘?dǎo)致并發(fā)數(shù)下降了多少多少之類?】
兩者的時(shí)間空間效率是完全一致的,即使我沒(méi)有量化過(guò),也可以肯定,不會(huì)導(dǎo)致并發(fā)數(shù)下降。



# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 16:40 by OwnWaterloo
@cppexplore

【查表是本質(zhì)】
這句你說(shuō)到重點(diǎn)了,虛函數(shù)和你實(shí)現(xiàn)的那個(gè)還有哪些所謂的用C實(shí)現(xiàn)OO的,都是查表。

【為什么要使用虛函數(shù)?更容易理解?MFC的消息映射展現(xiàn)方式很難理解嗎? 虛函數(shù)更容易擴(kuò)展嗎?】
你這個(gè)實(shí)現(xiàn)就是在『模擬』虛函數(shù)。

上面的時(shí)空分析,可以量化,我有把握你會(huì)同意我的觀點(diǎn)——兩者時(shí)空效率完全一樣——這個(gè)擴(kuò)展性嘛,不容易量化 ……

你可以試著把你的實(shí)現(xiàn)用虛函數(shù)改寫一下(再次說(shuō)明,時(shí)空效率完全一樣)。看看是否覺(jué)得虛函數(shù)更容易理解,更容易擴(kuò)展。



btw:推薦你看看這個(gè),MFC會(huì)什么會(huì)采用消息映射而不是虛函數(shù)的理由,《C++多態(tài)技術(shù)的實(shí)現(xiàn)和反思》
http://dev.yesky.com/189/2385189.shtml

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-18 18:03 by OwnWaterloo
@cppexplore

再看了下你的實(shí)現(xiàn),好像我們討論的著重點(diǎn)不一樣。

1. 你的系統(tǒng)里,是不是首先有這樣一個(gè)需求:
因?yàn)槟撤N原因(分布式,進(jìn)程間,無(wú)鎖線程),消息的發(fā)送者不能直接調(diào)用消息處理函數(shù),而是傳送一個(gè)消息代碼來(lái)表示需要處理的類型?

消息代碼即是win32中的WM_XX或者你的系統(tǒng)中的 enum MsgType { MSG_TYPE_1=65, ...  };



2. 消息的處理者,又需要按照約定(即消息代碼的含義),將其映射到某個(gè)處理函數(shù)中。

如 win32 中
switch (message) {
case WM_XXX:
   return OnXXX(hwnd,message,wparam,lparam);
...
}

或者你的系統(tǒng)中的
switch(msg->type)
{
    
case MSG_TYPE_1:
         do_msg_type_1_();
         
break;
    
case MSG_TYPE_2:
         do_msg_type_2_();
         
break;
    ..
    
default:
             do_default_msg_();
             
break;
}



在這一步,確實(shí)是你的實(shí)現(xiàn)方式時(shí)間效率比較高。
但是在win32中, 這樣做不太現(xiàn)實(shí) ……  1000多個(gè)消息,表格就要包含1000多項(xiàng),而且大多都是DefWndProc。

并且,在這一步中,虛函數(shù)根本就提供不了任何幫助
你的著重點(diǎn)在這一步?


3. 你想實(shí)現(xiàn)一個(gè)消息處理者B,它對(duì)大多數(shù)消息的處理方式同A一樣,這時(shí)候如何盡可能的使用A的實(shí)現(xiàn)?
(暫不說(shuō)依賴于某實(shí)現(xiàn)是不太恰當(dāng)?shù)脑O(shè)計(jì),在MFC中多如牛毛……)

我的著重點(diǎn)在這里,我對(duì)處理這步的觀點(diǎn)是: 『消息類型做數(shù)組下標(biāo)了,直接定位取處理函數(shù)』與『覆寫虛函數(shù)』相比,時(shí)空效率是相同的,我覺(jué)得后者更容易理解和擴(kuò)展。


# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)[未登錄](méi)  回復(fù)  更多評(píng)論   

2009-02-18 18:21 by cppexplore
@OwnWaterloo
怎么不直接去我blog回復(fù)呢 呵呵
其實(shí) 時(shí)間消耗 之類并不是我最得意的東西,這種實(shí)現(xiàn)的細(xì)節(jié) 我并不太關(guān)注,所以質(zhì)疑你以前說(shuō)的 “虛函數(shù)占用較多資源而導(dǎo)致不得已采用消息路由”,如何實(shí)現(xiàn)并不重要,關(guān)鍵的是容易理解,容易擴(kuò)展,容易維護(hù),容易移植,容易簡(jiǎn)單化。
win32 你是指win32 的界面設(shè)計(jì)? 業(yè)務(wù)系統(tǒng)里 基本不同的消息有不同的實(shí)現(xiàn),我的本意其實(shí)都不在實(shí)現(xiàn),而在于簡(jiǎn)單的思想,因此是查表實(shí)現(xiàn) 還是虛函數(shù)實(shí)現(xiàn) 也都無(wú)所謂,只要最后有統(tǒng)一的擴(kuò)展方式。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)[未登錄](méi)  回復(fù)  更多評(píng)論   

2009-02-18 18:55 by cppexplore
@OwnWaterloo
呵呵,最后的問(wèn)題歸結(jié)為:哪種更容易理解和擴(kuò)展。
超大工程當(dāng)然是數(shù)組方式之上用宏展現(xiàn)最容易理解和擴(kuò)展了,簡(jiǎn)潔直接。幾十w行的代碼,用虛函數(shù),文件數(shù)量的迅速膨脹 找個(gè)東西都找不到在哪里,所有東西交織錯(cuò)亂在一起,最終維護(hù)程序的人都會(huì)想:要是有張表就好了,只看表就知道那個(gè)函數(shù)處理哪個(gè)消息,而宏的展現(xiàn)就是如此。 當(dāng)然如果用宏包裹下虛函數(shù)的實(shí)現(xiàn),結(jié)果就一樣了。
并且數(shù)組表只是一個(gè)思路,不攜帶任何面向?qū)ο蟮恼Z(yǔ)義,在這個(gè)業(yè)務(wù)系統(tǒng)里可用,在那個(gè)業(yè)務(wù)系統(tǒng)里也可用,虛函數(shù)有這么好的移植性嗎?有這么簡(jiǎn)單化嗎?

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 01:57 by OwnWaterloo
@cppexplore
【怎么不直接去我blog回復(fù)呢 呵呵】
好像是cppblog對(duì)url的分析有點(diǎn)問(wèn)題,這個(gè)url: http://www.shnenglu.com/CppExplore/archive/2008/11/07/66216.html
會(huì)被截取,只將前面一部分(也就是你的主頁(yè))制作成鏈接,點(diǎn)過(guò)去沒(méi)看見(jiàn)什么文章……
后來(lái)才發(fā)現(xiàn)這個(gè)問(wèn)題,找到那篇文章……
【容易理解,容易擴(kuò)展,容易維護(hù),容易移植,容易簡(jiǎn)單化】
嗯,這是重點(diǎn)。同時(shí)我也贊同你文章里最后一句話【一句話:重要的是思想,不是平臺(tái)和語(yǔ)言。】
 
"你的實(shí)現(xiàn)就是模擬C++虛函數(shù)的經(jīng)典實(shí)現(xiàn)",這個(gè)觀點(diǎn)你贊同嗎?
你的系統(tǒng)需要考慮向C(以及不支持虛函數(shù)的語(yǔ)言)移植嗎?
 
如果贊同且不需要,那么繼續(xù)討論理解擴(kuò)展維護(hù)簡(jiǎn)單
你的系統(tǒng)具體要做什么不太了解,我用win32作例子可以嗎?比如,現(xiàn)在需要關(guān)心的消息只有2個(gè):
enum MsgType {
    WM__LBUTTONDOWN 
/*= 0*/,
    WM__SIZING,
    
// 
};
struct Msg {
    MsgType type;
    HWND    hwnd;
    WPARAM  wparam;
    LPARAM  lparam;
};

如果使用C++虛函數(shù)機(jī)制:
 
class IHandler {
public:
    
virtual ~IHandler() {};
protected:
    
virtual void OnLButtonDown(POINTS pt,bool ctrl,bool shift,bool l,bool m,bool r) = 0 {};
    
virtual void OnSizing(RECT& rc,int side) = 0 {};
public:
    LRESULT Do(Msg
* msg) {
        
switch (msg->type) {
            
case WM__LBUTTONDOWN:
                OnLButtonDown(MAKEPOINTS(msg
->lparam)
                             ,msg
->wparam & MK_CONTROL
                             ,msg
->wparam & MK_SHIFT
                             ,msg
->wparam & MK_LBUTTON
                             ,msg
->wparam & MK_MBUTTON
                             ,msg
->wparam & MK_RBUTTON);
                
return 0;
            
case WM__SIZING:
                OnSizing(
*reinterpret_cast<RECT*>(msg->lparam),msg->wparam);
                
return 0;
        }

        
return DefWindowProc(msg->hwnd,msg->type,msg->wparam,msg->lparam);
    }

}
;
 
具體的消息處理類可以這樣:
class Handler1 : public IHandler {
    
void OnLButtonDown(POINTS pt,bool ctrl,bool shift,bool l,bool m,bool r) {
        IHandler::OnLButtonDown(pt,ctrl,shift,l,m,r);
    }

    
void OnSizing(RECT& rc,int side) {
        IHandler::OnSizing(rc,side);
    }

}
;
 
上面的基類的虛函數(shù)帶有默認(rèn)實(shí)現(xiàn),但設(shè)置為純虛函數(shù)。
具體類必須實(shí)現(xiàn)每個(gè)消息處理過(guò)程,如果不關(guān)心,可以簡(jiǎn)單使用基類實(shí)現(xiàn)。
另一種方式:基類提供默認(rèn)實(shí)現(xiàn),并且不是純虛函數(shù);具體類只需覆寫關(guān)心的消息。
 
另一方面,上面的基類沒(méi)有使用表格,如果覺(jué)得switch case 不好維護(hù),也可以使用表格。
 
兩方面都采用另一種方案的話,基類就如下:
class IHandler {
public:
    
virtual ~IHandler() {};
private:
    
virtual void OnLButtonDown(POINTS pt,bool ctrl,bool shift,bool l,bool m,bool r)  {};
    
virtual void OnSizing(RECT& rc,int side)  {};
public:
    LRESULT Do(Msg
* msg) {
        assert(msg
->type>=0 && msg->type<WM__SIZING);
        
return MsgProcs[msg->type](msg->hwnd,msg->type,msg->wparam,msg->lparam,this);
    }


private:
    typedef LRESULT (
*MsgProc)(HWND,MsgType,WPARAM,LPARAM,IHandler* handler);
    
const static MsgProc MsgProcs[];
    
static LRESULT OnLButtonDown(HWND,MsgType,WPARAM wparam,LPARAM lparam,IHandler* handler) {
        handler
->OnLButtonDown(MAKEPOINTS(lparam)
                              ,wparam 
& MK_CONTROL
                              ,wparam 
& MK_SHIFT
                              ,wparam 
& MK_LBUTTON
                              ,wparam 
& MK_MBUTTON
                              ,wparam 
& MK_RBUTTON);
        
return 0;
    }

    
static LRESULT OnSizing(HWND,MsgType,WPARAM wparam,LPARAM lparam,IHandler* handler) {
        handler
->OnSizing(*reinterpret_cast<RECT*>(lparam),wparam);
        
return 0;
    }

}
;

const IHandler::MsgProc IHandler::MsgProcs[] = {
    IHandler::OnLButtonDown,
    IHandler::OnSizing,
}
;

具體類的編寫就更簡(jiǎn)單: 假設(shè)僅關(guān)心OnLButtonDown
class Handler1 : public IHandler {
    
void OnLButtonDown(POINTS pt,bool ctrl,bool shift,bool l,bool m,bool r) {
        printf(
"(%d,%d) ctrl=%d,shitf=%d\n",pt.x,pt.y,ctrl,shift);
    }

}
;

 

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 02:16 by OwnWaterloo
                              考慮擴(kuò)展
 
添加一個(gè)新的消息處理類。
如果基類不是純虛函數(shù),那最簡(jiǎn)單了,覆寫需要關(guān)心的消息就可以了。
如果是純虛函數(shù),需要實(shí)現(xiàn)所有消息處理函數(shù),對(duì)不關(guān)心的消息,使用基類默認(rèn)處理。
 
而你的方案,不得不將所有的消息都映射一遍——因?yàn)椤鞠㈩愋妥鰯?shù)組下標(biāo),直接定位取處理函數(shù)】——即使不關(guān)心而作一個(gè)空函數(shù)。 
BEGIN_MESSAGE_MAP(SessionManager,SessionMsg)
    ON_MESSAGE(MSG_TYPE_1, SessionManager::do_msg_type_1_)
    ON_MESSAGE(MSG_TYPE_2, SessionManager::do_msg_type_2_)
    
// .. MORE
END_MESSAGE_MAP()
如果不是這樣,請(qǐng)務(wù)必告訴我你是怎么不使用虛函數(shù)實(shí)現(xiàn)的。
 
 
添加一個(gè)新的消息種類(消息代碼)
如果可以保證消息代碼連續(xù),可以使用上面的方案2,在表格中多加入一條。
如果不能保證消息代碼連續(xù)(并且非常稀疏),就只能采用swtich case。
 
已經(jīng)編寫好的具體的消息處理類,如果都可以安全忽略該消息,那么可以采用上面的方案2——基類有默認(rèn)實(shí)現(xiàn)且不純虛——那么除了基類,已經(jīng)編寫好的具體類都不需要修改
如果不全都可以安全忽略該消息,那么可以采用上面的方案1——基類有空實(shí)現(xiàn),但是純虛——具類中可以忽略該消息的,使用基類實(shí)現(xiàn),不能忽略的,編寫處理函數(shù)。
 
而你的方案,一旦添加一個(gè)新的消息處理代碼(同時(shí)要保證連續(xù)),所有的消息處理類都必須在其表格中增加一項(xiàng)。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 02:16 by OwnWaterloo
移植性確實(shí)會(huì)在不支持虛函數(shù)的語(yǔ)言中完敗。
論理解、擴(kuò)展、維護(hù)、簡(jiǎn)單的話,你現(xiàn)在仍然覺(jué)得虛函數(shù)比不上表格嗎?

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)[未登錄](méi)  回復(fù)  更多評(píng)論   

2009-02-19 10:16 by cppexplore
@OwnWaterloo
呵呵 你覺(jué)得你的想法來(lái)源于面向?qū)ο蟮募埳险劚](méi)有貶義)以及基于win32的mfc框架程序設(shè)計(jì)。
我的實(shí)現(xiàn)不是為了模擬虛函數(shù)的實(shí)現(xiàn),只是為了實(shí)現(xiàn)一個(gè)易維護(hù)的消息映射而已。
首先 對(duì)象A不能直接向?qū)ο驜直接發(fā)送消息,需要調(diào)用對(duì)象B的ON_send_msg,由B自己的方法向自己發(fā)送消息,由B的DO_Msg方法處理消息,當(dāng)然發(fā)送動(dòng)作和處理動(dòng)作在不同的線程內(nèi)。任何對(duì)象向B發(fā)送消息都要調(diào)用B自己的方法。也就是說(shuō)對(duì)象B的具體消息類型對(duì)其它對(duì)象是不可見(jiàn)的。
因此對(duì)象B中的消息類型是連續(xù)的,并且不存在自己不感興趣的消息,既然不感興趣,就不會(huì)存在這個(gè)消息類型,只要是存在的就是感興趣的,就是要處理的。也不存在對(duì)多個(gè)消息,處理方式相同的問(wèn)題,既然處理方式相同,它們就是同一個(gè)消息。
其次 你還是回避了大型程序開(kāi)發(fā)中,使用虛函數(shù)方式,文件個(gè)數(shù)膨脹的問(wèn)題。
最后 我討論的是線程間的消息傳遞和映射,你的有偏向于 已經(jīng)發(fā)送到UI線程的消息,對(duì)責(zé)任鏈模式上的 各個(gè)對(duì)象的后續(xù)處理。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 22:42 by OwnWaterloo
@cppexplore

第1個(gè)疑問(wèn):
系統(tǒng)中所有類使用的消息代碼是否是同一套?都是
enum MsgType
{
MSG_TYPE_1=65,//64一下預(yù)留,用于統(tǒng)一的管理控制
MSG_TYPE_2,
..
MSG_TYPE_MAX
};
???

第2個(gè)疑問(wèn):(同時(shí)也是回答)
確實(shí)如你所說(shuō),我是【紙上談兵】。
我沒(méi)有【大型程序】的開(kāi)發(fā)經(jīng)驗(yàn),更是不能理解:
【大型程序開(kāi)發(fā)中,使用虛函數(shù)方式,文件個(gè)數(shù)膨脹的問(wèn)題。】
這是為什么? 請(qǐng)指教~~~ 昨天就想問(wèn)你了,字打多了就忘了……

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)[未登錄](méi)  回復(fù)  更多評(píng)論   

2009-02-19 22:51 by cppexplore
@OwnWaterloo
不是同一套,只有64以下的是相同。64以上的各個(gè)線程之間可以重復(fù),因?yàn)閷?duì)其他對(duì)象是不可見(jiàn)得,所以不存在沖突問(wèn)題。可以定義USER_MSG_START=64.
項(xiàng)目越大,越需要表格,容易維護(hù),容易擴(kuò)展,容易找對(duì)應(yīng)關(guān)系,也就是看一個(gè)文件就知道所有,而不是在幾十個(gè)上百個(gè)文件里查找。當(dāng)然要看你的虛函數(shù)實(shí)現(xiàn)成什么樣子了。
我舉的例子,對(duì)象B是管理類,同時(shí)也是線程類。里面管理了很多的對(duì)象,B拿到消息也是找到對(duì)應(yīng)的對(duì)象去處理,貌似你一直談的是后續(xù)。
而你在MFC里看到的是同一套,那是因?yàn)樗鼈兌荚赨I線程里,同屬于一個(gè)線程,一個(gè)管理類。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2009-02-19 23:23 by OwnWaterloo
@cppexplore
我覺(jué)得加QQ聊會(huì)快一點(diǎn)…… “六久久思武柳留靈”

不是同一套,那么A向B發(fā)一個(gè)65以上的消息,B如何知道代表什么含義呢?
要么:A只向B發(fā)64以下的消息。
要么:存在T1,T2, ... Tn個(gè)線程,每個(gè)線程下分別有
A11,A12, ... An1...
A21,A22, ... An2...
...
A[i][j]只會(huì)和A[i][k]直接交互
A[i][j]和A[k][l]通過(guò)某種機(jī)制間接交互



-----------------------------
【貌似你一直談的是后續(xù)。 】
可能是這樣的,我在
http://www.shnenglu.com/Fox/archive/2008/09/29/63056.aspx#74178
也說(shuō)了。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)[未登錄](méi)  回復(fù)  更多評(píng)論   

2009-02-20 10:19 by cppexplore
@OwnWaterloo
上班不能qq 呵呵 下班加你
A不能以指定消息值的方式向B發(fā)消息,通過(guò)調(diào)用B自身的ON_MSG方法發(fā)送。也就是除了B自己,誰(shuí)也不知道它具體消息的枚舉值。
64一下的也是調(diào)用B自身的方法發(fā)送,不過(guò)這些是B基類中的方法。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:04 by
人 需要一種簡(jiǎn)單的 東西來(lái)支撐屬于自身內(nèi)心的簡(jiǎn)單,這樣的簡(jiǎn)單一直以來(lái)是無(wú)形的,就如同所有存在的 對(duì)于支撐簡(jiǎn)單的東西已經(jīng) 進(jìn)行過(guò)的時(shí)候,那么內(nèi)心當(dāng)中還是缺少對(duì)于無(wú)法割舍的簡(jiǎn)單的 內(nèi)涵

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:06 by
在某一種環(huán)境下面其實(shí)簡(jiǎn)單的來(lái)說(shuō)在于一旦沒(méi)有了這樣的一種現(xiàn)實(shí),簡(jiǎn)單的環(huán)境是否在可能變化的環(huán)境當(dāng)中產(chǎn)生簡(jiǎn)單的過(guò)程那樣如此簡(jiǎn)單明了

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:07 by
所以自己的內(nèi)心真誠(chéng)的東西不是對(duì)于某一種勢(shì)力的那種附和,而是對(duì)于在這個(gè)過(guò)程當(dāng)中自身能夠決定進(jìn)入某一種勢(shì)力需要的那種條件的 認(rèn)可

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:08 by
在各種各樣的 范圍內(nèi)決定一個(gè)人能夠簡(jiǎn)單的進(jìn)行自身的活動(dòng)范圍內(nèi) 并且 能夠達(dá)到一些盡可能需要的行為內(nèi),需要的不僅僅是可靠性的 過(guò)程,更重要的是價(jià)值活動(dòng)的產(chǎn)生

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:09 by
在過(guò)程行為當(dāng)中能夠明確的 在于是已經(jīng)形成出來(lái)的新的一種競(jìng)爭(zhēng)力自身需要的一種內(nèi)心活動(dòng) 當(dāng)中產(chǎn)生的角色轉(zhuǎn)換的 過(guò)程當(dāng)中需要的互動(dòng)意識(shí)與能力

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2011-10-15 16:10 by
因此各種各樣的簡(jiǎn)單絕對(duì)不是取決于自身在竭盡全力自后需要的條件,而是自身竭盡全力的過(guò)程當(dāng)中自己需要的休息的素質(zhì)與能力的那種背景考量的能力

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:10 by
基本上來(lái)說(shuō)一個(gè)人成熟的機(jī)制恐怕是能夠讓自己能夠在不斷的磨合當(dāng)中逐漸消失成見(jiàn)的過(guò)程,就一個(gè)成熟的那種業(yè)績(jī)體系來(lái)說(shuō),實(shí)際上現(xiàn)在的復(fù)雜在于業(yè)績(jī)對(duì)象的那種針對(duì)的安全對(duì)象的成熟度沒(méi)有,如果僅僅針對(duì)的是一種瘋子般的業(yè)務(wù)來(lái)說(shuō)的業(yè)績(jī)或者組織層面來(lái)說(shuō)的業(yè)績(jī),這樣的機(jī)制成熟的業(yè)績(jī)體系是不存在的一個(gè)方式。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:13 by
實(shí)際上業(yè)績(jī)組合套拳的組合一定夾雜某一種對(duì)于私心認(rèn)可的范疇內(nèi)達(dá)到的應(yīng)急范疇內(nèi)實(shí)現(xiàn)對(duì)于業(yè)績(jī)整個(gè)機(jī)制的認(rèn)識(shí),從表面上來(lái)看,一旦業(yè)績(jī)沒(méi)有屬于自己范圍的業(yè)績(jī)過(guò)程,整個(gè)的業(yè)績(jī)鏈被居心叵測(cè)的人所掌握,那么業(yè)績(jī)機(jī)制上面的成熟機(jī)制在實(shí)現(xiàn)的過(guò)程永遠(yuǎn)被這樣或者那樣的理由所圈繞。一個(gè)成熟的業(yè)績(jī)機(jī)體本身上面是由于其中業(yè)績(jī)機(jī)體上面有按照其中規(guī)律方式運(yùn)轉(zhuǎn)的模式旋轉(zhuǎn),而與時(shí)代與行業(yè),和管理它的人就更加沒(méi)有關(guān)系的了

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:16 by
業(yè)績(jī)機(jī)制上面的成熟度在于在不斷的磨合的組合的過(guò)程當(dāng)中永遠(yuǎn)不可能按照面上面的業(yè)績(jī)組合形成業(yè)績(jī)機(jī)制過(guò)程,業(yè)績(jī)機(jī)制表明的是在業(yè)績(jī)最初形成的時(shí)候,需要使用各種各樣關(guān)于技巧性的使用,一旦業(yè)績(jī)成熟,則不過(guò)是一種對(duì)于業(yè)績(jī)形成上面需要依照的規(guī)律模式行駛其中業(yè)績(jī)機(jī)制形成的規(guī)律線而已。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:19 by
業(yè)績(jī)機(jī)制形成的規(guī)律線絕對(duì)不是建立在回復(fù)其它層面的上面的不斷的 解釋層次上面表現(xiàn)出來(lái)的那種心安理得局面上面的業(yè)績(jī)機(jī)制,業(yè)績(jī)機(jī)制的形成在于自己認(rèn)為需要付出多少的代價(jià)愿意承受這樣的一種業(yè)績(jī)機(jī)制的形成,業(yè)績(jī)機(jī)制的形成一般是競(jìng)爭(zhēng)分析--競(jìng)爭(zhēng)對(duì)手分析---柜臺(tái)分析---賺錢分析---承載風(fēng)險(xiǎn)分析---合理的業(yè)績(jī)軌道,這個(gè)業(yè)績(jī)機(jī)制的形成在于一旦在那種對(duì)于業(yè)績(jī)本身模式不認(rèn)可,而且浮于人事層面上面是永遠(yuǎn)不可能體會(huì) 到這樣的一個(gè)業(yè)績(jī)機(jī)制形成的過(guò)程的。

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:22 by
基于對(duì)于業(yè)績(jī)機(jī)制形成的事實(shí),然后規(guī)劃屬于自身現(xiàn)狀的業(yè)績(jī)狀況就能夠發(fā)現(xiàn),充分的運(yùn)用屬于自己的認(rèn)識(shí)與人事與實(shí)力來(lái)驗(yàn)證對(duì)于業(yè)績(jī)機(jī)制的本身帶來(lái)的效果,然后再這樣的一種效果當(dāng)中明確這樣的一種業(yè)績(jī)機(jī)制承載出來(lái)一個(gè)怎么樣的自己的體驗(yàn)當(dāng)中,從而對(duì)于自己有一個(gè)或者有一種全新的認(rèn)識(shí)的過(guò)程,至少在這個(gè)過(guò)程當(dāng)中,能夠承載屬于自己職業(yè)生命力的安全模式

# re: 消息映射機(jī)制的簡(jiǎn)單實(shí)現(xiàn)  回復(fù)  更多評(píng)論   

2012-04-16 09:25 by
確切的說(shuō),業(yè)績(jī)機(jī)制承載的職業(yè)生命力具體表現(xiàn)在屬于一種胸襟,沒(méi)有一種胸襟,格局的誕生恐怕只能夠越來(lái)越小,胸襟不是以職業(yè)生命力的安全作為安全,而恰恰相反,胸襟是站在或者基于職業(yè)生命力維護(hù)的基礎(chǔ)上面去考慮胸襟本身的得失或者愿意承受的東西和不愿意承受的順應(yīng)心靈的一種呼喚。
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美电影免费观看高清| 亚洲三级电影在线观看| 午夜欧美电影在线观看| 久久精品亚洲精品国产欧美kt∨| 中文精品99久久国产香蕉| 久久另类ts人妖一区二区| 久久国产毛片| 在线成人免费观看| 91久久国产自产拍夜夜嗨| 欧美精品在线一区| 性高湖久久久久久久久| 久久精品欧美日韩| 91久久久久久久久| 亚洲一区视频在线| 亚洲高清在线播放| 一区二区三区日韩精品视频| 国产日韩精品久久| 欧美va天堂va视频va在线| 欧美日产一区二区三区在线观看| 亚洲欧美春色| 久久一区激情| 亚洲欧美国内爽妇网| 久久久久.com| 亚洲一区二区三区免费观看| 久久精品1区| 一区二区三区产品免费精品久久75| 亚洲一区二区三区三| 亚洲人成绝费网站色www| 亚洲一区日本| 日韩视频一区二区三区在线播放| 亚洲欧美国产制服动漫| 亚洲欧洲久久| 久久久久九九九| 亚洲欧美精品在线观看| 欧美成人精品三级在线观看 | 欧美风情在线| 久久久久国产精品一区三寸| 欧美激情精品久久久久久免费印度| 欧美一区二区精美| 欧美绝品在线观看成人午夜影视 | 久久精品一区二区三区不卡| 欧美人成免费网站| 欧美成人r级一区二区三区| 国产精品午夜视频| 99ri日韩精品视频| 日韩网站在线| 另类专区欧美制服同性| 久久国产天堂福利天堂| 国产精品久久久久久妇女6080| 亚洲欧洲日韩在线| 亚洲激情成人网| 久久久成人精品| 久久九九全国免费精品观看| 欧美午夜不卡视频| 日韩午夜免费视频| av成人免费观看| 欧美精品1区2区| 亚洲第一网站| 亚洲日韩欧美视频一区| 免播放器亚洲| 亚洲国产mv| 99国产精品久久久| 欧美日本在线看| 日韩视频在线你懂得| 日韩视频中文字幕| 欧美日韩激情小视频| 久久综合网络一区二区| 美女精品自拍一二三四| 国产一区日韩欧美| 久久久久成人精品| 麻豆精品国产91久久久久久| 韩国一区二区在线观看| 久久精品女人天堂| 亚洲第一福利社区| 一本色道久久综合精品竹菊| 欧美日产国产成人免费图片| 一区二区三区不卡视频在线观看| 亚洲视频一区二区免费在线观看| 欧美日韩一区在线观看视频| 一本色道久久88综合亚洲精品ⅰ| 亚洲综合999| 国产午夜精品全部视频在线播放| 久久国产免费看| 欧美大秀在线观看| 一区二区三区高清| 国产精品永久入口久久久| 久久精品网址| 亚洲人成网站777色婷婷| 亚洲欧美成人| 亚洲国产99精品国自产| 欧美日产一区二区三区在线观看| 亚洲欧美国产日韩天堂区| 久久天天躁狠狠躁夜夜av| 亚洲人成毛片在线播放女女| 国产精品另类一区| 久热re这里精品视频在线6| 亚洲精品日日夜夜| 久久婷婷影院| 亚洲一二三区精品| 在线观看欧美亚洲| 欧美性久久久| 免播放器亚洲一区| 亚洲影视在线| 亚洲国产人成综合网站| 久久激情视频久久| 日韩视频一区二区三区在线播放免费观看| 欧美午夜精品久久久久久孕妇| 香蕉av福利精品导航| 亚洲精品一区在线| 麻豆成人综合网| 欧美在线视频不卡| 亚洲最新色图| 影音先锋久久| 国产日韩1区| 国产精品播放| 欧美日本亚洲视频| 久久偷看各类wc女厕嘘嘘偷窃| 一本到高清视频免费精品| 欧美va天堂va视频va在线| 欧美一区二区视频免费观看| 中文av字幕一区| 亚洲精品日韩久久| 伊人久久大香线蕉av超碰演员| 国产精品久久久久久久久搜平片| 欧美成人免费大片| 久久免费视频观看| 欧美在线视频在线播放完整版免费观看 | 一本色道久久综合亚洲精品不| 欧美国产丝袜视频| 久久久高清一区二区三区| 亚洲第一色在线| 韩国成人福利片在线播放| 91久久综合| 日韩午夜免费| 亚洲欧洲中文日韩久久av乱码| 国产一区香蕉久久| 国产女人aaa级久久久级| 欧美视频官网| 欧美三级电影大全| 欧美日韩一区二区精品| 欧美日韩1区| 欧美三级日韩三级国产三级| 欧美日韩福利在线观看| 欧美精品一区在线播放| 欧美成人亚洲成人| 欧美—级在线免费片| 欧美激情综合| 欧美日韩精品一区视频| 欧美日韩一卡二卡| 国产精品观看| 国产欧美日韩在线| 国内外成人免费视频| 伊人狠狠色j香婷婷综合| 在线观看欧美成人| 日韩视频永久免费观看| 一区二区三区国产精华| 亚洲亚洲精品在线观看| 久久精品91久久久久久再现| 久久免费视频在线观看| 欧美成人精品不卡视频在线观看| 欧美大片在线观看一区| 日韩亚洲欧美一区二区三区| 亚洲欧美国产视频| 久久欧美中文字幕| 欧美日本成人| 国产欧美精品一区二区色综合| 国内免费精品永久在线视频| 亚洲激情在线视频| 亚洲男女自偷自拍图片另类| 久久免费高清视频| 亚洲高清视频一区二区| 在线亚洲欧美专区二区| 久久国产加勒比精品无码| 欧美华人在线视频| 国产女人18毛片水18精品| 亚洲激情第一页| 亚洲欧美日韩国产成人| 久久综合中文色婷婷| 日韩视频在线一区二区| 欧美一区二区三区精品| 欧美激情aaaa| 国产午夜精品久久久| 99热在这里有精品免费| 久久成人av少妇免费| 亚洲国产精品久久91精品| 亚洲性感美女99在线| 免费视频一区| 国产婷婷精品| 亚洲一区二区三区精品动漫| 免费试看一区| 午夜老司机精品| 欧美日韩成人综合| 在线免费观看日本欧美| 亚洲欧洲av一区二区三区久久| 欧美电影电视剧在线观看| 午夜一区二区三区在线观看| 欧美日韩裸体免费视频| 亚洲激情影视| 久久伊人精品天天| 欧美一区亚洲|