只为记忆更加深刻
如果程序变的不是非常枯燥乏味,学的人就会有兴趣很多,学ui就是一种.虽然学ui只是起步,但足够增加对学习的信心,也为后续打下基础.
有些人喜欢先探秘,比如先看深入浅出浅出MFC,我一直以来的想法是先学后用,如果连用都用不好,我想我也并不具备设计框架的能力.只有知道框架要做什么事情以后,自然自己心中会提出疑问.
Hello World程序
// Define a window class derived from CFrameWnd class CHelloWindow : public CFrameWnd { public: CHelloWindow() { Create(NULL, _T("Hello World!"), WS_OVERLAPPEDWINDOW, rectDefault); } }; #endif // Define an application class derived from CWinApp class CHelloApp : public CWinApp { public: virtual BOOL InitInstance() { m_pMainWnd = new CHelloWindow(); m_pMainWnd->ShowWindow(SW_SHOWNA); m_pMainWnd->UpdateWindow(); return TRUE; } }; CHelloApp HelloApp; // HelloApp's constructor initializes and runs the app
上面这段程序,实现了一个最简单的MFC程序,作为.net程序员,总是喜欢与.net中winfrom或者wpf进行比较.
CFrameWnd可以理解为窗体的基类
CWinApp 程序入口点,用于管理应用程序
virtual BOOL Create( LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle = WS_OVERLAPPEDWINDOW, const RECT& rect = rectDefault, CWnd* pParentWnd = NULL, LPCTSTR lpszMenuName = NULL, DWORD dwExStyle = 0, CCreateContext* pContext = NULL );
一个最简单的窗体需要在构造函数中调用Create方法用于创建和初始化窗体的一些参数,即必须提供基本窗体参数,c++具备函数默认参数功能,所以最简单的只需要提供两个参数即可,其他参数随着时间的增长自然会熟悉,不需要去强记.
c++风格的参数选择
在c#中,习惯于使用枚举进行同一项的参数选择,但c++则喜欢定义常量,当然其实其他语言也这么做,相对而言,个人认为枚举的做法更加优雅.所以看c++程序需要接受这种风格,而且将会大量出现
注意new
写c#程序new一个对象是非常正常的,c++的new就是申请内存,必须要删除掉的,没有GC,一看到new就要注意了。默认情况下,一个对象的初始化是不需要用new的,只需要声明,这是最大的区别,刚开始会看起来不习惯,看多了就好了,这是最大的注意点.
初始化程序
InitInstance方法提供了接口进行程序初始化,声明了一个窗体,并显示.
m_pMainWnd = new CHelloWindow();
m_pMainWnd->ShowWindow(SW_SHOWNA);
m_pMainWnd->UpdateWindow();
ShowWindow用于设定窗体初始化的状态,并不是真正Show,奇怪为何不命名SetShowWindowState这样的方法,让人误解.来看下参数的定义,均是这种风格.不查文档或者不熟悉源码,基本就不知道他们的存在…如果改成枚举就可以SW.xxxx了.很厌恶…
/* * ShowWindow() Commands */ #define SW_HIDE 0 #define SW_SHOWNORMAL 1 #define SW_NORMAL 1 #define SW_SHOWMINIMIZED 2 #define SW_SHOWMAXIMIZED 3 #define SW_MAXIMIZE 3 #define SW_SHOWNOACTIVATE 4 #define SW_SHOW 5 #define SW_MINIMIZE 6 #define SW_SHOWMINNOACTIVE 7 #define SW_SHOWNA 8 #define SW_RESTORE 9 #define SW_SHOWDEFAULT 10 #define SW_FORCEMINIMIZE 11 #define SW_MAX 11
UpdateWindow方法将会重绘窗体,呈现窗体.调用此方法将会触发ON_WM_PAINT消息.
注意c#很容易捕获一个事件,MFC与win32则称这些事件为消息,因为windows事件就是基于消息.所以两者概念上几乎是相同,说法不同,当然我更喜欢说事件.但不得不说消息:).
消息映射
在没有封装的情况下,默认捕获消息是用switch来判断的,很不方便,MFC通过消息映射机制来简化了这一操作.比如下面代码
BEGIN_MESSAGE_MAP( CMainWindow, CFrameWnd ) //{{AFX_MSG_MAP( CMainWindow ) ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP()
BEGIN_MESSAGE_MAP和END_MESSAGE_MAP用于声明消息的触发回调方法,(.net则更简单,直接重写即可)然后重写方法
void CMainWindow::OnPaint() { CRect rect; GetClientRect(rect); CPaintDC dc(this); dc.DrawText (_T ("Hello, MFC"), -1, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); }
以上用GDI在窗体中间画了一段文字
对象获取方法
在.net中若获取一个对象则,直接调函数返回,如 IList list=object.GetList();
到了c++这里则变成 IList list;GetLisht(&list);这种风格也非常的多,这可能就是语言特性决定的做法.需要特别的注意.
这样一个简单的MFC程序就完成了