C/C++游戏之旅(二)————窗体上添加控件和图形
人山人海的十一假期结束了,继续我们的游戏开发学习,今天继续我们的win32基础编程,在窗体上创建菜单、事件响应和绘制图形等。好吧(你已经烦了),废话少说,开始了:一、窗口上添加菜单
首先,创建菜单头文件MENU.H文件,定义菜单选项,内容如下:
#define MENU_FILE_ID_OPEN 10000#define MENU_FILE_ID_CLOSE 10001#define MENU_FILE_ID_SAVE 10002#define MENU_FILE_ID_EXIT 10003
然后,创建资源文件MENU.RC,声明菜单按钮,内容如下:
#include "MENU.H"MainMenu MENU DISCARDABLE{POPUP "文件"{MENUITEM "打开",MENU_FILE_ID_OPENMENUITEM "关闭",MENU_FILE_ID_CLOSEMENUITEM "保存",MENU_FILE_ID_SAVEMENUITEM "退出",MENU_FILE_ID_EXIT}}
最后加载菜单:
winclass.lpszMenuName="MainMenu";//菜单资源名称
//将菜单句柄传入createWindow()函数
LoadMenu(hinstance,"MainMenu")//返回菜单句柄
好了运行的你的工程,出现结果了吗?我相信你肯定出现了,因为你超牛的!
二、响应菜单事件
其实,很简单啦,当您每次单击菜单时,就向我们定义的winproc回调函数发送了一个WM_COMMAND类型的消息,所以我们只要处理该消息,便可以达到响应事件的效果,我们在毁掉函数中加入如下代码:
case WM_COMMAND:{switch(LOWORD(wparam)){//老实说:我也不知道这个函数是什么意思,从何而来,起什么作用 case MENU_FILE_ID_EXIT: { // 退出 PostQuitMessage(0); } break; case MENU_FILE_ID_OPEN: { } break; case MENU_FILE_ID_CLOSE: { } break; case MENU_FILE_ID_SAVE: { } break;}}
好了,随便你怎么搞了,总之,在里面做你想做的事情!
三、在窗体上画点东西
根据windows的处理方法,我们需要创建画笔和刷子这两个对象,然后,让他和图形设备描述表关联之后,我们才能驱动硬件在屏幕上绘制图形。所以,我们的步骤如下:
先获取图形设备描述表
HDC hdc = GetDC(hwnd);
其次,创建画笔和刷子
HPEN white_pen = CreatePen(PS_SOLID, 1, RGB(255,255,255));
HPEN black_pen = CreatePen(PS_SOLID, 1, RGB(0,0,0));
HBRUSH green_brush = CreateSolidBrush(RGB(0,255,0));
HBRUSH black_brush = CreateSolidBrush(RGB(0,0,0));
然后,关联
SelectObject(hdc, black_pen);
SelectObject(hdc, black_brush);
之后,画圆
Ellipse(hdc, ball_x, ball_y, ball_x + 50, ball_y + 50);
上面只是关键得代码,下面我贴上完整的代码:
#include "main2.h"#include "MENUs.h"#define WIN32_LEAN_AND_MEAN#include <stdlib.h>#include <windows.h> #include <windowsx.h>#include <stdio.h>#include <math.h>#include <mmsystem.h>#define WINDOW_CLASS_NAME "MY_CLASS"#define WINDOW_WIDTHGetSystemMetrics(SM_CXFULLSCREEN)#define WINDOW_HEIGHT GetSystemMetrics(SM_CYFULLSCREEN)//系统进程回调函数LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam){PAINTSTRUCTps;//图形绘制结构体HDChdc;//句柄switch(msg){case WM_CREATE: //窗口创建时 {return(0);} break;case WM_PAINT: //窗口重绘时{hdc = BeginPaint(hwnd,&ps);//开始绘制 EndPaint(hwnd,&ps);//结束绘制return(0); } break;case WM_DESTROY://窗口销毁时{PostQuitMessage(0);return(0);} break;case WM_COMMAND:{switch(LOWORD(wparam)){//老实说:我也不知道这个函数是什么意思,从何而来,起什么作用 case MENU_FILE_ID_EXIT: { // 退出 PostQuitMessage(0); } break; case MENU_FILE_ID_OPEN: { } break; // handle each of sounds case MENU_FILE_ID_CLOSE: { } break; case MENU_FILE_ID_SAVE: { } break;}}default:break; }//将消息队列中 不属于该进程的消息发送给系统进程return (DefWindowProc(hwnd, msg, wparam, lparam));}//程序入口int WINAPI WinMain(HINSTANCE hinstance,//应用程序当前事例的句柄 HINSTANCE hprevinstance,//应用程序的前事例的句柄。对于一个32的位程序,该参数总为NULL LPSTR lpcmdline,//指向应用程序命令行的空字符串的指针,不包括函数名。获得整个命令行,参看GetCommandLine int ncmdshow//指明窗口如何显示 ){WNDCLASSEX winclass;//声明窗体信息结构体HWND hwnd=NULL;MSG msg; HDC hdc;winclass.cbSize=sizeof(WNDCLASSEX);//计算结构体大小winclass.style=CS_DBLCLKS | CS_OWNDC;//设置窗口风格,宽和高改变时刷新窗口winclass.lpfnWndProc=WindowProc;//指向时间句柄的函数指针,基本上都是响应某个操作的回调函数(是我们自己定义的函数),这里设为空。//下面两个字段原本是为了指示windows将附加的运行时间告诉系统的,大多数人都设为0winclass.cbClsExtra=0;winclass.cbWndExtra=0;winclass.hInstance=hinstance;//系统传给winmain函数的句柄winclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//设置窗体图标winclass.hCursor=LoadCursor(NULL,IDC_ARROW);//设置光标winclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//获取系统画刷、画笔、调色板或字体的一个句柄。winclass.lpszClassName=WINDOW_CLASS_NAME;//为自己创建的结构体赋别名,将来用它可以来引用该结构体winclass.lpszMenuName="MainMenu";//菜单资源,以后再作解释winclass.hIconSm=LoadIcon(NULL,IDI_APPLICATION);//应用程序图标//注册结构体if(!RegisterClassEx(&winclass)){return(0);}int x=GetSystemMetrics(SM_CXFULLSCREEN);//获取全屏 x的宽度int y=GetSystemMetrics(SM_CYFULLSCREEN);//获取全屏 y的高度//创建窗口hwnd=CreateWindowEx(NULL,WINDOW_CLASS_NAME,"哥的第一个窗口",WS_OVERLAPPEDWINDOW|WS_VISIBLE,0,0,x,y,NULL,LoadMenu(hinstance,"MainMenu"),hinstance,NULL);if(NULL==hwnd){return(0);}//得到图形设备描述表hdc = GetDC(hwnd);//创建花笔和刷子HPEN white_pen = CreatePen(PS_SOLID, 1, RGB(255,255,255));HPEN black_pen = CreatePen(PS_SOLID, 1, RGB(0,0,0));HBRUSH green_brush = CreateSolidBrush(RGB(0,255,0));HBRUSH black_brush = CreateSolidBrush(RGB(0,0,0));// 园的开始坐标int ball_x = WINDOW_WIDTH/2;int ball_y = WINDOW_HEIGHT/2;// 园的移动距离int xv = 5;int yv = 5;// 循环发送消息while(TRUE){ // 获取消息if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { // 是否退出 if (msg.message == WM_QUIT) break; //转换消息 TranslateMessage(&msg); // 发送消息 DispatchMessage(&msg); } // 图形设备描述表选择画笔和刷子 SelectObject(hdc, black_pen); SelectObject(hdc, black_brush); //画圆 Ellipse(hdc, ball_x, ball_y, ball_x + 50, ball_y + 50); //移动园 ball_x+=xv; ball_y+=yv; // 边界检测 if (ball_x < 0 || ball_x > WINDOW_WIDTH - 50) { xv=-xv;ball_x+=xv; } else // 边界检测 if (ball_y < 0 || ball_y > WINDOW_HEIGHT - 50) { yv=-yv; ball_y+=yv; } // 图形设备描述表选择画笔和刷子 SelectObject(hdc, white_pen); SelectObject(hdc, green_brush); // 画圆 Ellipse(hdc, ball_x, ball_y, ball_x +50, ball_y + 50); //休眠10毫秒 Sleep(50);} // end while//释放所有笔和刷子DeleteObject(white_pen);DeleteObject(black_pen);DeleteObject(green_brush);DeleteObject(black_brush);//释放图形设备描述表ReleaseDC(hwnd,hdc);return(msg.wParam);}
页:
[1]