xresizable.h

来自「Visual_C++[1].NET_Bible1 Visual_C++宝典书中」· C头文件 代码 · 共 269 行

H
269
字号
// XResizable.h : header file
//

#ifndef _TRESIZABLE_H_
#define _TRESIZABLE_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// These flags indicate how resizing is to be done
enum EResizeFlags {
	//
	// we get the difference between new and old sizes
	// and apply that difference in some propertion
	// the suffix of the RESIZE_XXX flags determine
	// how that proportion is calculated
	//
	// for left/right/width flags the suffix means:
	//
	// _LFIX	means there is no change
	// _RFIX	means that the full difference in sizes is applied
	// _LPROP	means we work out the ratio of left coord of
	//			control to total width and apply that proportion of
	//			the difference
	// _RPROP	as above, but from the right coord
	// _CPROP	as above, but from the centre of the control
	//
	// in addition for the width flags
	// _PROP	makes the left LPROP and the right RPROP so the control
	//			moves and grows propertionally to the change
	//
	// similarly for the top/bottom/heigght flags
	//
	RESIZE_LEFT_LFIX = 00000,
	RESIZE_LEFT_LPROP = 00001,
	RESIZE_LEFT_RPROP = 00002,
	RESIZE_LEFT_CPROP = RESIZE_LEFT_LPROP|RESIZE_LEFT_RPROP,
	RESIZE_LEFT_RFIX = 00004,
	RESIZE_LEFT_FLAGS = RESIZE_LEFT_LPROP|RESIZE_LEFT_RPROP|RESIZE_LEFT_RFIX,

	RESIZE_RIGHT_LFIX = 00000,
	RESIZE_RIGHT_LPROP = 00010,
	RESIZE_RIGHT_RPROP = 00020,
	RESIZE_RIGHT_CPROP = RESIZE_RIGHT_LPROP+RESIZE_RIGHT_RPROP,
	RESIZE_RIGHT_RFIX = 00040,
	RESIZE_RIGHT_FLAGS = RESIZE_RIGHT_LPROP|RESIZE_RIGHT_RPROP|RESIZE_RIGHT_RFIX,

	RESIZE_WIDTH_LFIX = RESIZE_LEFT_LFIX|RESIZE_RIGHT_LFIX,
	RESIZE_WIDTH_LPROP = RESIZE_LEFT_LPROP|RESIZE_RIGHT_LPROP,
	RESIZE_WIDTH_RPROP = RESIZE_LEFT_RPROP|RESIZE_RIGHT_RPROP,
	RESIZE_WIDTH_CPROP = RESIZE_LEFT_CPROP|RESIZE_RIGHT_CPROP,
	RESIZE_WIDTH_RFIX = RESIZE_LEFT_RFIX|RESIZE_RIGHT_RFIX,
	RESIZE_WIDTH_PROP = RESIZE_LEFT_LPROP|RESIZE_RIGHT_RPROP,
	RESIZE_WIDTH_FLAGS = RESIZE_LEFT_FLAGS|RESIZE_RIGHT_FLAGS,
	
	RESIZE_TOP_TFIX = 00000,
	RESIZE_TOP_TPROP = 00100,
	RESIZE_TOP_BPROP = 00200,
	RESIZE_TOP_CPROP = RESIZE_TOP_TPROP|RESIZE_TOP_BPROP,
	RESIZE_TOP_BFIX = 00400,
	RESIZE_TOP_FLAGS = RESIZE_TOP_TPROP|RESIZE_TOP_BPROP|RESIZE_TOP_BFIX,

	RESIZE_BOTTOM_TFIX = 00000,
	RESIZE_BOTTOM_TPROP = 01000,
	RESIZE_BOTTOM_BPROP = 02000,
	RESIZE_BOTTOM_CPROP = RESIZE_BOTTOM_TPROP|RESIZE_BOTTOM_BPROP,
	RESIZE_BOTTOM_BFIX = 04000,
	RESIZE_BOTTOM_FLAGS = RESIZE_BOTTOM_TPROP|RESIZE_BOTTOM_BPROP|RESIZE_BOTTOM_BFIX,

