Windows应用程序组成及编程步骤

应用程序的组成

  1. 源程序文件
  2. 头文件
  3. 模块定义文件
  4. 资源描述文件
  5. 项目文件(工程文件Project)

Windows源程序组成结构

  • 入口函数 | WinMain
    • 所有程序的入口,类似Main函数
    • 完成定义和初始化,产生消息循环
  • 窗口函数 | WndProc
    • 完成消息循环的响应

WinMain函数

  • 注册窗口类,建立窗口及执行必要的初始化
  • 进入消息循环,根据接受的消息调用相应的处理过程
  • 当消息循环检索到WM_QUIT时,终止程序运行

WinMain函数的基本组成:

函数说明

int WINAPI WinMain 
     (HINSTANCE hThisInst, //应用程序当前实例句柄
     HINSTANCE hPrevInst, //应用程序其他实例句柄
     LPSTR lpszCmdLine, //指向程序命令行参数的指针
     Int nCmdShow //应用程序开始执行时窗口显示方式的整数值标识 )

注意

Windows是多任务管理的,也就是说在这个应用程序中,我们可以启动或者执行另外一个应用程序或者实例,那么你要运行另外一个应用程序或者实例,必须有一个句柄去指向你所要执行的其他应用程序或者实例。那既然你要执行其他应用程序,你就要有一个指向程序的命令的这个 参数的指针,以及应用程序开始执行时窗口所显示的标识。
注意,Windows既然是多任务管理的,也就是说。同一个应用程序的多个窗口可能会同时存在,那么每一个窗口我们都称之为一个实例的情况下,也就是说多个窗口每一个都要有一个句柄指向一个窗口,这样的话,我们才能识别到不同的窗口,也就是说用一个句柄唯一的指向一个窗口对象,所以我们操作不同实例的时候,都是把指向这个实例的句柄找到,通过句柄去操作这个对象。

初始化

  • 窗口类定义:定义窗口的形式与功能(加载图标标识LoadIcon、加载光标LoadCursor、加载其它GetStockObject)
  • 窗口类的注册:窗口类必须先注册后使用,RegisterObject
  • 创建窗口实例:CreatWindow
  • 显示窗口:ShowWindow、UpdateWindow

窗口类定义

通过给窗口类数据结构WNDCLASS赋值完成该数据结构中包含窗口类的各种属性,句柄可以理解为数据类型

  • LoadIcon
    • 作用:在应用程序中加载一个窗口图标
    • 原型:HICON LoadIcon(HINSTANCE hInstance,//图标资源所在的模块语句,NULL则使用系统预定义图标 LPCTSTR lpIconName//图标名或系统预定义图标是别名)
  • LoadCursor
    • 作用:是在应用程序中加载一个窗口光标
    • 原型:HCURSOR LoadCurdor(HINSTANCE hInstance , //光标资源所在的模块语句,NULL则使用系统预定义光标LPCTSTR lpCursorName)

调用GetStockObject函数获取系统提供的背景刷 HBRUSH GetStockObject(int nBrush);

窗口注册类

  • Windows系统本身提供部分预定义的窗口类,程序员也可以自定义窗口类,窗口类必须是先注册后使用
  • 窗口类的注册由函数RegisterClass()实现
  • RegisterClass(&wndclass);//wndclass为窗口类结构
  • RegisterClass函数的返回值是一个布尔值,注册成功则返回真

创建窗口实例

创建一个窗口类的实例由函数CreateWindow()来实现

函数原型

HWND CreateWindow
(LPCTSTR lpszClassName, //窗口类名
LPCTSTR lpszTitle,  //窗口标题名
DWORD dwStyle,  //创建窗口样式
int x,y,    //窗口左上角坐标
int nWidth,nHeight,//窗口宽度和高度
HWND hwndParent,    //该窗口的父窗口句柄
HMENU hMenu,    //窗口主菜单句柄
HINSTANCE hInstance,    //创建窗口的应用程序当前句柄
LPVOID lpParam  //指向一个传递给窗口的参数值的指针)

Windows应用程序组成及编程步骤_第1张图片

显示窗口

窗口类的显示由ShowWindow和UpdateWindow函数来实现
窗口显示形式标识 ShowWindow(hwnd , nCmdshow);
应用程序调用ShowWindow函数在屏幕上显示窗口

Windows应用程序组成及编程步骤_第2张图片

窗口显示但不激活,窗口不激活情况下是不能操作的,Windows时多任务多窗口的应用程序,当运行程序时,当前激活的窗口只有一个窗口,其余则是后台运行状态。

显示窗口后,应用程序调用UpdateWindows更新并绘制用户区并发出WM_PAINT消息

消息循环
Windows将产生的消息放到一个消息队列去,然后WinMain函数是将消息传递给窗口处理函数WndProc函数进行相应的处理

消息循环的常见格式

MSG Msg;
...
while(GetMessage (&Msg,NULL,0,0))
{TranslateMessage(&Msg);//将消息的虚拟键转换为字符信息
DispatchMessage(&Msg);//将消息传递到指定窗口函数
}

函数GetMessage形式为:

GetMessage
(lpMSG,     //指向MSG结构的指针
hwnd,   //从哪一个窗口获得消息
nMsgFilteMin,   //用于消息过滤的最小信号值,也就是说,消息有个编号,编号有个区间,用来过滤这个区间是否是合理的消息。它要完成的就是从消息队列中读取一条消息get message,然后给它放到这个message结构中
nMsgFilterMax   //用于消息过滤的最大信号值)

窗口函数WinProc

  • 定义了应用程序对接收到的不同消息的响应
  • 包含了对各种可能接收到的消息的处理过程

Windows应用程序组成及编程步骤_第3张图片

函数窗口的一般形式

LRESULT CALLBACK WndProc
(HWND hwnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{...
    switch(message) //message为标识的信息
    {case...
            ...
            break;
        ...
    case WM_DESTROY:
    PostQuitMessage(0);
    default:
        return DefWindowProc 
        (hwnd,
        message,
        wParam,
        lParam);//为未定义处理过程的消息提供缺省处理
    }
    return (0);
}

比如说WndProc WndProc的这个是消息处理函数,针对的哪一个窗口的消息,这里有个窗口的句柄,传过来的什么消息是message以及消息的字参数和长字参数, 那么这个switch就看这个地方传过来的消息,放到这个message,然后对这个message进行判断 。满足哪一个case那么就对这个case里面就响应相应的message操作。
可能是鼠标左键操作 可能是鼠标右键操作等等等等,这些都是属于消息 都是放到message里面。
那么这里面有一个特殊的消息就是DESTROY,遇到这个DESTROY消息就是退出消息循环,还有一个是Default消息缺省的DefWindowProc也是四个参数
跟这个WndProc的一样,为什么会有DefWindowProc?也就是说你这里如果定义了鼠标左键操作、鼠标右键操作、 单击鼠标、 双击鼠标以及键盘的ABCDE操作。比如说你响应的这五个键盘消息,这时候用户操作出错,他按了一个K键,好了, 那么这个K键肯定也是作为一个消息要传过来的,传过来你系统要怎么处理这个消息,大家知道switch-case构架里面都有一个Default 这个缺省操作。那么这时候缺省的操作的话,我们在学习C程序设计的时候,可能你会做的一个Default操作很简单就是break
就是不管它 不处理,但是在我们这个面向对象程序设计里面,它是这样的 它是用的DefWindowProc的
就是前面处理不了的操作 都在这里面操作,那这里面怎么操作、操作了什么 用户不要管它,你只要把这一行写上就行了。
它实际上做的事情就是过滤掉前面那个case里面没有列出来的消息
它都给它过滤掉了 也是不处理,在消息处理程序当中一般都有这个DESTROY这个消息,它 用来关闭窗口,这时候它在应用程序中实际上发出了一个QUIT消息 请求了退出,那么它的处理函数是PostQuitMessage。那么根据消息码来决定你是怎么个退出法,那么这个是WndProc构架,WndProc构架大家,程序C语言程序设计如果学得比较扎实的话,对于这个构架实际上是非常容易理解的,那这里面有两个数据类型 LRESULT和CALLBACK,LRESULT消息是一种消息处理结果的返回值的数据类型
它实际上就是一个长整的long,CALLBACK这个是表示这个函数是给系统调用的,有时候我们称为回调函数。

你可能感兴趣的:(MFC可视化编程)