我做了个MFC的dlg, 现在想使用这个代码的功能, 如果直接派生, 会有一大堆错误, 而且是我无法解决的, 最终显示_model 没有定义...我已经把这段代码改成MFC的了, 但是问题来了, 他使用了模板, 也就是说, 其他Cwnd类型的窗口(对话框) 只需要派生他, 就可以实现他的功能.T* pT = static_cast<T*>(this); 这一句太奇妙了, 可是我MFC怎么用呢?
//////////////////////////////////////////////////////////////////////////////////////////////
// ATL implementation for AppBar support
#pragma once#ifndef __cplusplus
#error ATL requires C++ compilation (use a .cpp suffix)
#endif#ifndef __ATLBASE_H__
#error appbar.h requires atlbase.h to be included first
#endif#ifndef __ATLAPP_H__
#error appbar.h requires atlapp.h to be included first
#endif#ifndef __ATLWIN_H__
#error appbar.h requires atlwin.h to be included first
#endif#ifndef __ATLGDI_H__
#error appbar.h requires atlgdi.h to be included first
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////
// class CAppBar
// give derived window the ability to dock on any side of the screen
// gain behavior similar with Windows Task bar
//
// Author: Yao Zhifeng
// Contact: [email protected]
//
// Usage:
// 1.use this class as a base class
// 2.use CHAIN_MSG_MAP to chain message to this class
// 3.call InitAppBar in the OnCreate or OnInitDialog function
// 4.(optional) call DockAppBar to dock the window to any side of the screen
// 5.(optional) call SetAutoHide to change the autohide behavior
// 6.(optional) call SetKeepSize to enable keeping original window size when docking on the screen
// 7.(optional) if you want to do any specific operation when docking side changed, 
//   override OnDockingChanged function in ATL way
//
// template argument:
// T: derived class, must also derived from CWindowImpl directly or indirectly
//
template <class T>
class CAppBar
{
public: //constants
enum DockingSide
{
APPBAR_DOCKING_NONE = 0x00,
APPBAR_DOCKING_LEFT = 0x01,
APPBAR_DOCKING_RIGHT = 0x02,
APPBAR_DOCKING_TOP = 0x04,
APPBAR_DOCKING_BOTTOM = 0x08,
APPBAR_DOCKING_ALL = 0x0f };private:
CRect m_rcOriginal; //window rect while not docking on any side
CRect m_rcStartDraging;
CRect m_rcLastDraging;
CPoint m_ptStartDraging;
bool m_bDraging; UINT m_uCallback; //callback message for calling by system
UINT m_uFlags; //docking flags
UINT m_uCurrentDockingSide;
bool m_bRegistered; //if registered
bool m_bAutoHide;
bool m_bHiding;
bool m_bKeepSize; UINT m_uHidingTimer;
UINT m_uShowingTimer;public:
CAppBar()
{
m_uCallback = ::RegisterWindowMessage("AppBar Callback Message");
m_uFlags = APPBAR_DOCKING_NONE;
m_uCurrentDockingSide = APPBAR_DOCKING_NONE;
m_bRegistered = false;
m_bDraging = false;
m_bAutoHide = false;
m_bHiding = false;
m_uHidingTimer = 1;
m_uShowingTimer = 2;
m_bKeepSize = false;
}
~CAppBar()
{
} BEGIN_MSG_MAP(CAppBar)
MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
MESSAGE_HANDLER(WM_NCHITTEST, OnNcHitTest)
MESSAGE_HANDLER(WM_TIMER, OnTimer)
MESSAGE_HANDLER(m_uCallback, OnAppBarNotify)
END_MSG_MAP()public:
//////////////////////////////////////////////////////////////////////////
// Initialize
// must be called right after window be created
void InitAppBar(UINT uFlags=APPBAR_DOCKING_ALL, bool bAutoHide=false, bool bKeepSize=false)
{
T* pT = static_cast<T*>(this); m_uFlags = uFlags;
m_bAutoHide = bAutoHide;
m_bKeepSize = bKeepSize; //record the original window rect
pT->GetWindowRect(&m_rcOriginal); } ///////////////////////////////////////////////////////////
//change the autohide behavior
void SetAutoHide(bool bAutoHide)
{
if (m_bAutoHide != bAutoHide)
{
UINT uCurrentSide = m_uCurrentDockingSide;
RegisterAppBar(false);
m_bAutoHide = bAutoHide;
DockAppBar(uCurrentSide);
}
} ///////////////////////////////////////////////////////////
//change the keepsize behavior
void SetKeepSize(bool bKeepSize)
{
if (m_bKeepSize != bKeepSize)
{
UINT uCurrentSide = m_uCurrentDockingSide;
RegisterAppBar(false);
m_bKeepSize = bKeepSize;
DockAppBar(uCurrentSide);
}
} //////////////////////////////////////////////////////////
// dock window to one side of the screen
void DockAppBar(UINT uFlag)
{
T* pT = static_cast<T*>(this); if (uFlag == APPBAR_DOCKING_NONE)
{
//Undock the window
RegisterAppBar(false);
m_uCurrentDockingSide = uFlag;
pT->MoveWindow(&m_rcOriginal);
}
else
{
//docking flag must match the initial flags
ATLASSERT((uFlag & m_uFlags)!=0); if (!m_bRegistered)
RegisterAppBar(true); //record the original position before becoming an appbar
if (m_uCurrentDockingSide == APPBAR_DOCKING_NONE)
pT->GetWindowRect(&m_rcOriginal); //autohide processing
APPBARDATA abd;
abd.cbSize = sizeof(abd);
abd.hWnd = pT->m_hWnd;
abd.uEdge = GetEdge(uFlag);
abd.lParam = m_bAutoHide ? TRUE:FALSE; ::SHAppBarMessage(ABM_SETAUTOHIDEBAR, &abd); //set area and move window
RECT rc = SetAppBarPos(uFlag);
m_uCurrentDockingSide = uFlag; //for autohide&keepsize setting
//reajust the window position
if (m_bAutoHide && m_bKeepSize)
rc = QueryDockingRect(uFlag);
pT->MoveWindow(&rc); pT->OnDockingChanged(uFlag); //start the hiding timer to hide the autohide appbar
if (m_bAutoHide)
{
m_uHidingTimer = pT->SetTimer(m_uHidingTimer, 500);
}
}
} //////////////Message Handlers///////////////////////////////////////////////////// LRESULT OnWindowPosChanged(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
T* pT = static_cast<T*>(this); WINDOWPOS *pWindowPos = (WINDOWPOS*)lParam;

//default processing
::DefWindowProc(pT->m_hWnd, uMsg, wParam, lParam); if (m_uCurrentDockingSide==APPBAR_DOCKING_NONE)
{
//update original rect
pT->GetWindowRect(&m_rcOriginal);
}
else
{
if (!m_bHiding)
{
//if window being sized when docked, update appbar area
if (m_uCurrentDockingSide==APPBAR_DOCKING_LEFT || m_uCurrentDockingSide==APPBAR_DOCKING_RIGHT)
{
m_rcOriginal.right = m_rcOriginal.left + pWindowPos->cx;
SetAppBarPos(m_uCurrentDockingSide);
}
else if (m_uCurrentDockingSide==APPBAR_DOCKING_TOP || m_uCurrentDockingSide==APPBAR_DOCKING_BOTTOM)
{
m_rcOriginal.bottom = m_rcOriginal.top + pWindowPos->cy;
SetAppBarPos(m_uCurrentDockingSide);
}
}
} if (m_bRegistered && m_uCurrentDockingSide!=APPBAR_DOCKING_NONE)
{
APPBARDATA abd;
memset(&abd, 0, sizeof(APPBARDATA));
abd.cbSize = sizeof(abd);
abd.hWnd = pT->m_hWnd; ::SHAppBarMessage(ABM_WINDOWPOSCHANGED, &abd);
} return 0;
}

解决方案 »

  1.   

    后面的代码我就不贴了, 严重BScsdn, 代码过长 -_-
      

  2.   

    T* pT = static_cast<T*>(this);   
    传统面向对象的MFC架构下怎么做?当然是virtual函数.但virtual函数带来速度和空间开销.这也是为什么wtl和mfc比   
    时会被称为轻量级..等等的原因. WTL和MFC在对c++的运用上几乎不是一路的。WTL基本的特性是基于ATL,而设计ATL就是为了将接口和实现分开,你上面所提的内容都是接口部分,而且T* pT = static_cast<T*>(this); 这种典型的多种继承,对子类进行绑定的做法,要转到MFC不好搞,你还是试试Virtual函数吧,或者将对像的构建和销毁移出来就可以不用这一句了.
      

  3.   

    这个appbar网上有对应的SDK版本,比较容易移植成MFC,你贴的是WTL的。到CPPblog上搜!
      

  4.   


    那是因为我放弃了那个WTL, 然后只有他一个人回答,我就把分给他了