//头文件: /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //文件名称:Alignability.h //功能说明: 使你的窗口具有子窗口对齐能力。 //用法说明:1,设置父窗口类的句柄。(对于基于对话框的程序,在OnInitDialog函数中调用。) // 2,调用SetItemAlignable函数,传入一个子窗口句柄及对齐方式(对齐方式可用按位或运算符多选)。 // 如果父窗口句柄及相应子窗口的句柄无效,或子窗口句柄并非父窗口的子窗口,函数调用将失败。 // (对于基于对话框的程序,在OnInitDialog函数中调用。) // 3,当你的窗口的子控件需要对齐的时候,调用Align函数。(通常在父窗口的WM_SIZE消息 // 处理函数中调用。 //备注:为了使它能用于其它C系统编程环境,我避免了对MFC类的使用,这让代码有点发福,如果要用于C // 语言SDK编程就要将vector用数组代替... // 2005-2-28. writer by txf. // 如果你有更好的改进,记得通知我:[email protected] ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef ALIGNABILITY_H_ #define ALIGNABILITY_H_ #include "windows.h" #include <vector> using std::vector; enum AlignType{ leftalign = 1, topalign = 2, rightalign = 4, bottomalign = 8 }; class CAlignability { public: BOOL SetParentHwnd(HWND hwndParent); HWND GetParentHwnd() const; void Align(); //进行对齐。 struct AlignCfg{ public: AlignCfg(HWND hwndChild, AlignType eType, RECT oriEDs) :m_hwndChild(hwndChild), m_oriEDs(oriEDs), m_eType(eType){} HWND m_hwndChild;//子窗口的句柄. AlignType m_eType; //对齐方式. RECT m_oriEDs; //子控件初始时(通常为设计时)到父窗口的四边的边距. }; CAlignability(HWND hwndParent); virtual ~CAlignability(); BOOL SetItemAlignable(UINT nSubWndId, AlignType aligntype); BOOL SetItemAlignable(HWND hwndChild, AlignType aligntype); private: HWND m_hwndParent; vector<AlignCfg> m_alignset; };
#endif //ALIGNABILITY_H_
//实现文件: // Alignable.cpp: implementation of the CAlignable class. // ////////////////////////////////////////////////////////////////////// #include "Alignability.h" #include <assert.h>
#ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif
////////////////////////////////////////////////////////////////////// // Construction/Destruction //////////////////////////////////////////////////////////////////////
CAlignability::CAlignability(HWND hwndParent) :m_hwndParent(hwndParent) { assert(::IsWindow(m_hwndParent)); }
CAlignability::~CAlignability() {
} BOOL CAlignability::SetItemAlignable(UINT nSubWndId, AlignType aligntype) { HWND hwndChild(GetDlgItem(m_hwndParent, nSubWndId)); return SetItemAlignable(hwndChild, aligntype); } BOOL CAlignability::SetItemAlignable(HWND hwndChild, AlignType aligntype) { if(! ::IsWindow(m_hwndParent)) { assert(0);//Parent window is Invalid. return FALSE; } RECT subWndRect, parentWndRect; ::GetClientRect(m_hwndParent, &parentWndRect); if(::IsWindow(hwndChild)) { ::GetWindowRect(hwndChild, &subWndRect); POINT pt; pt.x = subWndRect.left; pt.y = subWndRect.top; ::ScreenToClient(m_hwndParent, &pt); subWndRect.left = pt.x, subWndRect.top = pt.y; pt.x = subWndRect.right; pt.y = subWndRect.bottom; ::ScreenToClient(m_hwndParent, &pt); subWndRect.right = pt.x, subWndRect.bottom = pt.y; RECT oriEDs; oriEDs.left = subWndRect.left - parentWndRect.left; oriEDs.right = parentWndRect.right - subWndRect.right; oriEDs.top = subWndRect.top - parentWndRect.top; oriEDs.bottom = parentWndRect.bottom - subWndRect.bottom; m_alignset.push_back(AlignCfg(hwndChild, aligntype, oriEDs)); return true; } return FALSE; } void CAlignability::Align() { if(! ::IsWindow(m_hwndParent)) { assert(0);//Can't AAlign: Parent window is Invalid. return; } RECT rect; ::GetClientRect(m_hwndParent, &rect); const int cxParent = rect.right - rect.left; const int cyParent = rect.bottom - rect.top; HWND hwndChild = 0; for(long i=0, n=m_alignset.size(); i < n; ++i) { hwndChild = m_alignset[i].m_hwndChild; if(::IsWindow(hwndChild) && ::IsChild(m_hwndParent, hwndChild)) { ::GetWindowRect(hwndChild, &rect); POINT pt; pt.x = rect.left; pt.y = rect.top; ::ScreenToClient(m_hwndParent, &pt); rect.left = pt.x, rect.top = pt.y; pt.x = rect.right; pt.y = rect.bottom; ::ScreenToClient(m_hwndParent, &pt); rect.right = pt.x, rect.bottom = pt.y;
const int oriWidth = rect.right - rect.left; const int oriHeight= rect.bottom - rect.top; if(m_alignset[i].m_eType & leftalign) { rect.left = m_alignset[i].m_oriEDs.left; if(!(m_alignset[i].m_eType & rightalign)) rect.right = rect.left + oriWidth; //保持宽度不变. } if(m_alignset[i].m_eType & topalign) { rect.top = m_alignset[i].m_oriEDs.top; if(!(m_alignset[i].m_eType & bottomalign)) rect.bottom = rect.top + oriHeight; //保持高度不变. } if(m_alignset[i].m_eType & rightalign) { rect.right = cxParent - m_alignset[i].m_oriEDs.right; if(!(m_alignset[i].m_eType & leftalign)) rect.left = rect.right - oriWidth; //保持宽度不变. } if(m_alignset[i].m_eType & bottomalign) { rect.bottom = cyParent - m_alignset[i].m_oriEDs.bottom; if(!(m_alignset[i].m_eType & topalign)) rect.top = rect.bottom - oriHeight; //保持高度不变. } ::MoveWindow(hwndChild, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE); } else { assert(0); //SetAlign to a item failed. } } }
HWND CAlignability::GetParentHwnd() const { return m_hwndParent; }
BOOL CAlignability::SetParentHwnd(HWND hwndParent) { if(::IsWindow(hwndParent)) { m_hwndParent == hwndParent; return TRUE; } return FALSE; }

|