现在的位置: 首页 > 综合 > 正文

Win32 and MFC

2013年06月22日 ⁄ 综合 ⁄ 共 3802字 ⁄ 字号 评论关闭
//Hello world  application class
class CMyApp : public CWinApp
{
public:
    
virtual BOOL InitInstance();
}
;

// frame window class
class CMyFrame : public CFrameWnd
{
public:
    CMyFrame();
protected:
    
// "afx_msg" indicates that the next two functions are part
    
//  of the MFC library message dispatch system
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg 
void OnPaint();
    DECLARE_MESSAGE_MAP()
}
;

// MyApp.cpp
   #include <afxwin.h> // MFC library header file declares base classes
#include "myapp.h"
 
CMyApp theApp; 
// the one and only CMyApp object
 
BOOL CMyApp::InitInstance()
{
    m_pMainWnd 
= new CMyFrame();
    m_pMainWnd
->ShowWindow(m_nCmdShow);
 
    m_pMainWnd
->UpdateWindow();
    
return TRUE;
}


BEGIN_MESSAGE_MAP(CMyFrame, CFrameWnd)
    ON_WM_LBUTTONDOWN()
    ON_WM_PAINT()
END_MESSAGE_MAP()

CMyFrame::CMyFrame()
{
    Create(NULL, _T(
"MYAPP Application"));    // _T转换ascii字符为unicode
}

 
void CMyFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
    TRACE(
"Entering CMyFrame::OnLButtonDown - %lx, %d, %d ",
          (
long) nFlags, point.x, point.y);               // 非常方便的方法,在debug模式向控制台输出信息
}

 
void CMyFrame::OnPaint()
{
    CPaintDC dc(
this);
    dc.TextOut(
00"Hello, world!");
}

CWinAPP可以理解为是MFC程序的进入点,每一个application只有一个application对象,这个对象与其他对象协同工作,并且此对象应该继承自CWinAPP。你应该定义你的CWinAPP对象为全局变量。

实际上系统生成的WinMain入口函数依赖以下方法来获得你定义的CWinApp对象的相关信息

  • AfxGetApp   Obtains a pointer to the CWinApp object.

  • AfxGetInstanceHandle   Obtains a handle to the current application instance.

  • AfxGetResourceHandle   Obtains a handle to the application's resources.

  • AfxGetAppName   Obtains a pointer to a string containing the application's name. Alternately, if you have a pointer to the CWinApp object, use m_pszExeName to get the application's name.

根据MSDN所提供的信息,CWinAPP继承自CWinThread。 MFC支持多线程,每一个applications至少含有一个线程,而被你的CWinAPP对象使用的线程是主线程。

CWinAPP控制程序的初始化,运行和终止。通过覆写虚函数你可以定义自己的操作。这些操作都是impure virtual的(关于impure virtual参见Effective C++ 条款34 区分接口继承和实现继承),最典型的有:

InitInstance Override to perform Windows instance initialization, such as creating your window objects.

Run Runs the default message loop. Override to customize the message loop.

ExitInstance Override to clean up when your application terminates.

在这个程序中,CWinAPP派生出一个application class,而且覆写了InitInstance函数来创建程序的主窗口对象,在本例中是CMyFrame,继承自CFrameWnd。

关于CFrameWnd和相关类型:

CFrameWnd

The base class for an SDI application's main frame window. Also the base class for all other frame window classes.

CMDIFrameWnd

The base class for an MDI application's main frame window.

CMDIChildWnd

The base class for an MDI application's document frame windows.

CMiniFrameWnd

A half-height frame window typically seen around floating toolbars.

COleIPFrameWnd

Provides the frame window for a view when a server document is being edited in place.

在MFC的Application Wizard中,根据选择的不同(SDI or MDI or Others),将会自动派生以上类中的一个来产生不同的窗口框架。

Windows应用程序是靠消息来驱动的,消息是一个描述事件的结构

在Windows应用程序的主函数中,首先要注册窗口类,然后创建并显示窗口。创建窗口后程序就进入消息循环,在消息循环中,程序不断地获得消息并将消息派送给对应的窗口函数进行处理。在上述程序中定义了两个消息处理函数(OnPaint、OnLButtonDown),通过宏定义注册

窗口函数是处理事件的地方,它为switch-case结构,每一个case对应一段消息相应代码。
CWinApp类是MFC对Windows主函数的封装,通过派生 CWinApp可以得到自己的应用程序类,在应用程序类中主要实现了全局初始化操作,应用程序类创建了主窗口后便进入了消息循环。即

InitInstance -> Run

消息映射:

在上述程序中,用户按下鼠标左键,windows会自动发送WM_LBUTTONDOWN消息给该窗口,如果用户程序需要对这个事件有所相应的话,在视图类中就必须包含于下面给出函数类似的成员函数

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{

          
// TODO: EVENT PROCESSING CODE HERE

}

在头文件中也应包含相应的函数原型说明

afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg 宏没有其他用途,只是表明该函数是针对消息映射函数而言的。

在代码文件中还要有一个消息映射宏,该消息映射宏用来将OnLButtonDown函数和应用框架连接起来
BEGIN_MESSAGE_MAP(CMyView, CView)
    ON_WN_LBUTTONDOWN()
END_MESSAGE_MAP()

在头文件中还要包含宏
DECLARE_MESSAGE_MAP()

那么怎样才能知道哪个函数和哪个Windows消息对应呢,每一个消息处理函数的名称是唯一的,如在上例中改变了OnLButtonDown函数名,则消息不会被处理。除了一些特殊的消息,Class view提供的Properties窗口提供的Code wizard已经可以自动编制大多数的消息处理函数。

 

关于重绘,在另一个实验中,我在CView中添加了对LBUTTONDOWN的处理,在其中调用

InvalidateRect(&m_rectEllipse); // 设置矩形区域为无效,可激活WM_PAINT消息。

同时在处理WN_PAINT消息的函数 OnDraw(CDC* pDC)中加入

pDC->GetClipBox(&rect);            // 可只对无效的矩形框进行重绘来提高效率

抱歉!评论已关闭.