创娱点餐助手

    来创娱半年多了,一直觉的这边的包餐福利挺好的,虽然没有什么大鱼大肉,但是能让员工自己点餐的方式还是挺人性化的,菜单的种类还挺多,基本可以满足我的各种口味吧。但是有一点点瑕疵的是,公司的点餐网站似乎永远不那么人性化,公司500多号人,不要求你做的界面多好看,但是起码要满足同事们的基本需求吧,每次点餐都搞得挺麻烦的。而且界面用户体验很差。

    公司的点餐系统是网页形式的,但是页面巨丑,而且每次选择一个菜项都是一个好长好长的下拉框,而且没有随机点餐的功能,没有自动分类的功能,周一到周五的午餐和晚餐每次都要从一个长长的下拉框选择,要是有不小心刷新了网页或是关闭了就要重新开始选择。公司大群里也经常能看到有同事吐槽这个东西。于是我就想我是程序员啊,我完全可以不用他的点餐系统,自己开发一个,只要从它的内网上获取菜单数据,然后自己选择好提交都它的网站后台就行了啊!越想越兴奋,

马上就开干了。然后就有了如下点餐助手C#开发 哈哈。

QQ截图20180113213741.png

QQ截图20180113214256.png

看起来虽然简陋,但是我感觉比公司运维做的网页版好多了,起码可以帮助有选择困难的同事,随机选择自己喜欢的类型,还不必每次都去选择每天的饭菜。当然为了人性化,如果随机到自己不喜欢的饭菜还是可以自己再自主选择的,而且还加入了2种搭配方式,一开始本来是想自己用的,但是当我发给行政MM后他们都觉得很棒,索性直接发给全公司人用好了哈哈。上面还有关键字过滤功能,我会在下一个版本中完善它。

MFC框架类

1.Cwnd

Cwnd类是MFC中一个重要的类,它封装了与窗口有关的操作。

2.MFC中的WinMain

MFC中的WinMain函数在APPMODUL.cpp中,在编译的时候才会连接进来。

3.theApp全局对象

在程序入口函数加载前,系统已经为全局变量或全局对象分配了内存空间并为它们赋与了初值。对于全局对象,要先调用构造函数对其进行初始化。调用theApp时会选调用设用其父类CwinApp的构造函数。

4.CWinApp

在文件appcore.cpp中

5.AfxWinMain函数

WinMain函数实际上是调用AfxWinMain函数来实现的。AfxWinMain位于WINMAIN.app中。

  1. 设计和注册窗口

MFC已经为我们预定义了一些默认的标准窗口类,只需要选择所需的窗口类,然后注册就可以了。窗口类的注册是由AfxEndDeferRegisterClass函数完成的。AfxEndDeferRegisterClass函数判断窗口类的类型,然后赋予相应的类名,这些类名都是MFC预定义的。之后计用AfxRegisterClass函数注册窗口类。

AfxRegisterClass函数首先获得窗口柯类信息。如果该窗口类已经注册,则直接返回一个真值;如果尚未注册,就调用RegisterClass函数注册该窗口类。

  1. 创建窗口

在MFC程序中,窗口的创建功能由Cwnd类的CreateEx函数实现,该函数的声明位于AFXWin.h文件中。实现代码位于WINCORE.CPP文件中。如果在子类的PreCreateWindow函数中修改了CREATESTRUCT结构体的值,那么,接下来调用CreateWindowEx函数时,其参数就会发生相应的改变,从而就会创建一个符合我们要求的窗口。

  1. 显示及更新窗口

在Test程序的应用程序类(CTestApp)中有一个名为m_pMainWnd的成员变量。该变量是一个Cwnd类型的指针,它保存了应用程序框架窗口对象的指针。也就是说,是指向CmainFrame对象的指针。

在CtestApp类的InitInstance函数内部有如下代码。

m_pMainWnd->ShowWindow(SW_SHOW);

m_pMainWnd->UpdateWindow();

这两行代码的功能是显示应用程序框架窗口和更新这个窗口。

  1. 消息循环

CwinThread类的Run函数就是完成消息循五常这一任务的,该函数是在AfxWinMain函数中调用的。

调用形式如下

pThread->Run();

  1. 窗口过程函数

AfxEndDeferRegisterClass函数有这样一句代码。

wndcls.lpfnWndProc=DefWindowProc;这行代码的作用指定一个默认的窗口过程DefWindowProc。但实际上,MFC程序并不是把所有消息都交给DefiWindowProc这一默认的窗口过程来处理的,而是采用一种称之为消息映射的机制来处理各种消息的。

11.MFC程序运行过程

首先利用全局应用程序对象theApp启动应用程序。正是产生了这个全局对象,基类CWinApp中的this指针才能指向这个对象。如果没有这个全局对象,程序在编译时不会出错,但是在运行时就会出错。

调用全局应用程序对象的构造函数,从而就会先调用其基类CWinApp的构造函数后者完成应用程序的一些初始化工作,并将用应程序对象的指针保存起来。

进入WinMain函数。在AfxWinMain函数中可以获取子类(对Test程序来说,就是CtestApp类)的指针,利用此指针调用虚函数:InitInstance,根据多态性原理,实际上调用的是子类(CTestApp)的InitInstance函数。后者完成应用程序的一些初始化工作,包括窗口类的注册、创建、窗口的显示和更新。期间会多次调用CreateEx函数,因为一个单文档MFC应用程序有多个窗口,包括框架窗口、工具条、状态条等。

进入消息循环。虽然也设置了默认的窗口过程函数,但是,MFC应用程序实际上是采用消息映射机制来处理各种消息的。当收到WM_QUIT消息时,退出消息循环,程序结束。

  1. 文档视类结构

MFC程序除了主框架窗口外,还有一个窗口视类窗口,对应的类是Cview类,Cview类也派生于CWnd类。

CtestDoc类派生于Cdocument类。其基类是CcmdTarget,后者又派生于Cobject类,CtestDoc不是一个窗口类,是一个文档类。

  1. 窗口类、窗口类对象与窗口

C++窗口类对象与窗口并不是一回事,它们之间惟一的关系就是C++窗口类对象内部定义了一个窗口句柄变量,保存了与这个C++窗口类对象相关的那个窗口的句柄。窗口销毁时,与之对应的C++窗口类对象销毁与否,要看其生命周期是否结束,但C++窗口类对象销毁时,与之相关的窗口也将销毁。

为什么要使用注册窗口类?

为什么要使用注册窗口类?

在一个窗口中,可能有不同的按钮,它们的工作原理都是一样的。但是各个按钮可能都有不同的表现形式,比如大小,颜色等。所以在这种情况下,我们需要将创建窗口的共性提取出来,然后再设置每个具体的窗口。这样就更加符合面向对象的原理。

当应用程序取得消息后,DispatchMessage是如何知道要发给谁去处理呢?

这是因为在注册窗口类时,已经指定了。否则windows不可能知道。