Beruflich Dokumente
Kultur Dokumente
MFC Overview
Well over 200 classes exist, ranging from GUI to data
manipulation to OLE support to Internet support
Typical MFC naming convention (follows
Hungarian)C<class name> example CPen
Most MFC classes are subclasses of class CObject
CObject
CWnd
MFC Fundamentals
Several classes are fundamental encapsulations of Win32
functionality (well cover some of these much more)
CWinApp encapsulates the concept of a Win32 application
CCmdTarget encapsulates message pump functionality
CWnd encapsulates a generic window
CDialog encapsulates a generic dialog window
CString encapsulates C-style string manipulation (similar
to std::string) (not derived from CObject)
Many, many more CEditBox, CListBox, CMenu, CDC,
CBitmap, etc.
Some functionality has been abstracted without the use of
classes generally Afx<function name>()
Generally stick to available Afx-equivalent functions in
MFC apps if possible
MFC Messaging
So, how is WinMain, WndProc, Messaging, etc. handled in
an MFC app?
MFC applications instantiate a CWinApp-derived class
(derived by you)
CWinApp is typically global and only instantiated once at
program startup (global vars allocated at program start)
CWinApp constructor, called implicitly, kicks things off
CWinApp handles the message pump Peek, Get, Idle,
Pump, etc see CWinApp::Run
It also provides two methods, InitInstance, ExitInstance, to
allow you to initialize at app startup, or cleanup at exit
CWinApp delivers windows messages to windows
belonging to it
Those windows (CWnd derivatives) invoke various virtual
functions based on messages received
CWinApp::Run()
WM_PAINT
(hwnd, rect)
CWinApp::PumpMessage()
AfxWndProc()
(PeekMessage)
(Get/Translate/Dispatch)
CWnd::WindowProc()
Message Map Magic
CWnd::OnPaint()
CYourWnd::OnPaint()
(voila)
CMainFrame
Frame window class container for your main
window in an SDI app, handles most messages,
accelerators, menus, resizing, etc.
Frame windows are somewhat special (more
special in MDI apps)
CChildView
Your window!
// main symbols
// CMyApp:
// See HelloWorldMFC.cpp for the implementation
class CMyApp : public CWinApp
{
public:
CMyApp();
// Overrides
public:
virtual BOOL InitInstance();
// Implementation
public:
afx_msg void OnAppAbout();
DECLARE_MESSAGE_MAP()
};
}
// CMyApp message handlers
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
protected:
virtual void DoDataExchange(CDataExchange* pDX);
DDX/DDV support
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
//
#include "ChildView.h"
class CMainFrame : public CFrameWnd
{
public:
CMainFrame();
protected:
DECLARE_DYNAMIC(CMainFrame)
// Attributes
public:
// Operations
public:
// Overrides
public:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra,
AFX_CMDHANDLERINFO* pHandlerInfo);
// Implementation
public:
virtual ~CMainFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
CChildView
m_wndView;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMainFrame
IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_SETFOCUS()
END_MESSAGE_MAP()
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
// TODO: add member initialization code here
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// CChildView window
#include "stdafx.h"
#include "HelloWorldMFC.h"
#include "ChildView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CChildView
// Attributes
public:
// Operations
public:
// Overrides
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
// Implementation
public:
virtual ~CChildView();
// Generated message map functions
protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};
CChildView::CChildView()
{
}
CChildView::~CChildView()
{
}
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
// CChildView message handlers
BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;
cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass =
AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW),
reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);
return TRUE;
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
void CChildView::OnPaint()
{
CPaintDC dc(this);
dc.TextOut(10,10,"Hello world!");
}
In-Class Project
Create your own MFC application just like the example
Non-dialog based, SDI
Draw the random shapes (Joe not sure which homework
this was or if it was even a homework at all)
Hints:
You will need to handle WM_PAINT
and perhaps WM_TIMER? F1 help on SetTimer
Homework
MFC-ize homework
MFC Continues
Well continue to MFCize various previously
assigned programs
Same concepts apply MFC provides class
encapsulations of the majority of Win32
functionality
Well review the MFCizing of HW5 which
covers:
Additional WM_**** handlers (WM_VSCROLL, etc.)
Child controls (/windows) (CButton, etc.)
Handling control commands
(ON_COMMAND[_RANGE])
Menus
Accelerators
WM_DRAWITEM
As you know, this message allows us to
draw our own controls
This is a basic MFC message conversion
added message handler (via IDE)
CChildView::OnDrawItem()
MFC passes us a pointer to the relevant
DRAWITEMSTRUCT as a param
Not a lot new here
Note: CWnd::OnDrawItem() may cause
trouble, recommend not calling it
WM_VSCROLL - OnVScroll
CScrollBar encapsulates child scroll control
Called on parent window (our CChildView) when a child
scroll control (SB_VERT) has been affected
We assigned child-parent relationship when we called
maScrolls[X].Create(,this,) in
CChildView::OnCreate()
Most windows have only one vertical scroll bar (and
perhaps one horizontal bar)
Thus, MFC does not send the control ID in the
OnVScroll() param list
No problem, MFC does supply the actual pointer to the
CScrollBar object that was affected
We can compare HWNDs to determine which control was
affected
The rest of the function is nearly identical to the
WM_VSCROLL handler (with typical MFC changes)
ON_COMMAND_RANGE
Instructs MFC to invoke a particular method on a
window when any of the commands in the given
range are received (for example, child controls)
Part of the message map macro example:
ON_COMMAND_RANGE(1, 10, OnCommands)
ON_COMMAND - Menus
MFC, by default, gives us a default menu
Each menu selection corresponds to a specific ID
(event)
We can use the IDE to edit the menu and correlate
specific menu events with specific functions on
our window(s)
Its quite similar to the WM_**** - message
handler correlation technique
As we add menu event handlers, Visual adds
ON_COMMAND entries into our windows
message map
Lets take a look
& in front of a character represents a menu
shortcut (&Edit->&Copy becomes Edit->Copy)
Accelerators
An accelerator is an even shorter cut
Control-C for copy, for example
Visual lets you edit the accelerator table
directly
You can also hook accelerators to functions
similarly to hooking menu events
Typically accelerators are hooked to menu
events, so thats what well look at
Lets take a look
AfxBeginThread(SomeThreadFunc, (LPVOID)this);
}
UINT CChildView::SomeThreadFunc( LPVOID pParam )
{