初学者分析MFC代码2

来源:互联网 发布:十二楼李渔知乎 编辑:程序博客网 时间:2024/06/03 01:22

作者:liguisen

blog:http://blog.csdn.net/liguisen/

上一篇我们把所有注释都去掉了,再来看看还能不能删掉一些代码?(代码篇幅较长,请耐心看)
  先看StdAfx.h:
  #if !defined(AFX_STDAFX_H__582A90CE_7355_479E_9E7F_F376479662DA__INCLUDED_)
#define AFX_STDAFX_H__582A90CE_7355_479E_9E7F_F376479662DA__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif

#define VC_EXTRALEAN  

#include <afxwin.h>        
#include <afxext.h>        
#include <afxdisp.h>       
#include <afxdtctl.h>  
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>   
#endif

#endif

include我们是熟悉的,其它的代码......就不太懂了,能删掉吗?试一试,把#include <afxwin.h>前面的都删掉,编译,出问题了fatal error C1020: unexpected #endif,哦,多了一个#endif,原来刚才删的时候前面有一个#if是和#endif搭配的,把最后一个#endif删掉,编译,运行,没问题。既然是这样,把#include <afxdtctl.h>后面的也删掉,这样,最后就只剩下:
#include <afxwin.h>        
#include <afxext.h>        
#include <afxdisp.h>       
#include <afxdtctl.h>

  再看StdAfx.cpp,天啊,居然只有一句:#include "stdafx.h",我们知道,cpp是实现文件,那不等于什么都没有做吗?我们试着把StdAfx.cpp整个从工程里面删掉(在FileView里面删掉,然后关闭工程,在资源管理器里面把这个文件删掉,重新打开工程)。编译,又出问题了fatal error C1083: Cannot open precompiled header file: 'Debug/Test1.pch': No such file or directory,看来这个还不能随便删:)。把这个工程关闭,打开我们备份(注意:我们是在搞破坏,每一步都要做好备份)的工程。
  继续看其它文件,和上面类似,最后的Test1.h是这样的:
#include "resource.h"
class CTest1App : public CWinApp
{
public:
 CTest1App();

 public:
 virtual BOOL InitInstance();
 DECLARE_MESSAGE_MAP()
};

最后的Test1.cpp是这样的:
#include "stdafx.h"
#include "Test1.h"
#include "Test1Dlg.h"

BEGIN_MESSAGE_MAP(CTest1App, CWinApp)
 ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

CTest1App::CTest1App()
{
}

CTest1App theApp;

BOOL CTest1App::InitInstance()
{
 AfxEnableControlContainer(); 
#ifdef _AFXDLL
 Enable3dControls();   
#else
 Enable3dControlsStatic(); 
#endif

 CTest1Dlg dlg;
 m_pMainWnd = &dlg;
 int nResponse = dlg.DoModal();
 if (nResponse == IDOK)
 {
  
 }
 else if (nResponse == IDCANCEL)
 {
  
 } 
 return FALSE;
}

最后的Test1Dlg.h是这样的:
class CTest1Dlg : public CDialog
{
public:
 CTest1Dlg(CWnd* pParent = NULL); 
 enum { IDD = IDD_TEST1_DIALOG };
 protected:
 virtual void DoDataExchange(CDataExchange* pDX); 
protected:
 HICON m_hIcon;
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 DECLARE_MESSAGE_MAP()
};

最后的Test1Dlg.cpp是这样的:
#include "stdafx.h"
#include "Test1.h"
#include "Test1Dlg.h"
class CAboutDlg : public CDialog
{
public:
 CAboutDlg();
 enum { IDD = IDD_ABOUTBOX };

 protected:
 virtual void DoDataExchange(CDataExchange* pDX);   

protected:
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 
END_MESSAGE_MAP()

CTest1Dlg::CTest1Dlg(CWnd* pParent )
 : CDialog(CTest1Dlg::IDD, pParent)
{
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTest1Dlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CTest1Dlg, CDialog)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()

BOOL CTest1Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 SetIcon(m_hIcon, TRUE);   
 SetIcon(m_hIcon, FALSE);  

 return TRUE; 
}

void CTest1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}

void CTest1Dlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this);

  SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

  int cxIcon = GetSystemMetrics(SM_CXICON);
  int cyIcon = GetSystemMetrics(SM_CYICON);
  CRect rect;
  GetClientRect(&rect);
  int x = (rect.Width() - cxIcon + 1) / 2;
  int y = (rect.Height() - cyIcon + 1) / 2;

  dc.DrawIcon(x, y, m_hIcon);
 }
 else
 {
  CDialog::OnPaint();
 }
}

HCURSOR CTest1Dlg::OnQueryDragIcon()
{
 return (HCURSOR) m_hIcon;
}

你一定要有耐心仔细观察代码!!

还能再删掉一些吗?能,仔细看看Test1.cpp,在BOOL CTest1App::InitInstance()中有:
AfxEnableControlContainer(); 
#ifdef _AFXDLL
 Enable3dControls();   
#else
 Enable3dControlsStatic(); 
#endif
   上面这些代码是干什么的?跟前面的有点像,应该可以删掉吧?别急!新建一个跟我们这个几乎一样的基于对话框的工程Temp,在选择了Dialog based后别按Finish,Next,你会发现有3项被选中了,把3D controls、Active Controls去掉后Finish,打开Temp.cpp,你会发现那些代码没有了,还犹豫什么?在Test1.cpp中也把它删掉吧!
   再仔细一点,你会发现:
   int nResponse = dlg.DoModal();
 if (nResponse == IDOK)
 {
  
 }
 else if (nResponse == IDCANCEL)
 {
  
 }
  实际起作用的也就是dlg.DoModal(),其它的删掉。
  删了这么多,编译试一试吧,没问题,运行,没问题。按F1试一试?出来一个windows 帮助的对话框,提示我们没有Test1.hlp文件,要不要查找?当然不!那是我们这个程序的帮助文件,我们没有做这个文件,它是不存在的。回到代码里来,找到
BEGIN_MESSAGE_MAP(CTest1App, CWinApp)
 ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
这是什么暂时不用管,我只看到里面有什么Help字样,估计跟我们刚才的操作有关,删掉,编译,又出问题了error LNK2001: unresolved external symbol "protected: virtual struct AFX_MSGMAP const * __thiscall CTest1App::GetMessageMap(void)const " (?GetMessageMapCTest1AppMBEPBUAFX_MSGMAPXZ),出现unresolved external symbol????不知该如何翻译好,不懂的自己查字典吧。我们到Test1.h里看看,有一句DECLARE_MESSAGE_MAP(),跟刚才删掉的都有MESSAGE_MAP,把它也删掉。编译运行没问题,按F1没反应,一切猜测证明是正确的:)。
   在程序标题栏单击右键,点关于,出来一个“关于对话框”,这个大家都很熟悉。它对我们整个程序没什么影响,把它删掉吧。
   它在Test1Dlg.cpp里,找到了带有AboutDlg字样的代码没有?删吧!(再次提醒,注意备份)一大段:
class CAboutDlg : public CDialog
{
public:
 CAboutDlg();
 enum { IDD = IDD_ABOUTBOX };

 protected:
 virtual void DoDataExchange(CDataExchange* pDX);   

protected:
 DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
 
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
 
END_MESSAGE_MAP()
在BOOL CTest1Dlg::OnInitDialog()中的:
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu* pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }
还要把:
void CTest1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
 if ((nID & 0xFFF0) == IDM_ABOUTBOX)
 {
  CAboutDlg dlgAbout;
  dlgAbout.DoModal();
 }
 else
 {
  CDialog::OnSysCommand(nID, lParam);
 }
}
改为:
void CTest1Dlg::OnSysCommand(UINT nID, LPARAM lParam)

 CDialog::OnSysCommand(nID, lParam);
}
然后再到ResourceView里面把about对话框的面板也删掉,编译运行,你会发现“关于”对话框没有了。
加油,再接再厉!仔细看看,有个:
void CTest1Dlg::DoDataExchange(CDataExchange* pDX)
{
 CDialog::DoDataExchange(pDX);
}
看字面意思是做数据交换,目前我们没有做任何数据交换啊,删掉试一试,同时把Test1Dlg.h中关于这个函数的声明virtual void DoDataExchange(CDataExchange* pDX);也删掉。编译运行都没问题。


  代码越来越少了:)。再看:

BOOL CTest1Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 SetIcon(m_hIcon, TRUE);   
 SetIcon(m_hIcon, FALSE);
 return TRUE; 
}
SetIcon应该是设置图标的,Icon就是图标的意思嘛,删!再运行,发现标题栏的那个图标没有了,不影响我们的核心。于是把所有跟Icon有关的代码删掉,代码较多,列出删掉代码后的Test1Dlg.h和Test1Dlg.cpp:
////////////////////////////////////////////////////////////////
Test1Dlg.h:
lass CTest1Dlg : public CDialog
{
public:
 CTest1Dlg(CWnd* pParent = NULL); 
 enum { IDD = IDD_TEST1_DIALOG };
protected:
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 DECLARE_MESSAGE_MAP()
};
///////////////////////////////////////////////////////////////////
Test1Dlg.cpp:
#include "stdafx.h"
#include "Test1.h"
#include "Test1Dlg.h"

CTest1Dlg::CTest1Dlg(CWnd* pParent )
 : CDialog(CTest1Dlg::IDD, pParent)
{
}

BEGIN_MESSAGE_MAP(CTest1Dlg, CDialog)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
END_MESSAGE_MAP()

BOOL CTest1Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 return TRUE; 
}

void CTest1Dlg::OnSysCommand(UINT nID, LPARAM lParam)

 CDialog::OnSysCommand(nID, lParam);
}

void CTest1Dlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this);
 }
 else
 {
  CDialog::OnPaint();
 }
}
然后在ResourceView里面,点开Icon文件夹,把那个图标删掉,rebuild all。你会发现标题栏图标没有了,在资源管理器里面打开Debug文件夹,那个exe文件的图标也变成了那种Dos程序的图标了。


今天就到这里,总结一下:
///////////////////////////////////////////////////
StdAfx.h:
#include <afxwin.h>        
#include <afxext.h>        
#include <afxdisp.h>       
#include <afxdtctl.h>
//////////////////////////////////////////////////
StdAfx.cpp:
#include "stdafx.h"
/////////////////////////////////////////////////
Test1.h:
#include "resource.h"
class CTest1App : public CWinApp
{
public:
 CTest1App();
 public:
 virtual BOOL InitInstance();
};
//////////////////////////////////////////////////
Test1.cpp:
#include "stdafx.h"
#include "Test1.h"
#include "Test1Dlg.h"
CTest1App::CTest1App()
{
}
CTest1App theApp;

BOOL CTest1App::InitInstance()
{
 CTest1Dlg dlg;
 m_pMainWnd = &dlg;
 dlg.DoModal(); 
 return FALSE;
}
///////////////////////////////////////////////////
Test1Dlg.h:
lass CTest1Dlg : public CDialog
{
public:
 CTest1Dlg(CWnd* pParent = NULL); 
 enum { IDD = IDD_TEST1_DIALOG };
protected:
 virtual BOOL OnInitDialog();
 afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
 afx_msg void OnPaint();
 DECLARE_MESSAGE_MAP()
};
///////////////////////////////////////////////////////////////////
Test1Dlg.cpp:
#include "stdafx.h"
#include "Test1.h"
#include "Test1Dlg.h"

CTest1Dlg::CTest1Dlg(CWnd* pParent )
 : CDialog(CTest1Dlg::IDD, pParent)
{
}

BEGIN_MESSAGE_MAP(CTest1Dlg, CDialog)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
END_MESSAGE_MAP()

BOOL CTest1Dlg::OnInitDialog()
{
 CDialog::OnInitDialog();
 return TRUE; 
}

void CTest1Dlg::OnSysCommand(UINT nID, LPARAM lParam)

 CDialog::OnSysCommand(nID, lParam);
}

void CTest1Dlg::OnPaint()
{
 if (IsIconic())
 {
  CPaintDC dc(this);
 }
 else
 {
  CDialog::OnPaint();
 }
}
代码还多吗?下一篇继续!

 
原创粉丝点击