天天看点

使用CSplitterWnd类静态分割的窗口的隐藏[转]

标题略长……之前百度了很多,也看过了很多程序,那个时候稍微有点小青涩,所以那些东西根本是看不懂什么意思…现在回过头来看,其实还是很容易就实现的…当然,话题很初级,不是面向中高级群体的,凑合写这凑合看,也是为了像当初我这么羞射的人看的……

首先说一下,使用CSplitterWnd类分割窗口。用这个可以动态分割,也可以静态分割。具体怎么动态分割我忘了,静态分割的方法大概就是在MainFrame类中重载某个函数…在里面添加分割代码,首先CreateStatic,然后再为每一个分隔出来的窗口添加View类。当初因为什么原因一定要用这种方式我想不起来了。只是认为还有更好的方式实现多窗口啊,多视图什么的。比如使用VS的那种风格,叫什么dockable之类的,如果仅仅是想添加一个可以拖动的对话框工具栏,那么直接使用CDialogBar会更简单啊。使用静态分割窗口是我那个时候的噩梦。根本搞不清楚如何隐藏。废话少说,如果要隐藏静态分隔出来的窗口,有个问题必须要先了解,那就是这些分个窗口的资源ID。嗯。这些资源的ID是有限制的,固定在AFX_IDW_PANE_FIRST和AFX_IDW_PANE_LAST之间。并且大小为16*16.也就是16行16列的意思。好了,言归正传,以下内容我只是复制的自己论文的一部分,当然是为了凑字数,实在不知道写点啥…

1. 获取要隐藏窗口的指针,调用ShowWindow(SW_HIDE)隐藏窗口;

2. 为该窗口指定一个新的ID资源,这个资源不会与现存的资源冲突;

3. 如果该窗口的后面还有其他窗口资源,那么需要将后面的窗口ID全部重新向前移动一位;

4. 将CSplitterWnd类中的保护成员变量m_nCols(如果是行则为m_nRows)减一,调用RecalcLayout。

代码才是事实,所以下面是具体事例:

使用CSplitterWnd类静态分割的窗口的隐藏[转]

1 void CMySplitterWnd::HideLeftCol() //用于隐藏左侧工具栏窗口
 2 {
 3     CWnd* pPaneHide = GetPane(0, 0);
 4     pPaneHide->ShowWindow(SW_HIDE);
 5 //将隐藏窗口资源ID分配到当前行的最大列之外
 6     pPaneHide->SetDlgCtrlID(AFX_IDW_PANE_FIRST + m_nCols); 
 7     CWnd* pPane = GetPane(0, 1);
 8     pPane->SetDlgCtrlID(IdFromRowCol(0, 0)); //将下一列的资源提前
 9     m_nCols--;
10     RecalcLayout();
11 }      
使用CSplitterWnd类静态分割的窗口的隐藏[转]

这当然不是什么通用的代码,所以别想什么复制粘贴的事情了。这段代码具体来说,看类的名字也许就知道,我是自定义了一个叫做CMySplitterWnd类,这样,我自己分割窗口当然用CMySplitterWnd类啦。

下面讲解一下代码,因为针对性特别强嘛,所以我说明一下,我用CMySplitterWNd类分割成了左右两部分,我想隐藏的是左侧窗口,所以第3行,pPaneHide就是我想要隐藏的窗口的指针,通过GetPane(0,0)获取。第4行没啥好说的,第6行,这里我也是有疑问的,为什么要这么做?我知道第六行代码的含义是将隐藏窗口的资源ID重新分配,只是我不知道是否可以分配到一个更广阔的地方呢?我自己也确实懒得实验…总之这里就是把要隐藏的窗口的ID分配到了当前行的最大列之外一个。这里需要强调一下,这个程序很单一,因为我知道自己将窗口分割成了1行2列,所以才用这么偷懒的方式书写。按照道理应该是如下书写:

pPaneHide->SetDlgCtrlID(AFX_IDW_PANE_FIRST +current_row*16+ m_nCols);      

一定要记得是当前行啊!由于当前行是0,所以我忽略掉了……接下来的事情就简单了,诚如所见,就是将剩下的还在的窗口的ID重新分配一下,该提前的提前。第8行代码的作用不就是如此么。注意第九行啊,一定要写上。不写有什么影响我不清楚,但是我认为后果一定很严重…这是CSplitterWnd类的内部保护成员,代表分个窗口的列数(看名字就知道。。。我还这么罗嗦。。。)

如果要把隐藏的窗口再显示回来,自然就是上面步骤逆转一下就好了,

使用CSplitterWnd类静态分割的窗口的隐藏[转]
void CMySplitterWnd::ShowLeftCol()
{
    m_nCols++;
//根据ID将隐藏的窗口找出来
    CWnd* pPanShow = GetDlgItem(AFX_IDW_PANE_FIRST + m_nCols);
    pPanShow->ShowWindow(SW_SHOWNA);
    CWnd* pPane = GetPane(0, 0);
    pPane->SetDlgCtrlID(IdFromRowCol(0, 1));
    pPanShow->SetDlgCtrlID(IdFromRowCol(0, 0));
    RecalcLayout();
}      
使用CSplitterWnd类静态分割的窗口的隐藏[转]

我想到了这里,应该都能懂了,所以就写到这里吧!如果我有空并且还没忘记这个地方的话,到时候会补上一个示例程序。

以上。

使用CSplitterWnd类静态分割的窗口的隐藏[转]
1 void CMySplitterWnd::HideLeftCol() //用于隐藏左侧工具栏窗口
 2 {
 3     CWnd* pPaneHide = GetPane(0, 0);
 4     pPaneHide->ShowWindow(SW_HIDE);
 5 //将隐藏窗口资源ID分配到当前行的最大列之外
 6     pPaneHide->SetDlgCtrlID(AFX_IDW_PANE_FIRST + m_nCols); 
 7     CWnd* pPane = GetPane(0, 1);
 8     pPane->SetDlgCtrlID(IdFromRowCol(0, 0)); //将下一列的资源提前
 9     m_nCols--;
10     RecalcLayout();
11 }      
使用CSplitterWnd类静态分割的窗口的隐藏[转]
pPaneHide->SetDlgCtrlID(AFX_IDW_PANE_FIRST +current_row*16+ m_nCols);      
使用CSplitterWnd类静态分割的窗口的隐藏[转]
void CMySplitterWnd::ShowLeftCol()
{
    m_nCols++;
//根据ID将隐藏的窗口找出来
    CWnd* pPanShow = GetDlgItem(AFX_IDW_PANE_FIRST + m_nCols);
    pPanShow->ShowWindow(SW_SHOWNA);
    CWnd* pPane = GetPane(0, 0);
    pPane->SetDlgCtrlID(IdFromRowCol(0, 1));
    pPanShow->SetDlgCtrlID(IdFromRowCol(0, 0));
    RecalcLayout();
}      
使用CSplitterWnd类静态分割的窗口的隐藏[转]