.......
在VIEW菜单中选择ClassWizard菜单项,系统打开MFC ClassWizard对话框,接下来我们要为视窗类添加处理键盘事件的成员函数。在Classname一栏中选中类CMyView,然后在messages一栏中选中消息wm_char,单击add function按钮,系统就自动往CMyView类中添加了处理wm_char消息的成员函数的框架。单击edit code按钮,接下来对OnChar这个成员函数进行编辑和修改。
可以看出系统已经自动在这个成员函数中添加了CMyView的基类CView的WM_CHAR消息的处理函数。注意这一行代码:
BEGIN_MESSAGE_MAP(CMyView, CView)
//{{AFX_MSG_MAP(CMyView)
ON_WM_CHAR()
ON_WM_LBUTTONDOWN()
ON_WM_CANCELMODE()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, 
  CView::OnFilePrintPreview)
END_MESSAGE_MAP()
它被放在mfc的消息映射宏BEGIN_MESSAGE_MAP中,它的作用就是把windows系统发来的WM_CHAR消息连接到CMyView类的成员函数OnChar上,即把这个成员函数作为处理WM_CHAR消息的过程。接下来我们就往这个成员函数中添加处理WM_CHAR消息的具体代码。
首先在OnChar函数中添加如下的代码:
void CMyView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
// TODO: Add your message handler code here and/or call default
   CMyDoc * pdoc;
   pdoc=GetDocument();
}
这段代码的作用是首先定义一个指向文档类对象的指针pdoc,然后利用CMyView类的成员函数getdocument()获取指向当前视窗类所对应的文档类对象的指针,并把这个指针赋给定义的文档类型指针pdoc,这样我们在后面就可以用“pdoc_>mystring”的方式访问文档类中定义的公有数据成员mystring了。
接着往函数OnChar中添加如下的代码:
pdoc_>mystring=nChar;
CClientDC mydc(this);
mydc.TextOut(0,0,pdoc_>mystring,
pdoc_>mystring.GetLength());

这段代码中的第一行代码的作用是根据从消息WM_CHAR中传来的参数nchar,也就是键盘中输入的字符的ASCII码,把输入的字符添加到文档中的字符串对象mystring中。
在介绍第二行代码前要先介绍设备描述表的概念。设备描述表也称为设备上下文,在windows环境中,当需要对一个对象,如打印机,屏幕,窗口等进行输出时,就必须先获取这个对象的设备描述表,然后通过这个设备描述表来进行输出。使用设备描述表带来的最大的好处就是输出格式的一致性,因为输出不再是直接针对具体的设备,而是通过统一格式的设备描述表间接地实现。第二行代码的作用就是定义并生成了一个当前视窗的客户区的设备描述表对象MYDC,其中的参数THIS是面向对象语言中的一个重要的关键字。指代成员函数所在类的对象的指针。在生成了视窗的客户区的设备描述表MYDC之后,我们可以利用它在视窗的客户区中输出数据了。
这段代码的第三行就是调用设备描述表MYDC的方法TEXTOUT,在视窗的客户区中输出文档中的字符串MYSTRING了。
我们在前面曾经指出,一个文档可以对应多个视窗。如果用户通过某个视窗更改了文档中的数据,就比如上面的代码当中,我们通过视窗CMYWIVE更改了文档中的字符串对象MYSTRING,那么系统又如何维护同一文档的不同的视窗显示的数据的一致性呢?我们接着在OnChar函数中输入如下的代码:
pdoc_>UpdateAllViews(this,0L,0);
这行代码的作用就是通知本视窗所在的文档的所有其他的视窗,文档中的数据已经更新,这些视窗应该重新从文档中取回数据用来显示,这样就维持了同一文档的所有视窗的数据的一致性。这一行是视窗类中对文档的数据作了修改以后需要加的一条典型语句。
接下来运行这个程序,在BUILD菜单中选择REBUILD ALL菜单项来编译连接应用程序,然后单击BUILD菜单的EXECUTE菜单项运行程序,从键盘上输入一些字符,可以发现这些字符显示在视窗也就是主窗口的客户区当中。
.......
在CV中OnChar函数原来的代码是:
void CMyView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
// TODO: Add your message handler code here and/or call default
CView::OnChar(nChar, nRepCnt, nFlags);
}
请问这些代码应该加在那里,为什么?

