关于MFC学习的第一篇文章

来源:互联网 发布:ubuntu下cp命令 编辑:程序博客网 时间:2024/05/06 13:08

 呵呵,这是我第一次在CSDN中写文章,本来不准备发出来的,感觉我的水平次而且写的也比较乱,而且这是一篇读书的笔记。可是呢,觉得也是自己付出一定劳动的东西,也许对大家中的一部分跟我一样的初学者有点作用,所以厚着脸皮发出来了,大家如果能够看到的话,随意指正,指出理解错误的地方,对于什么版权的问题,希望有关人包涵。

 Jeff Klose  ProGramming Windows with MFC.Second Edition.这本书别人推荐的,感觉还是不错的,我看的是英文原版的,陆续把每章的读书概要写出来。

前言
MFC我也曾经看过一部分,但是从来没有系统的学习过,因为工程需要,所以只是需要的部分看了看,看了就用,囫囵吞枣,一知半解的,须知知识还是要稳扎稳打,否则被人问起来,吞吐不清,容易贻笑大方。 
我看的书是Jeff Klose写的ProGramming Windows with MFC.Second Edition.in English结合这本书以及经验,写一下读书笔记,以便以后使用查看以及回忆。
 
书分成四个部分,分别是基础,文档/视图模式,基础之上的内容以及关于COM,OLE,ActiveX技术等。
 
jeffpro@msn.com 作者e_mail
 
 
Part 1
Chapter 1 Hello, MFC
something in Introduction:
"Most Windows applications were written in C, and the fledgling Windows programmer faced the daunting task not only of learning the ins and outs of a new operating system but also of getting acquainted with the hundreds of different application programming interface (API) functions that Windows supports."
上述是以前的情况,SDK就是用c。
下面是windows类库的概念以及MFC的地位。
windows class lib--- class library that abstracts the API and encapsulates the basic behavior of windows and other objects in reusable classes, makes Windows programming simpler.
MFC ---- Other Windows class libraries are available, but only MFC was written by the company that writes the operating system. it provides a comprehensive set of classes representing everything from windows to ActiveX controls in order to make the job of writing Windows applications easier.
 
作者指出,我们需要首先理解windows的编程模式,尤其对不了解的人
 
windows编程模式理解
一般而言,过去的操作系统用的是:a procedural programming model in which programs execute from top to bottom in an orderly fashion.过程化的模式,从头到尾的顺序执行。如main一样。
 
注意,其中main might call other functions and these functions might call even more functions, but ultimately it is the program—not the operating system—that determines what gets called and when. 读者注:这句话说得很好 J
 
而Windows:event-driven programming model,事件驱动模式
 
读者注:对于一个程序函数中中使用for(;;)或者while(1)的死循环,一般里面都是基于事件驱动的一个处理。这种函数执行应该作为线程或者任务必须架构在操作系统的调度之上,实现并行。
 
什么是事件?An event could be a keystroke, a mouse click, or a command for a window to repaint itself, among other things.
读者注:事件就是一些windows程序想要知道而且知道后回去做一些事的消息。
怎么驱动,如图所示:
 
 
 
上面是一个windows事件驱动的例子。WM_?是表示消息,即是一些事件。
Winmain相当于一个main函数在c程序的地位,执行的时候在Winmain启动后首先初始化,然后就陷入死循环的接受消息,对应收到的消息,有message loop对应把不同消息Dispatc给不同的Message handler。
对应于c里面,就是一个Switch这个消息的类型,然后case WM_A:执行对应WM_A的代码 break;ase WM_B:执行对应WM_B的代码 break;…
Winmain收到WM_QUIT后退出循环,进而退出整个程序体。
 
而Messages that an application doesn't process are passed on to an API function named DefWindowProc, which provides default responses to unprocessed messages.
DefWindowProc的地位就是如此。
从书中这段程序显然可见:
 
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,
    LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
 
    switch (message) {
   
    case WM_PAINT: /*画个园*/
        hdc = BeginPaint (hwnd, &ps);
        Ellipse (hdc, 0, 0, 200, 100);
        EndPaint (hwnd, &ps);
        return 0;
 
    case WM_DESTROY:/*退出*/
        PostQuitMessage (0);
        return 0;
    }
    return DefWindowProc (hwnd, message, wParam, lParam);/*默认的用DefWindowProc 执行*/
}
事件:
事件传给Message Loop包括:a message ID, and two 32-bit parameters known as wParam and lParam.即上面程序中的参数中UINT message, WPARAM wParam,LPARAM lParam,其中对于不同信息,WPARAM wParam,LPARAM lParam代表不同的意义,但是就是给的信息就是了。
 
