视图切换

skyliubin 2002-04-28 08:36:54
在vc++中,单一视图中怎么样实现试图(Formview)的切换?
意思是在单一视图中我做新增几个视图,然后不知道怎么样切换这些视图来实现不同的功能?
...全文
92 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
qindq 2002-06-17
  • 打赏
  • 举报
回复
MSDN中的程序,照抄给你:

BOOL CMainFrame::OnViewChange(UINT nCmdID)
{
CView* pViewAdd;
CView* pViewRemove;
CDocument* pDoc = GetActiveDocument();
UINT nCmdID;

nCmdID = LOWORD(GetCurrentMessage()->wParam);

if((nCmdID == ID_VIEW_VIEW1) && (m_currentView == 1))
return;
if((nCmdID == ID_VIEW_VIEW2) && (m_currentView == 2))
return;

if (nCmdID == ID_VIEW_VIEW2)
{
if (m_pView2 == NULL)
{
m_pView1 = GetActiveView();
m_pView2 = new CMyView2;

//Note that if OnSize has been overridden in CMyView2
//and GetDocument() is used in this override it can
//cause assertions and, if the assertions are ignored,
//cause access violation.

m_pView2->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
rectDefault, this, AFX_IDW_PANE_FIRST + 1, NULL);
}
pViewAdd = m_pView2;
pViewRemove = m_pView1;
m_currentView= 2;
}
else
{
pViewAdd = m_pView1;
pViewRemove = m_pView2;
m_currentView= 1;
}

// Set the child i.d. of the active view to AFX_IDW_PANE_FIRST,
// so that CFrameWnd::RecalcLayout will allocate to this
// "first pane" that portion of the frame window's client area
// not allocated to control bars. Set the child i.d. of the
// other view to anything other than AFX_IDW_PANE_FIRST; this
// examples switches the child id's of the two views.

int nSwitchChildID = pViewAdd->GetDlgCtrlID();
pViewAdd->SetDlgCtrlID(AFX_IDW_PANE_FIRST);
pViewRemove->SetDlgCtrlID(nSwitchChildID);

// Show the newly active view and hide the inactive view.

pViewAdd->ShowWindow(SW_SHOW);
pViewRemove->ShowWindow(SW_HIDE);

// Connect the newly active view to the document, and
// disconnect the inactive view.
pDoc->AddView(pViewAdd);
pDoc->RemoveView(pViewRemove);

SetActiveView(pViewAdd);
RecalcLayout();
}
public 2002-06-17
  • 打赏
  • 举报
回复
http://www.codeproject.com/docview/switchingviews.asp
freelybird 2002-06-17
  • 打赏
  • 举报
回复
这个问题比较容易. 留下mail,我给你发一个project.
hy_xiong 2002-06-17
  • 打赏
  • 举报
