GDI是什么?
微软公司设计的一套API
为什么使用它?
GDI是图形显示程序与实际物理设备两者之间的桥梁,使得用户无需关心具体设备的细节,只需在一个逻辑设备中进行操作
怎么使用它?
需要把握一个核心:设备上下文(DC):显示器和以及显示器所有的配置 ,我们需要得到DC的句柄才可以去在上面进行绘图操作
怎么获得DC句柄呢?
使用GDI的目的:在Window屏幕上显示出好看的游戏画面,需要理解以下概念
屏幕区:略
客户区:见下图
窗口区:在客户区周围包了一层窗口的边框,这些窗口边框包围着客户区,共同组成了窗口区
ClientToScreen(...)
ScreenToClient(...)
引入头文件,定义常量,定义全局变量,函数声明
#include
#define WINDOW_WIDTH 800 //使程序易修改
#define WINDOW_HEIGHT 600
#define WINDOW_TITLE L"GDI程序核心框架" //使程序易读
HDC g_hdc=NULL; // 创建相应类型的设备环境句柄
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
VOID Game_Paint( HWND hwnd);
BOOL Game_CleanUp(HWND hwnd );
定义程序的入口函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX wndClass = { 0 };
wndClass.cbSize = sizeof( WNDCLASSEX ) ;
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon=(HICON)::LoadImage(NULL,L"icon.ico",IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE);
wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
wndClass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = L"ForTheDreamOfGameDevelop";
if( !RegisterClassEx( &wndClass ) )
return -1;
HWND hwnd = CreateWindow( L"ForTheDreamOfGameDevelop",WINDOW_TITLE,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH,
WINDOW_HEIGHT, NULL, NULL, hInstance, NULL );
MoveWindow(hwnd,250,80,WINDOW_WIDTH,WINDOW_HEIGHT,true);
ShowWindow( hwnd, nShowCmd );
UpdateWindow(hwnd);
MSG msg = { 0 };
while( msg.message != WM_QUIT )
{
if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
UnregisterClass(L"ForTheDreamOfGameDevelop", wndClass.hInstance);
return 0;
}
定义回调函数,游戏窗口的事件会通过Window的消息机制传递进来
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT paintStruct;
switch( message )
{
case WM_PAINT:
g_hdc = BeginPaint( hwnd, &paintStruct ); //得到设备环境句柄
Game_Paint( hwnd);
EndPaint( hwnd, &paintStruct );
ValidateRect(hwnd, NULL);
break;
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
DestroyWindow(hwnd);
break;
case WM_DESTROY:
Game_CleanUp(hwnd);
PostQuitMessage( 0 );
break;
default:
return DefWindowProc( hwnd, message, wParam, lParam );
}
return 0;
}
封装功能函数,将对应的事件处理过程外包出去
VOID Game_Paint( HWND hwnd )
{
}
BOOL Game_CleanUp( HWND hwnd )
{
ReleaseDC(hwnd,g_hdc);
return TRUE;
}