这是一个最基本的windows程序展示了最基本的windows窗体和基本的消息循环是游戏开发的入门功夫,以下代码经过详细的注解,直接复制以后可以直接在DEV-C++下和VC6.0下编译运行。
//#define WIN32_LEANNAND_MEAN
//#ifdef DEBUG_MODE
//printf("Debug mode is Active!");
//#endif
#include <windows.h>
#include "resourse.h"
HWND hWnd;
LRESULT CALLBACK MsgHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return(DefWindowProc(hWnd,msg,wParam,lParam));
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{ //声明窗口类
WNDCLASSEX wc;
wc.cbSize=sizeof(WNDCLASSEX);
wc.style =CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc=MsgHandler;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance =hInstance;
wc.hIcon =LoadIcon(NULL,"ICON_FOOLY");
wc.hCursor =LoadCursor(NULL,IDC_ARROW);
//wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hbrBackground=(HBRUSH)(BLACK_BRUSH);
wc.lpszMenuName =NULL;
wc.lpszClassName ="Sample Class";
wc.hIconSm =LoadIcon(NULL,IDI_WINLOGO);
//注册窗口类
RegisterClassEx(&wc);
//创建窗口
if (!(hWnd=CreateWindowEx(NULL,"Sample Class", "Sample Window",WS_POPUP|WS_VISIBLE,
0, 0 ,640, 480 ,NULL, NULL, hInstance, NULL))) {return(0);}
ShowWindow(hWnd,nCmdShow);
UpdateWindow(hWnd);
return(0);
}
//1。HINSTANCE 是一个句柄类型的标志符变量hInstance是一个整数,用于标志程序实例。
//window设置这个参数并把它传递给你的程序代码。
//2。HINSTANCE hPrevInstance 已经被废除掉了。只是为古老的Window版本服务
//3。LPSTR lpCmdLine:是一个指向字符串的指针,它仅在DOS的命令窗口输入
//或是RUN对话框中输入时才起作用。
//4。int nCmdShow:决定了窗口在初始化时显示的状态。
//Windows通常给这个参数分配一个值。通常是一个SW_打头的常量
//Example:SW_SHOWNORMAL表示默认的状态SW_MAXINIZE或SW_MINMIZE表示最大与最小模式
//**************************************************************//
//×××××××消息处理××××××××××××××××××××//
//*************************************************************//
//在Windows下的编程不得不考虑其它正在运行的程序;于是Windows通过
//"消息"来连接操作“申请”和具体的操作 :准确的说是我们指示程序
//或程序本身向Windows发出处理的“如移动窗口..”申请,Windows根据实际的
//情况考察实际的情况,拒绝或发出指令让程序(计算机)作出相应的动作
//*****◎ WM_ACTIVATE:一个新窗口被激活。
//◎ WM_CLOSE:一个窗口被关闭。
//◎ WM_COMMAND:一个菜单功能被选择。
//◎ WM_CREATE:一个窗口被建立。
//◎ WM_LBUTTONDBLCLK:鼠标左键被双击。
//◎ WM_LBUTTONDOWN:鼠标左键被按下。
//◎ WM_MOUSEMOVE:鼠标被移动。
//◎ WM_MOVE:一个窗口被移动。
//◎ WM_PAINT:窗口的一部分需要重画。
//◎ WM_RBUTTONDBLCLK:鼠标的右键被双击。
//◎ WM_RBUTTONDOWN:鼠标的右键被按下。
//◎ WM_SIZE:窗口的大小被改变。
//◎ WM_USER:干你想干的。
//*************************************************************************
//总之,无论何时Windows都要掌控所有的消息,并且Windows是不断的收到各种消息
//*************************************************************************
//×××××××××××××××××××××××××××××××××××//
//**********Windows是通过一个“CALLBACK函数类型”实现的*****************//
//×××××你只要声明一个CALLBACK类型的函数就行了×××××××××××//
//×××××××××××××××××××××××××××××××××××//
//*******Windows窗口类**************************************************//
//××××××××××××××××××××××××××××××××××//
//typedef struct_WNDCLASSEX{
//UINT cbSize;//指定了以字节为单位的结构大小。通过sizeof(WNDCLASSEX)实现
//UINT style;//窗口风格。符号常量:
//CS_HREDRAW(客户区的宽度改变就重新绘制窗口)|
//CS_VREDRAW(客户区的高度改变就重新绘制窗口)|
//CS_OWNDC(该类中的窗口分配唯一的设备上下文)|
//CS_DBLCLKS(双击鼠标时向窗口发送双击消息)
//WNDPROC lpfnWndproc;//窗口过程的指针。一般指向CALLBACK函数(简单理解为函数的地址就是函数的名字)
//int cbClsExtra;//为类保留的额外信息。一般设为0;因为大多数的程序用不到它
//int cbWndExtra;//同上
//HANDLE hInstance;//指向窗口过程实例的句柄。同时也是WinMain()函数的参数之一
//HICON hIcon;//指向窗口图标的句柄。通常用LoadIcon(NULL,IDI_WINLOGO)函数设置
//HCURSOR hCursor;//窗口光标的句柄。通常用LoadCursor(NULL,IDC_ARROW)函数设置
//HBRUSH hbrBackground;//重画窗口的"画刷"。可以用GetStockObject(BLACK_BRUSH)函数设置
//如:BLACK_BRUSH,WHITE_BRUSH,GRAY_BRUSH等等
//LPCTSTR lpszMenuName;//建立有下拉菜单的窗口(必须给这个参数赋一个菜单名称)。可以现设为NULL
//LPCTSTR lpszClassName;//一个类的名字塞 。简单一个字符串就可以了
//HICON hIconSm; //指向一个小图标的句柄显示在窗口的标题栏里。要用到LoadIcon()函数
//} WNDCLASSEX;
//RegesterClassEx(&wc);
//创建窗口
//HWND CreateWindowEx(
//DWORD dwEXStyle,//扩充的窗口风格。以WS_EX_打头一般设为NULL
//LPCTSTR lpClassName,//窗口类的命名称。
//LPCTSTR lpWindowName,//将显示在标题栏里的简短文字
//DWORD dwStyle,//窗口的风格。以WS_打头的
//如果你要只有一个标题栏的、可以改变大小的就选择WS_OVERLAPPED
//如果你要选择一个可以最大化、最小化。随意改变大小的窗口就选择WS_OVERLAPPEDWINDOW
//如果只要一个光秃秃的窗口就选择WS_POPUP;如果只想显示一个黑色的大方框就WS_VISIBLE.
//int x,//窗口左上角的坐标
//int y,
//int nWidth,//窗口的长宽,单位是『象素』
//int nHeight,
//HWND hWndParent, //指向父窗口的句柄 。NULL是指Window桌面就是父窗口
//HMENU hMenu,//窗口上的菜单句柄。可以用LoadMenu()调用自己的菜单资源
//HINSTANCE hInstance,//一个句柄。指向由windows传递给WinMain()的实例
//LPVOID lpParam//游戏编程中不用它 。设为NULL
//) ;
//**********************************************************************//
//跟踪你的窗口和使用GDI
//HDC设备上下文是一个表现一组图形对象和属性的结构,还有一些输出设备的设置与属性。
//HDC允许你直接操作图形,不用考虑低级的细节
//Windows的GDI是一个图形翻译系统,介于应用程序与图形硬件之间的一层
//GDI可以输出到任意的兼容设备,不过经常使用的设备是视频监视器、图形硬拷贝设备(打印机或绘图仪)、或者是内存中的图元文本。
//GDI函数能够绘制直线、曲线、封闭的图形和文本。
//所有访问GDI的Windows函数都需要一个设备上下文句柄作为参数。
//得到一个窗口的上下文句柄。使用函数
//HDC GetDC(
//HWND hWnd//handle to a windows (如果你传递的hWnd是NULL则得到整个屏幕的设备上下文)
//);//如果调用失败则返回的是NULL
//如果结束使用DC时就一定要释放DC:使用函数:
//int ReleaseDC(
//HWND hWnd,//handle to window
//HDC hDC//handle to device context
//);//若成功则返回值是(1),否则是(0)
//******************************************************
//××××××××追踪窗口的状态×××××××××××
//窗口被用户移动->发送WM_MOVE消息,窗口新位置的坐标存在lParam中(lParam的低字段存储窗口客户区左上角的坐标x,高字段中存储坐标y)
//窗口的大小改变->发送WM_SIZE消息,lParam中低字段中存储客户区的宽度,lParam的高字段存储高度。
//同WM_MOVE不同的是wParam参数也控制了一些重要的东西。
//SIZE_MAXHIDE:其它的窗口被最大化咯 SIZE_MAXIMIZED:本窗口被最大化
//SIZE_MAXSHOW:其它的窗口被还原拉
//SIZE_MINIMIZED:本窗口给最小化了
//SIZE_RESTORED:窗口被改变了尺寸,既没最小化,又没最大化
//如果在编写窗口的实例时,将窗口的当前位置和大小保存在几个全局变量中
//假设如此命名这些全局变量为xPos,yPos;xSize,ySize
//最好这样控制WM_MOVE和WM_SIZE这两个消息:
//if (msg==WM_SIZE)
//{
// xSize=LOWORD(lParam);
// ySize=HIWORD(lParam);
//}
//if (msg==WM_MOVE)
//(
// xPos=LOWORD(lParam);
// yPos=HIWORD(lParam);
//)
//一个窗口被激活|解除激活->发送WM_ACTIVATE消息
//通过检测wParam的低字段来得知是否被激活或是解除
//WA_CLICKACTIVE:窗口被鼠标激活
//WA_ACTIVE:窗口被其它的东西激活(键盘、函数调用、等等)
//WA_INSCTIVE:窗口被解除激活。
//为了处理这条消息,我保留了另一个全局变量bFocus当收到WM_ACTIVATE的消息时它的值将做如下的改变
//if(msg==WM_ACTIVATE)
//{
// if(LOWORD(wParam)=WA_INACTIVE)
// bFocus=false;
// else
// bFocus=true;
// //tell windows we handled it
// return(0);
//}
//有两个相关联的消息WM_KILLFOCUS和WM_SETFOCUS,在窗口接收到输入焦点的时候,Windows消息WM_SETFOCUS被发送给它,在失去焦点的时候则发送WM_KILLFOCUS消息。应用程序可以截取这些消息以得知输入焦点的任何改变情况。
//☆ WM_PAINT 消息 WN_PAINT消息通知程序,全部或部分客户窗口需要重新绘制。
//当用户在最小化、重叠或调整客户的窗口区域的时候,就会产生这条消息。
//重新绘制。你需要做两件事情。First你要用到WM_PAINT消息专用的一对函数
//第一个就是BeginPaint()函数。原型如下:
//HDC BeginPaint(
//HWND hWnd,//handle to window
//LPPAINTSTRUCT lpPaint//pointer to structure for paint information
//);
//typedef struct tagPAINTSTRUCT{
//HDC hdc;
//bool fErase;//指明应用程序是否应该抹去背景。如果是false说明系统已经删除了背景
//RECT rcPaint;//RECT 告诉你需要被重画的无效区域的矩形
//bool fRestore;//保留的成员
//bool fIncUpdate;//保留的成员
//byte rgbReserved[32]; //保留的成员
//} PAINTSTRUCT;
//BeginPaint()函数做了三件事:
//一.使窗口再次有效直到WM_PAINT消息发出之前都是有效
//二.如果我们在窗口类(window class)里定义了背景画刷,就用这个画刷来重绘无效区域
//三.返回了被重绘区域的句柄
//typedef struct_RECT{
//long left;
//long top;
//long right;
//long bottom;
//} RECT;//注意的是RECT只包含左上角,并不包含右下角:
//例如:RECT myRect={0,0,5,5};它只包含象素(0,0)并没到达(5,5),所以矩形的右下角实际是(4,4)
//第二件事情就是释放DC。用EndPaint()函数。函数的原型如下
//bool EndPaint(
//bool hWnd;//handle to window
//const PAINTSTRUCT *lpPaint//pointer to structure for paint data
//) ;
//你还可以通过调用ValidateRect()函数代替BeginPaint()函数使得窗口再次有效。但你得手工操作一切。可能我们真的什么时候就要用到它。所以给你它的原形:
//BOOL ValidateRect(
//HWND hWnd, // handle of window
//CONST RECT *lpRect // address of validation rectangle coordinates
//);
//假设我们已经定义了一个全局的变量hMainWindow作为我们的窗口句柄。
//if (msg == WM_PAINT)
//{
//PAINTSTRUCT ps; // declare a PAINTSTRUCT for use with this message
//HDC hdc; // display device context for graphics calls
//hdc = BeginPaint(hMainWindow, &ps); // validate the window
//// your painting goes here!
//EndPaint(hMainWindow, &ps); // release the DC
//// tell Windows we took care of it
//return(0);
//}
//**************************************************************************//
//********************窗口关闭消息处理×××××××××××××××××//
//WM_CLOSE消息处理一个窗口或者应用程序应该被关闭时发出WM_CLOSE消息,
//当接收到WM_CLOSE消息时,如果你愿意,向用户提出是否真的退出。
//你知道让用户作确认或有错误出现或有什么应该注意的事情发生的时候,往往弹出一个消息框
//代码如下:
//if (msg == WM_CLOSE)
//{
//if (MessageBox(hMainWindow, "Are you sure want to quit?", "Notice", MB_YESNO | MB_ICONEXCLAMATION) == IDNO)
//return(0);
//// otherwise, let the default handler take care of it
//}
//WM_DESTORY消息 WM_DESTROY消息有点儿不同。它是窗口正在关闭时发出的。
//当得到WM_DESTROY消息的时候,窗口已经从视觉上被删除。
//一个主窗口被关闭,并不意味着应用程序结束了,它将在没有窗口的条件下继续运行。
//然而,当一个用户关闭了主窗口,也就意味着他要结束应用程序,
///所以如果你希望应用程序结束,
//在收到WM_DESTROY消息的时候,你必须发出一个WM_QUIT消息。你可以使用PostMessage()函数,
//原型如下: VOID PostQuitMessage(int nExitCode);
Axes Studio
凌小雨