菜鸟请教

solarhe 2004-04-26 03:24:10
1。为什么框架类和视图类的构造函数都被声明为protected
2。在别的类中如何获取他的成员变量并对其赋值(不包扩指针型的方法)
...全文
49 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
solarhe 2004-04-28
  • 打赏
  • 举报
回复

请教enoloo(行者无疆)

因为我建立的是无模式对话框我需要一个

CPointView *m_parent;(我的工程名叫point);

编译时:
\point\mldlg.h(17) : error C2143: syntax error : missing ';' before '*'
\point\mldlg.h(17) : error C2501: 'CPointView' : missing storage-class or type specifiers
\point\mldlg.h(17) : error C2501: 'm_parent' : missing storage-class or type specifiers
Generating Code...
Compiling...
PointView.cpp
\point\mldlg.h(17) : error C2143: syntax error : missing ';' before '*'
\point\mldlg.h(17) : error C2501: 'CPointView' : missing storage-class or type specifiers
\point\mldlg.h(17) : error C2501: 'm_parent' : missing storage-class or type specifiers
\Point\PointView.cpp(113) : error C2039: 'm_parent' : is not a member of 'CMLDlg'
\point\mldlg.h(13) : see declaration of 'CMLDlg'
Generating Code...
Error executing cl.exe.

Point.exe - 7 error(s), 0 warning(s)
我以为是没包含试图类的头文件
可是包含进去更多的错误!
GodInNight 2004-04-27
  • 打赏
  • 举报
回复
惭愧! 偶太弱智了!
彻底明白了。 偶上个问题不是问题了。

多谢enoloo(行者无疆)
GodInNight 2004-04-27
  • 打赏
  • 举报
回复
enoloo(行者无疆),你解释了一些问题,但还有一个问题请教:

#define IMPLEMENT_DYNCREATE(class_name, base_class_name) CObject* PASCAL class_name::CreateObject() { return new class_name; }
CreateObject作为一个静态方法
new class_name的时候,创建了一个对象,这时应该调用class_name 类的构造函数,问题是这个class_name类的构造函数是保护的,这样编译能通过?!

麻烦再做一下解释,多谢!

wzff3000 2004-04-27
  • 打赏
  • 举报
回复
点管理菜单给分,别忘了给小弟几分。嘿嘿!
enoloo 2004-04-27
  • 打赏
  • 举报
回复
CView* p = ((CMainFrame*)AfxGetMainWnd())->GetActiveView();

或者:
CView* p = ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->GetActiveView();

AfxGetMainWnd()返回的,或者m_pMainWnd都是CWnd*类型,需要强制转换成你的窗口类。
CWnd类里面是没有GetActiveView()函数的。GetActiveView()是CFrameWnd中的函数。

注意在doc中包含CMainFrame的头文件。
solarhe 2004-04-27
  • 打赏
  • 举报
回复
我在文档类中想调用视图类的方法采用如下方法:
CView *p;
p=::AfxGetApp()->m_pMainWnd->GetActiveView()
系统提示GetActiveView()不是框架类的成员,
可是在框架类里我这样做又是对的:
this->GetActiveView()
请楼上指教》
enoloo 2004-04-27
  • 打赏
  • 举报
回复
在基于单文档的应用程序中加入具有对话框风格的工具栏

//用CDialogBar把,写一个类CMyDialogBar从CDialogBar继承,可以在上面添加按钮,组合框等,很方便的。

www.vccode.com有很多toolbar的例子。

更新的信息访问www.codeguru.com
solarhe 2004-04-27
  • 打赏
  • 举报
回复
请教enoloo(行者无疆)
我的目的是在基于单文档的应用程序中加入具有对话框风格的工具栏(我在一本书上看到,但做了不对头),比如可以自由添加button等控件!
我在MainFrm.h中定义了:
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CToolBar m_wndmy;/////我的定义
然后在CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)中这样写到:
//.....