回复
这是我看的一篇关于单文档多视的文章:你也看看吧,我做过可以成功!
怎 样 在 一 个Pane 中 显 示 多 种View ?
河 南 大 学 数 学 系 祁 文 文 ----
在MS Windows 中, 一 个 窗 口 可 以 分 割 成 若 干 个 子 窗 口, 每 一 个 子 窗 口 称 作 一 个 窗 片(pane), 每 个 窗 片 可 以 独 立 控 制, 这 给 界 面 设 计 提 供 了 很 大 的 方 便。 ---- 利 用VC 可 以 很 方 便 地 实 现 分 割 窗 口。 分 割 的 方 法 有 两 种: 动 态 和 静 态。 动 态 分 割 时 可 以 根 据 用 户 的 需 要 分 割 成 数 目 不 同 的 窗 片, 但 所 有 窗 片 的 属 性 和 父 窗 口 都 是 一 样 的; 而 静 态 分 割 的 窗 片 的 数 目 在 程 序 中 指 定, 运 行 时 是 固 定 的, 但 每 个 窗 片 可 以 有 各 自 不 同 类 型 的 视(View), 因 此 其 使 用 范 围 更 为 广 泛。 本 文 所 讨 论 的 问 题 仅 限 于 静 态 分 割。 ---- 窗 片 中 视 的 类 型 大 多 是 在 主 窗 口 的 创 建 过 程 中 指 定 的。 这 也 就 意 味 着, 一 个 窗 片 虽 然 可 以 显 示 任 意 类 型 的 视, 但 是 这 种 类 型 一 旦 确 定, 在 程 序 运 行 过 程 中 就 难 以 改 变。 ---- 一、 我 要 的 是 这 样 的 ! ---- 但 是 我 们 有 时 确 实 需 要 改 变 一 个 窗 片 所 显 示 的 视 的 类 型, 也 就 是 说, 需 要 让 一 个 窗 片 显 示 多 种 类 型 的 视。 例 如 一 个 窗 口 被 分 割 成 两 部 分, 一 边 是 命 令 窗 口, 另 一 边 是 工 作 窗 口, 根 据 命 令 窗 口 中 发 出 的 不 同 命 令, 需 要 变 换 不 同 的 工 作 类 型, 这 就 需 要 工 作 窗 口 中 能 够 显 示 多 种 类 型 的 视 窗, 那 么, 如 何 做 到 这 一 点 呢 ? ---- 二、 你 可 以 这 样 做 ! ---- 从 图1 中 可 以 看 到, 本 程 序 共 有 三 个 视 类, 分 别 是: ---- ? 命 令 视 类CCmdView: 用 来 控 制 右 边 窗 片 中 不 同 视 的 显 示; ---- ? 选 项 按 钮 视 类CRdiView: 显 示 在 右 窗 片 中 的 选 项 视 类; ---- ? 检 查 按 钮 视 类CChkView: 显 示 在 右 窗 片 中 的 检 查 视 类。 ---- 这 三 个 视 类 都 是CFormView 的 子 类。 ---- 下 面 我 们 来 看 如 何 在 右 窗 片 内 进 行 两 类 视 间 的 切 换。 实 际 上, 由 视A 切 换 到 视B 的 原 理 很 简 单, 那 就 是: ---- 1. 从 窗 片 中 删 除 视A; ---- 2. 往 窗 片 中 添 加 视B。 ---- 步 骤1 的 实 现 非 常 简 单, 仅 用 一 条 语 句 即 可: ---- m_wndSplitter.DeleteView(0, 1); ---- 但 它 是 必 不 可 少 的, 因 为 你 不 能 让 一 个 窗 片 同 时 包 含 两 个 视。 我 本 来 希 望 往 一 个 窗 片 中 添 加 新 的 视 时,VC 会 自 动 将 原 来 的 视 删 掉, 可 是 它 不 干。 ---- 我 们 来 看 如 何 实 现 步 骤2, 当 一 个 窗 片 是 空 的 时 候, 怎 样 往 里 面 添 加 一 个 视 呢 ? 其 实 这 样 的 功 能 在 程 序 里 我 们 已 经 用 过 了, 看 下 面 的 语 句: BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { … … if (!m_wndSplitter.CreateView(0, 0, pContext->m_pNewViewClass, size, pContext)) … …}---- 是 的, 用 的 就 是CSplitterWnd::CreateView(), 要 注 意 的 是 它 共 有 五 个 参 数, 其 中 前 两 个 用 来 指 定 分 割 窗 口 的 窗 片, 第 三 个 用 来 指 定 视 的 类 型, 第 四 个 指 定 视 的 大 小。 最 后 的 一 个 我 们 暂 时 用 不 上, 用 空 值NULL 就 可 以 了。 ---- 这 样 我 们 就 可 以 编 写 视 切 换 的 代 码 了。 因 为 视 切 换 要 操 纵m_wndSplitter, 而 它 是 主 窗 口 的 成 员, 因 此 切 换 过 程 最 好 设 计 为 主 窗 口 的 成 员 函 数。 但 是 切 换 命 令 是CCmdView 接 受 的, 因 而 可 以 让CCmdView 接 受 到 视 更 改 消 息 后, 将 消 息 传 给 主 窗 口, 由 主 窗 口 完 成 视 更 改。 具 体 的 代 码 是 这 样 的: ---- 命 令 视 类 中 的 消 息 映 射: BEGIN_MESSAGE_MAP(CCmdView, CFormView) … … ON_BN_CLICKED(IDC_CHECK, OnSwitchToCheckView) ON_BN_CLICKED(IDC_RADIO, OnSwitchToRadioView) … …END_MESSAGE_MAP() 命 令 视 类 中 的 消 息 响 应:void CCmdView::OnSwitchToCheckView() { AfxGetApp()->m_pMainWnd->SendMessage(WM_COMMAND, ID_CHECK);}void CCmdView::OnSwitchToRadioView() { AfxGetApp()->m_pMainWnd->SendMessage(WM_COMMAND, ID_RADIO);} 主 窗 口 中 的 消 息 映 射:BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd) … … ON_COMMAND(ID_CHECK, OnSwitchToCheckView) ON_COMMAND(ID_RADIO, OnSwitchToRadioView) … …END_MESSAGE_MAP() 主 窗 口 中 的 消 息 响 应:void CMainFrame::OnSwitchToCheckView() { m_wndSplitter.DeleteView(0, 1); m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CChkView), CSize(0, 0), NULL); m_wndSplitter.RecalcLayout();}void CMainFrame::OnSwitchToRadioView() { m_wndSplitter.DeleteView(0, 1); m_wndSplitter.CreateView(0, 1,RUNTIME_CLASS(CRdiView),CSize(0, 0), NULL); m_wndSplitter.RecalcLayout();}---- 好 啦, 运 行 一 下 这 个 程 序, 感 觉 是 否 不 错 ? 看 来 大 功 告 成 了, 可 是 … … ---- 三、 还 有 一 个 问 题 ---- 在 运 行 我 们 辛 辛 苦 苦 编 出 来 的 程 序 时, 回 头 看 看VC 的 调 试 窗 口, 你 会 发 现 有 很 多 行 这 样 的 话: ---- Create view without document. ---- 这 是 说 我 们 创 建 了 视, 可 是 没 有 相 应 的 文 档。 好 在 这 只 是 警 告 信 息, 不 是 什 么 错 误, 如 果 你 不 需 要 相 应 的 文 档, 就 完 全 不 用 去 管 它。 可 是,VC 中 一 种 很 重 要 的 结 构 就 是 文 档- 视 结 构, 利 用 这 种 结 构, 对 数 据 操 纵 起 来 非 常 方 便。 如 果 需 要 建 立 与 视 相 对 应 的 文 档, 应 该 怎 么 办 呢 ? ---- 这 就 涉 及 到VC 中 文 档- 视 结 构 的 知 识, 不 过 不 用 怕 麻 烦, 与 本 文 有 关 的 就 只 有 这 么 两 点 而 已: ---- 1. 利 用VC 创 建 的 应 用 程 序 一 般 都 会 管 理 一 些 文 档 模 板(Document Template), 文 档 类 和 视 类 的 对 应 关 系 就 是 在 文 档 模 板 里 描 述 的。 ---- 2. 一 个 文 档 可 以 有 多 个 视, 创 建 视 的 时 候, 需 要 根 据 文 档 和 视 的 对 应 关 系, 给 出 它 所 依 附 的 文 档。 ---- 怎 样 实 现 上 述 第 一 点 呢 ? ---- 首 先 建 立 相 应 的 文 档 类:CRdiDoc 和CChkDoc。 ---- 其 次 是 定 义 相 应 的 文 档 模 板, 这 是 应 用 类 的 成 员 变 量。 因 为 在 别 的 类 中 要 使 用 它 们, 我 们 将 之 定 义 为 公 共 类 型: class CViewSwitcherApp : public CWinApp{ … …public: CSingleDocTemplate* m_pRdiDocTemplate; CSingleDocTemplate* m_pChkDocTemplate; … …} 然 后 创 建 这 两 个 文 档 模 板, 并 加 入 到 模 板 列 表 中:BOOL CViewSwitcherApp::InitInstance(){ … … m_pRdiDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CRdiDoc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CRdiView)); AddDocTemplate(m_pRdiDocTemplate); m_pChkDocTemplate = new CSingleDocTemplate( IDR_MAINFRAME, RUNTIME_CLASS(CChkDoc), RUNTIME_CLASS(CMainFrame), RUNTIME_CLASS(CChkView)); AddDocTemplate(m_pChkDocTemplate); … …}---- 至 于 第 二 点, 是 在 创 建 视 时 完 成 的。 还 记 得 创 建 视 的 情 况 么 ? 当 时 有 一 个 叫 做pCreateContext 的 参 数, 我 们 将 之 置 为 空, 这 里 就 要 用 到 它 了。 ---- pCreateContext 是 一 个 指 向 被 称 作" 创 建 上 下 文"(CreateContext) 结 构 的 指 针, 这 个 结 构 中 保 存 一 些 与 创 建 视 相 关 的 内 容。 在 创 建 主 窗 口 时, 系 统 会 构 造 这 样 一 个 结 构, 并 将 它 作 为 参 数 传 递 到 与 创 建 视 有 关 的 函 数 中。 但 现 在 我 们 不 创 建 主 窗 口, 因 此 不 得 不 自 己 构 造 这 样 一 个 结 构。 实 际 上, 该 结 构 中 我 们 所 要 使 用 的 字 段 只 有 三 个: ---- 1. 新 视 所 属 的 文 档 模 板m_pNewDocTemplate; ---- 2. 新 视 的 类 型m_pNewViewClass; ---- 3. 新 视 所 属 的 文 档m_pCurrentDoc; ---- 其 中 仅 有 第 三 项 需 要 新 建, 前 两 项 都 是 已 知 的, 只 要 指 定 即 可。 以 切 换 到 选 项 视 为 例, 修 改 后 的 代 码 是: void CMainFrame::OnSwitchToRadioView() { m_wndSplitter.DeleteView(0, 1); CCreateContext createContext; // 定 义 并 初 始 化CreateContext // 获 取 新 视 所 属 的 文 档 模 板 CSingleDocTemplate* pDocTemplate = ((CViewSwitcherApp*)AfxGetApp())-> m_pRdiDocTemplate; // 创 建 新 文 档 并 初 始 化 CDocument* pDoc = pDocTemplate->CreateNewDocument(); pDoc->OnNewDocument(); // 设 置CreateContext 相 关 字 段 createContext.m_pNewViewClass = RUNTIME_CLASS(CChkView); createContext.m_pCurrentDoc = pDoc; createContext.m_pNewDocTemplate = pDocTemplate; m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CRdiView), CSize(0, 0), &createContext); m_wndSplitter.RecalcLayout();}---- 四、 最 后 的 修 改 ---- 为 了 使 这 个 程 序 更 符 合 要 求, 我 们 还 要 做 一 些 与 更 换 视 无 关 的 修 改。 在 这 个 程 序 中 我 们 一 共 定 义 了 三 种 类 型 的 文 档, 程 序 启 动 时 一 般 要 新 建 一 个 文 档 开 始 工 作, 可 是 它 不 知 道 要 选 择 哪 一 种, 就 弹 出 一 个 对 话 框 来 询 问。
Suncanoe 2002-06-17
  • 打赏
  • 举报
回复
为什么我的程序运行到delete pOldActiveView;时就出错
如果我是在FormView类和CView类之间切换该怎么办?
Richuen22 2002-06-17
  • 打赏
  • 举报
回复
主要是SetActiveView及RemoveView的类函数应用。
cainiao000 2002-06-17
  • 打赏
  • 举报
回复
视图切换

void CRightPaneFrame::SwitchToView(UINT nView)
{

CView* pOldActiveView = GetActiveView();
CView* pNewActiveView = NULL;

switch (nView)
{
case VIEW_PRINT1:
pNewActiveView = (CView*) printview;

break;

case VIEW_LIST1:
pNewActiveView = (CView*) listview;

break;

}

if (pNewActiveView)
{
// don't switch when views are the same
if (pOldActiveView == pNewActiveView) return;

SetActiveView(pNewActiveView);
pNewActiveView->ShowWindow(SW_SHOW);
pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST);

pOldActiveView->ShowWindow(SW_HIDE);
pOldActiveView->SetDlgCtrlID(m_nCurrentViewID);
m_nCurrentViewID = nView;
//
RecalcLayout();
}
}
surfl 2002-04-28
  • 打赏
  • 举报
回复
单文档多视图
void CMainFrame::SwitchToForm(int nForm)
{
CView* pOldActiveView=GetActiveView();
CView* pNewActiveView=(CView*)GetDlgItem(nForm);
if(pNewActiveView==NULL)
{
switch(nForm)
{
case IDD_DOCMANGE_FORM:
pNewActiveView=(CView*) new CDocMangeView;
break;
case IDD_FILELIST:
pNewActiveView=(CView*) new CFile_List;
break;
case IDD_PROLIST:
pNewActiveView=(CView*) new CPro_List;
break;
}
CCreateContext context;
context.m_pCurrentDoc=pOldActiveView->GetDocument();
pNewActiveView->Create(NULL,NULL,0L,CFrameWnd::rectDefault,this,nForm,
&context);
pNewActiveView->OnInitialUpdate();
}
SetActiveView(pNewActiveView);
pNewActiveView->ShowWindow(SW_SHOW);
pOldActiveView->ShowWindow(SW_HIDE);
::SetWindowLong(pNewActiveView->m_hWnd,GWL_ID,AFX_IDW_PANE_FIRST);
RecalcLayout();
delete pOldActiveView;
}

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