c语言的应用场景(!c语言)
老铁们,大家好,相信还有很多朋友对于c语言的应用场景和!c语言的相关问题不太懂,没关系,今天就由我来为大家分享分享c语言的应用场景以及!c语言的问题,文章篇幅可能偏长,希望可以帮助到大家,下面一起来看看吧!
C++和C语言的区别
首先鄙视一下给E语言打广告的,人家问C和C++的区别,你说那没用的干啥?E配和C/C++一起相提并论吗?
正式解答:
从语法上讲:不严格的说C是C++的子集,也就是C++包含C语言的大部分语法.当然由于C++和C都有不同的版本(ANSI/ISO),各编译器对标准支持的程度也不一样.C++不一定能百分百兼容C.
从编程思想上讲:
C是典型的命令式编程,也就是作者精确的设计出程序的每一个过程.程序一步步的执行.
C++严格的讲并不是完全的面向对象编程,而是支持多重编程范式的语言.用C++来编写程序可以是命令式的,也可以是面对对象的,甚至可以是函数式编程.(C也可以用特殊技术模似面向对象和其它的编程风格,但还是以命令式编程为主)
从应用上讲:
C一般应用于要求高效,资源有限,与硬件相关度较大贴近底层的环境.如操作系统,驱动程序和嵌入式系统的编写.
C++执行效率高,又具有良好的软件工程性.适用于大规模的应用软件,游戏引擎的开发.我们所使用的大部分应用软件和几乎所有的大型游戏都是用C++编写的.
C和C++都是伟大的语言.他们创造出了不计其数的高品质软件,正是这些软件,悄悄的改变着我们的生活.在这个新语言层出不穷,人心浮躁的时代.它们不仅仅是一种技术,更是一种信仰!
C语言怎么学习啊
如何学习C语言
时间:2007-1-5 17:23:03作者:梁肇新
某天,你需要完成一个求100的阶乘的作业,于是你搬来一个最新的电脑,为它安装了最新的windows vista操作系统,然后坐在它的身前,喊“喂电脑,给我计算100的阶乘”,电脑说“ok, wait a moment”;过了一会,一盘香菇小白菜端了上来!呵呵,电脑不是waiter,你喂它它是不会有反应的,如果你真的wait a moment,恐怕你就需要wait one more moment了!一万年后,人们就把你命名成“望夫崖”。
既然电脑不是伺应生,听不懂我们的话,那么我们要怎么控制它呢?如果你们给我装聋作哑,我会告诉你期末挂了你,哦,你立马老实了!对于电脑,我要怎么才能使唤它,让它为我工作呢?不错,我们有个强力工具,C语言!
好,我们把上面的场景复习一下:
你要我算100的阶乘,于是我去机房上机,编写了一个程序:
(参加ppt......)
运行程序,哦,结果出来了!
有人认为,现在是java和.net的时代,有谁还需要C以及汇编呢?孰不知,java和.net是建立在软件之上的,是为了垄断市场而建立起来的体系,犹如挖好一个金壁辉煌的坑,请你往下跳,还自以为站在巨人的肩膀上,事实上成了坑底之蛙。要成为一个真正的程序员,并期望成为一个程序员高手,必须从机器出发,从cpu到操作系统,再到软件体系,高手的境界就是悟道后的明镜灵台,软件设计出神入化,我就是程序,程序就是我。
听完我讲高手的境界,于是乎你很受感动,说:我要努力学习,向高手学习!隔天就买了一堆MFC, VB, JAVA以及.NET的书回来,早上五点钟起来背书!这样是不行的,正确的入门方法只有一个,要证大道,唯有此法!同学们,从C语言入手,努力学好C语言!
旁观者李四说:此人大笨也!我用鼠标随便拖几个控件,就是一个xxx管理系统了,你用C语言恐怕是一年也写不出来吧!好吧,我要承认,讲这话的都已经是mS的奴才了,别的我不了解,MFC本身就是一个封闭的架构,从MFC入手学习,你只会形成一种封闭的思维模式,因为MS希望很多人只学会表面的东西,不致成为高手,所以它大力推荐所谓的可视化的程序开发工具,也真有很多人愿意上他的当,最后真正迷失方向。说他坐不了程序吧,他也可以作,但是如果程序复杂一点,出现问题时,问题出再哪里就搞不清楚了,反正是不清楚!
梁肇新,大牛啊,他说:“我就搞不懂了,用鼠标怎么写程序呢?在我的公司里,高手的键盘响个不停,鼠标偶尔响一下,新手是鼠标响个不停,键盘偶尔响一下,他们的薪水相差的就不是一倍那么多了!”
C语言是各大操作系统的基础,Unix、Linux、Windows其内核都清一色是C语言开发的,(某些地方是和汇编语言混合开发的),君不见Windows API都是C语言函数的接口?Unix/Linux绝大多数应用都是C语言开发的;Windows应用程序用纯API开发已然不多,大多都是依靠某种Application Framework,比如所谓的VC++,其实就是指VC IDE+ C++语言+ MFC(现在重点已转向ATL、WTL),但是Windows服务、网络、驱动程序等底层软件,还是C语言开发的。各种语言的编译器,包括java虚拟机,都是用C语言开发的。各种嵌入式设备,如手机、PDA也都是C语言开发的。C语言历史悠久,其内容也绝非谭浩强老师的《C语言程序设计(第二版)》所描述的那么简单——那本书只是针对中国国情的教学入门书而已。
学生总喜欢问:那种语言好?学那种语言有前途?这种问题天天在讨论,永无休止。其实我觉得大家所关心的,无非是那种语言更有“钱途”,学习那种语言毕业后能够轻松找到高薪的工作——当年我也是这么想。那么,我告诉你,如果你精通C语言,请你去华为,不要在小池塘里浪费青春了!
OK,听了我苦口婆心的劝告,你准备从C语言入手,开始攀登程序员高手这座山峰了,在你出发之前,你的行囊中需要准备什么呢?
第一个要装进行囊和你一起前进是“规范的格式”,有很多教科书,参考书,不太注重程序的格式的问题,写出的程序就象一堆堆的垃圾一样,这也导致了现在很多人写的程序中有很多的废码,垃圾代码,这和那些入门的书有非常大的关系,要把那些作者都拿来打打PP。真正的商业程序绝对是规范的,张三写的程序和李四的程序格式大致相同,各种标识符的命名规则一样,否则谁也看不懂你写的程序。如果写出来的代码谁也看不懂,那绝对是垃圾。如果要把那些垃圾翻半天,勉强才把金子找出来,那这样的程序不如不要,还不如重新写过,这样,思路会更清楚一点。所以说,规范的格式是入门的基础。那这个规范的格式包括什么呢?不少啊,要坚持才能做到!长标志符命名,代码缩进,一对大括号范围不超过一屏幕,等等。
第二个要装进行囊的是耐心,所谓工欲善其事,必先利其器。要想成功,没有一个相对平淡的过程是不可能的。这不仅仅指你在学习过程中要有耐心,要循序渐进,而且也说的是另一个重要的方面:调式程序。调试是写程序过程中一个重要的方面,如果有人能一次写成程序,牛啊,而且是大牛,不光是大牛,还是老子骑的那头青牛,凡人是做不道的!调试是每个程序必定经历的历程。经常有同学问我:老师,我的程序完全没错误啊,都是照书抄的啊!怎么就运行不出来呢?对于这个问题我也看不出来!你们有问题可以找我,找其他的老师,老师找谁啊?李师父?那是很荒谬的!我就只好坐下来调试,这个说实话,调试是很枯燥的,所以有同学抱怨说我操作太快,不理解为什么要这样,为什么要那样,我的脾气不太好,一烦躁就会骂人地,所以,这个就需要你们自己修炼内功了!
有了这两个就可以了,可以出发了,估计有人说了,英语和数学不要了?大家都说大学生了,这种问题就不要问了嘛!你已经用早晨和傍晚的时光学习了英语了,我这个没有要去,计算机专业英语超简单,小学水平而已,记住一些专业词汇就可以了!关于数学,说数学好,写程序就好是没有科学根据的!我就有个同学,数学回回100分,写程序也就是hello world的程度,不过人家现在是数学博士了!惭愧啊!做为的大学生,而且是我们这个专业的大学生,已经完全具备了写程序所需要的数学素养了!所以这个不是我们要担心的,Ready? Go!
第一招,学什么呢?打狗棍法!呵呵
有一个伟人说过:“重复权威是成熟的必经之路”,这是站在巨人的肩膀上的做法,习武之人首先要学的都是各种套路,比方说辟邪剑法,然后才能融会贯通,开宗流派;我们学习写程序也要这样来,这是一个捷径,帮你走得更远得捷径。
看书,看好书!书中所写,是前人数十年经验所写,看十本书,就相当于汲取了前人数十年的功力,那么你的内功也会迅速上升1甲子。:)书当然要看好书,只有好书才营养丰富。要做到读书破万卷,编程如有神;枯燥的看书是很郁闷的,很容易变成化石!现在很多是书都是用源码说明问题的,源码就像是动画、就像是幻灯片,把书中的招式一一演练给你看。可以说高手的经验大都是源自代码,最后也都化成源码展现在大家面前,把书上的程序一个一个的输入(用键盘,用你的手指)到电脑中,编译运行。自己手工输入这一步不能省略,现在很多书有配套源码,很多同学或者成年人学习的时候都耍小聪明,直接把源码复制过去编译运行,hoho,这是没有效果的。
自然,我让你输入程序不是让你练习盲打,你在输入的过程就可以品出程序的好坏来了,如果发现自己输入了很多重复代码,那至少这个程序的结构就不好了,穷则变,变则通嘛,你就想改进它啊,这不是很好吗?
当然,程序输得多了,盲打功力也上了一个台阶,键盘敲得快了,薪水也跟着涨上去了!^_^
不过,键盘敲得快不代表你的程序就写得好,否则学校只要每个学生发一份盲打联系软件,四年毕业后,个个都是程序高手了!
好了,你输了一个程序进电脑了,锻炼了手部肌肉,也运行出了结果,愉悦了身心,就此满足了?那离高手还远呢,要变成高手,你还要锻炼一下你得脑部肌肉!拿起你得笔,拿起你得纸,用你得大脑,这号称世界上最精密的机器来运行你输入的程序,记录下不同运行时刻变量的值,记录下程序的运行分支,最后发现,这个程序被你解剖到了纸上,我相信也解剖到了你的心里!这是捷径的核心,一定要记住,输入的程序不是说正确运行就完事了,要去阅读一下代码,利用笔和纸做辅助工具,做一下笔记,这就是重复权威,当然,如果你是天才,那请你塞上耳朵,你不在我们讨论的范围之内!
为什么这一步很重要呢?
大家刚开始学习的时候,是不是有种感觉,如果让你写一个程序,你从哪里下手呢?前面?后面?上面?下面?为了解决这个问题,我的程序该如何写呢?抓耳挠腮,好烦啊,于是乎干脆睡觉去,不写了,你看,这种行为是要打PP的!
练武功,总是先重复师父的动作,才能有自己的动作,所以也让我们重重复别人写的程序开始,然后再写自己的程序吧!
遵循这个方法,你们就跟着组织走上了通往罗马的大路了!
接下来,你得走啊,不走怎么到罗马呢?把你学会的程序设计方法应用到你写的程序中去啊!
某天,你看到这里有个问题,你有了想法,怎么办?上机去,和键盘奋战去!stop, stop!暂停一下,上机之前,不要忘记了你的笔和纸,勇敢地把你的想法写下来,如果写不出来,就不要去机房浪费爸爸妈妈的血汗钱了!
当然,你不能乱写啊,写出来的东西怎么样才叫不是乱写的呢?实践是检验真理的唯一标准!用你的大脑去运行一边啊,不是叫“人程序合一”嘛?,这就是了!学武功就要学绝世武功!虽然号称最精密,实际效果上,人脑还是没有电脑的准确度的,如果你的大脑能马马虎虎地运行出来之后,那么OK,带上规范的格式和耐心,去上机吧!
自然,我们说一天到晚面对字符界面的TC是有些郁闷,大家都习惯了windows,微软的客户体念设计中心可不是吹出来的!windows多好,色彩斑斓的。当你修炼到我这个程度的时候,非要听这京剧才文思泉涌的写程序的时候,当然要用windows下的集成开发环境了。但是对大家来说,不是现在,windows是很危险地,程序员还是回到TC中去吧!
TC至少有一个好处,可以锻炼我们使用组合键的习惯,可以锻炼我们使用键盘编程的习惯,回想我们刚刚说的梁某说的话“用鼠标怎么编程呢?”有同学不免要提出疑问了,我是80年代甚至是90年代生人,你还让我面对那么枯燥的输入输出界面?我跟你有代沟!我期待有更丰富更吸引人的交互手段哦,这个问题问得好,C语言中也有图形啊,完全可以满足大家寓教于乐得心理!让我们来看这个程序,很简单,就是在屏幕上话一个周期得正弦波!
(参见ppt......)
运行效果是不是很好?你学数据结构的时候,树啊,图啊,你都可以这样输出啊,很多地方你都可以做的更好呢!
好了,到这里,我们基本解决了在学习C语言程序设计时的一些方法论的东西,关于具体的学习过程,如果你要我在这里给你们讲指针要如何学习?函数要如何学习?那我讲的内容也不会多于任课老师的内容,或者开个专题叫“如何学好指针”,当然,如果你愿意和我探讨一下指针的本质和高级应用的话,课后,课后啊!
现在,我们要谈最后一个问题!我们这个专业的女生的比例较其他的工科专业还是要高一些的,不知道为什么经常到如下的说法:1,我是女生,我不适合写程序啊;2,我的性格比较外向,不适合坐下来安静的写程序呢!
性格外向不适合写程序?你们看我啊,觉得我是性格内向的任吗?程序员也非常需要发散的外向型思维,老比,地球上最富裕的人说,他招程序员更愿意招原来是学物理的人,因为学物理的人的思维可以从极大(宇宙)到极小(原子)。所有,说性格外向不适合写程序的话是懒惰的借口,是要掩盖他不可告人的目的的接口!狂打PP!
女生又为什么不适合写程序呢?我到知道一个理由,对皮肤不好啊!你们看我这满脸沧桑的,就知道了!除此之外,还会又其他的理由吗?英国科学家早就证明了男女的区别完全不是人们想象的那样,很多方面女性是要超过男性的!想想以前的母系社会,现在的惠安女!
我就见过一个上市公司的研发二部全是女性!,从软件工程师到硬件工程师再到部门经理都是女性,业绩根本不输其他的研发部门,这个公司在湖南,不是我瞎掰的!
如何用c语言编写图形操作的软件呢
学MFC吧~~你的困惑一下子就会解除的~~~
用纯C语言编带界面的也不是不可能~~就是要用到WINDOWS API~~给你一段代码试试吧~~是我做的一个OPENGL的程序~~~在VISUAL STUDIO.NET 2003下编译通过~~代码如下~~
#define WM_TOGGLEFULLSCREEN(WM_USER+1)//定义全屏/窗口切换消息
#define TIMER1 101//定义时钟代号,设置为101号
#define TITLE"5DG'S Color Shading"//定义窗口标题
#define CLASSNAME"5DG_OPENGL"//定义窗口类名
#define WIDTH 640//定义窗口宽度
#define HEIGHT 480//定义窗口高度
#define BPP 16//定义每象素的位数
#define NUM 200//定义绘制圆时用的顶点数(用顶点组成的线段逼近圆)
//在此处引用程序要求的头文件:
#include<windows.h>// Windows的头文件
#include<gl\gl.h>// OpenGL32库的头文件
#include<gl\glu.h>// Glu32库的头文件
#include<math.h>//数学函数库的头文件
//在此处加入程序要求的库到链接器中:
#pragma comment(lib,"opengl32.lib")//链接时查找OpenGL32.lib
#pragma comment(lib,"glu32.lib")//链接时查找glu32.lib
//在此处定义与窗口相关的结构体:
typedef struct{//定义处理键盘的结构体
BOOL keyDown [256];//存储键盘按键状态的数组
} Keys;
typedef struct{//定义存储应用程序实例的结构体
HINSTANCE hInstance;//应用程序实例
const char* className;//应用程序类名
} Application;
typedef struct{//定义初始化窗口所需信息
Application* application;//所属的应用程序
char* title;//窗口标题
int width;//窗口宽度
int height;//窗口高度
int bitsPerPixel;//每像素的位数
BOOL isFullScreen;//是否全屏
} GL_WindowInit;
typedef struct{//定义窗口结构体
Keys* keys;//键盘
HWND hWnd;//窗口句柄
HDC hDC;//设备描述表
HGLRC hRC;//绘制描述表
GL_WindowInit init;//提供Window初始化信息的结构体
} GL_Window;
//此代码模块中包含的函数的前向声明:
BOOL Initialize(GL_Window* window, Keys* keys);//设置你绘制前的初始化值
void DrawSceneGL(void);//在这里完成场景的绘制
void Update(void);//在此处更新对消息的动作
void Deinitialize(void);//在此处做退出前扫尾工作
//在此处定义全局变量:
GL_Window* OGL_window;//存储窗口信息
Keys* OGL_keys;//存储按键信息
//在此处定义用户变量:
void ResizeWindowGL(int width, int height)//重新设置窗口大小
{
glViewport(0, 0,(GLsizei)(width),(GLsizei)(height));//重置当前视口大小
glMatrixMode(GL_PROJECTION);//切换到投影矩阵模式
glLoadIdentity();//重置投影矩阵
gluPerspective(45,(float)width/(float)height, 0.1, 100);//设置透视投影
glMatrixMode(GL_MODELVIEW);//切换到模型视图矩阵
glLoadIdentity();//重置模型视图矩阵
}
BOOL ChangeScreenResolution(int width, int height, int bitsPerPixel)//修改屏幕分辨率
{
DEVMODE dmScreenSettings;//设备设置模式
ZeroMemory(&dmScreenSettings, sizeof(DEVMODE));//清空
dmScreenSettings.dmSize= sizeof(DEVMODE);// Devmode结构的大小
dmScreenSettings.dmPelsWidth= width;//设置为屏幕宽度
dmScreenSettings.dmPelsHeight= height;//设置为屏幕高度
dmScreenSettings.dmBitsPerPel= bitsPerPixel;//设为指定位长;
dmScreenSettings.dmFields= DM_BITSPERPEL| DM_PELSWIDTH| DM_PELSHEIGHT;
//尝试设置显示模式并返回结果。注: CDS_FULLSCREEN移去了状态栏
if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!= DISP_CHANGE_SUCCESSFUL)
{
return FALSE;//分辨率修改失败,返回 False
}
return TRUE;//分辨率修改成功,返回 True;
}
BOOL CreateWindowGL(GL_Window* window)//建立OpenGL窗口
{
DWORD windowStyle= WS_OVERLAPPEDWINDOW;//设置窗口样式
DWORD windowExtendedStyle= WS_EX_APPWINDOW;//设置窗口扩展样式
PIXELFORMATDESCRIPTOR pfd=//像素格式描述符(pfd)的设置
{
sizeof(PIXELFORMATDESCRIPTOR),//像素的尺寸
1,//版本号
PFD_DRAW_TO_WINDOW|// pfd必须支持窗口绘制
PFD_SUPPORT_OPENGL|// pfd必须支持OpenGL
PFD_DOUBLEBUFFER,// pfd必须支持双缓存
PFD_TYPE_RGBA,//像素格式为RGBA
window->init.bitsPerPixel,//设置颜色深度
0, 0, 0, 0, 0, 0,//忽略颜色位数
0,//无Alpha缓存
0,//忽略偏移位
0,//无累积缓存
0, 0, 0, 0,//忽略累积缓存位
16,//深度缓存为16位
0,//无模板缓存
0,//无辅助缓存
PFD_MAIN_PLANE,//主要绘制层
0,//保留位
0, 0, 0//忽略层遮罩
};
RECT windowRect={0, 0, window->init.width, window->init.height};//定义窗口大小
GLuint PixelFormat;//保存像素格式
if(window->init.isFullScreen== TRUE)//切换全屏
{
if(ChangeScreenResolution(window->init.width, window->init.height, window->init.bitsPerPixel)== FALSE)
{
//全屏切换失败
MessageBox(HWND_DESKTOP,"无法切换到全屏模式,在窗口模式下运行.\nMode Switch Failed,Running In Windowed Mode.","Error", MB_OK| MB_ICONEXCLAMATION);
window->init.isFullScreen= FALSE;//设置 isFullscreen为False
}
else//全屏切换成功
{
ShowCursor(FALSE);//隐藏鼠标
windowStyle= WS_POPUP;//设置窗口样式
windowExtendedStyle|= WS_EX_TOPMOST;//设置窗口扩展样式
}
}
else
{
//调整窗口大小,包括窗口边界
AdjustWindowRectEx(&windowRect, windowStyle, 0, windowExtendedStyle);
}
//开始创建 OpenGL窗口
window->hWnd= CreateWindowEx(windowExtendedStyle,//窗口扩展样式
window->init.application->className,//应用程序类名
window->init.title,//窗口标题
windowStyle,//窗口样式
0, 0,//窗口的 X,Y坐标位置
windowRect.right- windowRect.left,//窗口宽度
windowRect.bottom- windowRect.top,//窗口高度
HWND_DESKTOP,//父窗口为桌面
0,//无菜单
window->init.application->hInstance,//传入应用程序实例
window);
if(window->hWnd== 0)//窗口是否成功创建
{
return FALSE;//若失败,则返回FALSE
}
window->hDC= GetDC(window->hWnd);//取得当前窗口的设备描述表
if(window->hDC== 0)//若未得到设备描述表
{
DestroyWindow(window->hWnd);//销毁该窗口
window->hWnd= 0;//窗口句柄清零
return FALSE;//返回FALSE
}
PixelFormat= ChoosePixelFormat(window->hDC,&pfd);//选择兼容的像素格式
if(PixelFormat== 0)//若选择失败
{
ReleaseDC(window->hWnd, window->hDC);//释放设备描述表
window->hDC= 0;//将设备描述表清零
DestroyWindow(window->hWnd);//销毁窗口
window->hWnd= 0;//窗口句柄清零
return FALSE;//返回FALSE
}
if(SetPixelFormat(window->hDC, PixelFormat,&pfd)== FALSE)//设置像素格式并判断是否失败
{
ReleaseDC(window->hWnd, window->hDC);//释放设备描述表
window->hDC= 0;//将设备描述表清零
DestroyWindow(window->hWnd);//销毁窗口
window->hWnd= 0;//窗口句柄清零
return FALSE;//返回FALSE
}
window->hRC= wglCreateContext(window->hDC);//取得绘制描述表
if(window->hRC== 0)//若未得到绘制描述表
{
ReleaseDC(window->hWnd, window->hDC);//释放设备描述表
window->hDC= 0;//将设备描述表清零
DestroyWindow(window->hWnd);//销毁窗口
window->hWnd= 0;//窗口句柄清零
return FALSE;//返回FALSE
}
if(wglMakeCurrent(window->hDC, window->hRC)== FALSE)//设置绘制描述表并判断是否失败
{
wglDeleteContext(window->hRC);//删除绘制描述表
window->hRC= 0;//将绘制描述表清零
ReleaseDC(window->hWnd, window->hDC);//释放设备描述表
window->hDC= 0;//将设备描述表清零
DestroyWindow(window->hWnd);//销毁窗口
window->hWnd= 0;//窗口句柄清零
return FALSE;//返回FALSE
}
ShowWindow(window->hWnd, SW_NORMAL);//显示窗口
ResizeWindowGL(window->init.width, window->init.height);//重设窗口
ZeroMemory(window->keys, sizeof(Keys));//清空键盘缓冲区
return TRUE;//窗口创建成功
}
BOOL DestroyWindowGL(GL_Window* window)//销毁窗口并释放程序所用的资源
{
if(window->hWnd!= 0)//窗口释放有句柄?
{
if(window->hDC!= 0)//窗口是否有得到绘制描述表?
{
wglMakeCurrent(window->hDC, 0);//将当前描述表指针置为0
if(window->hRC!= 0)//该窗口是否有绘制描述表
{
wglDeleteContext(window->hRC);//释放绘制描述表
window->hRC= 0;//将绘制描述表清零
}
ReleaseDC(window->hWnd, window->hDC);//释放设备描述表
window->hDC= 0;//将设备描述表清零
}
DestroyWindow(window->hWnd);//销毁窗口
window->hWnd= 0;//将窗口句柄清零
}
if(window->init.isFullScreen)//若窗口在全屏模式下
{
ChangeDisplaySettings(NULL,0);//切换为桌面分辨率
ShowCursor(TRUE);//显示鼠标
}
return TRUE;//返回TRUE
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)//窗口消息处理
{
GL_Window* window=(GL_Window*)(GetWindowLong(hWnd, GWL_USERDATA));//取得窗口信息
switch(uMsg)//取得Window的消息
{
case WM_SYSCOMMAND://截取系统命令
{
switch(wParam)//监听系统调用
{
case SC_SCREENSAVE://要运行屏保?
case SC_MONITORPOWER://显示器进入节电模式?
return 0;//提前返回0,防止系统调用执行
}
break;//退出
}
case WM_CREATE://创建窗口
{
CREATESTRUCT* creation=(CREATESTRUCT*)(lParam);//保存窗口结构指针
window=(GL_Window*)(creation->lpCreateParams);
SetWindowLong(hWnd, GWL_USERDATA,(LONG)(window));//改变窗口属性
return 0;//返回
}
case WM_TIMER:// TIMER事件
{
InvalidateRect(window->hWnd, NULL, FALSE);//使窗口失效
break;
}
case WM_PAINT:// PAINT消息处理,在此处绘图
{
DrawSceneGL();//在此处绘图
SwapBuffers(window->hDC);//交换缓存
ValidateRect(window->hWnd, NULL);//使窗口有效
break;
}
case WM_CLOSE://关闭窗口
{
PostMessage(window->hWnd, WM_QUIT, 0, 0);//结束程序
return 0;
}
case WM_SIZE://窗口大小变化
{
ResizeWindowGL(LOWORD(lParam), HIWORD(lParam));//修改窗口大小为 Width= LoWord, Height= HiWord
return 0;//返回
}
case WM_KEYDOWN://按键按下时更新键盘缓冲
if((wParam>= 0)&&(wParam<= 255))//按键是否合法?
{
window->keys->keyDown[wParam]= TRUE;//设相应键为 True
return 0;//返回
}
break;//退出
case WM_KEYUP://按键松开时更新键盘缓冲
if((wParam>= 0)&&(wParam<= 255))//按键是否合法?
{
window->keys->keyDown[wParam]= FALSE;//设相应键为为 FALSE
return 0;//返回
}
break;//退出
case WM_TOGGLEFULLSCREEN://开关全屏模式
{
Deinitialize();//做扫尾工作
DestroyWindowGL(window);//销毁窗口
window->init.isFullScreen=!window->init.isFullScreen;//改变窗口模式
CreateWindowGL(window);//重新创建窗口
Initialize(window, window->keys);//初始化OpenGL绘制程序
break;//退出
}
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);//将本程序不处理的消息传给 DefWindowProc
}
BOOL RegisterWindowClass(Application* application)//为本应用程序注册一个类
{
WNDCLASSEX windowClass;//窗口类
ZeroMemory(&windowClass, sizeof(WNDCLASSEX));//清空内存
windowClass.cbSize= sizeof(WNDCLASSEX);//窗口类的大小
windowClass.style= CS_HREDRAW| CS_VREDRAW| CS_OWNDC;//在窗口移动,改变大小的时候重绘
windowClass.lpfnWndProc=(WNDPROC)(WindowProc);//用WindowProc函数处理消息
windowClass.hInstance= application->hInstance;//设置实例
windowClass.hbrBackground=(HBRUSH)(COLOR_APPWORKSPACE);//类背景的画刷颜色
windowClass.hCursor= LoadCursor(NULL, IDC_ARROW);//载入鼠标指针
windowClass.lpszClassName= application->className;//设置应用程序的类名
if(RegisterClassEx(&windowClass)== 0)//注册类失败?
{
MessageBox(HWND_DESKTOP,"应用程序类注册失败!\nRegisterClassEx Failed!","Error", MB_OK| MB_ICONEXCLAMATION);
return FALSE;//返回False(注册失败)
}
return TRUE;//返回True(注册成功)
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
Application application;//应用程序
GL_Window window;//窗口
Keys keys;//键盘按键
MSG msg;// Window消息
BOOL bRet;//保存消息获得是否成功
//给应用程序赋值
application.className= CLASSNAME;//程序类名字
application.hInstance= hInstance;//程序入口
//窗口相关信息设置
ZeroMemory(&window, sizeof(GL_Window));//清零窗口变量的内存空间
window.keys=&keys;//设置按键
window.init.application=&application;//设置窗口程序
window.init.title= TITLE;//设置标题
window.init.width= WIDTH;//设置窗口宽度
window.init.height= HEIGHT;//设置窗口高度
window.init.bitsPerPixel= BPP;//设置每像素的位数
window.init.isFullScreen= FALSE;//设置初始窗口是否全屏否(FALSE)
ZeroMemory(&keys, sizeof(Keys));//键盘缓冲清零
if(RegisterWindowClass(&application)== FALSE)//注册类是否失败
{
MessageBox(HWND_DESKTOP,"窗口类注册失败!\nError Registering Window Class!","Error", MB_OK| MB_ICONEXCLAMATION);
return-1;//结束程序
}
if(CreateWindowGL(&window)== TRUE)//创建窗口是否成功
{
if(Initialize(&window,&keys)== FALSE)//初始化OpenGL绘制程序
{
PostMessage(window.hWnd, WM_QUIT, 0, 0);//抛出消息WM_QUIT
}
}
else
{
return 0;//退出程序
}
while((bRet= GetMessage(&msg, NULL, 0, 0)!= 0))//循环直到收到消息为WM_QUIT
{
if(bRet!=-1)
{
Update();//更新处理消息事件
TranslateMessage(&msg);//传递消息
DispatchMessage(&msg);//分派消息
}
else
{
break;//退出循环
}
}
//退出消息循环,准备退出程序
Deinitialize();//做退出前的扫尾工作
DestroyWindowGL(&window);//销毁窗口
UnregisterClass(application.className, application.hInstance);//注销窗口类
return 0;//退出程序
}
BOOL Initialize(GL_Window* window, Keys* keys)//用户绘制场景相关的函数在此处定义
{
//设置全局变量
OGL_window= window;
OGL_keys= keys;
//建立时钟
SetTimer(window->hWnd, TIMER1, 33, NULL);
//在此处初始化绘制场景
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);//清屏为黑色
glClearDepth(1.0f);//设置深度缓存
glDepthFunc(GL_LEQUAL);//选择深度测试方式
glEnable(GL_DEPTH_TEST);//开启深度测试
glShadeModel(GL_SMOOTH);//阴暗处理采用平滑方式
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//最精细的透视计算
return TRUE;//初始化成功返回TRUE
}
void DrawSceneGL(void)//绘制场景
{
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);//清除颜色和深度缓存
glLoadIdentity();//重置当前矩阵
//在此处添加代码进行绘制:
glShadeModel(GL_SMOOTH);//阴暗处理采用平滑方式(Smooth Shading)
glTranslatef(-1.5f, 1.0f,-6.0f);//坐标原点往左移1.5f,往上移1.0f,往内移6.0f
glBegin(GL_TRIANGLES);//开始绘制一个三角形
glColor3ub(255, 0, 0);//定义上顶点为红色
glVertex3f(0.0f, 1.0f, 0.0f);//绘制上顶点
glColor3ub(0, 255, 0);//定义左下顶点为绿色
glVertex3f(-1.0f,-1.0f, 0.0f);//绘制左下顶点
glColor3ub(255, 255, 0);//定义右下顶点为黄色
glVertex3f(1.0f,-1.0f, 0.0f);//绘制右下顶点
glEnd();
glTranslatef(3.0f, 0.0f, 0.0f);//向右平移3.0f
glColor3ub(0, 255, 255);//定义正方形的颜色
glBegin(GL_QUADS);//开始绘制一个正方形
glVertex3f(-1.0f, 1.0f, 0.0f);//绘制左上角顶点
glVertex3f(-1.0f,-1.0f, 0.0f);//绘制左下角顶点
glVertex3f( 1.0f,-1.0f, 0.0f);//绘制右下角顶点
glVertex3f( 1.0f, 1.0f, 0.0f);//绘制右上角顶点
glEnd();
glTranslatef(-1.5f,-2.0f, 0.0f);//向左移1.5f,向下移2.0f
glColor3f(0.0f, 0.8f, 0.2f);//绿色
glBegin(GL_LINE_LOOP);//绘制圆
for(int i=0; i<NUM; i++)
{
glVertex3f(1.5f*(float)sin(2.0f*3.14f*i/NUM), 0.0f, 1.5f*(float)cos(2.0f*3.14f*i/NUM));
}
glEnd();
glFlush();//刷新GL命令队列
}
void Update(void)//在此处更新对消息的动作
{
if(OGL_keys->keyDown[VK_ESCAPE]== TRUE)//判断ESC键是否按下
{
PostMessage(OGL_window->hWnd, WM_QUIT, 0, 0);//结束程序
}
if(OGL_keys->keyDown[VK_F1]== TRUE)//判断F1是否按下
{
PostMessage(OGL_window->hWnd, WM_TOGGLEFULLSCREEN, 0, 0);//在全屏/窗口模式间切换
}
}
void Deinitialize(void)//在此处做退出前扫尾工作
{
KillTimer(OGL_window->hWnd, TIMER1);//释放时钟
}
OK,本文到此结束,希望对大家有所帮助。