MFC基础知识

MFC终究是避不开的,那就慢慢来学习吧

看网上都推荐《深入浅出MFC》。结果发现并没有很容易的入门。我个人还是推荐《MFCWindows 应用程序设计》。任哲

一、预备知识

  代码运行机理探究:

    我们运行程序时,程序是怎么运作的呢。这一点分析清楚,有助于我们理解窗口运行机制。我们编写完代码后,点击编译,把所有文件都连接起来,形成一个可以被操作系统执行的文件。但操作系统怎么来执行我们的程序呢?它是通过调用系统调用来执行。正如我们在操作系统上所知道的,操作系统会提供我们用户接口。通过这个接口来调用我们的程序,由于语言的特性,调用我们的程序后,要有一个主函数。我们平常编写的console程序,入口是main。即控制台通过main函数进入执行我们的代码。而Windows程序则不同,它的入口函数是winmain。直观来说:Windows程序的架构是这样的:

Windows程序代码---------(winmain)-----------Windows操作平台-------------------硬件系统

而console程序的架构是:

console application 程序代码-------(main)----------MSDOS-------------Windows操作平台-----------硬件系统。(其中,MSDOS实质是一个运行平台,在Windows操作系统之上,与Windows程序相比,增加了一个中间层。提供了一个可视化界面。MSDOS不仅可以调用库函数,也可以调用Windows的API。)

Windows程序的特点:

  Windows程序除了入口为winmain的主函数,还有一个消息处理函数,两者并不是调用关系,这两个函数都是系统调用的。主函数主要进行的操作是:1.创建程序图形窗口界面。2.进入一个叫做消息循环的循环中,并在这个循环中等待用户事件的产生。当收到事件后,主函数把事件的消息传到系统。系统再次调用Windows程序的消息处理函数。循环这种操作,直到事件是一个终止程序运行的事件。

Windows API的特点:

  为了支持应用程序的设计和运行,Windows在系统函数中,向用户开放了一些可以由应用程序调用的函数(API)。实质上,这些API函数是一种软中断。因此称为系统调用。我们在操作系统中,也简要的学过:用户只有通过中断才能进入操作系统。

  Windows API主要分为三大类型:

    1.窗口管理函数:窗口的创建,移动,修改。

    2.图形设备函数:实现图形的绘制及操作,图形设备接口(GDI)

    3.系统服务函数:与操作系统有关的功能。

Windows开发工具:SDK,实际上就是利用Windows API。

Windows的特殊数据类型:

   1.用typedef   起的别名。

   2.特殊的数据类型:

    1.句柄。是一个结构体。用来隐藏内部的信息。句柄实质上是结构类型变量指针的再封装。避免用户直接操作指针操作的危险。虽然与指针形式相同,但不能像指针那样参与运算。

      HINSTACE句柄:应用程序实例句柄。在用户眼里程序可能就是静态的代码,操作系统中,程序是动态的过程。程序利用HINSTACE这种结构来管理这种动态行为。这个变量就代表了正在运行的一个程序。

    2.WNDCLASS。结构体。这个结构体是Windows程序创建窗口的参数。其声明如下:

typedef struct _WNDCLASS
{
    UNIT style;//指定窗口风格,通常选择style=0
    WNDPROC lpfnWndproc;//函数指针,指向消息处理函数
    int cbClsExTra;
    int cbWndExTra;
    HANDLE hInstance;//多窗口时,这个是和主窗口相同的。
    HICON hIcon;//用户使用的图标。
    HCURSOR hCursor;//窗口所使用的光标。
    HBRUSH hbrBackground;//窗口背景颜色
    LPCTSTR lpseMenuName;//窗口的菜单
    LPCTSTR lpszClassName;//窗口的类名

}WNDCLASS;

  3.Windows函数的调用。

    主要是宏定义的理解。像WINAPI  CALLBACK 等。这些属于修饰符,用来说明调用的顺序。程序被系统调用时,总要传一些参数,这些修饰符就是来说明传递参数的顺序的,因为使用堆栈来进行存储的,所以对参数顺序肯定是有要求的。比如你的main函数是应该先传递左边的参数,还是括号右边的。比较常用的就是_stdcall和_cdecl。_cdecl是默认vc++调用方式。但是,在winAPI中,都遵循_stdcall.所以在编写Windows程序时,也要声明这种修饰符。声明调用方式。WINAPI 和CALLBACK这些都是经过宏定义之后别名。其实质是_stdcall.

窗口的创建:

  步骤是先定制窗口,在注册窗口,然后是创建,最后是显示在屏幕上。

  代码结构是:

//1.定制窗口,利用结构体赋值来声明。
WNDCLASS wc;
wc.style=0;
...
//2.窗口的注册
BOOL RegisterClass (WNDCLASS & wc);
//3.窗口的创建
//利用CreateWindow()来创建,用很多参数。
HWND hwnd;
hwnd=CreateWindow("class name","title","style",x,y,w,h,fatherhandle,hMenu,hInstance,NULL)
//4.窗口的显示
BOOL ShowWindow(
    HWND hwnd,

    int nCmdshow   //窗口的显示方式
    );
BOOL UpdateWindow(HWND hwnd);

事件、消息循环和窗口函数。

  用户所提出的一个服务就是一个事件。这些事件的信息在Windows程序中构造了一个结构体用来存储这些消息。MSG。其结构是:

typedef struct tagMsg
{
    HWND hwnd;//产生消息的窗口句柄,即事件的地点
    UNIT messeage;//窗口消息的标识码,用宏定义来标识的。
    WPARAM wparam;//事件的附加消息
    LPARAM lparam;//事件的附加消息
    DWORD time;//产生的时间
    POINT pt;//发送消息时,光标所在的位置。
}MSG;

  系统消息的标识码一般以VM_开头。

  消息队列和消息循环:

MSG msg;
while(GetMessage(&msg,NULL,NULL,NULL)){
    TranslateMessage(&msg);//将键盘码消息转换为字符消息
    DispatchMessage(&msg);//把消息派送给系统
}

    消息派送给系统后,系统根据消息的hwnd找到窗口,然后根据窗口的lpfwinproc来找到消息处理函数,所以说消息处理函数是由系统调用的。消息处理完成后,会返回循环函数继续等待。多个消息时,会有一个消息队列进行缓存。也有不经过消息队列直接送达窗口的。

windows程序的结构:

  一个入口为winmain的主函数(包括窗口的创建,以及消息的循环)

int WINAPI WinMain(HINSTANCE hInstance,
    hINSTANCE PreInstance,
    LPSTR lpCmdbine,
    int nCmdshow){

    //窗口的创建
    //消息循环
};

  另一个是窗口函数(消息处理函数。)

LRESULT CALLBACK WndProc(HWND hwnd,
    UNIT messeage,
    WPARAM wparam,
    LPARAM lparam){
    //消息处理函数
}

 学到现在应该形成这样一个概念:

    

猜你喜欢

转载自www.cnblogs.com/meikon/p/9608320.html