	RESIZE_HEIGHT_TFIX = RESIZE_TOP_TFIX|RESIZE_BOTTOM_TFIX,
	RESIZE_HEIGHT_TPROP = RESIZE_TOP_TPROP|RESIZE_BOTTOM_TPROP,
	RESIZE_HEIGHT_BPROP = RESIZE_TOP_BPROP|RESIZE_BOTTOM_BPROP,
	RESIZE_HEIGHT_CPROP = RESIZE_TOP_CPROP|RESIZE_BOTTOM_CPROP,
	RESIZE_HEIGHT_BFIX = RESIZE_TOP_BFIX|RESIZE_BOTTOM_BFIX,
	RESIZE_HEIGHT_PROP = RESIZE_TOP_TPROP|RESIZE_BOTTOM_BPROP,
	RESIZE_HEIGHT_FLAGS = RESIZE_TOP_FLAGS|RESIZE_BOTTOM_FLAGS,
	
	// These are special/common combinations of flags
	// proportional
	RESIZE_PROP = RESIZE_WIDTH_PROP|RESIZE_HEIGHT_PROP,
	// keep in same position relative to top left
	RESIZE_NONE = RESIZE_WIDTH_LFIX|RESIZE_HEIGHT_TFIX,
	// single line control (fixed height) anchored to the top
	RESIZE_SINGLE_LINE_AT_TOP = RESIZE_WIDTH_PROP|RESIZE_HEIGHT_TFIX,
	// single line control (fixed height) anchored to the centre
	RESIZE_SINGLE_LINE_AT_CENTRE = RESIZE_WIDTH_PROP|RESIZE_HEIGHT_CPROP,
	// single line control (fixed height) anchored to the bottom
	RESIZE_SINGLE_LINE_AT_BOTTOM = RESIZE_WIDTH_PROP|RESIZE_HEIGHT_BFIX,
	// single line control RJ (fixed height) anchored to the top
	RESIZE_SINGLE_LINE_AT_TOP_RJ = RESIZE_WIDTH_RPROP|RESIZE_HEIGHT_TFIX,
	// single line control RJ (fixed height) anchored to the centre
	RESIZE_SINGLE_LINE_AT_CENTRE_RJ = RESIZE_WIDTH_RPROP|RESIZE_HEIGHT_CPROP,
	// single line control RJ (fixed height) anchored to the bottom
	RESIZE_SINGLE_LINE_AT_BOTTOM_RJ = RESIZE_WIDTH_RPROP|RESIZE_HEIGHT_BFIX,
	// full change
	RESIZE_FULL_CHANGE = RESIZE_LEFT_LFIX|RESIZE_RIGHT_RFIX|RESIZE_TOP_TFIX|RESIZE_BOTTOM_BFIX,
};

#include "XMessageMapForTemplates.h"
#include "XWndMultipleInheritance.h"

class CXResizable : public CXWndMultipleInheritance {
	// Construction
public:
	CXResizable(CWnd* pWnd) : CXWndMultipleInheritance(pWnd) {}
	// is this resizable?
public:
	virtual bool IsResizable() const;
	// get the previous, current and initial client and windows rects
public:
	void GetClientRectWas(CRect& rc) const { rc = m_rcWas; }
	void GetClientRectNow(CRect& rc) const { rc = m_rcNow; }
	void GetClientRectIni(CRect& rc) const { rc = m_rcIni; }
	void GetWindowRectWas(CRect& rc) const { rc = m_rwWas; }
	void GetWindowRectNow(CRect& rc) const { rc = m_rwNow; }
	void GetWindowRectIni(CRect& rc) const { rc = m_rwIni; }
	// draw the gripper
protected:
	virtual void GetGripperRect(CRect& rcGripper);
	virtual void DrawGripper(CDC* pDC);
protected:
	virtual bool IsResizeDirectly() const;
	// message map functions
protected:
	void OnSize(UINT nType, int cx, int cy) ;
	UINT OnNcHitTest(CPoint point);
	bool OnPaint();
	void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
	// control resizing
protected:
	virtual void ResizeControls();
	virtual void ResizeControl(UINT id,CWnd* pControl,CRect& rcControl, const CSize& szNow, const CSize& szWas, const CSize& szIni, const CSize& szDelta);
	virtual void ResizeControlUsingFlags(UINT id,CWnd* pControl,CRect& rcControl, const CSize& szNow, const CSize& szWas, const CSize& szIni, const CSize& szDelta);
	virtual UINT GetResizeFlags(UINT id,CWnd* pControl,CRect& rcControl, const CSize& szNow, const CSize& szWas, const CSize& szIni, const CSize& szDelta);
	virtual UINT GetSmartResizeFlags(UINT id,CWnd* pControl,CRect& rcControl, const CSize& szNow, const CSize& szWas, const CSize& szIni, const CSize& szDelta);
	// callbacks (and data) for resizing
private:
	// struct or pass info to EnumChildProp
	struct SResizeInfo {
		CSize szNow;
		CSize szWas;
		CSize szIni;
		CXResizable* pResizable;
		HDWP defer;
	};
	static BOOL CALLBACK EnumChildProc_ResizeControls(HWND hwnd, LPARAM lParam);
	static BOOL CALLBACK EnumChildProc_CountControls(HWND hwnd, LPARAM lParam);
	// cached rectangles for client/window
private:
	CRect m_rcNow;
	CRect m_rcWas;
	CRect m_rcIni;
	CRect m_rwNow;
	CRect m_rwWas;
	CRect m_rwIni;
};

