Click here to Skip to main content
15,891,926 members
Articles / Desktop Programming / MFC

Customizable Window Layouts

Rate me:
Please Sign up or sign in to vote.
5.00/5 (16 votes)
28 Jul 2008CPOL6 min read 40.1K   1.8K   51  
A class to facilitate user defined dialog and window control layouts.
////////////////////////////////////////////////
// positionwnd.h
//
// 2008 Roland Trainor
//

#ifndef _POSITIONWND_H_
#define _POSITIONWND_H_

#include "xmlfile.h"

#include <map>
#include <vector>

/////////////////////////////////////////////////////////////////////////////
// Forward declarations
class CPositionWnd;

/////////////////////////////////////////////////////////////////////////////
// CPositionWndXMLConfigParser
//
// Handles processing a CPositionWnd configuration.
//

class CPositionWndXMLConfigParser : public CXMLParser
{
public:
    // CWinInfo...
    class CWinInfo
    {
    public:
        CWinInfo();
        ~CWinInfo();
        CWinInfo* GetWinInfoForWindow(LPCSTR lpszId);

        CWinInfo* pParent;
        CRect rectPlacement;
        int nWidth, nHeight;
        CString strId;
        BOOL bTLTopLock, bTLLeftLock, bBRBottomLock, bBRRightLock;
        typedef std::map<CString, CWinInfo*> MAP_WININFOS;
        MAP_WININFOS m_mapWinInfos;
    };

    // Construction
    CPositionWndXMLConfigParser();

    // Access...
    operator CWinInfo&();

protected:
    // Processing...
    virtual void* OnElementBegin(LPCSTR lpszElementTag, void* pUserData);
    virtual void* OnElementEnd(LPCSTR lpszElementTag, void* pUserData);
    virtual void* OnProperty(LPCSTR lpszPropertyName, LPCSTR lpszPropertyValue, void* pUserData);
    
    CWinInfo*   m_pCurWinInfo;
    CWinInfo    m_winInfoRoot;
};


/////////////////////////////////////////////////////////////////////////////
// CPositionWndContainer
//

class CPositionWndContainer : public CWnd
{
public:
    // Construction/destruction...
    CPositionWndContainer();
    ~CPositionWndContainer();

    // Creation...
    BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);

    // Persistance...
    void LoadConfigFromString(LPCSTR lpszConfig);
    CString SaveConfigToString(void);

    // Attachement/detachment...
    void AttachWindow(CWnd* pWnd, BOOL bIncludeChildren = TRUE);
    void DetachWindow(CWnd* pWnd);
    void DetachAllWindows(void);

	virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);

    // Events...
	//{{AFX_MSG(CPositionWndContainer)
	afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnPaint();
	//}}AFX_MSG

    DECLARE_MESSAGE_MAP()

protected:
    // Persistance...
    void LoadConfigFromStringInternal(CPositionWndXMLConfigParser::CWinInfo& parentWinInfo);
    CString SaveConfigToStringInternal(int nLevel);

    typedef std::map<CWnd*, CPositionWnd*>  MAP_WND_TO_POSWND;
    
    CFont               m_font;
    MAP_WND_TO_POSWND   m_map;
    COLORREF            m_crBackground;
    CRect               m_rectOldSize;
    static CString      m_strClassName;
};

/////////////////////////////////////////////////////////////////////////////
// CPositionWnd
//
// Wrapper around a CWnd with the ability to allow the user to move and resize 
//  the window.
//

class CPositionWnd
{
    friend CPositionWndContainer;

public:
    // Construction/destruction...
    CPositionWnd();
    ~CPositionWnd();

    // Access...
    void SubclassWindowEx(CWnd* pWindow = NULL, BOOL bIncludeChildren = TRUE);
    void UnSubclassWindowEx(void);
    int GetLayoutWidth(void);
    int GetLayoutHeight(void);

