制作游戏用的C++函数

用户名:lw
访问量:1301
注册日期:
阅读量:5863
阅读量:12276
阅读量:418265
阅读量:1106293
51CTO推荐博文
& 若是大神,就不要看这篇文章了。欢迎大神前来指教。
& 学习C++的亲们,你们是不是大都都有不知从何学习编程的感觉?若是,则说明你们以前不了解编程,或者说对编程没有那种兴趣和激情,学习编程就像打游戏一样,没人教,你照样可以成为高手,因为你没日没夜的打游戏,怎么可能打不好!
& 所以说白了,编程就是打出来的,哪怕不懂,也要抄个100篇。
& &可以没人教,真正的牛人没听说是哪个老师叫出来的。
& &不多扯淡了,下面来玩一个大家都玩过的小游戏---贪吃蛇。玩过,那我们也做一个。
用面向对象实现三步走,一、定义类:public private,定义函数和变量。二、实现部分:即实现函数。三、主函数部分
//开始编写游戏需要的类
#include &graphics.h& //EasyX(绘图库,自己添加)
#include &stdio.h&
#include &conio.h&
#include &time.h&
#define UP & & &1
#define DOWN 2
#define LEFT 3
#define RIGHT 4
//格子类,定义一个格子的属性及行为
class Cell
friend class GameA &//设置友元函数
void setxy(short x, short y) & //设置格子左上角坐标
m_x = x, m_y =
void setfull(short full) &//设置格子属性,0为空,1为障碍,2为食物
void display(COLORREF color) &//设置格子颜色并显示
setfillstyle(m_color);
bar(m_x, m_y, m_x+7, m_y+7);
void LaserDisplay() &//显示镭射状态的格子
IMAGE image(10,10);
SetWorkingImage(&image);
DWORD* pMem = GetImageBuffer(&image);
for(int i = 0; i & 10 * 10; i++)
pMem[i] = BGR(RGB(0, 0, i * 256 / (10*10) ));
SetWorkingImage(NULL);
putimage(m_x,m_y,&image);
short ReturnFull() &//返回格子状态
Cell() &//构造函数
m_x = 0,m_y = 0,m_full = 0;
m_color = BLACK;
short m_x;
//格子的左上角X坐标
short m_y;
//格子的左上角Y坐标
//0为空,1为阻挡,2为食物
COLORREF m_ //格子颜色
//游戏区类,编写有关游戏区的一些操作
class GameArea &//游戏区域
Cell m_game[60][60];
//定义游戏区域(由360个格子组成)
friend void MessageDispose(); //设置友元函数
bool CreatFood()
//产生随机食物
srand(time(NULL));
//初始化随机数种子
m_random1 = rand()%58+1;
//随机生成一个0 - 58的整数
m_random2 = rand()%58+1;
//随机一个0 - 58的整数
if(m_game[m_random2][m_random2].m_full == 0) //检查生成的食物坐标是否在障碍上
m_game[m_random1][m_random2].display(GREEN);
m_game[m_random1][m_random2].m_full = 2;
//如果随机的食物正好出现在蛇身上,则进入下面的循环寻找可以生成食物的地方
for(m_random1 = 1;m_random1 & 59;m_random1++)
for(m_random2 = 1;m_random2 & 59;m_random2++)
if(m_game[m_random2][m_random2].m_full == 0)
m_game[m_random1][m_random2].display(GREEN);
m_game[m_random1][m_random2].m_full = 2;
//如果没有找到可以生成食物的地方,则通关
&//返回false即表示通关
void DelFood() //删除食物
m_game[m_random1][m_random2].m_full = 0; &//设置为0即代表格子属性为空
& & void ChangeColor(int flag1,int flag2,COLORREF color) &//设置指定格子的颜色
m_game[flag1][flag2].display(color);
void Init()
//初始化GAME区域
int flag1,flag2;
//标识变量
BeginBatchDraw();
//开始批量绘图
setfillstyle(BLACK); //设置当前颜色
bar(0,0,600,600);
//画无边框填充矩形(在这里的用途是用黑色清空游戏区域)
for(flag1 = 0;flag1 & 60;flag1++)
for(flag2 = 0;flag2 & 60;flag2++)
if(flag1 == 0 || flag1 == 59 || flag2 == 0 || flag2 == 59) //创建边界
{ & & & & & & & & & & &&
m_game[flag1][flag2].setfull(1);
m_game[flag1][flag2].setxy(flag1*10,flag2*10);
m_game[flag1][flag2].display(RGB(237,28,36));
//创建游戏区域
m_game[flag1][flag2].setfull(0);
m_game[flag1][flag2].setxy(flag1*10,flag2*10);
m_game[flag1][flag2].display(BLACK);
CreatFood();
EndBatchDraw();
int m_random1, m_random2;
//蛇类,定义蛇的数据结构以及蛇的行为
class Snake
//蛇头朝向
friend void MessageDispose();
friend int HitDetect();
friend void ReInit();&
head = NULL;
last = NULL;
now &= NULL;
void Init()
//初始化蛇的结构
if(head!=NULL) &//重玩游戏时,释放原先的链表所有结点
for(now = head-&now-&next != NULL;now = now-&next)
free(now-&prior);
head = (struct node*)malloc(sizeof(struct node)); &//为蛇头分配内存
head-&prior = NULL;
head-&m_x = 300;
head-&m_y = 300;
now = (struct node*)malloc(sizeof(struct node));
head-&next =
now-&prior =
now-&next = NULL;
now-&m_x = 300;
now-&m_y = 290;
toward = DOWN;
void SnakeAdd()
//当前指向蛇头
now-&prior = (struct node*)malloc(sizeof(struct node)); &//为新增的结点分配内存
now = now-& //让当前指向新分配的结点
now-&prior = NULL; &//置空当前结点的前趋
now-&next = //让当前结点的后继指向蛇头
switch(toward)
//根据当前蛇头方向确定新增部分的坐标
now-&m_x = head-&m_x;
now-&m_y = head-&m_y -10;
case DOWN:
now-&m_x = head-&m_x;
now-&m_y = head-&m_y + 10;
case LEFT:
now-&m_x = head-&m_x - 10;
now-&m_y = head-&m_y;
case RIGHT:
now-&m_x = head-&m_x + 10;
now-&m_y = head-&m_y;
head = //设置当前结点为蛇头
void SnakeDel()
//释放蛇尾结点(删除蛇尾)
last = last-&
free(last-&next);
last-&next = NULL;
void SnakeMove() //蛇身移动一格
SnakeAdd();
//增加蛇头
SnakeDel();
//删除蛇尾
struct node
//蛇身链表
struct node * &//下个结点
struct node * //上个结点
struct node *
struct node *
struct node *
//游戏类,用来初始化游戏的参数,及实现其他游戏操作
class Game
void Init()
closegraph();
initgraph(800,600);
setbkmode(TRANSPARENT);
//设置输出文字背景为透明
getfont(&f);
// 获取当前字体设置
f.lfHeight = 50;
// 设置字体高度为 48(包含行距)
_tcscpy(f.lfFaceName, _T(&黑体&));
// 设置字体为&黑体&
f.lfQuality = ANTIALIASED_QUALITY;
// 设置输出效果为抗锯齿 &
setfont(&f);
// 设置字体样式
void FailGame() &//游戏失败显示的画面
setcolor(RED);
setfont(70, 0, _T(&微软雅黑&));
outtextxy(150, 265, _T(&YOU LOSE!&));
void WinGame() //游戏胜利时显示的画面
setcolor(RED);
setfont(70, 0, _T(&微软雅黑&));
outtextxy(150, 265, _T(&YOU WIN!&));
FlushBatchDraw();
Sleep(10000);
//管理区类,定义管理区域的相关操作
class ManageArea &
friend void MessageDispose();
void TimeAdd(double add) //增加时间(可在类外直接调用实现动态刷新时间)
DisplayTime();
void ScoreAdd(short add) //增加分数(可在类外直接调用实现动态刷新分数)
m_score +=
DisplayScore();
void DisplayPause()
//显示暂停或者开始
BeginBatchDraw();
_stprintf(m_str_score, _T(&%d&), m_score);
setfont(25, 0, _T(&微软雅黑&));
setfillstyle(m_bgcolor);
bar(625,490,800,515);
setcolor(BLUE);
if(m_pause)
outtextxy(625, 490, _T(&开始(P键)&));
outtextxy(625, 490, _T(&暂停(P键)&));
EndBatchDraw();
void Init() &//初始化管理界面
m_time = 0.0;
m_score = 0;
m_leave = 1;
_stprintf(m_str_score, _T(&%d&), m_score); &//格式化转换类型
_stprintf(m_str_time, _T(&%.1lf&), m_time);
m_bgcolor = BLACK;
BeginBatchDraw();
setfillstyle(BLACK);
bar(601,0,800,600);
setfont(60, 0, _T(&微软雅黑&));
setcolor(GREEN);
outtextxy(625, 30, _T(&贪吃蛇&));
setfont(30, 0, _T(&微软雅黑&));
setcolor(RGB(128,0,255));
outtextxy(625, 140, _T(&制作:轻雨漫步&));
setfont(25, 0, _T(&微软雅黑&));
setcolor(BLUE);
outtextxy(625, 430, _T(&时间:&));
outtextxy(625, 460, _T(&分数:&));
outtextxy(625, 490, _T(&暂停(P键)&));
outtextxy(625, 520, _T(&重新游戏(R键)&));
setcolor(RED);
outtextxy(720, 400, m_str_leave);
outtextxy(680, 460, m_str_score);
outtextxy(680, 430, m_str_time);
EndBatchDraw();
TCHAR m_str_leave[2], m_str_time[33], m_str_score[5];
COLORREF m_
void DisplayTime() &//显示当前耗时
BeginBatchDraw();
_stprintf(m_str_time, _T(&%.1lf&), m_time);
setfont(25, 0, _T(&微软雅黑&));
setfillstyle(m_bgcolor);
bar(680,430,800,455);
setcolor(RED);
outtextxy(680,430,m_str_time);
EndBatchDraw();
void DisplayScore() &//显示当前分数
BeginBatchDraw();
_stprintf(m_str_score, _T(&%d&), m_score);
setfont(25, 0, _T(&微软雅黑&));
setfillstyle(m_bgcolor);
bar(680,460,800,485);
setcolor(RED);
outtextxy(680,460,m_str_score);
EndBatchDraw();
//游戏的消息控制,流程控制函数
void MessageDispose() &//消息处理函数
s.now = NULL;
bool Keepdown =
while(true)
Keepdown = &//是否持续按W A S D 中的一个按键
if(kbhit())
switch(c = getch()) &//处理按键消息(W A S D)
if(s.toward == UP)Keepdown =
else if(s.toward != DOWN&&s.toward != UP)s.toward = UP;
if(s.toward == DOWN)Keepdown =
else if(s.toward != UP&&s.toward != DOWN)s.toward = DOWN;
if(s.toward == LEFT)Keepdown =
else if(s.toward != RIGHT&&s.toward != LEFT)s.toward = LEFT;
if(s.toward == RIGHT)Keepdown =
else if(s.toward != LEFT&&s.toward != RIGHT)s.toward = RIGHT;
manager.m_pause = !manager.m_ //设置暂停或开始
manager.DisplayPause(); //显示暂停或开始
if(true == manager.m_pause) //如果暂停,直接进行下次循环
BeginBatchDraw();
switch(a.m_game[s.head-&m_x/10][s.head-&m_y/10].ReturnFull()) //检测蛇头遇到的情况
//遇到食物,蛇身加长
a.ChangeColor(s.head-&m_x/10,s.head-&m_y/10,BLUE);
s.SnakeAdd(); //蛇增长
a.ChangeColor(s.head-&m_x/10,s.head-&m_y/10,BLUE);
a.DelFood(); //删除食物
if(a.CreatFood() == false) //创建新食物,并检查是否通关
game.WinGame();
//游戏通关(当地图没地方创建食物时)
manager.ScoreAdd(1);
a.m_game[s.last-&m_x/10][s.last-&m_y/10].setfull(0);
//设置蛇尾经过处无障碍
a.ChangeColor(s.last-&m_x/10,s.last-&m_y/10,BLACK);
s.SnakeMove(); &//蛇移动一次
a.ChangeColor(s.head-&m_x/10,s.head-&m_y/10,BLUE);
a.m_game[s.head-&next-&m_x/10][s.head-&next-&m_y/10].setfull(1); //设置蛇头经过处有障碍
//遇到障碍物
game.FailGame();
a.ChangeColor(s.head-&m_x/10,s.head-&m_y/10,RGB(255,127,39));
FlushBatchDraw();
char c = ' ';&
while(c != 'r' && c != 'R') &//当游戏失败时,按R键可重新进行游戏
if(kbhit())
c = getch();
Sleep(10);
ReInit(); //重新开始游戏
EndBatchDraw();
if(Keepdown==false)
Sleep(100);
manager.TimeAdd(0.1); //增加时间
//当持续按下按方向键时
Sleep(40);
//适当休眠可以增加游戏流畅性
manager.TimeAdd(0.04); &//增加时间
//游戏初始化函数
void ReInit()
a.Init(); //初始化游戏区
s.Init(); &//初始化蛇
manager.Init(); &//初始化管理区
//绘制蛇的开始状态
s.now = s.
a.ChangeColor(s.now-&m_x/10,s.now-&m_y/10,BLUE);
s.now = s.
a.ChangeColor(s.now-&m_x/10,s.now-&m_y/10,BLUE);
//main函数,程序入口
int main(void)
game.Init();
//初始化游戏参数、设置
//初始化其他
MessageDispose(); //消息处理函数
了这篇文章
类别:未分类┆阅读(0)┆评论(0)当前位置:
&&>&&&&>&&&&>&&正文
用Visual C++编写完整的屏幕保护程序
8:48:48&&&&
评论(0)&&&&
阅读(3495)
屏幕保护程序是一个Win32应用程序,与一般的Win32应用程序不同之处在于:1、扩展名要求为 SCR ;2、命令行要有一定的格式,以便操作系统向其传递信息,如 运行模式,父窗口句柄(Handle to Parent Window)等 ;3、其他一些消息相应方面的要求。本文将首先介绍屏幕保护程序的命令行格式及实现的方法,然后介绍各个相应函数,并通过Window主函数WinMin()勾画出屏幕保护程序的主框架,最后介绍编译步骤和注意事项  屏幕保护程序的命令行格式 :文件名 \ [运行模式] \[窗口句柄]。  其中运行模式有五种选择:  1. “运行模式”= ‘c’ 或 ‘C ’, 句柄为一串数字, 或文件名后没有任何参数。  屏保程序设置方式,Window 显示属性_屏幕保护程序_设置按钮调用,数字为调用函数的窗口句柄(Handle to Parent Window)(十进制),如果没有数字,句柄为NULL。  2. “运行模式”=‘t’或‘T’。  测试方式,忽略句柄数字。  3. “运行模式”=‘p’或‘P’。  预览方式,Window 显示属性_屏幕保护程序_预览按钮调用,句柄为调用函数的窗口句柄。  4. “运行模式”=‘a’或‘A’。  密码设置方式, Window 显示属性_屏幕保护程序_密码保护_更改按钮调用。句柄为调用函数的Window 句柄。  5. 其它(通常“运行模式”=‘s’)  屏幕保护程序正常运行模式。  因此,编写屏幕保护程序的首要任务是过滤命令行,提取对应的系统调用方式和其他信息,本文用自定义函数ParseCommandline( )实现://用enum定义五种调用方式:enum SaverMode{ sm_config, sm_preview, sm_full, sm_test, sm_passwordchange}; //命令行过滤函数,命令行获得函数是用API GetCommandLine( )。SaverMode ParseCommandLine( TCHAR* pstrCommandLine ){ g_hWndParent = NULL; //全局变量(global varibale) 在头函数或主文件开始处定义。 // 跳过长文件名中的路径和空格。 if (*pstrCommandLine == TEXT('\"')) {  pstrCommandLine++;  while (*pstrCommandLine != TEXT('\0') && *pstrCommandLine != TEXT('\"'))   pstrCommandLine++;   If( *pstrCommandLine == TEXT('\"') )    pstrCommandLine++; } else {  while (*pstrCommandLine != TEXT('\0') && *pstrCommandLine != TEXT(' '))   pstrCommandLine++;   if( *pstrCommandLine == TEXT(' ') )    pstrCommandLine++; } // 跳过"/" 或 "-" while ( *pstrCommandLine != TEXT('\0') && *pstrCommandLine != TEXT('/') && *pstrCommandLine != TEXT('-') )  pstrCommandLine++; // 如果没有任何参数,为设置模式。 if ( *pstrCommandLine == TEXT('\0') )  return sm_ // 如果有参数,查看参数内容。 switch ( *(++pstrCommandLine) ) {  case 'c':  case 'C':   pstrCommandLine++;   while ( *pstrCommandLine && !isdigit(*pstrCommandLine) )    pstrCommandLine++;   if ( isdigit(*pstrCommandLine) )   {    #ifdef _WIN64 //考虑64位编译情况。     CHAR strCommandLine[2048];     DXUtil_ConvertGenericStringToAnsiCb( strCommandLine, pstrCommandLine, sizeof(strCommandLine));      //该函数仅在64位编译情况下使用。     g_hWndParent = (HWND)(_atoi64(strCommandLine));     #else     g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine)); //数字串变为        /Window句柄    #endif   }  else  {   g_hWndParent = NULL; } return sm_ case 't': case 'T':  return sm_ case 'p': case 'P':  //预览模式,后面有Window句柄,为十进制数字  pstrCommandLine++;  while ( *pstrCommandLine && !isdigit(*pstrCommandLine) )   pstrCommandLine++;  if ( isdigit(*pstrCommandLine) )  {   #ifdef _WIN64    CHAR strCommandLine[2048];    DXUtil_ConvertGenericStringToAnsiCb(strCommandLine, pstrCommandLine,   sizeof(strCommandLine));    g_hWndParent = (HWND)(_atoi64(strCommandLine));   #else    g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine));   #endif  }  return sm_  case 'a':  case 'A':   //密码设置模式,后面有Window句柄,为十进制数字   pstrCommandLine++;   while ( *pstrCommandLine && !isdigit(*pstrCommandLine) )    pstrCommandLine++;   if ( isdigit(*pstrCommandLine) )   {    #ifdef _WIN64     CHAR strCommandLine[2048];     DXUtil_ConvertGenericStringToAnsiCb(strCommandLine, pstrCommandLine,   sizeof(strCommandLine));     g_hWndParent = (HWND)(_atoi64(strCommandLine));    #else     g_hWndParent = (HWND)LongToHandle(_ttol(pstrCommandLine));    #endif   }   return sm_  default:   //其他选项,屏保实际运行模式(通常/s)   return sm_ }}///////////////////////   ParseCommandLine( ) 返回后,程序根据不同的返回值进行响应:  返回值=sm_preview或者sm_test 或者sm_full:  程序根据返回的运行模式和Window句柄使用CreateWindow函数创建窗口(Window)并返回指向该窗口的句柄。这部分功能包含在自定义的CreateSaverWindow()函数中。在sm_preview情况下,程序用消息循环的方式等待500ms使操作系统的控制面板有足够的时间初始化。然后,读注册表检查屏保是否设定了密码,如果是,在Win9x情况下,用LoadLibrary()和GetProcessAdress()函数从动态链接库(DLL)中获得密码验证函数指针供程序退出时使用,密码验证函数类型为BOOL PASCAL (HWND)。这部分功能包含在自定义函数InitSaver()中。  以上窗口创建使用同一个窗口类(Window Class(WNDCLASS)),当然也是同一个消息响应函数(Window’s Procedure)。最后显示窗口,开始消息循环。  返回值=sm_passwordchange:  用LoadLibrary()和 GetProcessAdress()API获得密码设置函数指针,密码设置函数类型为:DOWORD PASCAL ( LPCSTR, HWND, DWORD, LPVOID ),然后调用该函数进行密码更改。  返回值=sm_config  显示一个对话框(Dialog),获取用户信息,在程序中进行相应的更改。  屏幕保护程序的退出机制反映在程序的消息响应函数(Window’s Procedure)中,当按下键盘上任何一个健或者鼠标移动计数超过5次(防止桌面振动等因素导致的鼠标移动),程序进入退出机制,在sm_test或者sm--_full情况下查看屏幕保护程序是否设置密码,如果是,验证密码,正确,程序退出,错误,程序继续。当程序验证密码时,通过全局变量g_bCheckingSaverPassword告诉消息响应函数对屏幕刷新,以保证密码的输入。其他情况(sm_config, sm_preview)不用验证密码直接退出。这些功能包括在自定义的函数InterruptSaver( )和ShutdownSaver( )中。  上述各个函数的详细代码如下:  1、 CreateSaverWindow 函数:HWND CreateSaverWindow(SaverMode mode, HWND hWndParent,HINSTANCE hInstance){ HWND hW RECT DWORD dwS hWnd=NULL; switch ( mode ) {  case sm_preview:   GetClientRect(hWndParent, &rc );   dwStyle = WS_VISIBLE | WS_CHILD;   AdjustWindowRect( &rc, dwStyle, FALSE );   hWnd = CreateWindow( TEXT("SaverWndClass"), TEXT("SaverWindow"), dwStyle, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hWndParent, NULL, hInstance, NULL);     case sm_test:   rc.left = rc.top = 50;   rc.right = rc.left+600;   rc.bottom = rc.top+400;   dwStyle = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;   AdjustWindowRect( &rc, dwStyle, FALSE );   hWnd = CreateWindow( TEXT("SaverWndClass"), TEXT("SaverWindow"), dwStyle, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,    NULL, NULL, hInstance, NULL);     case sm_full:   rc.left=rc.top=0;   rc.bottom=GetSystemMetrics(SM_CYSCREEN);   rc.right=GetSystemMetrics(SM_CXSCREEN);   dwStyle = WS_VISIBLE | WS_POPUP;   hWnd = CreateWindowEx( WS_EX_TOPMOST, TEXT("SaverWndClass"),    TEXT("SaverWindow"), dwStyle, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);  }  if(mode == sm_preview )  {   // 开始预览时,进入一个短暂的循环以使系统显示控制面板有足够的时间初始化   g_bWaitForInputIdle = TRUE;   // 开始循环   PostMessage( g_hWnd, WM_USER, 0, 0 );   MSG   while( g_bWaitForInputIdle )   {    // 如果If 返回 FALSE, 结束循环    if( !GetMessage( &msg, g_hWnd, 0, 0 ) )    {     // 结束循环     PostQuitMessage(0);         }    TranslateMessage( &msg);    DispatchMessage( &msg);   }  }  return hW }   2、 Window消息响应函数:LRESULT CALLBACK SaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){ switch ( uMsg ) {  case WM_USER:   //预览开始循环,500ms空闲时间用于控制面板的初始化。   SetTimer( hWnd, 1, 500, NULL );     case WM_TIMER:   // 500ms时间到,预览循环结束。   g_bWaitForInputIdle = FALSE;   KillTimer( hWnd, 1 );     case WM_DESTROY:   ShutdownSaver();     case WM_SETCURSOR:   if ( g_SaverMode == sm_full && !g_bCheckingSaverPassword )   {    //隐藏鼠标指针    SetCursor( NULL );    return TRUE;   }     case WM_PAINT:  {   PAINTSTRUCT   BeginPaint( hWnd, &ps );   RECT   GetClientRect(hWnd,&rc);   FillRect(ps.hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH) ); //黑屏   EndPaint( hWnd, &ps );   return 0;  }  case WM_ERASEBKGND:   // 输入密码时对屏幕刷新   if( !g_bCheckingSaverPassword )    return TRUE;      case WM_MOUSEMOVE:   if( g_SaverMode != sm_test )   {    static INT xPrev = -1;    static INT yPrev = -1;    INT xCur = GET_X_LPARAM(lParam);    INT yCur = GET_Y_LPARAM(lParam);    if( xCur != xPrev || yCur != yPrev )    {     xPrev = xC     yPrev = yC     g_dwSaverMouseMoveCount++;     if ( g_dwSaverMouseMoveCount & 5 )      InterruptSaver();    }   }     case WM_KEYDOWN:  case WM_LBUTTONDOWN:  case WM_RBUTTONDOWN:  case WM_MBUTTONDOWN:   if( g_SaverMode != sm_test )    InterruptSaver();      case WM_ACTIVATEAPP:   if( wParam == FALSE && g_SaverMode != sm_test )    InterruptSaver();     case WM_POWERBROADCAST:   if( wParam == PBT_APMSUSPEND && g_VerifySaverPassword == NULL )    InterruptSaver();     case WM_SYSCOMMAND:    if ( g_SaverMode == sm_full )   {    switch ( wParam )    {     case SC_NEXTWINDOW:     case SC_PREVWINDOW:     case SC_SCREENSAVE:     case SC_CLOSE:     return FALSE;    };   }     }  return DefWindowProc( hWnd, uMsg, wParam, lParam ); }   3、 ChangePassword()函数VOID ChangePassword(){ // 载入密码更改函数动态链接库(Dynamic Linked Library) HINSTANCE mpr = LoadLibrary( TEXT("MPR.DLL") ); if ( mpr != NULL ) {  // 从动态链接数据库中提取密码设置函数  typedef DWORD (PASCAL *PWCHGPROC)( LPCSTR, HWND, DWORD, LPVOID );  PWCHGPROC pwd = (PWCHGPROC)GetProcAddress( mpr, "PwdChangePasswordA" );  //运行密码设置函数  if ( pwd != NULL )   pwd( "SCRSAVE", g_hWndParent, 0, NULL );   //释放动态链接库  FreeLibrary( mpr ); }}  4、 InitSaver()函数VOID InitSaver(){ //检查操作系统版本 OSVERSIONINFO  osvi.dwOSVersionInfoSize = sizeof(osvi); GetVersionEx( &osvi ); g_bIs9x = (osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); // 在运行模式下,如果操作系统是win9x,需要载入密码验证动态链接库。 if ( g_SaverMode == sm_full && g_bIs9x ) {  // 检查注册表查看屏保是否设定了密码  HKEY hK   if ( RegCreateKeyEx( HKEY_CURRENT_USER, REGSTR_PATH_SCREENSAVE, 0, NULL, 0,  KEY_READ, NULL, &hKey, NULL ) == ERROR_SUCCESS )   {    DWORD dwV   DWORD dwSize = sizeof(dwVal);    if ( (RegQueryValueEx( hKey, REGSTR_VALUE_USESCRPASSWORD, NULL, NULL,(BYTE *)&dwVal, &dwSize ) == ERROR_SUCCESS) && dwVal )    {     g_hPasswordDLL = LoadLibrary( TEXT("PASSWORD.CPL") );    if ( g_hPasswordDLL )     g_VerifySaverPassword= (VERIFYPWDPROC)GetProcAddress( g_hPasswordDLL, "VerifyScreenSavePwd" );     RegCloseKey( hKey );   }  } } if ( g_SaverMode == sm_full ) {  BOOL bU  SystemParametersInfo( SPI_SCREENSAVERRUNNING, TRUE, &bUnused, 0 ); //通知操作系统屏幕保护程序开始运行。 }}   5、屏保退出函数ShutdownSaver( )和InteruptSaver( ):VOID ShutdownSaver(){ // 通知操作系统屏幕保护程序退出 if ( g_SaverMode == sm_full ) {  BOOL bU  SystemParametersInfo( SPI_SCREENSAVERRUNNING, FALSE, &bUnused, 0 ); } if ( g_hPasswordDLL != NULL ) {  FreeLibrary( g_hPasswordDLL );  g_hPasswordDLL = NULL; }  PostQuitMessage( 0 );}/////////////////////////////////VOID InterruptSaver(){ BOOL bPasswordOkay = FALSE; if( g_SaverMode == sm_test ||g_SaverMode == sm_full&&!g_bCheckingSaverPassword ) {  if( g_bIs9x && g_SaverMode == sm_full )  {   // Win9x下如果g_VerifySaverPassword==NULL,则没有设屏保密码。   if ( g_VerifySaverPassword != NULL )   {    g_bCheckingSaverPassword = TRUE;//告诉消息响应函数正在验证密码    bPasswordOkay = g_VerifySaverPassword( g_hWnd );    g_bCheckingSaverPassword = FALSE; //密码验证结束。    if ( !bPasswordOkay )    {     //屏保程序继续运行…     SetCursor( NULL );     g_dwSaverMouseMoveCount = 0;         }   }  }  ShutdownSaver(); }}   屏保设置方式下的响应程序为自定义Doconfig( ),因篇幅的关系不再详细介绍,读者应当很容易自己加上,也可以定义为空函数:VOID Doconfig ( ) {}。  黑屏屏幕保护程序主入口函数如下:#include #include #include #include #include #include #include "Saver.h"#include "resource.h"HINSTANCE g_HWND g_hWndPBOOL g_bWaitForInputIHWND g_hWLRESULT CALLBACK SaverProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){ // TODO: Place code here. MSG g_bCheckingSaverPassword = FALSE; g_bIs9x = FALSE; g_dwSaverMouseMoveCount = 0; g_hWndParent = NULL; g_hPasswordDLL = NULL; g_hWnd = NULL; g_VerifySaverPassword = NULL; g_hinstance=hI WNDCLASS cls.hCursor = LoadCursor( NULL, IDC_ARROW ); cls.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE(IDI_MAIN_ICON) );  cls.lpszMenuName = NULL; cls.lpszClassName = TEXT("SaverWndClass"); cls.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); cls.hInstance = hI  cls.style = CS_VREDRAW|CS_HREDRAW; cls.lpfnWndProc = SaverP cls.cbWndExtra = 0;  cls.cbClsExtra = 0;  if(!RegisterClass( &cls ))  MessageBox(NULL,TEXT("Cant register window class"),TEXT("SaverWndClass"),MB_ICONERROR); SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_IDLE );  TCHAR* pstrCmdLine = GetCommandLine(); g_SaverMode = ParseCommandLine(pstrCmdLine); switch(g_SaverMode) {  case sm_preview:  case sm_full:  case sm_test:  g_hWnd=CreateSaverWindow(g_SaverMode,g_hWndParent,hInstance);  if ( g_hWnd == NULL )  {   MessageBox(NULL,TEXT("Can't Create Window"), TEXT("Create Window Terminated"),MB_ICONERROR);   return 0;  }else  {   ShowWindow(g_hWnd,nCmdShow);   UpdateWindow(g_hWnd);  }  InitSaver();  while(GetMessage(&msg,NULL,0,0))  {   TranslateMessage(&msg);   DispatchMessage(&msg);  }   case sm_config:  Doconfig();   case sm_passwordchange:  ChangePassword();   } return 0;}   至此,黑屏屏幕保护程序代码编写完成,下一步是输入VC++6.0 并进行编译,具体步骤如下:  1、 打开VC++ 6.0, 从文件菜单中选择 New, 选中工程(Project)窗口,从窗口中选中Win32 Application项,在右侧的Locatioon(工程文件保存位置)填入位置信息(如填D\ScreenSaver),在其上边的Project name(工程名)栏中填入适当的名称(如Saver),按OK按钮,这时出现新的窗口,有三个选项,选择 A Simple Apllication, 按Finish(完成)健,接下来出现确认窗口,按OK,完成初步Win32 Application工程的创建。  2、 在ClassView窗口的Globles项下找到WinMain函数,双击鼠标打开C++文件(本文为Saver.cpp),按照前面的各条程序输入相应内容。  3、 选择FileView窗口选项,从主窗口文件菜单中选择New,选择File(文件),从文件类型中选择C\C++ Header File,输入文件名(最好与工程名同名,如Saver),确认后,新的头文件出现在FileView窗口Header Files项下(本文文件名为Saver.h)。  双击新创建的头文件(Saver.h),在头文件中输入以上函数和全局变量的说明(Declaration):enum SaverMode{sm_config,sm_preview,sm_full,sm_test,sm_passwordchange};typedef BOOL (PASCAL * VERIFYPWDPROC) (HWND);DWORD g_dwSaverMouseMoveCBOOL g_bIs9x;HINSTANCE g_hPasswordDLL;VERIFYPWDPROC g_VerifySaverPBOOL g_bCheckingSaverPSaverMode g_SaverMSaverMode ParseCommandLine( TCHAR* pstrCommandLine );HWND CreateSaverWindow(SaverMode mode, HWND hWndParent,HINSTANCE hInstance);VOID InitSaver();VOID ChangePassword();VOID Doconfig( );   4、 确保在C++主文件中包含头文件,即在主文件(Saver.cpp)中,包含#include 语句。  5、 在插入(Insert)菜单中选择资源(Resource),在随后出现的菜单中选择资源类型为图标(Icon),按新建按钮,这时,空白图标出现在右边窗口,对其进行编辑后,用鼠标选定该图标,从查看菜单中打开属性窗口(Properties),将该图标的ID 改为IDI_MAIN_ICON,按保存按钮,这时出现窗口,要求选择Resource Script文件名,填入适当的文件名(本文填Saver),按OK健,这时,工程目录中应当出现以rc为扩展名的文件。选择FileView窗口,选择Resource Files项,按鼠标右健,选择Add Files to Folder…项,将Resource.h和新建立的Saver.rc文件加入Resource项下。这时,出现ResourceView窗口选项,从该窗口中可以查看本工程的资源(Resource)情况。  6、 在工程菜单中,选择设置(Settings…), 在Setting for栏目中分别选择Win32 Release和Win32 Debug项,在右边的Link窗口中,将Output File Name中的文件名从exe扩展名改为scr扩展名。  这时,完成编译环境的设置和输入工作,从编译菜单中选Build,如果没有输入错误,即可顺利编译成功。
游戏程序设计相关文章}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信