两个怪问题,高手也迷惑

enyuan 2001-08-27 10:01:39
一个程序能否建立多个sdi窗口?
对话框能否有工具条/状态条?
...全文
108 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
xjl1980_81 2001-08-27
  • 打赏
  • 举报
回复
我来回答第二个问题:
给我你的EMAIL,我发个EXAMPLE给你
luoshayu 2001-08-27
  • 打赏
  • 举报
回复
第一个问题我来回答吧
class CMyTemple
{
public:
CDocument * GetTheDocument();
CFrameWnd * GetTheFrameWnd();
CView * GetTheView();
BOOL IsEnable();
BOOL m_enable;
CFrameWnd *m_FrameWnd;
CView *m_View;
CDocument *m_Document;
void Run();
CSingleDocTemplate* m_pTemplate;
CWnd *m_parent;
CString m_title;
CMyTemple(CRuntimeClass *pDoc,CRuntimeClass *pWnd,CRuntimeClass *pView,CWnd *pParent,CString title="查看信息");
virtual ~CMyTemple();

};
CMyTemple::CMyTemple(CRuntimeClass *pDocClass,CRuntimeClass *pWndClass,CRuntimeClass *pViewClass,CWnd *pParent,CString title)
{
if(pDocClass==NULL || pWndClass==NULL || pViewClass ==NULL)
{
m_enable=FALSE;
return ;
}
else
{
m_enable=TRUE;
m_pTemplate = new CSingleDocTemplate(
NULL,
pDocClass,
pWndClass, // main SDI frame window
pViewClass);
m_parent=pParent;
m_title=title;
}
}

CMyTemple::~CMyTemple()
{
if(m_pTemplate!=NULL)
{
delete m_pTemplate;
}
}

void CMyTemple::Run()
{
//打开新文档模板
//得到文档
CDocument *pDoc=m_pTemplate->OpenDocumentFile(NULL);
//保存文档
m_Document=pDoc;
//得到视图
POSITION po=pDoc->GetFirstViewPosition();
CView *pView=pDoc->GetNextView(po);
//保存视图
m_View=pView;
//得到窗口
CFrameWnd *pWnd=(CFrameWnd *)pView->GetParent();
//保存窗口
m_FrameWnd=pWnd;
//设置父窗口
pWnd->SetParent(m_parent);
//得到显示器大小
CPoint point;
point.x=m_parent->GetDC()->GetDeviceCaps(HORZRES);
point.y=m_parent->GetDC()->GetDeviceCaps(VERTRES);
CString str;
str.Format("%d..%d",point.x,point.y);
// AfxMessageBox(str);
//设置窗口大小
CRect rect;
rect.left=point.x/3;
rect.right=(point.x*2)/3;
rect.top=point.y/3;
rect.bottom=(2*point.y)/3;
m_parent->ScreenToClient(&rect);
//设置窗口大小为指定的大小
pWnd->MoveWindow(rect);
//设置窗口的标题
pWnd->SetWindowText(m_title);
//设置窗口模式
//...........
//更新窗口
pWnd->UpdateWindow();
//显示窗口
pWnd->ShowWindow(SW_SHOW);
}

BOOL CMyTemple::IsEnable()
{
return m_enable;
}

CView * CMyTemple::GetTheView()
{
return m_View;
}

CFrameWnd * CMyTemple::GetTheFrameWnd()
{
return m_FrameWnd;
}

CDocument * CMyTemple::GetTheDocument()
{
return m_Document;
}
xyzboat 2001-08-27
  • 打赏
  • 举报
回复
我来回答问题1:
MFC程序有以下几种:
对话框,单文档单视,单文档多视(是不是你说的呢?),多文档多视。

当然,有人喜欢把后两种合在一起。

我不太明白SDI窗口是什幺,回答错了别怪我。
happylaodu 2001-08-27
  • 打赏
  • 举报
回复
我搞对话框比较熟一点,只回第二个问题:
在对话框中使用statusbar

1.定义结构数组:
static UINT BASED_CODE indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};