    // Persistance...
    void LoadConfigFromString(LPCSTR lpszConfig);
    CString SaveConfigToString(void);
    void LoadConfigFromStringInternal(CPositionWndXMLConfigParser::CWinInfo& parentWinInfo);
    CString SaveConfigToStringInternal(int nLevel);

protected:
    // Events...
    LRESULT WindowProcInt(UINT uMsg, WPARAM wParam, LPARAM lParam);
    LRESULT DialogProcInt(UINT uMsg, WPARAM wParam, LPARAM lParam);
public:
    void OnSize(UINT nType, int cx, int cy);
protected:
    void OnPaint();
    void OnPopupMenu(void);
    BOOL OnRButtonDown(UINT nFlags, CPoint point);
    BOOL OnLButtonDown(UINT nFlags, CPoint point);
    BOOL OnLButtonUp(UINT nFlags, CPoint point);
    BOOL OnMouseMove(UINT nFlags, CPoint point);

    void OnEditLButtonDown(UINT nFlags, CPoint point);
    void OnEditLButtonUp(UINT nFlags, CPoint point);
    void OnEditMouseMove(UINT nFlags, CPoint point);

    void EnterEditMode(BOOL bHideChildren = FALSE);
    void ExitEditMode(void);

    void EnterMoveMode(void);
    void ExitMoveMode(void);

    void EnterSizeMode(void);
    void ExitSizeMode(void);

    void UpdateCursor(CPoint point);

    void UpdateStickyMovePoint(int& nX, int& nY);
    void UpdateStickySizePoint(int& nX, int& nY);

    void UpdateSnapToMovePoint(int& nX, int& nY);
    void UpdateSnapToSizePoint(int& nX, int& nY);

    void SetWindowPosFromLayout(void);
    void UpdateLayoutInformationFromWindow(void);

    typedef std::vector<CPositionWnd*>      VECT_CHILD_WINDOWS;
    typedef std::map<HWND, CPositionWnd*>   MAP_HWND_TO_WND;

    // Data...
    CWnd*               m_pWnd;
    WNDPROC             m_pWndProc;
    WNDPROC             m_pDlgProc;
    BOOL                m_bEditing;
    BOOL                m_bMoving;
    BOOL                m_bSizing;
    BOOL                m_bTLTopLock;
    BOOL                m_bTLLeftLock;
    BOOL                m_bBRBottomLock;
    BOOL                m_bBRRightLock;
    BOOL                m_bSticky;
    BOOL                m_bHidingChildren;
    BOOL                m_bSnapTo;
    HCURSOR             m_oldCursor;
    HCURSOR             m_curCursor;
    CRect               m_rectOldSize;
    CRect               m_rectMoveControl;
    CRect               m_rectSizeControl;
    CRect               m_rectTLTopLockControl;
    CRect               m_rectTLLeftLockControl;
    CRect               m_rectBRBottomLockControl;
    CRect               m_rectBRRightLockControl;
    CRect               m_rectSelected;
    CPoint              m_pointSelected;
    CRect               m_rectLayoutPositions;
    int                 m_nLayoutWidth;
    int                 m_nLayoutHeight;
    VECT_CHILD_WINDOWS  m_vectChildWindows;

protected:
    // Statics...
    static void CreateCursors(void);
    static void CleanupCursors(void);
    static void SubclassWindow(HWND hwnd, CPositionWnd* pWnd);
    static void UnSubclassWindow(HWND hwnd, CPositionWnd* pWnd);
    static LRESULT CALLBACK MasterWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    static LRESULT CALLBACK MasterDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

    static HCURSOR          m_cursorTopLock;
    static HCURSOR          m_cursorTopUnLock;
    static HCURSOR          m_cursorLeftLock;
    static HCURSOR          m_cursorLeftUnLock;
    static HCURSOR          m_cursorBottomLock;
    static HCURSOR          m_cursorBottomUnLock;
    static HCURSOR          m_cursorRightLock;
    static HCURSOR          m_cursorRightUnLock;
    static MAP_HWND_TO_WND  m_mapWindows;
};

#endif //_POSITIONWND_H_

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions