随笔-4  评论-9  文章-0  trackbacks-0
                                                            MFC编程学习心得(1)
转载请声明出处,谢谢了
我是刚从vc的sdk编程过渡到这个MFC编程当中的,有些不适应,出了错误改起来很费力,打击了我不小的积极性,于是我苦思良久,看了看一下MFC的CWnd类的函数表,
关注到了这个函数--WindowProc,这个函数是cwnd类的一个虚函数,功能就是处理窗口的消息的,跟sdk编程中的窗口消息函数是一回事,写法大同小异,用这个方法写的程序,开发效率要快很多呢(对于MFC的初学者),下面我来介绍一下吧。
我的开发环境是Microsoft Visual C++ 6.0;
选择WIN32 Application工程建一个空的工程,然后加一个.cpp文件,关键的一部是alt—f7打开settings选项,在general选项中的MICROSOFT foundation classes选项中选择use MFC in a static library,这样就可以在这个工程中使用MFC基础类库编程了,这样可以大大的提高编程的效率,减小了出错的几率。
好吧,开始进入今天的主题吧。大家都知道MFC工程中有界面的程序肯定有两个类,一个是CWND类,另一个就是应用程序类CWINAPP类,所以今天讲那这两个类写程序例子(很基础的,但是很关键).
定义一个类,是CWINAPP类的派生类,写法是这样的大家看代码吧。
大家可以把下面的类定义写在一个头文件里,留着备用。
  class CMyApp::public CWinApp
  { 
   public:
   virtual BOOL InitInstance(); //这个类中就这一个函数,他的作用就是创建一个CWnd类的一个,大家笼统的就这么理解吧,关键还是看代码去理解吧。
  };
下面在定义个CWND类的派生类:
  class CMyWnd::public CWnd
  {
   public:
   CMyWnd();  //这个函数是构造函数,一些东西要在这里初始化呢
   virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam ); //今天的主角就是这个函数了
  }
在添加一个.cpp文件吧;下面就是这些类函数的实现代码了,在.cpp文件中写的
现看看CWyApp类中的InitInstance函数吧;
  最先定义一个CMyApp类的对象:
  CMyApp theApp;
  BOOL CMyApp::InitInstance()
  {
   m_pMainWnd=new CMyWnd;
   ::ShowWindow(*m_pMainWnd,this->m_nCmdShow);
   ::UpdateWindow(*m_pMainWnd);
   return TRUE;   //这个函数就这样完成了,三行代码,很简单,主要是显示窗口,更新窗口重头戏在后面呢!
  }
  CMyWnd::CMyWnd()
  {
   LPCTSTR lpszClassName=AfxRegisterWndClass(CS_HREDRAW |CS_VREDRAW,::LoadCursor(NULL,IDC_ARROW),  //注册窗口
  (HBRUSH)(COLOR_3DFACE+1)); //注册窗口
 CreateEx(WS_EX_CLIENTEDGE,lpszClassName,"新的开始",
  WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0);  //创建窗口
 
  }
  
  
  
  
  
关键的代码就是下面的这段,可以是说一个窗口的消息函数,所有的消息都要在这个函数中处理,和SDK编程中的消息写法一样,不用象在MFC中那样添加消息映射了,理解起来很方便,很直观。 
LRESULT CMyWnd::WindowProc(UINT message,WPARAM wParam,LPARAM lparam)// 这个函数相当于WinMain函数中的窗口函数
{
 HDC hdc;
 PAINTSTRUCT ps;
 switch (message)
 {
 case WM_CREATE:
  {
   ::SetWindowText(m_hWnd,"hello First WND");
   ::CreateWindowEx(0,"button","测试",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,50,50,110,30,m_hWnd,
    (HMENU)IDB_BUTTON,AfxGetApp()->m_hInstance,0);
   break;
  }
 case WM_COMMAND:  // 这个消息是用来接收控件发送来的消息的,
  {
   switch (LOWORD(wParam))
   {
   case IDB_BUTTON:  //我们的按钮控件的ID
    {
     //::SendMessage(m_hWnd,WM_CLOSE,0,0);  //测试只用
     HWND findwnd=::FindWindow(NULL,"你要找的窗口的名字"); //返回你要找的窗口的窗口句柄
     ::SetWindowText(findwnd,"text");  //设置你要找的窗口的名字
     break;
    }
   }
   break;
  }
 case WM_NCDESTROY:  
  {
   ::PostQuitMessage(0);
   //delete this;  //不注释会出错的
   break;
  }
 case WM_PAINT:   //窗口重画是调用这个函数
  {
   hdc=::BeginPaint(m_hWnd,&ps);
   ::TextOut(hdc,50,50,"hello First WND",strlen("hello First WND"));
   break;
  }
 case WM_CLOSE:   //窗口关闭时调用这个消息
  {
   int confirm;
   confirm=::MessageBox(NULL,"确定关闭么","    ",MB_YESNO|MB_ICONQUESTION);
   
   break;
  }
 
 }
 return Default();  //交给系统处理
}
做一下总结吧,看得懂的人明白了吧,其实只是吧CWND类的WindowProc函数给重载了,然后就像在SDK编程中窗口函数中写法是一样的。
最后祝大家新年快乐,万事如意。
再见了。
posted on 2008-12-31 09:32 烟雨八戒 阅读(4846) 评论(3)  编辑 收藏 引用

评论:
# re: MFC编程学习心得(1) 2009-01-02 12:54 | 徐东海
楼主你好,看了你的文章写得很好,不过有点疑问
BOOL CMyApp::InitInstance()
{
m_pMainWnd=new CMyWnd;
::ShowWindow(*m_pMainWnd,this->m_nCmdShow);
::UpdateWindow(*m_pMainWnd);
return TRUE; //这个函数就这样完成了,三行代码,很简单,主要是显示窗口,更新窗口重头戏在后面呢!
}

这段代码中的ShowWindow(*m_pMainWnd,this->m_nCmdShow);第一个参数应该是窗口句柄啊,m_pMainWnd->m_hWnd这个参数才正确吧

应该修改如下
::ShowWindow(m_pMainWnd->m_hWnd,this->m_nCmdShow);
::UpdateWindow(m_pMainWnd->m_hWnd);  回复  更多评论
  
# re: MFC编程学习心得(1)[未登录] 2009-01-02 14:31 | 烟雨八戒
@徐东海
你可能知道CWinThread::m_pMainWnd是一个数据成员来保存你的线程的主窗口对象的指针,他代表一个窗口,去地址就是这个窗口的地址,所以就是更新这个窗口和现实这个窗口,你的那个方法也是可行的。我把代码上传到我的博客了,你可以下载一下,谢谢你的评论,大家多多交流才会进步的快。  回复  更多评论
  
# re: MFC编程学习心得(1) 2009-01-02 14:36 | 烟雨八戒

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理