2.Create等:
if (!m_statusBar.Create(this)||
!m_statusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
else
m_statusBar.SetPaneInfo(0, m_statusBar.GetItemID(0),
SBPS_STRETCH, NULL );

在对话框中使用statusbar比较麻烦,除了要创建之外,还得进行如下工作:

1.用reposQuery得出ControlBar需要占用多少空间。
CRect rcClientStart;
CRect rcClientNow;
GetClientRect(rcClientStart);
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,
AFX_IDW_CONTROLBAR_LAST,
0, reposQuery, rcClientNow);

2.挪动原有控件为ControlBar挪出空间
// Now move all the controls so they are in the same relative
// position within the remaining client area as they would be
// with no control bars.
CPoint ptOffset(rcClientNow.left - rcClientStart.left,
rcClientNow.top - rcClientStart.top);

CRect rcChild;
CWnd* pwndChild = GetWindow(GW_CHILD);
while (pwndChild)
{
pwndChild->GetWindowRect(rcChild);
ScreenToClient(rcChild);
rcChild.OffsetRect(ptOffset);
pwndChild->MoveWindow(rcChild, FALSE);
pwndChild = pwndChild->GetNextWindow();
}

3.调整窗口大小
// Adjust the dialog window dimensions
CRect rcWindow;
GetWindowRect(rcWindow);
rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
MoveWindow(rcWindow, FALSE);

4.最后真正放置ControlBar
// And position the control bars
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

***其实在对话框中放置任何ControlBar都要做这个工作。

***最好是非模式对话框,因为模式对话框中有些更新工作不能正常进行。
可用SetPaneText函数改变状态栏某一栏的文本。
如:
CString buffer;
buffer.Format("ROW = %-5d COL = %3d",line,start-lineIndex);
m_statusBar.SetPaneText(0,buffer);

如果像上面那样要用到CAPS、NUM等标志,则又要麻烦一点。
1. 自己生成一个CStatusBar的子类,为其重载OnIdleUpdateCmdUI函数(相应于WM_IDLEUPDATECMDUI消息,要自己加,classwizard中没有)
(1)#include <afxpriv.h>
(2)ON_MESSAGE(WM_IDLEUPDATECMDUI, OnIdleUpdateCmdUI)
(3)afx_msg LRESULT OnIdleUpdateCmdUI(WPARAM wParam, LPARAM);
(4)
LRESULT CDlgStatusBar::OnIdleUpdateCmdUI(WPARAM wParam, LPARAM)
{
if (IsWindowVisible())
{
CFrameWnd *pParent = (CFrameWnd *)GetParent();
/* 它的父窗口不是CFrameWnd,但没关系,可以强制转换*/
if (pParent)
OnUpdateCmdUI(pParent, (BOOL)wParam);
}
return 0L;
}

2. 保证你的对话框是非模式对话框(参见相关文章),因为只有非模式对话框才有空闲来给你更新工具栏。

3.对话框类中加
(1)#include <afxpriv.h>
(2)ON_UPDATE_COMMAND_UI(ID_INDICATOR_CAPS, OnUpdateKeyIndicator)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_NUM, OnUpdateKeyIndicator)
ON_UPDATE_COMMAND_UI(ID_INDICATOR_SCRL, OnUpdateKeyIndicator)
(3)afx_msg void OnUpdateKeyIndicator(CCmdUI* pCmdUI);
(4)
void CBrowseDlg::OnUpdateKeyIndicator(CCmdUI* pCmdUI)
{
UINT nVK;
UINT flag = 0x0001;

switch (pCmdUI->m_nID)
{
case ID_INDICATOR_CAPS:
nVK = VK_CAPITAL;
break;

case ID_INDICATOR_NUM:
nVK = VK_NUMLOCK;
break;

case ID_INDICATOR_SCRL:
nVK = VK_SCROLL;
break;

default:
TRACE1("Warning: OnUpdateKeyIndicator - unknown indicator 0x%04X.\n",
pCmdUI->m_nID);
pCmdUI->ContinueRouting();
return; // not for us
}

pCmdUI->Enable(::GetKeyState(nVK) & flag);
// enable static text based on toggled key state
ASSERT(pCmdUI->m_bEnableChanged);
}

用工具条嘛,大体相同。

16,551

社区成员

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

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

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