📄 atlautosizedlg.h
字号:
*/
bool operator !=(int iVal) const
{
return m_iVal != iVal;
}
/// Greater than operator
/** \param iVal Value to be compared with
*/
bool operator >(int iVal) const
{
return m_iVal > iVal;
}
/// Greater-or-equal operator
/** \param iVal Value to be compared with
*/
bool operator >=(int iVal) const
{
return m_iVal >= iVal;
}
/// Lesser than operator
/** \param iVal Value to be compared with
*/
bool operator <(int iVal) const
{
return m_iVal < iVal;
}
/// Lesser-or-equal operator
/** \param iVal Value to be compared with
*/
bool operator <=(int iVal) const
{
return m_iVal <= iVal;
}
/// Add to the integer
/** \param iVal Value to be added
*/
int_no& operator+=(int iVal)
{
__int64 iTmp = (__int64)m_iVal + iVal;
if (iTmp > INT_MAX) {
m_iVal = INT_MAX;
} else if (iTmp < INT_MIN) {
m_iVal = INT_MIN;
} else {
m_iVal = (int)iTmp;
}
return *this;
}
/// Subtract from the integer
/** \param iVal Value to be subtracted
*/
int_no& operator-=(int iVal)
{
return operator-=(0 - iVal);
}
/// Add operator
/** \param iVal Value to be added
*/
const int operator+(int iVal) const
{
int_no iRes = *this;
iRes += iVal;
return iRes;
}
/// Subtract operator
/** \param iVal Value to be subtracted
*/
const int operator-(int iVal) const
{
return operator+(0 - iVal);
}
};
//
/// The main class for the positioning and sizing of the ctrls.
/** You MUST derive your class from this class. You CAN derive your class from CScrollImpl.
* You MUST chain this class to the BEGIN_MSG_MAP()/END_MSG_MAP(). You SHOULD chain this class
* before chaining CScrollImpl. You MUST remember to use the full name CAutoSizeWindow<T, ...> when
* using methods (hint: DoPaint) present in multiple base classes.
* You MUST manually call CAutoSizeWindow<T, ...>::DoPaint() from T::DoPaint() if you derive your class
* from CScrollImpl. You MUST let the handling of some messages proceed and not stop it unless you know
* what you are doing. This class processes WM_CREATE/WM_INITDIALOG, WM_GETMINMAXINFO, WM_PAINT, WM_SIZE.
* Note that if you want to handle WM_PAINT you MUST use a T::DoPaint method. This class will stop the
* handling of the WM_PAINT message.
* \param T The name of the derived class
* \param t_bAutoMinSize If true this class will automatically handle the minimum and maximum size of the window
*/
template <class T, bool t_bAutoMinSize = true>
class CAutoSizeWindow
{
protected:
typedef CAutoSizeWindow<T> thisClass; ///< A shortcut to the complete name of this class
public:
#pragma pack(push, 4)
/// The margins/gaps of the window
struct CMargins
{
int m_iLeftRight;
int m_iTopBottom;
int m_iXGap;
int m_iYGap;
};
/// The ctrl group
struct CCtrlGroup
{
int m_iSignature;
int m_iSize;
int m_iNumRows;
int m_iNumCtrls;
int m_iColWidthFixed;
int m_iColWidthMin;
int m_iColWidthMax;
int m_iColExpand;
int m_iColContract;
int m_iRowHeightFixed;
int m_iRowHeightMin;
int m_iRowHeightMax;
int m_iRowExpand;
int m_iRowContract;
int m_iNumCols;
int m_iCtrls[1];
};
/// The "container" for the main ctrl group
struct CWindowMapStruct
{
int m_iSignature;
CMargins m_margins;
CCtrlGroup m_header;
};
#pragma pack(pop)
TRANSPARENT_LIST(CAutoSizeWindow<T>); ///< Empty transparent list
protected:
struct CCtrlCounter;
/// Support struct of CCtrlCounter. It's built to be a linked list (each element points to the previous one)
struct CRowsIndex
{
CCtrlCounter *m_piNum;
CRowsIndex *m_pPrev;
};
/// Multiple "templated" static-based counter. t_iType is the Counter number
/** \return Counter value
*/
template<int t_iType>
int Func()
{
static int i = 0;
i++;
return i;
}
/// This "class" counts the number of controls of a ctrl group. It uses an external CRowsIndex to support itself
struct CCtrlCounter
{
int m_iID;
CCtrlCounter(int iID) : m_iID(iID)
{
}
CCtrlCounter(CRowsIndex* pri) : m_iID(0)
{
pri->m_piNum = this;
}
CCtrlCounter(CRowsIndex *&pcn, int iAdder, int iDiv, int iID) : m_iID(iID)
{
pcn->m_piNum->m_iID = (int)(this - pcn->m_piNum) - iAdder;
ATLASSERT(pcn->m_piNum->m_iID % iDiv == 0 && _T("Are you forgetting a WMB_COL()?"));
pcn->m_piNum->m_iID /= iDiv;
pcn = pcn->m_pPrev;
}
const CCtrlCounter operator++()
{
m_iID++;
return *this;
}
const CCtrlCounter operator++(int)
{
const CCtrlCounter tmp(*this);
++(*this);
return tmp;
}
operator int()
{
return m_iID;
}
};
public:
BEGIN_MSG_MAP(CAutoSizeWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_INITDIALOG, OnCreate)
if (t_bAutoMinSize) {
MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
}
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
END_MSG_MAP()
public:
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
T* pT = static_cast<T*>(this);
if (!pT->CtrlsInitialize()) {
ATLTRACE(_T("Not initialized.\n"));
}
__if_not_exists(T::GetScrollOffset) {
else if (t_bAutoMinSize) {
SIZE sizeMin, sizeMax;
pT->GetMinMaxSize(sizeMin, sizeMax);
RECT rectNew = {0, 0};
RECT rectClient;
pT->GetClientRect(&rectClient);
if (rectClient.right < sizeMin.cx) {
rectNew.right = sizeMin.cx;
} else if (rectClient.right > sizeMax.cy) {
rectNew.right = sizeMax.cx;
} else {
rectNew.right = rectClient.right;
}
if (rectClient.bottom < sizeMin.cy) {
rectNew.bottom = sizeMin.cy;
} else if (rectClient.bottom > sizeMax.cy) {
rectNew.bottom = sizeMax.cy;
} else {
rectNew.bottom = rectClient.bottom;
}
if (rectNew.right != rectClient.right || rectNew.bottom != rectClient.bottom) {
RECT rectWindow;
pT->GetWindowRect(&rectWindow);
pT->MapWindowPoints(NULL, (LPPOINT)&rectNew, 2);
rectNew.right += rectWindow.right - rectWindow.left - rectNew.right + rectNew.left;
rectNew.bottom += rectWindow.bottom - rectWindow.top - rectNew.bottom + rectNew.top;
pT->SetWindowPos(NULL, 0, 0, rectNew.right - rectNew.left, rectNew.bottom - rectNew.top, SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOZORDER|SWP_NOMOVE);
}
}
}
bHandled = FALSE;
return 0;
}
LRESULT OnGetMinMaxInfo(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/)
{
MINMAXINFO *pMinMax = (MINMAXINFO*)lParam;
T* pT = static_cast<T*>(this);
SIZE sizeMin, sizeMax;
pT->GetMinMaxSize(sizeMin, sizeMax);
RECT rectWindow, rectClient;
pT->GetWindowRect(&rectWindow);
pT->GetClientRect(&rectClient);
pT->MapWindowPoints(NULL, (LPPOINT)&rectClient, 2);
__if_not_exists(T::GetScrollOffset) {
pMinMax->ptMinTrackSize.x = sizeMin.cx + rectWindow.right - rectWindow.left - rectClient.right + rectClient.left;
pMinMax->ptMinTrackSize.y = sizeMin.cy + rectWindow.bottom - rectWindow.top - rectClient.bottom + rectClient.top;
}
if (pMinMax->ptMaxTrackSize.x > sizeMax.cx) {
pMinMax->ptMaxTrackSize.x = sizeMax.cx;
}
if (pMinMax->ptMaxTrackSize.y > sizeMax.cy) {
pMinMax->ptMaxTrackSize.y = sizeMax.cy;
}
if (pMinMax->ptMaxSize.x > sizeMax.cx) {
pMinMax->ptMaxSize.x = sizeMax.cx;
}
if (pMinMax->ptMaxSize.y > sizeMax.cy) {
pMinMax->ptMaxSize.y = sizeMax.cy;
}
return 0;
}
LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{
if (!wParam) {
T* pT = static_cast<T*>(this);
pT->CtrlsArrange();
}
bHandled = FALSE;
return 0;
}
LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
T* pT = static_cast<T*>(this);
POINT pt = {0};
__if_exists(T::GetScrollOffset) {
pT->GetScrollOffset(pt);
}
if(wParam != NULL) {
WTL::CDCHandle dc = (HDC)wParam;
dc.SetViewportOrg(-pt.x, -pt.y);
pT->DoPaint(dc);
} else {
WTL::CPaintDC dc(pT->m_hWnd);
dc.SetViewportOrg(-pt.x, -pt.y);
pT->DoPaint(dc.m_hDC);
}
return 0;
}
//
/// Initializes the window.
/** \param piCtrls Ctrls map
* \param bForce Force the initialization (the window will be reinitialized if already initialized)
* \return TRUE if successful, FALSE if failed
*/
BOOL CtrlsInitialize(CWindowMapStruct *piCtrls = T::GetWindowMap(), BOOL bForce = FALSE)
{
if (piCtrls->m_iSignature && !bForce) {
return TRUE;
}
T* pT = static_cast<T*>(this);
if (!pT->m_hWnd) {
ATLTRACE(_T("Window not initialized.\n"));
return FALSE;
}
#ifdef DEBUG
if (!pT->IsWindow()) {
ATLTRACE(_T("Window not initialized.\n"));
return FALSE;
}
#endif
if (!piCtrls->m_iSignature) {
pT->HandleTransparentMap();
}
RECT rectUnits = {4, 8, 0, 0};
ATLVERIFY(pT->MapDialogRect(&rectUnits));
LONG lXUnits = rectUnits.left, lYUnits = rectUnits.top;
CMargins marginsPix;
_CheckMargins(lXUnits, 4, lYUnits, 8, &piCtrls->m_margins, &marginsPix);
BOOL bRes;
ATLVERIFY((bRes = pT->_CtrlsInitialize(&piCtrls->m_header, &marginsPix, lXUnits, lYUnits)) != FALSE);
if (bRes) {
piCtrls->m_iSignature = 1;
return TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -