MFC分裂视窗如何动态调整运行类

我用MFC分裂视生成两个视图,其运行类分别是CView_0和CView_1:
m_wndSplitter.CreateView( 0, 0, RUNTIME_CLASS(CView_0), CSize(0,0), pContext );
m_wndSplitter.CreateView( 1, 0, RUNTIME_CLASS(CView_1), CSize(0,0), pContext );
在程序运行过程中,我想动态调整视的运行类在CView_0和CView_1间切换,请问如何实现?

[*] 您可以通过以下步骤动态更改视图的运行时类:

  1. 通过调用GetPane函数获取要更改的视图的指针。该函数接受一个索引,该索引指定要获取的视图在拆分器窗格中的位置。例如,要获取左边的视图,请使用索引0,要获取右边的视图,请使用索引1。

  2. 销毁当前视图。

  3. 通过调用CreateView函数创建新视图。此函数的第一个参数是要在哪个窗格中创建视图的索引,第二个参数是运行时类,第三个参数是视图的大小,第四个参数是指针上下文。在此情况下,您可以使用与之前相同的指针上下文。

  4. 将新创建的视图设置为窗格的活动视图,以便用户可以看到它。

下面是一个示例代码,演示如何在CView_0和CView_1之间动态切换:

// 获取要更改的视图的指针
CView* pOldView = (CView*) m_wndSplitter.GetPane(0, 0);

// 销毁当前视图
pOldView->DestroyWindow();

// 创建新视图
if (m_bShowView0)
{
    m_wndSplitter.CreateView(0, 0,
        RUNTIME_CLASS(CView_0), CSize(0,0),
        pContext);
}
else
{
    m_wndSplitter.CreateView(0, 0,
        RUNTIME_CLASS(CView_1), CSize(0,0),
        pContext);
}

// 将新创建的视图设置为窗格的活动视图
CView* pNewView = (CView*) m_wndSplitter.GetPane(0, 0);
m_wndSplitter.SetActivePane(0, 0, pNewView);

在这个例子中,我们假设有一个名为m_bShowView0的布尔变量,用于指示当前显示的是哪个视图。根据这个变量,我们选择创建CView_0或CView_1,然后将新视图设置为窗格的活动视图。

可以尝试使用以下代码实现在CView_0和CView_1之间切换:

// 获取当前激活的视图
CView* pActiveView = (CView*)m_wndSplitter.GetPane(m_wndSplitter.GetActivePane());

// 删除当前激活的视图
m_wndSplitter.DeleteView(m_wndSplitter.GetActivePane());

// 创建新视图
if (pActiveView->IsKindOf(RUNTIME_CLASS(CView_0)))
{
    m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CView_1), CSize(0, 0), pContext);
}
else if (pActiveView->IsKindOf(RUNTIME_CLASS(CView_1)))
{
    m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CView_0), CSize(0, 0), pContext);
}

// 重新激活视图
m_wndSplitter.SetActivePane(0, 0);

这段代码的基本思路是先获取当前激活的视图,然后根据其类型删除当前激活的视图,并根据需要创建新视图,最后重新激活新的视图。在本例中,我们检查当前激活的视图是否是CView_0,如果是,则创建CView_1,并且反之。注意,此代码假定您使用的是一个水平分裂窗口,其中第一列为索引0,第二列为索引1。

三步:
1,销毁当前视图
2,创建新的视图对象
3,调用 CSplitterWnd 的 ReplaceView 方法来替换当前视图

给你一个参考代码,希望对你有启发:

// 假设您有一个成员变量 m_wndSplitter,它是一个 CSplitterWnd 对象

void CMainFrame::SwitchToView0()
{
    // 销毁当前视图
    CView* pOldView = m_wndSplitter.GetPane(0, 0);
    m_wndSplitter.DeleteView(0, 0);

    // 创建新的视图对象
    CView_0* pNewView = new CView_0;

    // 替换当前视图
    m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CView_0), CSize(0, 0), pContext);
    m_wndSplitter.ReplaceView(pOldView, pNewView);
}

void CMainFrame::SwitchToView1()
{
    // 销毁当前视图
    CView* pOldView = m_wndSplitter.GetPane(0, 0);
    m_wndSplitter.DeleteView(0, 0);

    // 创建新的视图对象
    CView_1* pNewView = new CView_1;

    // 替换当前视图
    m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CView_1), CSize(0, 0), pContext);
    m_wndSplitter.ReplaceView(pOldView, pNewView);
}

如果您想在运行时动态切换MFC分裂视窗的运行类,则可以通过以下步骤实现:

在您的代码中定义两个运行类,如CView_0和CView_1。

在需要动态切换视图的地方,调用CWnd::DestroyWindow函数销毁当前视图。

在销毁当前视图之后,根据需要创建新视图,调用CWnd::CreateView函数创建新的视图,并设置新的运行类。

下面是一个简单的示例代码,演示如何在MFC分裂视窗中动态切换运行类:

// 销毁当前视图
CWnd* pOldWnd = m_wndSplitter.GetPane(0, 0);
if (pOldWnd != NULL)
{
    pOldWnd->DestroyWindow();
}

// 创建新的视图
CRuntimeClass* pNewViewClass = NULL;
if (m_bUseView0)
{
    pNewViewClass = RUNTIME_CLASS(CView_0);
}
else
{
    pNewViewClass = RUNTIME_CLASS(CView_1);
}
CView* pNewView = (CView*) m_wndSplitter.CreateView(0, 0, pNewViewClass, CSize(0, 0), pContext);

// 更新标志变量
m_bUseView0 = !m_bUseView0;


在这个示例中,我们首先销毁当前视图,然后根据需要创建新的视图,最后更新标志变量以便下一次切换视图时使用。需要注意的是,销毁当前视图时需要使用CWnd::DestroyWindow函数而不是CWnd::Destroy,因为后者不会自动调用析构函数。

希望这个示例可以帮助您理解如何在MFC分裂视窗中动态切换运行类。

要动态切换视图的运行类,你可以执行以下步骤:

1.首先,通过调用 m_wndSplitter.GetPane(0, 0) 和 m_wndSplitter.GetPane(1, 0) 方法获取到两个视图指针,这将允许您操作它们。

2.然后,您需要销毁当前的视图并创建新的视图。您可以使用 CWnd::DestroyWindow() 函数来销毁视图窗口,并使用 CWnd::Create() 函数创建新的视图窗口。

3.最后,您需要更新分隔器窗口中的视图指针。您可以使用 CSplitterWnd::SetRowInfo() 方法设置新的视图大小,并使用 CSplitterWnd::SetDlgItem() 方法设置新的视图指针。

以下是一个示例代码,演示如何在 CView_0 和 CView_1 之间切换视图运行类:

// 获取当前活动视图的指针
CView* pActiveView = (CView*)m_wndSplitter.GetActivePane();

// 获取要切换到的视图运行类
CRuntimeClass* pNewViewClass = NULL;
if (pActiveView->IsKindOf(RUNTIME_CLASS(CView_0)))
{
    pNewViewClass = RUNTIME_CLASS(CView_1);
}
else if (pActiveView->IsKindOf(RUNTIME_CLASS(CView_1)))
{
    pNewViewClass = RUNTIME_CLASS(CView_0);
}

// 销毁当前的视图
pActiveView->DestroyWindow();

// 创建新的视图
CView* pNewView = (CView*)pNewViewClass->CreateObject();
pNewView->Create(NULL, NULL, WS_CHILD | WS_VISIBLE, CRect(0, 0, 0, 0), &m_wndSplitter, AFX_IDW_PANE_FIRST, NULL);
pNewView->OnInitialUpdate();

// 设置新的视图指针
if (pNewViewClass == RUNTIME_CLASS(CView_0))
{
    m_wndSplitter.SetRowInfo(0, 200, 0);
    m_wndSplitter.SetDlgItem(pNewView->GetDlgCtrlID(), pNewView);
}
else if (pNewViewClass == RUNTIME_CLASS(CView_1))
{
    m_wndSplitter.SetRowInfo(1, 200, 0);
    m_wndSplitter.SetDlgItem(pNewView->GetDlgCtrlID(), pNewView);
}

仅为一个示例代码,您需要根据自己的代码进行适当的修改和调整。

该回答引用ChatGPT

在MFC中,可以使用CFrameWnd类的SetActiveView方法来实现动态切换视图。该方法可以将当前活动的视图设置为指定的视图。以下是示例代码:


// 切换到CView_0视图
CView* pView0 = (CView*)m_wndSplitter.GetPane(0, 0);
SetActiveView(pView0);




// 切换到CView_1视图
CView* pView1 = (CView*)m_wndSplitter.GetPane(1, 0);
SetActiveView(pView1);

在以上代码中,m_wndSplitter是CSplitterWnd类的实例,CView_0和CView_1是你定义的两个视图类。首先,通过m_wndSplitter.GetPane方法获取到指定的视图对象,然后调用SetActiveView方法将其设置为当前活动的视图。

注意,SetActiveView方法只能在MFC框架消息处理函数中调用。如果你需要在非消息处理函数中调用该方法,可以使用PostMessage函数将消息发送到主窗口,然后在消息处理函数中调用SetActiveView方法。

你可以使用MFC的SetActiveView()函数来实现动态调整视图的运行类。例如:
m_wndSplitter.SetActiveView(CView_0);
m_wndSplitter.SetActiveView(CView_1);


import pymssql

# 建立连接
conn = pymssql.connect(host='xxx', port='xxx', user='xxx', password='xxx', database='xxx', charset='utf8', autocommit=False)