if (!m_wndmy.Create(this, WS_CHILD | WS_VISIBLE | CBRS_RIGHT
| CBRS_SIZE_DYNAMIC,IDD_DIALOG1)) //||
//!m_wndmy.LoadToolBar(IDD_DIALOG1))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create

}
m_wndmy.EnableDocking(CBRS_ALIGN_LEFT|CBRS_ALIGN_RIGHT);
DockControlBar(&m_wndmy);
EnableDocking(CBRS_ALIGN_ANY);
//.....
并且创建了对话框资源!ID为:IDD_DIALOG1,并创建了对话框类!
但运行后的程序中的对话框工具栏小的看不见,而且不能拖大!
请各位指教!
solarhe 2004-04-27
  • 打赏
  • 举报
回复
怎么给分呀?
enoloo 2004-04-26
  • 打赏
  • 举报
回复
说得有点乱,以后我在总结把。
这么小的edit写东西也不方便。

enoloo 2004-04-26
  • 打赏
  • 举报
回复
CFrameWnd* CDocTemplate::CreateNewFrame函数我省略了一部分,如下:
if (pDoc != NULL)
ASSERT_VALID(pDoc);
// create a frame wired to the specified document

ASSERT(m_nIDResource != 0); // must have a resource ID to load from
CCreateContext context;
context.m_pCurrentFrame = pOther;
context.m_pCurrentDoc = pDoc;
context.m_pNewViewClass = m_pViewClass;
context.m_pNewDocTemplate = this;

if (m_pFrameClass == NULL)
{
TRACE0("Error: you must override CDocTemplate::CreateNewFrame.\n");
ASSERT(FALSE);
return NULL;
}
CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();
if (pFrame == NULL)
{
TRACE1("Warning: Dynamic create of frame %hs failed.\n",
m_pFrameClass->m_lpszClassName);
return NULL;
}
ASSERT_KINDOF(CFrameWnd, pFrame);

if (context.m_pNewViewClass == NULL)
TRACE0("Warning: creating frame with no default view.\n");
//注意这行CFrameWnd* pFrame = (CFrameWnd*)m_pFrameClass->CreateObject();!!!

这就是MFC “create from serialization only”的根源。
大家一定还记得: pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CStandard_testDoc),
RUNTIME_CLASS(CMainFrame), // main SDI frame window
RUNTIME_CLASS(CStandard_testView));
创建了一个模板,这个模板在内部保存了 文档/框架/视图的类名。
CRuntimeClass* m_pDocClass; // class for creating new documents
CRuntimeClass* m_pFrameClass; // class for creating new frames
CRuntimeClass* m_pViewClass; // class for creating new views

CRuntimeClass是用来根据类名动态创建类对象并动态识别类对象的。他怎么实现呢?就是通过内部按照类层次建立的一个链表。这个链表的每个节点都是一个CRumtimeClass对象。所以,能够通过这个表用类名动态创建一个对象,而且能通过一个对象得到一个类的名字。
//CRumtimeClass内部数据:
LPCSTR m_lpszClassName; //类名
int m_nObjectSize;
UINT m_wSchema; // schema number of the loaded class
CObject* (PASCAL* m_pfnCreateObject)(); // 创建一个对象的函数指针,
//实际上是CreateObject.

实际上,这就是所说的create from serialization 。

那么,这个CRumtimeClass怎么和CMainWnd联系呢?
//CMainWnd
DECLARE_DYNCREATE(CMainFrame) //.h
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd) //.cpp
这个宏展开就是:
#define DECLARE_DYNCREATE(class_name) DECLARE_DYNAMIC(class_name) static CObject* PASCAL CreateObject();

#define IMPLEMENT_DYNCREATE(class_name, base_class_name) CObject* PASCAL class_name::CreateObject() { return new class_name; } IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, class_name::CreateObject)
IMPLEMENT_DYNCREATE宏负责将这个类(CMainWnd)的信息插入到列表中。

#define IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) AFX_COMDAT const AFX_DATADEF CRuntimeClass class_name::class##class_name = { #class_name, sizeof(class class_name), wSchema, pfnNew, RUNTIME_CLASS(base_class_name), NULL }; CRuntimeClass* class_name::GetRuntimeClass() const { return RUNTIME_CLASS(class_name); }
//这样,当要创建对象的时候,就用CreateObject.实际上doctemplate在内部干这种事情。
//先说到这,有事要忙,回来接着看。
//说得不对的请指出。




