您的位置:首页 > 编程语言 > C语言/C++

子窗口(控件)对齐类的实现(C++实现)

2005-02-28 09:30 253 查看
//头文件://////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//文件名称:Alignability.h
//功能说明: 使你的窗口具有子窗口对齐能力。
//用法说明:1,在你的父窗口类中定义一个对齐类对象(当然也可放在类外).如: CAlignability m_align;
// 2,为对齐类对象设置父窗口类的句柄。如: m_align.SetParentHwnd(GetSafeHwnd()); (对于基于对话框的程序,在OnInitDialog函数中调用。)
// 3,调用对齐类对象的AddAlignItem函数,传入一个子窗口句柄或ID及对齐方式(对齐方式可用按位或运算符多选)。
// 如果对齐类对象中父窗口句柄及相应子窗口的句柄无效,或子窗口句柄并非父窗口的子窗口,函数调用将失败。
// 如:RECT eds = {0, 0, 0, 0}; m_align.AddAlignItem(IDC_EDIT_CONTENT, leftalign|topalign|rightalign|bottomalign, &eds);
// (对于基于对话框的程序,在OnInitDialog函数中调用。),在大部分情况下,你可以忽略AddAlignItem函数的最后一个参数,
// 这个参数是用来显示设置相应子控件的四边到父窗口四边的距离(以像素为单位),这对于非设计期放置的子控件的对齐设置很有用.
// 4,当你的窗口的子控件需要对齐的时候,调用Align函数。如:m_align.Align(); (通常在父窗口的WM_SIZE消息处理函数中调用)。

//备注:为了使它能用于其它C系统编程环境,我避免了对MFC类的使用,这让代码有点发福,如果要用于C
// 语言SDK编程就要将vector用数组代替...
// 2005-2-28. writer by txf.
// 如果你有更好的改进,记得通知我:tangxinfa@sina.com
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#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, int eType, RECT oriEDs)
:m_hwndChild(hwndChild), m_oriEDs(oriEDs), m_eType(eType){}
HWND m_hwndChild;//子窗口的句柄.
int m_eType; //对齐方式.
RECT m_oriEDs; //子控件初始时(通常为设计时)到父窗口的四边的边距.
};
CAlignability(HWND hwndParent=0);
virtual ~CAlignability();
BOOL AddAlignItem(int nSubWndId, int aligntype, RECT* lpEDs=0);
BOOL AddAlignItem(HWND hwndChild, int aligntype, RECT* lpEDs=0);
private:
HWND m_hwndParent;
vector<AlignCfg> m_alignset;
};

#endif //ALIGNABILITY_H_

//实现文件://////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

文件名称:Alignability.cpp
#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/*=0*/)
:m_hwndParent(hwndParent)
{
assert(::IsWindow(m_hwndParent));
}

CAlignability::~CAlignability()
{

}
BOOL CAlignability::AddAlignItem(int nSubWndId, int aligntype, RECT* lpEDs/* =0 */)
{
HWND hwndChild(GetDlgItem(m_hwndParent, nSubWndId));
return AddAlignItem(hwndChild, aligntype, lpEDs);
}
BOOL CAlignability::AddAlignItem(HWND hwndChild, int aligntype, RECT* lpEDs/* =0 */)
{
if(! ::IsWindow(m_hwndParent))
{
assert(0);//Parent window is Invalid.
return FALSE;
}
RECT subWndRect, parentWndRect;
::GetClientRect(m_hwndParent, &parentWndRect);

if(::IsWindow(hwndChild))
{
RECT oriEDs;
if(lpEDs)
oriEDs = *lpEDs;
else
{
::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;

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: