Windows消息机制
应用程序的输入由Windows系统以消息的形式发送给应用程序的窗口
MFC消息机制
使用MFC框架编程时,消息发送和处理的本质仍然是Windows消息机制,
MFC简化了程序员编程时处理消息的复杂性
MFC消息映射<程序启动机制,窗口创建机制,这是第三个机制,消息映射机制>
就是让程序员可以方便的指定要某个有消息处理能力的MFC类,能够处理某个消息
先写段代码吧,仍然用Win32来改吧。
// MFCBase.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "MFCBase.h"
class CMyFrameWnd:public CFrameWnd{
DECLARE_MESSAGE_MAP() //声明宏
public:
LRESULT OnCreate(WPARAM wParam,LPARAM lParam);
};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd) //实现宏这三个宏实现了消息映射机制
ON_MESSAGE(WM_CREATE,OnCreate)
END_MESSAGE_MAP()
LRESULT CMyFrameWnd::OnCreate(WPARAM wParam,LPARAM lParam){
AfxMessageBox(_T("wm_create"));
return 0;
}
class CMyWinApp: public CWinApp{
public:
virtual BOOL InitInstance();
};
CMyWinApp theApp;
BOOL CMyWinApp::InitInstance(){
CMyFrameWnd *pFrame=new CMyFrameWnd;
CString str=_T("this is a window");
LPCTSTR lpszWindowName=str;
pFrame->Create(NULL,lpszWindowName);
pFrame->ShowWindow(SW_NORMAL);
pFrame->UpdateWindow();
m_pMainWnd=pFrame;
return TRUE;
}
在FrameWnd添加消息宏定义
DECLARE_MESSAGE_MAP
添加消息宏实现
BEGIN_MESSAGE_MAP( theClass, parentClass )
END_MESSAGE_MAP( )
添加消息处理函数
afx_msg LRESULT OnPaint( WPARAM wParam, LPARAM lParam );
添加消息和处理函数的对应
ON_MESSAGE( WM_PAINT, OnPaint )
//
DECLARE_MESSAGE_MAP实际上是替换成了:
private:
static const AFX_MSGMAP_ENTRY _messageEntries[];
protected:
static AFX_DATA const AFX_MSGMAP messageMap;
virtual const AFX_MSGMAP* GetMessageMap() const;
BEGIN_MESSAGE_MAP(theClass,baseClass)实际上是替换成了:
PTM_WARNING_DISABLE
const AFX_MSGMAP* theClass::GetMessageMap() const
{ return GetThisMessageMap(); }
const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap()
{
typedef theClass ThisClass;
typedef baseClass TheBaseClass;
static const AFX_MSGMAP_ENTRY _messageEntries[] =
{
/OnMEssage
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
static const AFX_MSGMAP messageMap =
{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] };
return &messageMap;
}
//
AFX_MSGMAP_ENTRY结构
用于保存消息ID与对应函数指针及相关的信息
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; //消息ID
UINT nCode; //通知代码
UINT nID; //控件的ID
UINT nLastID; //控件的ID范围的最后
UINT nSig; //操作类型或pfn函数类型
AFX_PMSG pfn;//消息处理函数的函数指针
};
AFX_MSGMAP结构
用于保存GetBaseMap的函数地址,以及AFX_MSGMAP_ENTRY数组的地址.
struct AFX_MSGMAP
{
//函数指针
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
//AFX_MSGMAP_ENTRY类型指针
const AFX_MSGMAP_ENTRY* lpEntries;
};
class CMsgFrame : public CFrameWnd
{
private:
static const FX_MSGMAP_ENTRY _messageEntries[];
protected:
static AFX_DATA const AFX_MSGMAP messageMap;
static const AFX_MSGMAP* PASCAL _GetBaseMessageMap();
virtual const AFX_MSGMAP* GetMessageMap() const;
}
const AFX_MSGMAP* PASCAL CMsgFrame::_GetBaseMessageMap()
{ return &CFrameWnd::messageMap; }
const AFX_MSGMAP* CMsgFrame::GetMessageMap() const
{ return &CMsgFrame::messageMap; }
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP CMsgFrame::messageMap =
{
&CMsgFrame::_GetBaseMessageMap,
&CMsgFrame::_messageEntries[0]
};
AFX_COMDAT const AFX_MSGMAP_ENTRY CMsgFrame::_messageEntries[] =
{
{ WM_PAINT, 0, 0, 0, AfxSig_lwl,
(AFX_PMSG)(AFX_PMSGW)(LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM))&OnPaint },
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
/
_messageEntries[]
静态数组
类型为 AFX_MSGMAP_ENTRY
保存CMsgFrame中消息ID和对应的消息处理函数的数组
messageMap
静态变量
类型为 AFX_MSGMAP
保存了CMsgFrame中的_GetBaseMessageMap函数指针以及_messageEntries数组地址
GetBaseMessageMap
静态函数
获取父类的messageMap的地址
GetMessageMap
虚函数
获取本身的messageMap地址
//
消息处理函数WindowProc收到消息后,调用OnWndMsg处理消息
OnWndMsg如果不处理消息,WindowProc函数调用DefWindowProc默认处理消息并返回,否则OnWndMsg处理消息继续执行。
使用GetMessageMap函数获取该窗口类的messageMap变量的地址
const AFX_MSGMAP* pMessageMap;
pMessageMap = GetMessageMap();//拿到链表的尾结点,遍历找东西 。
在messageMap中的lpEntries数组中,查找消息ID所对应的数组元素
如果未找到,获取父类的messageMap指针,从父类的lpEntries数组继续查找
如果找到,获取找到的数组元素的地址lpEntry,退出查找过程,执行下一步
在messageMap中的lpEntries数组中,查找消息ID所对应的数组元素。
根据找到的消息处理函数的类型标识,调用对应的的函数指针,处理消息。
pWnd->WindowProc(nMsg,)//函数内部this指针为pFrame
{
OnWndMsg(nMsg)//函数内部this指针为pFrame
{
const AFX_MSGMAP* pMessageMap=GetMessageMap();//获取本类的静态变量地址(链表的尾结点)
const AFX_MSGMAP_ENTRY* lpEntry;
for(链表尾结点,pMessageMap!=NULL,pMessageMap=pMessageMap->pBaseMap)//遍历链表
{
lpEntry=AfxFindMessageEntry(pMessageMap->lpEntries,message,0,0);//找消息所对应 的数据元素
if(lpEntry!=NULL)
goto LDispatch;
}
LDispatch:
union MessageMapFunctions mmf;//联合体
mmf.pfn=lpEntry->pfn;//将数组元素最后一个成员函数指针OnCreate赋给mmf第一个成员
int nSig=lpEntry->nSig;//AfxSig_lwl.决定调用联合体的哪个成员
switch(nSig){
case AfxSig_lwl:
lResult=(this->*mmf.pfn_lwl)(wParam,lParam);
break;
}
}}
//
LRESULT CMyFrameWnd::OnPaint(WPARAM wParam,LPARAM lParam){
PAINTSTRUCT ps={0};
HDC hDC=::BeginPaint(this->m_hWnd,&ps);
::TextOut(hDC,100,100,"WM_PAINT",strlen("adfafd"));
::EndPaint(m_hwnd,&ps);
}
/
窗口消息
例如WM_CREATE、WM_PAINT、鼠标、键盘等消息,这些消息的处理方式是直接调用消息处理函数.
这类消息使用的宏
ON_MESSAGE( )
ON_WM_XXXXX( )
ON_WM_CREATE()
消息处理
基本采用前述的方式。
命令消息
菜单、工具栏、按钮等点击时的命令
消息首先发送到主窗口,由主窗口逐层向子窗口派发。
这类的消息使用的宏
ON_COMMAND(id,memberFxn )
ON_COMMAND_RANGE( )//多个按钮使用同一个处理函数
消息处理
在OnWndMsg中调用OnCommand处理函数进行消息处理。
通知消息
子窗口对父窗口的通知消息。
控件消息宏,例如:
EDIT控件 ON_EN_CHANGE
ON_NOTIFY/ON_NOTIFY_RANGE
消息处理
在OnWndMsg中调用OnNotify (OnCommand)处理函数进行消息处理
用户自定义消息
用户自注册消息的处理。
用户需调用RegisterWindowMessage函数注册消息,然后在消息映射中使用。
返回注册成功的消息ID(0xC000-0xFFFF)
消息映射宏:
ON_REGISTERED_MESSAGE
消息处理
与窗口消息处理类似,但是在查找消息处理函数和执行消息处理函数时不同。
// MFCBase.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "MFCBase.h"
#define WM_MYMESSAGE WM_USER+100 //自定义消息
//自注册消息
UINT WM_USERMSG=RegisterWindowMessage(_T("sadasd"));//自注册消息,与自定义消息差不多
class CMyFrameWnd:public CFrameWnd{
DECLARE_MESSAGE_MAP()
public:
//LRESULT OnCreate(WPARAM wParam,LPARAM lParam);
afx_msg int OnCreate(LPCREATESTRUCT cs);//afx_msg为占位符,表明这个函数处理消息的
afx_msg void OnPaint();
afx_msg void OnTest1();
afx_msg void OnTest(UINT nid);
afx_msg void OnEnChange();
afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);
afx_msg LRESULT OnUserMsg(WPARAM wParam,LPARAM lParam);
};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)
//ON_MESSAGE(WM_CREATE,OnCreate)
ON_WM_CREATE()
ON_WM_PAINT()
ON_COMMAND(1001,OnTest1)//控件命令
ON_COMMAND_RANGE(1002,1003,OnTest)
ON_EN_CHANGE(1004,OnEnChange)//编辑框通知消息
ON_MESSAGE(WM_MYMESSAGE,OnMyMessage)//自定义消息
ON_REGISTERED_MESSAGE(WM_USERMSG,OnUserMsg)//自注册消息
END_MESSAGE_MAP()
LRESULT CMyFrameWnd::OnUserMsg(WPARAM wParam,LPARAM lParam){
AfxMessageBox(_T("自己注册的消息"));
return 0;
}
LRESULT CMyFrameWnd::OnMyMessage(WPARAM wParam,LPARAM lParam){
AfxMessageBox(_T("自己的消息"));
return 0;
}
void CMyFrameWnd::OnEnChange(){
AfxMessageBox(_T("内容有变"));
}
void CMyFrameWnd::OnTest(UINT nid){
CString str;
str.Format(_T("%d"),nid);
AfxMessageBox(str);
}
void CMyFrameWnd::OnTest1(){
AfxMessageBox(_T("test1被点击"));
::SendMessage(m_hWnd,WM_MYMESSAGE,0,0);
::SendMessage(m_hWnd,WM_USERMSG,0,0);
}
int CMyFrameWnd::OnCreate(LPCREATESTRUCT cs){
//AfxMessageBox(_T("wm_create"));
//创建三个按钮控件
CreateWindowEx(0,_T("BUTTON"),_T("Text1"),WS_CHILD|WS_VISIBLE,50,50,100,100,m_hWnd,(HMENU)1001,AfxGetInstanceHandle(),NULL);
CreateWindowEx(0,_T("BUTTON"),_T("Text2"),WS_CHILD|WS_VISIBLE,250,250,100,100,m_hWnd,(HMENU)1002,AfxGetInstanceHandle(),NULL);
CreateWindowEx(0,_T("BUTTON"),_T("Text3"),WS_CHILD|WS_VISIBLE,450,250,100,100,m_hWnd,(HMENU)1003,AfxGetInstanceHandle(),NULL);
//文本编辑框
CreateWindowEx(WS_EX_CLIENTEDGE,_T("EDIT"),_T(""),WS_VISIBLE|WS_CHILD,300,100,50,50,m_hWnd,(HMENU)1004,AfxGetInstanceHandle(),NULL);
return 0;
}
void CMyFrameWnd::OnPaint(){
PAINTSTRUCT ps={0};
HDC hDC=::BeginPaint(m_hWnd,&ps);
::TextOut(hDC,0,0,_T("WM_PAINT"),strlen("WM_PAINT"));
::EndPaint(m_hWnd,&ps);
}
class CMyWinApp: public CWinApp{
public:
virtual BOOL InitInstance();
};
CMyWinApp theApp;
BOOL CMyWinApp::InitInstance(){
CMyFrameWnd *pFrame=new CMyFrameWnd;
CString str=_T("this is a window");
LPCTSTR lpszWindowName=str;
pFrame->Create(NULL,lpszWindowName);
pFrame->ShowWindow(SW_NORMAL);
pFrame->UpdateWindow();
m_pMainWnd=pFrame;
return TRUE;
}
应用程序的输入由Windows系统以消息的形式发送给应用程序的窗口
MFC消息机制
使用MFC框架编程时,消息发送和处理的本质仍然是Windows消息机制,
MFC简化了程序员编程时处理消息的复杂性
MFC消息映射<程序启动机制,窗口创建机制,这是第三个机制,消息映射机制>
就是让程序员可以方便的指定要某个有消息处理能力的MFC类,能够处理某个消息
先写段代码吧,仍然用Win32来改吧。
// MFCBase.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "MFCBase.h"
class CMyFrameWnd:public CFrameWnd{
DECLARE_MESSAGE_MAP() //声明宏
public:
LRESULT OnCreate(WPARAM wParam,LPARAM lParam);
};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd) //实现宏这三个宏实现了消息映射机制
ON_MESSAGE(WM_CREATE,OnCreate)
END_MESSAGE_MAP()
LRESULT CMyFrameWnd::OnCreate(WPARAM wParam,LPARAM lParam){
AfxMessageBox(_T("wm_create"));
return 0;
}
class CMyWinApp: public CWinApp{
public:
virtual BOOL InitInstance();
};
CMyWinApp theApp;
BOOL CMyWinApp::InitInstance(){
CMyFrameWnd *pFrame=new CMyFrameWnd;
CString str=_T("this is a window");
LPCTSTR lpszWindowName=str;
pFrame->Create(NULL,lpszWindowName);
pFrame->ShowWindow(SW_NORMAL);
pFrame->UpdateWindow();
m_pMainWnd=pFrame;
return TRUE;
}
在FrameWnd添加消息宏定义
DECLARE_MESSAGE_MAP
添加消息宏实现
BEGIN_MESSAGE_MAP( theClass, parentClass )
END_MESSAGE_MAP( )
添加消息处理函数
afx_msg LRESULT OnPaint( WPARAM wParam, LPARAM lParam );
添加消息和处理函数的对应
ON_MESSAGE( WM_PAINT, OnPaint )
//
DECLARE_MESSAGE_MAP实际上是替换成了:
private:
static const AFX_MSGMAP_ENTRY _messageEntries[];
protected:
static AFX_DATA const AFX_MSGMAP messageMap;
virtual const AFX_MSGMAP* GetMessageMap() const;
BEGIN_MESSAGE_MAP(theClass,baseClass)实际上是替换成了:
PTM_WARNING_DISABLE
const AFX_MSGMAP* theClass::GetMessageMap() const
{ return GetThisMessageMap(); }
const AFX_MSGMAP* PASCAL theClass::GetThisMessageMap()
{
typedef theClass ThisClass;
typedef baseClass TheBaseClass;
static const AFX_MSGMAP_ENTRY _messageEntries[] =
{
/OnMEssage
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
static const AFX_MSGMAP messageMap =
{ &TheBaseClass::GetThisMessageMap, &_messageEntries[0] };
return &messageMap;
}
//
AFX_MSGMAP_ENTRY结构
用于保存消息ID与对应函数指针及相关的信息
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; //消息ID
UINT nCode; //通知代码
UINT nID; //控件的ID
UINT nLastID; //控件的ID范围的最后
UINT nSig; //操作类型或pfn函数类型
AFX_PMSG pfn;//消息处理函数的函数指针
};
AFX_MSGMAP结构
用于保存GetBaseMap的函数地址,以及AFX_MSGMAP_ENTRY数组的地址.
struct AFX_MSGMAP
{
//函数指针
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
//AFX_MSGMAP_ENTRY类型指针
const AFX_MSGMAP_ENTRY* lpEntries;
};
class CMsgFrame : public CFrameWnd
{
private:
static const FX_MSGMAP_ENTRY _messageEntries[];
protected:
static AFX_DATA const AFX_MSGMAP messageMap;
static const AFX_MSGMAP* PASCAL _GetBaseMessageMap();
virtual const AFX_MSGMAP* GetMessageMap() const;
}
const AFX_MSGMAP* PASCAL CMsgFrame::_GetBaseMessageMap()
{ return &CFrameWnd::messageMap; }
const AFX_MSGMAP* CMsgFrame::GetMessageMap() const
{ return &CMsgFrame::messageMap; }
AFX_COMDAT AFX_DATADEF const AFX_MSGMAP CMsgFrame::messageMap =
{
&CMsgFrame::_GetBaseMessageMap,
&CMsgFrame::_messageEntries[0]
};
AFX_COMDAT const AFX_MSGMAP_ENTRY CMsgFrame::_messageEntries[] =
{
{ WM_PAINT, 0, 0, 0, AfxSig_lwl,
(AFX_PMSG)(AFX_PMSGW)(LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM))&OnPaint },
{0, 0, 0, 0, AfxSig_end, (AFX_PMSG)0 }
};
/
_messageEntries[]
静态数组
类型为 AFX_MSGMAP_ENTRY
保存CMsgFrame中消息ID和对应的消息处理函数的数组
messageMap
静态变量
类型为 AFX_MSGMAP
保存了CMsgFrame中的_GetBaseMessageMap函数指针以及_messageEntries数组地址
GetBaseMessageMap
静态函数
获取父类的messageMap的地址
GetMessageMap
虚函数
获取本身的messageMap地址
//
消息处理函数WindowProc收到消息后,调用OnWndMsg处理消息
OnWndMsg如果不处理消息,WindowProc函数调用DefWindowProc默认处理消息并返回,否则OnWndMsg处理消息继续执行。
使用GetMessageMap函数获取该窗口类的messageMap变量的地址
const AFX_MSGMAP* pMessageMap;
pMessageMap = GetMessageMap();//拿到链表的尾结点,遍历找东西 。
在messageMap中的lpEntries数组中,查找消息ID所对应的数组元素
如果未找到,获取父类的messageMap指针,从父类的lpEntries数组继续查找
如果找到,获取找到的数组元素的地址lpEntry,退出查找过程,执行下一步
在messageMap中的lpEntries数组中,查找消息ID所对应的数组元素。
根据找到的消息处理函数的类型标识,调用对应的的函数指针,处理消息。
pWnd->WindowProc(nMsg,)//函数内部this指针为pFrame
{
OnWndMsg(nMsg)//函数内部this指针为pFrame
{
const AFX_MSGMAP* pMessageMap=GetMessageMap();//获取本类的静态变量地址(链表的尾结点)
const AFX_MSGMAP_ENTRY* lpEntry;
for(链表尾结点,pMessageMap!=NULL,pMessageMap=pMessageMap->pBaseMap)//遍历链表
{
lpEntry=AfxFindMessageEntry(pMessageMap->lpEntries,message,0,0);//找消息所对应 的数据元素
if(lpEntry!=NULL)
goto LDispatch;
}
LDispatch:
union MessageMapFunctions mmf;//联合体
mmf.pfn=lpEntry->pfn;//将数组元素最后一个成员函数指针OnCreate赋给mmf第一个成员
int nSig=lpEntry->nSig;//AfxSig_lwl.决定调用联合体的哪个成员
switch(nSig){
case AfxSig_lwl:
lResult=(this->*mmf.pfn_lwl)(wParam,lParam);
break;
}
}}
//
LRESULT CMyFrameWnd::OnPaint(WPARAM wParam,LPARAM lParam){
PAINTSTRUCT ps={0};
HDC hDC=::BeginPaint(this->m_hWnd,&ps);
::TextOut(hDC,100,100,"WM_PAINT",strlen("adfafd"));
::EndPaint(m_hwnd,&ps);
}
/
窗口消息
例如WM_CREATE、WM_PAINT、鼠标、键盘等消息,这些消息的处理方式是直接调用消息处理函数.
这类消息使用的宏
ON_MESSAGE( )
ON_WM_XXXXX( )
ON_WM_CREATE()
消息处理
基本采用前述的方式。
命令消息
菜单、工具栏、按钮等点击时的命令
消息首先发送到主窗口,由主窗口逐层向子窗口派发。
这类的消息使用的宏
ON_COMMAND(id,memberFxn )
ON_COMMAND_RANGE( )//多个按钮使用同一个处理函数
消息处理
在OnWndMsg中调用OnCommand处理函数进行消息处理。
通知消息
子窗口对父窗口的通知消息。
控件消息宏,例如:
EDIT控件 ON_EN_CHANGE
ON_NOTIFY/ON_NOTIFY_RANGE
消息处理
在OnWndMsg中调用OnNotify (OnCommand)处理函数进行消息处理
用户自定义消息
用户自注册消息的处理。
用户需调用RegisterWindowMessage函数注册消息,然后在消息映射中使用。
返回注册成功的消息ID(0xC000-0xFFFF)
消息映射宏:
ON_REGISTERED_MESSAGE
消息处理
与窗口消息处理类似,但是在查找消息处理函数和执行消息处理函数时不同。
// MFCBase.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "MFCBase.h"
#define WM_MYMESSAGE WM_USER+100 //自定义消息
//自注册消息
UINT WM_USERMSG=RegisterWindowMessage(_T("sadasd"));//自注册消息,与自定义消息差不多
class CMyFrameWnd:public CFrameWnd{
DECLARE_MESSAGE_MAP()
public:
//LRESULT OnCreate(WPARAM wParam,LPARAM lParam);
afx_msg int OnCreate(LPCREATESTRUCT cs);//afx_msg为占位符,表明这个函数处理消息的
afx_msg void OnPaint();
afx_msg void OnTest1();
afx_msg void OnTest(UINT nid);
afx_msg void OnEnChange();
afx_msg LRESULT OnMyMessage(WPARAM wParam,LPARAM lParam);
afx_msg LRESULT OnUserMsg(WPARAM wParam,LPARAM lParam);
};
BEGIN_MESSAGE_MAP(CMyFrameWnd,CFrameWnd)
//ON_MESSAGE(WM_CREATE,OnCreate)
ON_WM_CREATE()
ON_WM_PAINT()
ON_COMMAND(1001,OnTest1)//控件命令
ON_COMMAND_RANGE(1002,1003,OnTest)
ON_EN_CHANGE(1004,OnEnChange)//编辑框通知消息
ON_MESSAGE(WM_MYMESSAGE,OnMyMessage)//自定义消息
ON_REGISTERED_MESSAGE(WM_USERMSG,OnUserMsg)//自注册消息
END_MESSAGE_MAP()
LRESULT CMyFrameWnd::OnUserMsg(WPARAM wParam,LPARAM lParam){
AfxMessageBox(_T("自己注册的消息"));
return 0;
}
LRESULT CMyFrameWnd::OnMyMessage(WPARAM wParam,LPARAM lParam){
AfxMessageBox(_T("自己的消息"));
return 0;
}
void CMyFrameWnd::OnEnChange(){
AfxMessageBox(_T("内容有变"));
}
void CMyFrameWnd::OnTest(UINT nid){
CString str;
str.Format(_T("%d"),nid);
AfxMessageBox(str);
}
void CMyFrameWnd::OnTest1(){
AfxMessageBox(_T("test1被点击"));
::SendMessage(m_hWnd,WM_MYMESSAGE,0,0);
::SendMessage(m_hWnd,WM_USERMSG,0,0);
}
int CMyFrameWnd::OnCreate(LPCREATESTRUCT cs){
//AfxMessageBox(_T("wm_create"));
//创建三个按钮控件
CreateWindowEx(0,_T("BUTTON"),_T("Text1"),WS_CHILD|WS_VISIBLE,50,50,100,100,m_hWnd,(HMENU)1001,AfxGetInstanceHandle(),NULL);
CreateWindowEx(0,_T("BUTTON"),_T("Text2"),WS_CHILD|WS_VISIBLE,250,250,100,100,m_hWnd,(HMENU)1002,AfxGetInstanceHandle(),NULL);
CreateWindowEx(0,_T("BUTTON"),_T("Text3"),WS_CHILD|WS_VISIBLE,450,250,100,100,m_hWnd,(HMENU)1003,AfxGetInstanceHandle(),NULL);
//文本编辑框
CreateWindowEx(WS_EX_CLIENTEDGE,_T("EDIT"),_T(""),WS_VISIBLE|WS_CHILD,300,100,50,50,m_hWnd,(HMENU)1004,AfxGetInstanceHandle(),NULL);
return 0;
}
void CMyFrameWnd::OnPaint(){
PAINTSTRUCT ps={0};
HDC hDC=::BeginPaint(m_hWnd,&ps);
::TextOut(hDC,0,0,_T("WM_PAINT"),strlen("WM_PAINT"));
::EndPaint(m_hWnd,&ps);
}
class CMyWinApp: public CWinApp{
public:
virtual BOOL InitInstance();
};
CMyWinApp theApp;
BOOL CMyWinApp::InitInstance(){
CMyFrameWnd *pFrame=new CMyFrameWnd;
CString str=_T("this is a window");
LPCTSTR lpszWindowName=str;
pFrame->Create(NULL,lpszWindowName);
pFrame->ShowWindow(SW_NORMAL);
pFrame->UpdateWindow();
m_pMainWnd=pFrame;
return TRUE;
}