10 of the most common messages

Message
Sent When
WM_CHAR
A character is input from the keyboard.
WM_COMMAND
The user selects an item from a menu, or a control sends a notification to its parent.
WM_CREATE
A window is created.
WM_DESTROY
A window is destroyed.
WM_LBUTTONDOWN
The left mouse button is pressed.
WM_LBUTTONUP
The left mouse button is released.
WM_MOUSEMOVE
The mouse pointer is moved.
WM_PAINT
A window needs repainting.
WM_QUIT
The application is about to terminate.
WM_SIZE
A window is resized.

 
注意,这里收到WM_DESTROY执行PostQuitMessage (0);发出WM_QUIT消息,从而关闭程序。比较搞笑。其中深意,似乎候的深入浅出中有讲,待查。
 
程序中WndProc函数注释
 
#include <windows.h>
 
LONG WINAPI WndProc (HWND, UINT, WPARAM, LPARAM);//声明一下
 
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpszCmdLine, int nCmdShow)
{//这是初始化的过程,非常典型
    WNDCLASS wc;
    HWND hwnd//这个hwnd就是这个程序所拥有的句柄
    MSG msg;//消息
 
    wc.style = 0;                                   // Class style
    wc.lpfnWndProc = (WNDPROC) WndProc;             // Window procedure address
    wc.cbClsExtra = 0;                              // Class extra bytes
    wc.cbWndExtra = 0;                              // Window extra bytes
    wc.hInstance = hInstance;                       // Instance handle
    wc.hIcon = LoadIcon (NULL, IDI_WINLOGO);        // Icon handle
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);      // Cursor handle
    wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); // Background color
    wc.lpszMenuName = NULL;                         // Menu name
    wc.lpszClassName = "MyWndClass";                // WNDCLASS name
 
    RegisterClass (&wc); //RegisterClass to register a window class
   
 
    hwnd = CreateWindow (//all-important CreateWindow function to create                                                    // the app lication's window.
        "MyWndClass",               // WNDCLASS name
        "SDK Application",          // Window title
        WS_OVERLAPPEDWINDOW,        // Window style
                /*WS_OVERLAPPEDWINDOW is a commonly used style t                hat creates a top-level window with a resizing b               order, a title bar, a system menu, and buttons for minimizing, maximizing, and closing the window. */
               
        CW_USEDEFAULT,              // Horizontal position
        CW_USEDEFAULT,              // Vertical position       
        CW_USEDEFAULT,              // Initial width
        CW_USEDEFAULT,              // Initial height
        HWND_DESKTOP,               // Handle of parent window
        NULL,                       // Menu handle
        hInstance,                  // Application's instance handle
        NULL                        // Window-creation data
    );
 
 
    ShowWindow (hwnd, nCmdShow);// make the window visible and ensure                                   //that its
                                //WM_PAINT handler is called                                                    //immediately.
    UpdateWindow (hwnd);
/////初始化结束
//循环体Message loop
    while (GetMessage (&msg, NULL, 0, 0)) {//blocks on the empty message                                                    //queue until a message is                                                     //available.
        TranslateMessage (&msg);//converts a keyboard message denoting
                // a character key to an easier-to-use WM_CHAR
                //message
        DispatchMessage (&msg);//DispatchMessage dispatches the message
                                 // to the window procedure.
    }
 
/////循环体结束
    return msg.wParam;
}
Hungarian Notation
匈牙利命名法:
Common Hungarian Notation Prefixes   命名时开头加的

Prefix
Data Type
b
BOOL
c or ch
char
clr
COLORREF
cx, cy
Horizontal or vertical distance
dw
DWORD
h
Handle
l
LONG
n
int
p
Pointer
sz
Zero-terminated string
w
WORD

 
prefix member variables with m_ so that it's obvious whether a variable is a member of a class.
读者注:一个好习惯对自己对别人都有利,最好一开始就形成。
Summary of 编程模式:
关键字:Message,基于消息的。注意理解那个程序的运转。
而MFC lends to Windows programs frees programmers to spend more time developing the structural components of a program and less time worrying about the style bits passed to CreateWindow and other nuances of the API.所以我们要用MFC:)