百叶窗:百叶窗式面板组



利用百叶窗式面板组可增大窗口可利用面积而且把常用工具放在窗口中比放在菜单中使用更方便现在些大型软件Software如Photoshop、Dreamweaver等都采用了这种方式在这些软件Software中百叶窗式面板组都做成了可停靠窗口我没有这种能力只能做成固定位置Control控件组使用时只能用在对话框或具有CFormView视图中整个制作很粗糙希望高手能加以改造 \"\"

核心思路是调整Control控件位置和显示/隐藏Control控件个面板被收起或展开时只要把它下面Control控件都隐藏或显示出来再调整各面板Control控件位置这样整个面板组就像百叶窗样可以收放自如了

显示/隐藏Control控件:
CWnd *pWnd;
pWnd = GetDlgItem( Control控件ID号 );
pWnd->ShowWindow( nShow );
GetDlgItem用于获取Control控件指针;
ShowWindow用于显示/隐藏Control控件当nShow为SW_SHOW时显示Control控件为SW_HIDE时隐藏Control控件

修改Control控件位置:
CWnd *pWnd;
pWnd = GetDlgItem( Control控件ID号 );
pWnd->SetWindowPos( NULL,x,y,0,0,SWP_NOZORDER | SWP_NOSIZE );
SetWindowPos把Control控件移到窗口(x,y)处大小不变

这个设计难点在控制Control控件位置上应该尽量采用相对位置在这里只要抓住在各种情况下标题条位置就可以了标题条下各Control控件位置都是相对于标题条当标题条位置改变时重新计算下Control控件位置就可以了

我定义了变量CPo m_TitlePt[3]存放 3个标题条位置其值在收放面板时进行设定
面板1标题条是固定只要设置好初值就行了;
面板2标题条是相对于面板1标题条有两种可能:
当面版1展开时其y坐标=标题条1.y+面板1高度即:m_TitlePt[1].y = m_TitlePt[0].y+m_BoxHeight[0];

\"\"
当面版1收起时其y坐标=标题条1.y+标题条1高度即:m_TitlePt[1].y = m_TitlePt[0].y+m_TitleHeight;

\"\"
面板3标题条是相对于面板2标题条也有两种可能:
当面版2展开时其y坐标=标题条2.y+面板2高度即:m_TitlePt[2].y = m_TitlePt[1].y+m_BoxHeight[1];
当面版2收起时其y坐标=标题条2.y+标题条2高度即:m_TitlePt[2].y = m_TitlePt[1].y+m_TitleHeight;
以下就是计算面板3各部分位置:


void CCurtainBoxDlg::CalculateControlPos3
{
m_TitlePt[2].x = m_BoxRext.left;//标题条位置(左上角坐标)
( b_Mark2 )//面板2是展开
m_TitlePt[2].y = m_TitlePt[1].y+m_BoxHeight[1];
//面板2是收起
m_TitlePt[2].y = m_TitlePt[1].y+m_TitleHeight;
m_ControlPt3[0] = CPo( m_TitlePt[2].x+5, m_TitlePt[2].y+m_TitleHeight+7 );//Control控件位置
m_ControlPt3[1] = CPo( m_TitlePt[2].x+85, m_TitlePt[2].y+m_TitleHeight+7 );
m_ControlPt3[2] = CPo( m_TitlePt[2].x+5, m_TitlePt[2].y+m_TitleHeight+35 );
}

面板下各Control控件位置是经反复调节确定其它两个面板用类似思路方法计算
计算好位置后就可以重新定位位置了以下为设置面板3各部分位置:

void CCurtainBoxDlg::SetBox3Pos
{
CWnd *pWnd = GetDlgItem( IDC_T99vLE3 );
pWnd->SetWindowPos( NULL, m_TitlePt[2].x, m_TitlePt[2].y,
0, 0, SWP_NOSIZE | SWP_NOZORDER );//调整标题栏位置
i;
for( i=0; i )
{
pWnd = GetDlgItem( m_Box3ID[i] );
pWnd->SetWindowPos( NULL, m_ControlPt3[i].x, m_ControlPt3[i].y,
0, 0, SWP_NOSIZE | SWP_NOZORDER );//调整Control控件位置
}
}
其中BOX3_NUMBER为面板3中Control控件数m_Box3ID存放Control控件ID号其值在化时已设置

解决了Control控件位置后就该考虑单击标题条后调整问题了
由于标题条是种自绘按钮(详见自己动手做按钮文)可直接用ClassWizard添加它们响应这里我用了 3个BOOL变量监视标题条状态:
BOOL b_Mark1;//面板1状态:true-展开、false-收缩
BOOL b_Mark2;//面板2状态
BOOL b_Mark3;//面板3状态
当单击个标题条时首先修改它状态变量再根据新状态计算和设置各Control控件位置再重绘整个Control控件组就行了还有个问题为了节省空间我只允许同时展开两个面板所以当展开个面板时若其它两个面板处于打开状态就应该先关闭
以下为单击面板3标题条时响应:

void CCurtainBoxDlg::OnTitle3
{
( m_Title3.ClickBut )
{
b_Mark3 = !b_Mark3;
( b_Mark1 && b_Mark2 && b_Mark3 )
{
b_Mark1 = false;
m_Title1.SetButStatus(BUT_STATUS_RIGHT);
;ShowBox1( SW_HIDE);
}
( b_Mark3 )
ShowBox3( SW_SHOW );

ShowBox3( SW_HIDE );
InvalidateBox;//刷新面板组
}
}




m_Title3.ClickBut是自绘标题条按钮成员用于判定单击处是否为标题条文字部分(参见CTitleBox类);
b_Mark3 = !b_Mark3为更改面板3状态;


其下是若 3个面板都是展开则关闭面板1;
ShowBox3为显示/隐藏面板3中各Control控件定义为:

void CCurtainBoxDlg::ShowBox3( nShow)
{
CWnd *pWnd;
for( i=0; i )
{
pWnd = GetDlgItem( m_Box3ID[i] );
pWnd->ShowWindow( nShow );
}
}


InvalidateBox计算和设置Control控件位置刷新面板组:

void CCurtainBoxDlg::InvalidateBox
{
CalculateControlPos1;//计算面板1各Control控件位置
SetBox1Pos;//重新设置面板1各Control控件位置
CalculateControlPos2;//计算面板2各Control控件位置
SetBox2Pos;//重新设置面板2各Control控件位置
CalculateControlPos3;//计算面板3各Control控件位置
SetBox3Pos;//重新设置面板3各Control控件位置
InvalidateRect( &m_BoxRext );//重绘面板背景以消除残留印记
}
以上为百叶窗式面板组设计思路


Tags:  百叶窗模型 flash百叶窗 实木百叶窗 百叶窗

延伸阅读

最新评论

发表评论