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

原创 2005年02月28日 09:30:00

//头文件://////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//文件名称: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;
}

MFC 子窗口全屏显示扩展控件

  • 2015年06月27日 21:03
  • 49KB
  • 下载

Mfc子窗口修改Static Text控件的字体、大小、颜色

开门见山:创建子窗口的方法请参考我上一篇博客:http://blog.csdn.net/u014411348/article/details/53911682 主窗口修改Static Text控件网上...

Windows不支持重叠子窗口、控件(overlapping controls)

同级别子窗口彼此覆盖时,Windows程序就会出现问题。尽管可以通过SetWindowPos()调整各个子窗口的z序,但是仍会存在问题。典型情况就是对话框中如果用一个子窗口覆盖整个客户区,对话框里的控...
  • smstong
  • smstong
  • 2014年12月29日 20:30
  • 2058

枚举遍历所有子窗口句柄控件类型标题

为指定的父窗口枚举子窗口、按钮  很早就写过类似spy++和查看密码窗口的东西,一直想给这个小东西再加点特别的。前段时间对软件安装注册发生了兴趣,有些软件如果你不输入正确注册码,那该死的“下一步”按钮...

mfc实现悬浮子窗口(动态实现)

  • 2016年04月19日 17:30
  • 42.76MB
  • 下载

子窗口使用父窗口的控件

1.   查看showModalDialog  参数              基本介绍: showModalDialog() (IE 4+ 支持) showModelessDialog() (I...

artDialog实现子窗口向父元素传递数据

案例:在页面A点击按钮,弹出artDialog窗口B,当关闭窗口B时,实现向父元素A传递数据。 一、方法一: 1、利用artdialog中的data方法进行传值与接收值。      ...

QMenu和QAction创建及信号槽关联,实现子窗口调用

在开发过程中我们经常用到Qmenu来列出我们需要的菜单,类似Office菜单栏中的'开始、插入、页面布局、视图',用户可以根据自己的需要在菜单中添加对应的QAction,从而实现菜单列表的添加。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:子窗口(控件)对齐类的实现(C++实现)
举报原因:
原因补充:

(最多只允许输入30个字)