enoloo 2004-04-26
  • 打赏
  • 举报
回复
protected: // create from serialization only
CMainFrame();

实际上,在内部CMainFrame是由doctemplate创建的。

CDocument* CSingleDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
BOOL bMakeVisible) //docsingl.cpp
{
pDocument = CreateNewDocument(); //在这里创建文档
ASSERT(pFrame == NULL); // will be created below
bCreated = TRUE;
if (pFrame == NULL) //一个很大的话题
{
ASSERT(bCreated);

// create frame - set as main document frame
BOOL bAutoDelete = pDocument->m_bAutoDelete;
pDocument->m_bAutoDelete = FALSE;
// don't destroy if something goes wrong
pFrame = CreateNewFrame(pDocument, NULL); //在这里创建框架窗口
pDocument->m_bAutoDelete = bAutoDelete;
if (pFrame == NULL)
{
AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
delete pDocument; // explicit delete on error
return NULL;
}
}
if (lpszPathName == NULL) //如果是新建文档
{
// create a new document
SetDefaultTitle(pDocument);

// avoid creating temporary compound file when starting up invisible
if (!bMakeVisible)
pDocument->m_bEmbedded = TRUE;

if (!pDocument->OnNewDocument()) //调用用户的新建文档函数拉~~ virtual!!!
{
// user has been alerted to what failed in OnNewDocument
TRACE0("CDocument::OnNewDocument returned FALSE.\n");
if (bCreated)
pFrame->DestroyWindow(); // will destroy document
return NULL;
}
}
CWinThread* pThread = AfxGetThread();
if (bCreated && pThread->m_pMainWnd == NULL)
{
// set as main frame (InitialUpdateFrame will show the window)
pThread->m_pMainWnd = pFrame; //主窗口
}
InitialUpdateFrame(pFrame, pDocument, bMakeVisible); //更新视图

return pDocument;

}

//注意上面的pFrame = CreateNewFrame(pDocument, NULL);这个函数。

CFrameWnd* CDocTemplate::CreateNewFrame(CDocument* pDoc, CFrameWnd* pOther) //doctempl.cpp
{
//....
// create new from resource
if (!pFrame->LoadFrame(m_nIDResource,
WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, // default frame styles
NULL, &context))
{
TRACE0("Warning: CDocTemplate couldn't create a frame.\n");
// frame will be deleted in PostNcDestroy cleanup
return NULL;
}

// it worked !
return pFrame;
}

//看看大家熟悉的LoadFrame函数:
enoloo 2004-04-26
  • 打赏
  • 举报
回复
sorry,sorry

来澄清一个错误:

框架类CFrameWnd的构造函数是public的,CWnd也是。MFC版本4.2.
视图类构造函数是protected的,他又纯虚函数,比如OnDraw.

特此更正。实在不好意思。

访问他们的变量还是通过子类对象,或者成员函数。
GodInNight 2004-04-26
  • 打赏
  • 举报
回复
第一问题很有意思:
MFC 加的注释是 // create from serialization only
neilxp(neilxp) 没有解释清楚。

外部没有调用构造函数的必要 不能简单说明问题。

实际上这些类对象是怎样创建的。期待有大侠说得清楚一点

enoloo 2004-04-26
  • 打赏
  • 举报
回复
1,框架类和视图类只能由其子类来构造。而且框架类和视图类不能实例化,也就是不能申明他们的对象。这是由c++的特性决定的。因为他们都有纯虚函数。
比如视图有:virtual void OnDraw(CDC* pDC) = 0;

2,通过子类对象来访问。内部的变量通过成员函数来访问。
subtop 2004-04-26
  • 打赏
  • 举报
回复
AfxGetMainWnd(),然后强制类型转换,可以得到框架类对象,然后访问其公共属性或方法
快乐鹦鹉 2004-04-26
  • 打赏
  • 举报
回复
你的要求还真有意思。不通过指针那通过什么啊?
申明成构造函数是因为不让外边调用,但是需要让子类可以使用
neilxp 2004-04-26
  • 打赏
  • 举报
回复
1.因为没在外部调用构造函数的必要
2用函数

16,471

社区成员

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

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

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