我现在需要做个像FontPage的动态切分框架那种的切分视,也就是在程序的运行过程中让用户来自定义窗口的切分。
可是困难许多,我思考了一下,有两种方案:
1、利用CSplitterWnd类来实现窗口的切分。
   难点:程序中可能要用到很多视,程序中不可能实现视图数组。用户切分的视到底有多少程序中很难进行判断,程序中一旦推出下次启动时很难进行恢复。
2、自己从CVIEW类做一个切分视。
   难点:虽然可以从线条数中来判断当前有多少窗口,可是如何正确识别横向和竖向有多少?每个切分窗口的位置判断起来很难把握。------------------------------------------
欢迎大家讨论或者给出实列代码,灌水者和UP者无分。
------------------------
问题解决后我在从个人帐户中转1000可用分给你。

解决方案 »

  1.   

    学习以下的代码不知道对你有没有帮助class CMultiViewSplitter : public CSplitterWnd  
    {public:
    CMultiViewSplitter();
    virtual ~CMultiViewSplitter();
    int AddView(int nRow, int nCol, CRuntimeClass * pViewClass, 
    CCreateContext* pContext);
    void ShowView(int nViewID);
    CWnd* GetView(int nViewID);protected:
    map<int, long> m_mapViewPane;
    map<long, int> m_mapCurrentViews;
    map<int, CWnd*> m_mapIDViews; int m_nIDCounter; CWnd* GetCurrentView(int nRow, int nCol, int * nCurID);
    void SetCurrentView(int nRow, int nCol, int nViewID);
    int HideCurrentView(int nRow, int nCol);
    void GetPaneFromViewID(int nViewID, CPoint * pane);
    // Generated message map functions
    //{{AFX_MSG(CCtlView)
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
    }; 
    int CMultiViewSplitter::AddView(int nRow, int nCol, CRuntimeClass * pViewClass, 
       CCreateContext* pContext)
    {
    // hide the current view of the pane
    int PreviousID = HideCurrentView(nRow, nCol); // create the new view, if fail, set the previous view current 
    if (CreateView(nRow, nCol, pViewClass, CSize(10,10), pContext) == 0)
    {
    if (PreviousID != -1)
    SetCurrentView(nRow, nCol, PreviousID);
    return -1;
    } // get and store the niew view
    int NewViewID = m_nIDCounter;
    CWnd* pNewWnd = GetPane(nRow, nCol);
    CPoint pane(nRow, nCol);
    long paneID = MAKELONG(pane.x,pane.y);
    m_mapViewPane.insert(map<int, long>::value_type(NewViewID,paneID));
    m_mapIDViews.insert(map<int, CWnd*>::value_type(NewViewID, pNewWnd)); // set the new view current
    SetCurrentView(nRow, nCol, NewViewID); RedrawWindow();
    m_nIDCounter ++;
    return NewViewID;
    }void CMultiViewSplitter::ShowView(int nViewID)
    {
    if (GetView(nViewID) == NULL)
    return; // find the pane containing the view 
    CPoint pane;
    GetPaneFromViewID(nViewID, &pane); // switch views
    HideCurrentView(pane.x, pane.y);
    SetCurrentView(pane.x, pane.y, nViewID); RecalcLayout();
    }CWnd* CMultiViewSplitter::GetView(int nViewID)
    {
    map<int, CWnd*>::iterator itView; itView = m_mapIDViews.find(nViewID);
    if(itView==m_mapIDViews.end())
    return NULL;
    else
    return (*itView).second;
    }CWnd* CMultiViewSplitter::GetCurrentView(int nRow, int nCol, int * nCurID)
    {
    long paneID = MAKELONG(nRow,nCol);

    map<long, int>::iterator itCur;
    itCur = m_mapCurrentViews.find(paneID);
    if (itCur == m_mapCurrentViews.end())
    return NULL;
    else
    {
    int PreviousID = (*itCur).second;
    *nCurID = PreviousID;
    return GetView(PreviousID);
    }
    }void CMultiViewSplitter::SetCurrentView(int nRow, int nCol, int nViewID)
    {
    long paneID = MAKELONG(nRow,nCol); map<long, int>::iterator itCur;
    itCur = m_mapCurrentViews.find(paneID);
    if (itCur != m_mapCurrentViews.end())
    (*itCur).second = nViewID;
    else
    m_mapCurrentViews.insert(map<long,int>::value_type(paneID,nViewID)); CWnd * pView = GetView(nViewID);
    pView->SetDlgCtrlID(IdFromRowCol(nRow, nCol));
    pView->ShowWindow(SW_SHOW);
    }int CMultiViewSplitter::HideCurrentView(int nRow, int nCol)
    {
    int prevID;
    CWnd * pCurView = GetCurrentView(nRow, nCol, &prevID);
    if (pCurView == NULL)
    return -1;
    else
    {
    pCurView->SetDlgCtrlID(0);
    pCurView->ShowWindow(SW_HIDE);
    return prevID;
    }
    }void CMultiViewSplitter::GetPaneFromViewID(int nViewID, CPoint * pane)
    {
    map<int, long>::iterator itPane;
    itPane = m_mapViewPane.find(nViewID);
    if (itPane==m_mapViewPane.end())
    {
    pane = NULL;
    return;
    }
    long paneID = (*itPane).second;
    CPoint p(paneID);
    pane->x = p.x;
    pane->y = p.y;
    }void CMultiViewSplitter::OnMouseMove(UINT nFlags, CPoint point) 
    {
    // TODO: Add your message handler code here and/or call default
    //CSplitterWnd::OnMouseMove(nFlags, point);
    CWnd::OnMouseMove(nFlags, point);
    }
    /*
    CNoDragSplitter::CMultiViewSplitter()
    {
    m_nIDCounter = 1;
    }CNoDragSplitter::~CMultiViewSplitter()
    {}BEGIN_MESSAGE_MAP(CNoDragSplitter, CSplitterWnd)
    //{{AFX_MSG_MAP(CMultiViewSplitter)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    */
      

  2.   

    楼上的,有没有使用这个类的完整例子?可否发给我?
    [email protected]
      

  3.   

    gz,楼主说的在理,的二种方案是不是可以在视的左上显示编号呢?
    就像photoshop里的切片有编号一样?
      

  4.   

    当然我需要调用用户设计的切分窗口来进一步处理需求啊!用自己设计VIEW我觉得最难处理的就是怎么给每个VIEW一个识别符号,然后我可以根据这个符号找出用户切分的矩形大小。再就是如何能把这些信息保存供下次启动时使用。
      

  5.   

    不知道Bcg是怎么解决的,好像Xt也比较好处理
      

  6.   

    可以通过一个关联两边窗口的类来实现,看过borland的方法后,很有启发
      

  7.   

    终于把问题搞定了,效果http://61.133.87.165/bbs/attachment.php?s=&postid=432958,大家帮忙测试一下。注意窗口数目不能多于32个,超过会出错!
    有个问题就是我目前暂时还实现不了拖动时的虚线功能,现在只能画个实线。请大家帮忙搞定啦!对提出有用意见者我将赠送源代码。