解决方案 »

  1.   

    添加在这行代码后面:// TODO: Add your message handler code here and/or call default
      

  2.   

    是指CView::OnChar(nChar, nRepCnt, nFlags);
    放在最后
      

  3.   

    void CMyView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
    {
    // TODO: Add your message handler code here and/or call default
       CMyDoc * pdoc;
       pdoc=GetDocument();
    pdoc_>mystring=nChar;
    CClientDC mydc(this);
    mydc.TextOut(0,0,pdoc_>mystring,
    pdoc_>mystring.GetLength());

    pdoc_>UpdateAllViews(this,0L,0);

    CView::OnChar(nChar, nRepCnt, nFlags);
    }
    是这样吗,不行,
    提示出错:my.exe - 6 error(s), 2 warning(s)
      

  4.   

    Compiling...
    myView.cpp
    D:\myProjects\my\myView.cpp(110) : error C2065: 'pdoc_' : undeclared identifier
    D:\myProjects\my\myView.cpp(110) : error C2065: 'mystring' : undeclared identifier
    D:\myProjects\my\myView.cpp(110) : warning C4800: 'unsigned int' : forcing value to bool 'true' or 'false' (performance warning)
    D:\myProjects\my\myView.cpp(110) : error C2106: '=' : left operand must be l-value
    D:\myProjects\my\myView.cpp(113) : error C2228: left of '.GetLength' must have class/struct/union type
    D:\myProjects\my\myView.cpp(113) : error C2664: 'int __thiscall CDC::TextOutA(int,int,const char *,int)' : cannot convert parameter 3 from 'bool' to 'const char *'
            Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
    D:\myProjects\my\myView.cpp(115) : error C2065: 'UpdateAllViews' : undeclared identifier
    D:\myProjects\my\myView.cpp(115) : warning C4552: '>' : operator has no effect; expected operator with side-effect
    Error executing cl.exe.Results
    my.exe - 6 error(s), 2 warning(s)
      

  5.   

    To :hnyyy(前进) :ok!
    pdoc_>改为了pdoc->Compiling...
    myView.cpp
    D:\myProjects\my\myView.cpp(110) : error C2039: 'mystring' : is not a member of 'CMyDoc'
            d:\myprojects\my\mydoc.h(13) : see declaration of 'CMyDoc'
    D:\myProjects\my\myView.cpp(112) : error C2039: 'mystring' : is not a member of 'CMyDoc'
            d:\myprojects\my\mydoc.h(13) : see declaration of 'CMyDoc'
    D:\myProjects\my\myView.cpp(113) : error C2039: 'mystring' : is not a member of 'CMyDoc'
            d:\myprojects\my\mydoc.h(13) : see declaration of 'CMyDoc'
    D:\myProjects\my\myView.cpp(113) : error C2228: left of '.GetLength' must have class/struct/union type
    Error executing cl.exe.Results
    my.exe - 4 error(s), 0 warning(s)
      

  6.   

    mydoc.h中
    定义一个
    CString  mystring;就行了。
      

  7.   

    定义过了,一开始就定义了!
    在左边的工作区用右键单击CMyDoc选项,在弹出的菜单中选中Add member variable菜单项。
    图2.2系统弹出Add Member Variable对话框。Variable Type一栏用来输入成员变量的类型。这里设置为CString,即字符串类型,Variable Declaration一栏用来输入变量的名字,这里不妨输入为mystring,Access组合框用来设置成员变量的访问权限,缺省为Public,设好后单击OK按钮关闭对话框。如下图2.3所示:
    图2.3这时,如果打开类CMyDoc的头文件、可以发现其中已经自动加入了我们定义的公有变量mystring。这个变量就可以作为我们的文档类的数据存储空间,因为mystring是公有成员,它就可以被文档对应的视窗所处理了。在mydoc.h中已有代码:
    // Implementation
    public:
    CString myString;
    virtual ~CMyDoc();
    #ifdef _DEBUG
    virtual void AssertValid() const;
    virtual void Dump(CDumpContext& dc) const;
    #endif
      

  8.   

    小弟来插一句,是不是你的代码输入有问题!不如,你定义了myString,却在用的时候打成了mystring,不要忘了c++失去分大小写的哟,我也犯过这样的错误!
      

  9.   

    void CMyView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
    {
    // TODO: Add your message handler code here and/or call default
       CMyDoc * pdoc;
       pdoc=GetDocument();
    pdoc_>mystring=nChar;
    CClientDC mydc(this);
    mydc.TextOut(0,0,pdoc_>mystring,
    pdoc_>mystring.GetLength());}