- code.zip
- emilio
- Progetti di Visual studio
- Article
- GE_NLIB_3
|
//DockMan.h
// does area management
#pragma once
#include "NLib/RegisterTypes.h"
namespace GE_{namespace NWin{
//temporary window hide
struct STmpWndHide
{
private:
HWND _hwnd;
bool _bShow;
public:
STmpWndHide(HWND hWnd)
{ _hwnd = hWnd; _bShow = 0!=ShowWindow(hWnd, SW_HIDE); }
~STmpWndHide()
{ ShowWindow(_hwnd, (_bShow)? SW_SHOW: SW_HIDE); }
};
//child window, atoadapting itself to a given area
interface IAutoLayout
{
//redo the layout. modify the ractangle to the remaining area
virtual void DoLayout(LPRECT lprc, HWND hMoving)=0;
virtual S_Sides::e_side GetSideAlignment()=0;
};
//toplevel window, handling layouts
interface ILayoutManager
{
virtual void RedoLayout(HWND hMoving)=0;
struct Autonotify: public NUtil::SNmHdr<Autonotify>
{//sent as notification to require layout recomputation
LPRECT _lprc; //poiter to the ayout rectangle
//pass the initial rectangle, return as the remaining part
HWND _hwndMoving; //the window that causes the layout
};
static ILayoutManager* Get(HWND hWnd);
};
//Giving to a window the capability to dock bars around
class EDockBar:
public EWnd,
public IAutoLayout,
public S_Sides
{
public:
//a window docked to this bar
struct XElem:
public EWnd,
public S_Sides
{
SPlace _plPlacement; //the obtained placement
SPlace _plWantedHorz; //the wanted placement
SPlace _plWantedVert;
SPlace _plWantedFloat;
SPlace& _plWanted(e_side side)
{ return isHorz(side)? _plWantedHorz: isVert(side)? _plWantedVert: _plWantedFloat; }
e_side _sdLastDocked;
UINT _nDragging;
SPoint _pntBegin;
EDockBar* _pBeginParent;
XElem();
virtual ~XElem() { Detach(); }
LRESULT OnNcLButtonDown(UINT hit, SPoint& point, bool& bHandled);
LRESULT OnMouseMove(UINT flag, SPoint& point, bool& bHandled);
LRESULT OnLButtonUp(UINT flag, SPoint& point, bool& bHandled);
LRESULT OnNcLButtonDblClk(UINT hittest, SPoint& point, bool& bHandled);
BEGIN_MSG_MAP(XElem)
GE_WM_NCLBUTTONDOWN(OnNcLButtonDown)
GE_WM_MOUSEMOVE(OnMouseMove)
GE_WM_LBUTTONUP(OnLButtonUp)
GE_WM_NCLBUTTONDBLCLK(OnNcLButtonDblClk)
GE_FORWARD_COMMANDS(GetParent(*this))
END_MSG_MAP()
};
typedef XElem* PElem;
typedef std::list<PElem> TLstElem;
protected:
e_side _side;
TLstElem _lstElem;
protected:
void DoInnerLayout(LPRECT lprc, HWND hMoving);
LRESULT OnParentNotifyDestroy(UINT nID, HWND hChild, bool& bHandled);
public:
virtual void DoLayout(LPRECT lprc, HWND hMoving);
virtual S_Sides::e_side GetSideAlignment() { return _side; }
HWND Create(HINSTANCE hInst, e_side side, HWND hParent);
void AddElement(HWND hWnd, LPCRECT lpPlacement);
void RemoveElement(HWND hWnd);
public:
BEGIN_MSG_MAP(EDockBar)
GE_WM_PARENTNOTIFY_DESTROY(OnParentNotifyDestroy)
GE_FORWARD_COMMANDS(GetParent(*this))
END_MSG_MAP()
//EWnd overrides
virtual ~EDockBar() { Detach(); }
};
//Giving a window the capability to fill an area
class EClientWnd:
public EWnd,
public IAutoLayout
{
public:
//IAutoayout
virtual void DoLayout(LPRECT lprc, HWND hMoving);
virtual S_Sides::e_side GetSideAlignment() { return S_Sides::sd_inside;}
//EWnd
virtual void OnAddRef(TRefCount* pRC);
virtual void OnRelease(TRefCount* pRC);
public:
BEGIN_MSG_MAP(EClientWnd)
END_MSG_MAP()
};
//translating sizing into layout management
struct XLayoutProvider:
public EWnd,
public ILayoutManager
{
private:
SRect _rcFree;
bool _bDoingLayout;
public:
LPCRECT GetFreeRect() const { return _rcFree; }
LRESULT OnSize(UINT flags, const NWin::SSize& sz, bool& bHandled);
LRESULT OnEraseBkg(HDC hDC, bool& bHandled);
XLayoutProvider() { _bDoingLayout = false; }
virtual ~XLayoutProvider() { Detach(); }
BEGIN_MSG_MAP(XLayoutProvider)
GE_WM_SIZE(OnSize)
GE_WM_ERASEBKGND(OnEraseBkg)
END_MSG_MAP()
//ILayoutManager
virtual void RedoLayout(HWND hMoving);
//helper
static XLayoutProvider* Get(HWND hWnd); //gets or create a CLayoutprovider for a given HWND
};
//giving a frame the capability to hav a client and dockbars
class EDockBarManager:
public EWnd,
public S_Sides
{
private:
EClientWnd _clientwindow;
EDockBar _barleft, _bartop, _barright, _barbottom;
EDockBar& bar(e_side side) { return (&_barleft)[side];}
protected:
LRESULT OnILayoutManagerAutonotify(int nID, ILayoutManager::Autonotify& nm, bool& bHandled);
public:
EDockBarManager();
BEGIN_MSG_MAP(EDockFrameWnd)
GE_FORWARD_COMMANDS(_clientwindow)
GE_NOTIFY_CODE_REGISTREDHANDLER(OnILayoutManagerAutonotify, ILayoutManager::Autonotify)
END_MSG_MAP()
void SetClient(HWND hWndClient);
void SetBars(f_sides flg = -1); //all bars
void DockElement(HWND hwnd, e_side side, LPCRECT lprcPlacement=NULL)
{ if (!!bar(side)) bar(side).AddElement(hwnd, lprcPlacement); }
void UndockRemoveElement(HWND hWnd)
{ _barleft.RemoveElement(hWnd); _bartop.RemoveElement(hWnd); _barright.RemoveElement(hWnd); _barbottom.RemoveElement(hWnd); }
//EWnd overrides
virtual ~EDockBarManager() { Detach(); }
};
}}
#ifdef GE_FORCEINLINE
#include "DockMan.cpp"
#endif
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Born and living in Milan (Italy), I'm an engineer in electronics actually working in the ICT department of an important oil/gas & energy company as responsible for planning and engineering of ICT infrastructures.
Interested in programming since the '70s, today I still define architectures for the ICT, deploying dedicated specific client application for engineering purposes, working with C++, MFC, STL, and recently also C# and D.