浅谈MFC

来源:互联网 发布:魔镜是啥软件 编辑:程序博客网 时间:2024/06/11 13:05

API:Application Program Interface
Windows操作系统留给了我们两种接口,一种是用户接口(例如我们桌面的图标,可以方便用户取得系统的服务)。另一种是程序接口(通过一个个的API函数来实现和操作系统的交互)主要是面向程序员。
MFC:Microsoft Foundtion Class
MFC是微软把大部分的API函数给我们封装了,更方便我们编程。体验过Windows程序设计的都知道,它是相当复杂繁琐的。其中的许多过程都是重复的,比如窗口的创建,窗口的注册,窗口更新。如果把这些函数封装起来,可以减轻程序编写的工作量,提高效率。于是就有了MFC。
但是不论MFC编程,还是WIN32 SDK编程,都是基于消息,因此全面深刻的理解Windows的消息机制是进行Windows程序设计的基础。
下面的这段代码是一个简单的窗口类,它封装了CreateWindowEx,ShowWindow,UpdateWindow。可以帮助理解MFC是如何对API函数进行封装的。

/*---------------------------------------------------
   CWnd.c  -- MFC program Demo
                 (c++) sixing, 2012.7.15
  ---------------------------------------------------*/
#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WinSunProc(//回调函数
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);

class CWnd  //窗口类,封装了窗口的创建,显示,更新3个API函数
{
public:
 BOOL CreateEx(DWORD dwExStyle,
          LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam);
    BOOL ShowWindow(int nCmdShow);  //这两个函数不在需要句柄参数,因为在类中定义了
 BOOL UpdateWindow();            //HWND m_hWnd,可以共用。
public:
 HWND m_hWnd;
};

BOOL CWnd::CreateEx(DWORD dwExStyle,
          LPCTSTR lpClassName,
    LPCTSTR lpWindowName,
    DWORD dwStyle,
    int x,
    int y,
    int nWidth,
    int nHeight,
    HWND hWndParent,
    HMENU hMenu,
    HINSTANCE hInstance,
    LPVOID lpParam)
{
 m_hWnd=CreateWindowEx(dwExStyle,lpClassName,lpWindowName,dwStyle,x,y,
     nWidth,nHeight,hWndParent,hMenu,hInstance,
     lpParam);
 if(m_hWnd!=NULL)
  return TRUE;
 else
  return FALSE;

}

BOOL CWnd::ShowWindow(int nCmdShow)
{
 return ::ShowWindow(m_hWnd,nCmdShow);
}

BOOL CWnd::UpdateWindow()
{
 return ::UpdateWindow(m_hWnd);
}

int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
)
{
 WNDCLASS wndcls;
 wndcls.cbClsExtra=0;
 wndcls.cbWndExtra=0;//两个额外的数值
 wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//窗口客户区的颜色
 wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);//加载光标
 wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);//加载图标
 wndcls.hInstance=hInstance;//程序的实例
 wndcls.lpfnWndProc=WinSunProc;//指向回调函数
 wndcls.lpszClassName="sixing";//窗口的名字
 wndcls.lpszMenuName=NULL;//指向要调用的菜单地址
 wndcls.style=CS_HREDRAW | CS_VREDRAW;//窗口的风格,发生水平和垂直改变时重新绘制窗口

 RegisterClass(&wndcls);

 CWnd wnd;
 wnd.CreateEx(WS_EX_ACCEPTFILES,"sixing","思行",WS_OVERLAPPEDWINDOW,//创建窗口
  0,0,600,400,NULL,NULL,hInstance,NULL);
 wnd.ShowWindow(SW_SHOWNORMAL);
 wnd.UpdateWindow();

 MSG msg;//定义消息结构体
 while(GetMessage(&msg,NULL,0,0))//设定消息循环
 {
  TranslateMessage(&msg);//把消息进行转换,如把WM_KEYDOWN,WM_KEYUP转换成WM_CHAR消息
  DispatchMessage(&msg);//向应用程序投递消息
 }
 return 0;
}

LRESULT CALLBACK WinSunProc(//回调函数
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
 switch(uMsg)
 {
 case WM_CHAR://程序接受的键盘消息时显示按下键的ASCII码值
  TCHAR szChar[20];
  wsprintf(szChar,"char is %d",wParam);
  MessageBox(hwnd,szChar,"思行",0);
  break;
 case WM_LBUTTONDOWN://左键按下消息
  MessageBox(hwnd,"mouse clicked","思行",0);
  HDC hdc;
  hdc=GetDC(hwnd);//获取设备环境句柄,向客户区显示内容时
  TextOut(hdc,0,50,"努力学习软件设计技术",strlen("努力学习软件设计技术"));
  ReleaseDC(hwnd,hdc);//释放设备环境句柄,必须有
  break;
 case WM_PAINT://窗口重绘消息
  HDC hDC;
  PAINTSTRUCT ps;
  hDC=BeginPaint(hwnd,&ps);//获取设备环境句柄
  TextOut(hDC,0,0,"多抽出一分钟学习 生命更加精彩",strlen("多抽出一分钟学习 生命更加精彩"));
  EndPaint(hwnd,&ps);//释放设备环境句柄,必须有
  break;
 case WM_CLOSE://窗口关闭消息
  if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))
  {
   DestroyWindow(hwnd);//会产生销毁窗口的消息WM_DESTROY
  }
  break;
 case WM_DESTROY://窗口销毁消息
  PostQuitMessage(0);
  break;
 default://对于程序不关心的消息默认的归宿
  return DefWindowProc(hwnd,uMsg,wParam,lParam);
 }
 return 0;
}