# 检查连接是否成功
if conn:
    print('连接数据库成功!')
else:
    print('连接数据库失败!')

cursor = conn.cursor()

# 更新state=1的数据
if not tradedf_1.empty:
    sql = "update gold_transaction set A=(%s),state=(%s),B=(%s),C=(%s),D=(%s),E=(%s),F=(%s) where id=(%s) "
    cursor.executemany(sql, commit_list_1)
    print('state=1数据更新成功')
    conn.commit()

# 更新state=2的数据
if not tradedf_2.empty:
    sql = "update gold_transaction set A=(%s),state=(%s),B=(%s),C=(%s),D=(%s),E=(%s),F=(%s) where id=(%s) "
    cursor.executemany(sql, commit_list_2)
    print('state=2数据更新成功')
    conn.commit()

# 更新state=-1的数据
if not tradedf_3.empty:
    sql = "update gold_transaction set state=(%s) where id=(%s) "
    cursor.executemany(sql, commit_list_3)
    print('state=-1数据更新成功')
    conn.commit()

# 关闭连接
conn.close()

要在MFC分裂视窗中动态调整视图的运行类,可以使用以下步骤:

1 在需要进行运行类切换的地方添加代码,以获取指向当前视图的指针,例如:

CView* pCurrentView = (CView*) m_wndSplitter.GetPane(0,0);

2 调用分裂视图窗口的RemoveView()函数,删除当前视图,例如:

m_wndSplitter.RemoveView(0,0);

3 调用CreateView()函数创建新的视图,例如:

m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CNewView),CSize(0,0),pContext);

在这里,CNewView是新视图的运行类。如果需要切换到另一个视图,可以更改参数中的RUNTIME_CLASS()函数。
4 通过调用SetActivePane()函数,将焦点设置为新创建的视图,例如:

m_wndSplitter.SetActivePane(0,0);

这将激活新视图,并将其显示在分裂视图窗口的左侧。
5 重绘窗口以确保新的视图已正确显示,例如:

m_wndSplitter.RecalcLayout();

这将重新计算分裂视图窗口的大小和位置,并更新它们以包含新的视图。

通过这些步骤,您可以动态地切换MFC分裂视窗中的视图运行类,并更新窗口以反映更改。

先销毁当前的视图。

调用CWnd::DestroyWindow()函数销毁视图的窗口。

调用CSplitterWnd::CreateView()函数创建新的视图,并传递新的运行类。

下面是示例代码,假设你想要切换到CView_1:

// 销毁当前的视图
CView* pOldView = (CView*)m_wndSplitter.GetPane(0, 0);
pOldView->DestroyWindow();

// 创建新的视图
CView_1* pNewView = (CView_1*)RUNTIME_CLASS(CView_1)->CreateObject();
m_wndSplitter.CreateView(0, 0, pNewView->GetRuntimeClass(), CSize(0, 0), pContext);
pNewView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
pNewView->SendMessage(WM_INITIALUPDATE, 0, 0);


// 销毁当前的视图
CView* pOldView = (CView*)m_wndSplitter.GetPane(0, 0);
pOldView->DestroyWindow();

// 创建新的视图
CView_1* pNewView = (CView_1*)RUNTIME_CLASS(CView_1)->CreateObject();
m_wndSplitter.CreateView(0, 0, pNewView->GetRuntimeClass(), CSize(0, 0), pContext);
pNewView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
pNewView->SendMessage(WM_INITIALUPDATE, 0, 0);

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

以下答案基于ChatGPT与GISer Liu编写:
您可以通过以下步骤来实现动态调整视图的运行类:

1.首先获取要修改的视图的指针,可以通过 GetPane() 函数获取:

CView\_0\* pView0 = (CView\_0\*)m\_wndSplitter.GetPane(0, 0); CView\_1\* pView1 = (CView\_1\*)m\_wndSplitter.GetPane(1, 0);

2.销毁该视图,使用 DestroyWindow() 函数:

pView0->DestroyWindow(); pView1->DestroyWindow();

3.创建新的视图,使用 CreateView() 函数,其中第三个参数是要创建的视图的运行类:

if (bUseView0) { m\_wndSplitter.CreateView(0, 0, RUNTIME\_CLASS(CView\_0), CSize(0, 0), pContext); } 
else { m\_wndSplitter.CreateView(1, 0, RUNTIME\_CLASS(CView\_1), CSize(0, 0), pContext); }

其中,变量 bUseView0 表示当前要使用哪个视图。

4.调整窗口大小,可以使用 RecalcLayout() 函数:

m\_wndSplitter.RecalcLayout();

这样就可以动态调整视图的运行类了。


CView_0 *pView0=((CView_0*)m_wndSplitter.GetPane(0,0));

这样获取到创建的view,想怎么操作就按你需求来