win32绘制文字 矩形 圆形 多边形 位图

此程序中包涵了一般画法和离屏绘制,相信很快就能看懂。程序中所用到的是369 * 300 名为end.bmp的位图

一般画法会闪烁,而离屏绘制不会,这就是离屏绘制的好处。


#include <iostream>
#include <string.h>
#include <windows.h>
#include <stdlib.h>
using namespace std;
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) 

HWND main_window_handle = NULL; 
HDC windowDC = NULL;		  //windows屏幕设备
HDC endDC = NULL;			  //游戏终结图像内存设备
HBITMAP endBMP = NULL;		  //游戏终结图像内存句柄
HDC bufferDC = NULL;          //缓冲设备环境
HBITMAP bufferBMP = NULL;	  //缓冲位图句柄
RECT g_ClientRect;
void game_main();

//消息回调函数
LRESULT CALLBACK textprom(HWND    hwnd, 
                          UINT    msg, 
                          WPARAM  wparam, 
                          LPARAM  lparam) { 
    // this is the main message handler of the system 
    PAINTSTRUCT ps; 
    HDC         hdc; 
	int result; 
    switch (msg) 
    { 
    case WM_CREATE:
        return 0; 
    case WM_CLOSE:
		result = MessageBox(hwnd,"你确定离开游戏么?","离开游戏",MB_YESNO|MB_ICONQUESTION);
        if(result == IDYES)
            return (DefWindowProc(hwnd,msg,wparam,lparam));
		//释放资源
		ReleaseDC(main_window_handle, endDC);
		ReleaseDC(main_window_handle, bufferDC);
		ReleaseDC(main_window_handle, windowDC);
		return 0;
    case WM_PAINT: 
        hdc = BeginPaint(hwnd, &ps); 
        EndPaint(hwnd, &ps); 
        return 0; 
    case WM_DESTROY:
		//释放资源
		ReleaseDC(main_window_handle, endDC);
		ReleaseDC(main_window_handle, bufferDC);
		ReleaseDC(main_window_handle, windowDC);
        PostQuitMessage(0); 
        return 0; 
 
    default: 
        break; 
    } 
 
    return DefWindowProc(hwnd, msg, wparam, lparam); 
}

/* 绘制矩形 **************************************************************************/ 
int Draw_Rectangle(int x1, int y1, int x2, int y2, int color) 
{ 
    // this function uses Win32 API to draw a filled rectangle 
    HBRUSH      hbrush; 
    HDC         hdc; 
    RECT        rect; 
 
    SetRect(&rect, x1, y1, x2, y2); 
 
    hbrush = CreateSolidBrush(color); 
    hdc = GetDC(main_window_handle); 
 
    FillRect(hdc, &rect, hbrush); 
    ReleaseDC(main_window_handle, hdc); 
    DeleteObject(hbrush); 
 
    return 1;
}
//写文本 
int DrawText_GUI(TCHAR *text, int x, int y, int color) 
{ 
    HDC hdc; 
    hdc = GetDC(main_window_handle); 
    SetTextColor(hdc, color); 
    SetBkMode(hdc, TRANSPARENT);
    TextOut(hdc, x, y, text, lstrlen(text));
    ReleaseDC(main_window_handle, hdc);
    return 1; 
}
int APIENTRY WinMain(HINSTANCE hCurrentInst,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow){
 	WNDCLASS wndClass;
	HWND hWnd;
	MSG msg;	
	
	//定义窗口
	wndClass.style=CS_HREDRAW | CS_VREDRAW;
	wndClass.lpfnWndProc=textprom;
	wndClass.cbClsExtra=0;
	wndClass.cbWndExtra=0;
	wndClass.hInstance=hCurrentInst;
	wndClass.hIcon=LoadIcon(NULL,MAKEINTRESOURCE(101));
	wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
	wndClass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
	wndClass.lpszMenuName=NULL;
	wndClass.lpszClassName="Snake_CLASS";
	//注册窗口
	RegisterClass(&wndClass);
	
	//创建窗口
	hWnd=CreateWindow(
		"Snake_CLASS",
		"skyblue snake",
		WS_DLGFRAME | WS_MINIMIZEBOX | WS_SYSMENU,
		100,100,
		600,600,
		NULL,NULL,
		hCurrentInst,
		NULL);

	main_window_handle  = hWnd; 

	//显示窗口
	ShowWindow(hWnd,nCmdShow);
	UpdateWindow(hWnd);

	//获取当前主窗口设备与windowDC关联
	windowDC=GetDC(NULL);	
	//创建与windowDC兼容的内存设备环境
	bufferDC=CreateCompatibleDC(windowDC);
	endDC=CreateCompatibleDC(windowDC);	

	//位图的初始化和载入位图	
	bufferBMP=CreateCompatibleBitmap(windowDC,600,600);
	endBMP = (HBITMAP)LoadImage(NULL,"end.bmp",IMAGE_BITMAP
				,369,300,LR_LOADFROMFILE);

	//声明位图与设备环境的关联
	SelectObject(bufferDC,bufferBMP);
	SelectObject(endDC,endBMP);
	
	while(GetMessage(&msg,NULL,0,0))
	{
		game_main();
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return 0;
}
void game_main(){
	if (KEY_DOWN(VK_ESCAPE))	//按ESC键时
        PostMessage(main_window_handle, WM_DESTROY, 0, 0);

	//这个是为了离屏绘制,获得窗口距屏幕左顶角的坐标
	GetWindowRect(main_window_handle, &g_ClientRect);
	/*关于bitblt:
		第2、3个参数是所要绘制的图像左上角距画布左上角的横纵坐标
	    第3、4个是所要绘制的图像的大小
	    第7、8是从图片的什么位置开始画
	 */
	//绘制外壳区域到缓冲
	BitBlt(bufferDC, 30, 40, 369, 300, endDC, 0, 0, SRCCOPY);
	SetBkMode(bufferDC, TRANSPARENT); 
    SetTextColor(bufferDC, RGB(250, 250, 250)); 
	char szText[30] = "ESC键退出";
	TextOut(bufferDC, 160, 12, szText,strlen(szText));	
	//将整个画面从缓冲DC拷贝出屏幕
	BitBlt(windowDC, g_ClientRect.left + 20, g_ClientRect.top + 26, 
			580, 570, bufferDC,0,0,SRCCOPY);
	Draw_Rectangle(30, 0, 130, 30, RGB(204, 204, 204));
	DrawText_GUI("黄雀在行动", 35, 7, RGB(0, 0, 0)); 
}

另外一些图形绘制,给出简要代码

//绘制椭圆
void Draw_Ellipse(HDC &hdc, int type, int x, int y){

int color =  RGB(0, 255, 0);

HBRUSH brush = CreateSolidBrush(color);

SelectObject(bufferDC, brush);

Ellipse(bufferDC, x, y, x + 50, y + 50);

DeleteObject(brush);

}

绘制多边形

void Draw_Polygon(HDC &hdc){

int color =  RGB(255, 0, 0);
HBRUSH brush = CreateSolidBrush(color);
POINT point_list[4];
point_list[0].x = 40;
point_list[0].y = 40;
point_list[1].x = 60;
point_list[1].y = 60;
point_list[2].x = 40;
point_list[2].y = 80;
point_list[3].x = 20;
point_list[3].y = 60;
SelectObject(hdc, brush);

Polygon(hdc, point_list, 4);//4表示4边形

DeleteObject(brush);

}


发布了102 篇原创文章 · 获赞 14 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/fofu33/article/details/10976483