/////////////////////////////////////////////////////////////////////////////
// TXResizable dialog

#pragma warning (disable: 4355) // 'this' : used in base member initializer list

template <class TDIALOGORPAGE>
class TXResizable : public TDIALOGORPAGE, public CXResizable {
	// Construction (all sorts)
public:
	TXResizable()
		: TDIALOGORPAGE()
		, CXResizable(this)
	{}
	TXResizable(UINT nIDTemplate)
		: TDIALOGORPAGE(nIDTemplate)
		, CXResizable(this)
	{}
	TXResizable(LPCTSTR lpszTemplateName)
		: TDIALOGORPAGE(lpszTemplateName)
		, CXResizable(this)
	{}
	TXResizable(UINT nIDTemplate, UINT nIDCaption)
		: TDIALOGORPAGE(nIDTemplate,nIDCaption)
		, CXResizable(this)
	{}
	TXResizable(LPCTSTR lpszTemplateName, UINT nIDCaption)
		: TDIALOGORPAGE(lpszTemplateName,nIDCaption)
		, CXResizable(this)
	{}
	TXResizable(UINT nIDTemplate, CWnd* pParentWnd)
		: TDIALOGORPAGE(nIDTemplate,pParentWnd)
		, CXResizable(this)
	{}
	TXResizable(LPCTSTR lpszTemplateName, CWnd* pParentWnd)
		: TDIALOGORPAGE(lpszTemplateName,pParentWnd)
		, CXResizable(this)
	{}
	
	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(TXResizable)
	//}}AFX_VIRTUAL
	
	// Implementation
public:
	virtual ~TXResizable() {}
	// Generated message map functions
protected:
	//{{AFX_MSG(TXResizable)
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg UINT OnNcHitTest(CPoint point);
	afx_msg void OnPaint();
	afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP_FOR_TEMPLATE()
};

#pragma warning (default: 4355) // 'this' : used in base member initializer list

/////////////////////////////////////////////////////////////////////////////
// the body of TXResizable is inline in this .h file
// because it is a template
/////////////////////////////////////////////////////////////////////////////

BEGIN_MESSAGE_MAP_FOR_TEMPLATE(TXResizable<TDIALOGORPAGE>, TDIALOGORPAGE)
//{{AFX_MSG_MAP(TXResizable)
ON_WM_SIZE()
ON_WM_NCHITTEST()
ON_WM_PAINT()
ON_WM_GETMINMAXINFO()
//}}AFX_MSG_MAP
END_MESSAGE_MAP_FOR_TEMPLATE()

/////////////////////////////////////////////////////////////////////////////
// CAutoToolTips message handlers

template <class TDIALOGORPAGE> void TXResizable<TDIALOGORPAGE>::OnSize(UINT nType, int cx, int cy) {
	// we call the base class, then CXResizable (which does the resizing of controls)
	TDIALOGORPAGE::OnSize(nType, cx, cy);
	CXResizable::OnSize(nType,cx,cy);
}

template <class TDIALOGORPAGE> UINT TXResizable<TDIALOGORPAGE>::OnNcHitTest(CPoint point) {
	// first ask CXResizable for the hit point (it may be on the corner gripper)
	UINT nHit = CXResizable::OnNcHitTest(point);
	// if it isn't then go to the base class
	if (nHit == HTNOWHERE) {
		nHit = TDIALOGORPAGE::OnNcHitTest(point);
	}
	return nHit;
}

template <class TDIALOGORPAGE> void TXResizable<TDIALOGORPAGE>::OnPaint() {
	// let CXResizable do the painting if it wants to
	if (! CXResizable::OnPaint()) {
		// if it didn't do it, then give the base class a chance
		TDIALOGORPAGE::OnPaint();
	}
}

template <class TDIALOGORPAGE> void TXResizable<TDIALOGORPAGE>::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) {
	// we call the base class, then CXResizable (which works out the minimum size based on original size)
	TDIALOGORPAGE::OnGetMinMaxInfo(lpMMI);
	CXResizable::OnGetMinMaxInfo(lpMMI);
}

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?