GUI框架:談談框架,寫寫程式碼
阿新 • • 發佈:2018-12-27
@ OwnWaterloo
你用的是和atl一樣的方式?
將hwnd"替換"為this? 而非"插入"一個this?
是嗎?
====================
是的。因為這樣才能相容x64平臺:x64前8個引數通過暫存器傳遞。
@ cexer
SetProp 結合 GUID更理想,而GUID可以用API獲取。
以後多交流!期待你的GUI框架下一篇...^_^
================
|||||||||||||||||||||
發現一個類中有6萬個指標時,如果指標初始化了,還是佔用記憶體。
沒辦法,為了降低成本,不能在類中放那麼多指標了。
所以,使用bitset來幫忙。
先看訊息註冊(比原來的難看多了,沒找到好方法,詳見: http://topic.csdn.net/u/20091119/15/07d7e755-c733-4195-8cc4-306560d6fbc4.html )
class MainFrm : public Frame
{
public:
MainFrm() : Frame(_T("Test Demo!"), _T("MainFrame")), m_testBtn(_T("Test!"))
{
Add(&m_testBtn);
m_testBtn.Get<EvtLButtonDown>(m_testBtn.IdLButtonDown).Bind(this, &MainFrm::OnLBtnClicked);
Get<EvtCreate>(IdCreate).Bind(this, &MainFrm::OnCreate);
}
~MainFrm()
{
Get<EvtCreate>(IdCreate).UnBind(this, &MainFrm::OnCreate);
}
qpEvt OnCreate(EvtCreate& evt)
{
qpDbgInt(evt.handled);
}
qpEvt OnLBtnClicked(EvtLButtonDown& evt)
{
qpDbgInt(evt.owner);
}
protected:
Button m_testBtn;
};
用bitset + map<short, void*> + enum來降低成本:
#define IMPLEMENT_EVENT(X, Y) \
public: \
template <typename T> \
Event<T>& Get(X id) \
{ \
if (m_evtMap.get() == NULL) \
{ \
qpNewPtrEx(p, EventMap); \
m_evtMap.reset(p); \
} \
if (m_evtFlag[id] == 0) \
{ \
qpNewPtrEx(p, Event<T>); \
if (p != NULL) \
{ \
m_evtFlag[id] = 1; \
m_evtMap->insert(std::make_pair(static_cast<short>(id), p)); \
return *static_cast<Event<T>*>(p); \
} \
} \
else \
{ \
EventMap::iterator it = m_evtMap->find(static_cast<short>(id)); \
if (it != m_evtMap->end()) return *static_cast<Event<T>*>(it->second); \
} \
qpASSERT(false); \
qpNewPtrEx(p, Event<T>); \
return *std::auto_ptr<Event<T>>(p); \
} \
protected: \
typedef std::map<short, void*> EventMap; \
std::auto_ptr<EventMap> m_evtMap; \
std::bitset<Y> m_evtFlag;
std::bitset的使用,可以判斷相應訊息是否註冊,不用每一個訊息都進入一次Event了,但由於使用map來查詢訊息,效率上還是下降了。
沒辦法:只能用時間換空間!
你用的是和atl一樣的方式?
將hwnd"替換"為this? 而非"插入"一個this?
是嗎?
====================
是的。因為這樣才能相容x64平臺:x64前8個引數通過暫存器傳遞。
@ cexer
SetProp 結合 GUID更理想,而GUID可以用API獲取。
以後多交流!期待你的GUI框架下一篇...^_^
================
|||||||||||||||||||||
發現一個類中有6萬個指標時,如果指標初始化了,還是佔用記憶體。
沒辦法,為了降低成本,不能在類中放那麼多指標了。
所以,使用bitset來幫忙。
先看訊息註冊(比原來的難看多了,沒找到好方法,詳見:
class MainFrm : public Frame
{
public:
MainFrm() : Frame(_T("Test Demo!"), _T("MainFrame")), m_testBtn(_T("Test!"))
{
Add(&m_testBtn);
m_testBtn.Get<EvtLButtonDown>(m_testBtn.IdLButtonDown).Bind(this, &MainFrm::OnLBtnClicked);
Get<EvtCreate>(IdCreate).Bind(this, &MainFrm::OnCreate);
}
~MainFrm()
{
Get<EvtCreate>(IdCreate).UnBind(this, &MainFrm::OnCreate);
}
qpEvt OnCreate(EvtCreate& evt)
{
qpDbgInt(evt.handled);
}
qpEvt OnLBtnClicked(EvtLButtonDown& evt)
{
qpDbgInt(evt.owner);
}
protected:
Button m_testBtn;
};
用bitset + map<short, void*> + enum來降低成本:
#define IMPLEMENT_EVENT(X, Y) \
public: \
template <typename T> \
Event<T>& Get(X id) \
{ \
if (m_evtMap.get() == NULL) \
{ \
qpNewPtrEx(p, EventMap); \
m_evtMap.reset(p); \
} \
if (m_evtFlag[id] == 0) \
{ \
qpNewPtrEx(p, Event<T>); \
if (p != NULL) \
{ \
m_evtFlag[id] = 1; \
m_evtMap->insert(std::make_pair(static_cast<short>(id), p)); \
return *static_cast<Event<T>*>(p); \
} \
} \
else \
{ \
EventMap::iterator it = m_evtMap->find(static_cast<short>(id)); \
if (it != m_evtMap->end()) return *static_cast<Event<T>*>(it->second); \
} \
qpASSERT(false); \
qpNewPtrEx(p, Event<T>); \
return *std::auto_ptr<Event<T>>(p); \
} \
protected: \
typedef std::map<short, void*> EventMap; \
std::auto_ptr<EventMap> m_evtMap; \
std::bitset<Y> m_evtFlag;
std::bitset的使用,可以判斷相應訊息是否註冊,不用每一個訊息都進入一次Event了,但由於使用map來查詢訊息,效率上還是下降了。
沒辦法:只能用時間換空間!