打开ege.h头文件,从上到下慢慢看一下,试着分析分析。
首先ege不是一个标准c语言图形库,它大部分用的是c语言代码,少量也使用了c++的特性。
比如名称空间,类等。
所以编译需要c++编译器,而不是ANSI C编译器。
-
_MSC_VER 是什么?
编译器自己的宏定义,提供了vs的版本,不同的vs这个值不一样,无需用户定义,vs2015这个值就是1900. -
#pragma once
#pragma 编译器命令,用代码的方式告诉IDE应该怎么做,和鼠标操作效果一样,不过代码灵活性更高,更“自动”,不同的编译器有不一样的命令,移植性较差。这句话告诉编译器,整个头文件只编译一次,和传统的#if defined #endif 效果一样,后者属于标准库,更有移植性。
3. __cplusplus
也是编译器自己的宏定义,说明是c++编译,这句话的意思是,如果没使用c++编译器就弹出错提示“you must use c++”,退出编译。
4. defined(_INC_CONIO) || defined(CONIO_H) 如果定义了conio就提示出错,“不能在graphics.h前加入conio.h头文件”,退出编译。
-
#include “windows.h” ,底层实现基于win32
EGEAPI这一段主要是为了定义函数的调用方式,_cdecl是C和C++程序的缺省调用方式,采用__cdecl约定时,函数参数按照从右到左的顺序入栈,并且由调用函数者把参数弹出栈以清理堆栈。
因此,实现可变参数的函数只能使用_cdecl调用约定。由于每一个使用__cdecl约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大。
而采用__stdcall约定时,函数参数按照从右到左的顺序入栈,被调用的函数在返回前清理传送参数的栈,函数参数个数固定。
由于函数体本身知道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈。
7.
这一部分定义了不少宏函数,带参数的宏。
EGERGB(r, g, b) ( ((r)<<16) | ((g)<<8) | (b))
RGB颜色值是一个24位整数,给定的参数r,g,b都只有8位,最后需要用3个8位来拼接成一个完整的24位,EGERGB(r,g,b)中r本来是8位,往左移动16位就成了一个24位形式的r;g本来是8位,往左移动8位就成了一个16位形式的g,b不变还是8位。
再把3个数用| 按位与运算,就拼接成一个完整的24位。
左移 配合 | 在字节中有融合的意思
EGEGET_R(c) ( ((c)>>16) & 0xFF )
c是一个24位的数,现在想获取它的高8位即R色,把c右移16位已经得到一个8位值,为什么要&0xFF?
如果是正数,高位右移时补齐为0,那加不加&0xFF都一样。
但如果是负数,高位右移时补齐为1,必须加&0xFF来截断。
c不是一个RGB颜色么,怎么会是负数呢? 计算机内部只看最高位是不是1,如果为1,它就认为是个负数。
所以RGB颜色我们表示的时候都是正数,但在计算机内部,有可能存储是个负数。
右移 配合 &0xFF在字节处理中意味着截断
#define EGEGET_R(c) ( ((c)>>16) & 0xFF )
#define EGEGET_G(c) ( ((c)>> 8) & 0xFF )
#define EGEGET_B(c) ( ((c)) & 0xFF )
#define EGEGET_A(c) ( ((c)>>24) & 0xFF )
8.
自己定义了一个PI
把windows的消息事件定义成了枚举常量。
还有鼠标消息。
16种颜色常量。
13种填充模式。
5种文本的对齐方式
-
6种线条样式
-
可以不用winmain函数的原理
学windows编程的时候,都是要求winmain为入口,而控制台编程的时候,是通常的main为入口。
为什么ege图形库没有使用winmain,也能创建窗口呢?
操作系统装载应用程序后,做完初始化工作就转到程序的入口点执行。
程序的默认入口点实际上是由连接程序设置的,不同的连接器选择的入口函数也不尽相同。
告诉linker怎么链接,subsystem后面参数可以指定四种方 式:“CONSOLE|WINDOWS|NATIVE|POSIX”
在微软的vs编译器下,连接器对控制台程序设置的入口entry函数是 mainCRTStartup,也即 main 函数
窗口程序入口entry是WinMainCRTStartup,也即winmain
通过变换有以下四种组合,能实现console和windows模式的混合。
#pragma comment( linker, "/subsystem:windows /entry:WinMainCRTStartup" )
#pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" )
#pragma comment( linker, "/subsystem:console /entry:mainCRTStartup" )
#pragma comment( linker, "/subsystem:console /entry:WinMainCRTStartup" )
综上ege.h头文件中的意思如果使用_MSC_VER(vs编辑器),那么就不要控制台,入口点是main函数。
实现了避开winmain的效果。