C++学习 2018-12-4

本文详细介绍了Win32编程的基础知识,包括句柄、API、消息宏等核心概念,以及如何使用HDC、HWND和HINSTANCE句柄进行绘图、创建窗口和加载资源。通过示例代码展示了创建窗口、响应消息、加载位图和处理鼠标事件的过程。

1.Win32复习

1.Win32内容

包括 句柄API(接口函数)消息宏

2.画刷之类的称为 GDI
3. HDCHWND 称为用户对象。
4. 进程线程 称为内核对象。
5. 句柄 是当作指针来用的。
6.句柄与API的关系

操作内存空间必须有的东西。

7.

when:什么时候–消息
what:做什么事–句柄与API

8.几个常用函数

1.HINSTANCE:实例的句柄(当前的应用程序),加载外部资源时需要使用。
2.HDC:环境设备句柄(通常用来处理绘图)。
3.HWND:窗口句柄(窗口的有关操作)。

9.WinMain函数中包含的部分(创建win32应用程序的步骤)

1.设计窗口
cbSize 时必须进行赋值。
2.注册窗口
3.创建窗口
创建窗口时会发送一条 WM_CREATE 消息。
4.显示窗口
5.循环消息处理

10.WM_CREATE:创建窗口的第一个消息,窗口创建的时候有没有额外的需要进行初始化的内容(例如添加一个按钮)。
11.Win32应用程序创建窗口的模版
#include <windows.h>

// HINSTANCE 实例句柄           加载一个外部的资源需要用
// HWND      代表窗口           和窗口相关的操作
// HDC       环境设备句柄       绘图的操作

// Window Message
// WM_LBUTTONDOWN
// WM_KEYDOWN
// WM_PAINT
// WM_TIMER
// ........

LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
HINSTANCE g_hIns;

int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR pCmdLine,int nCmdShow)
{
	g_hIns = hInstance;
	//  1. 设计
	WNDCLASSEX wndclass;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.cbSize = sizeof(WNDCLASSEX);
	wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wndclass.hCursor = ::LoadCursor(0,MAKEINTRESOURCE(IDC_ARROW));
	wndclass.hIcon = 0;
	wndclass.hIconSm = 0;
	wndclass.hInstance = hInstance;
	wndclass.lpfnWndProc = WndProc;
	wndclass.lpszClassName = "lele";
	wndclass.lpszMenuName = 0;
	wndclass.style = CS_VREDRAW|CS_HREDRAW;
	//  2. 注册
	if( ::RegisterClassEx(&wndclass)==FALSE)
	{
		::MessageBox(0,"注册失败","提示",MB_OK);
		return 0;
	}
	//  3. 创建
	HWND hwnd = ::CreateWindow("lele","O(∩_∩)O哈哈~",WS_OVERLAPPEDWINDOW,0,0,500,500,0,0,hInstance,0);
	if(hwnd == 0)
	{
		::MessageBox(0,"创建失败","提示",MB_OK);
		return 0;		
	}
	//  4. 显示
	::ShowWindow(hwnd,SW_SHOW);
	//  5. 消息循环
	MSG msg;
	while(::GetMessage(&msg,0,0,0))
	{
		//  翻译
		::TranslateMessage(&msg);
		//  分发
		::DispatchMessage(&msg);
	}


	return 0;
}



//  消息的处理函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CLOSE:
		::PostQuitMessage(0);
		break;
	}
	return ::DefWindowProc( hwnd, uMsg, wParam, lParam);
}
在消息的处理函数中加入WM_CREATE消息处理机制。
//  消息的处理函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CLOSE:
		::PostQuitMessage(0);
		break;

	case WM_CREATE:
		::CreateWindow("button", "MakeSure", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 0, 0, 50, 50, hwnd, 0, g_hIns, 0);
		break;
	}
	return ::DefWindowProc( hwnd, uMsg, wParam, lParam);
}

2.贴图

1.定义图片句柄

HBITMAP g_h_bitmap

2.创建窗口时加载位图

在WM_CREATE中 LoadBitMap(g_hIns, MakeIntresoutce(Image_ID))。

3.WM_CLOSE时删除图片

DeleteObject(g_h_bitmap); h_hIns = 0;

4.按下左键时贴图,贴图的步骤:

1.创建一个兼容性 dc ,获得目标dc,此处一共有两个 dc ,一个是目标,一个是源。
dc = GetDC(hwnd); 对应的是 ReleaseDC(dc);
创建的兼容性dc:CreateCompatibleDC; 对应的是 DeleteDC;
向兼容性DC中加图片:SelectObject(img_dc, g_h_bitmap);
拷贝图片:::BitBlt(dc, 0, 0, 100, 100, hdc, 0, 0, SRCPAINT)。
2.每个dc都有位图;
3.从源 拷贝到 目标。

HBITMAP g_h_bitmap_w;
HBITMAP g_h_bitmap_b;

void ShowBitmap()
{

}

//  消息的处理函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	switch (uMsg)
	{
		// 创建窗口时的第一个消息,窗口创建的时候有没有额外的需要初始化内容(例如添加一个按钮)
	case WM_CREATE:
		{
			//::CreateWindow("button", "确定", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 220, 200, 50, 50, hwnd, 0, g_hIns, 0);
			// 加载位图
			g_h_bitmap_b = LoadBitmap(g_hIns, MAKEINTRESOURCE(IDB_BITMAP2));
			g_h_bitmap_w = LoadBitmap(g_hIns, MAKEINTRESOURCE(IDB_BITMAP1));
		}
		break;

	case WM_LBUTTONDOWN:
		{
			// 创建两个dc
			HDC dc = ::GetDC(hwnd);
			HDC com_dc = CreateCompatibleDC(dc);
			// 两个dc中都要有位图
			::SelectObject(com_dc, g_h_bitmap_w);
			::BitBlt(dc, 0, 0, 100, 100, com_dc, 0, 0, SRCAND);

			::SelectObject(com_dc, g_h_bitmap_b);
			::BitBlt(dc, 0, 0, 100, 100, com_dc, 0, 0, SRCPAINT);

			// 删除一个dc,释放一个dc
			::ReleaseDC(hwnd, dc);
			::DeleteDC(com_dc);
		}
		break;

	case WM_KEYDOWN:
		{
			HDC dc = GetDC(hwnd);
			switch (wParam)
			{
			case VK_RETURN:
				{
					::SetTimer(hwnd, 10, 50, 0);
				}
				break;

			default:
				break;
			}
			
		}
		break;

	case WM_TIMER:
		{
			switch (wParam)
			{
			case 10:
				{
					x += 2;

				}
				break;

			default:
				break;
			}
		}
		break;

	case WM_CLOSE:
		{
			DeleteObject(g_h_bitmap_w);
			DeleteObject(g_h_bitmap_b);
			g_hIns = 0;
			::PostQuitMessage(0);
		}
		break;

	default:
		break;
	}
	return ::DefWindowProc( hwnd, uMsg, wParam, lParam);
}

3.移动图片

1.现将贴图封装为一个函数。
2.重绘消息 WM_PAINT。
3.可以启动定时器来让图片一直移动。
HBITMAP g_h_bitmap_w;
HBITMAP g_h_bitmap_b;
int x = 0;
int y = 0;
void ShowBitmap(HDC& dc)
{
	HDC com_dc = CreateCompatibleDC(dc);
	// 两个dc中都要有位图
	::SelectObject(com_dc, g_h_bitmap_w);
	::BitBlt(dc, x, y, 100, 100, com_dc, 0, 0, SRCAND);
	::SelectObject(com_dc, g_h_bitmap_b);
	::BitBlt(dc, x, y, 100, 100, com_dc, 0, 0, SRCPAINT);
	// 删除一个dc,释放一个dc
	::DeleteDC(com_dc);
}
//==================================================================================================================



//  消息的处理函数
LRESULT CALLBACK WndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	switch (uMsg)
	{
		// 创建窗口时的第一个消息,窗口创建的时候有没有额外的需要初始化内容(例如添加一个按钮)
	case WM_CREATE:
		{
			//::CreateWindow("button", "确定", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 220, 200, 50, 50, hwnd, 0, g_hIns, 0);
			// 加载位图
			g_h_bitmap_b = LoadBitmap(g_hIns, MAKEINTRESOURCE(IDB_BITMAP2));
			g_h_bitmap_w = LoadBitmap(g_hIns, MAKEINTRESOURCE(IDB_BITMAP1));
		}
		break;

	

	case WM_KEYDOWN:
		{
			HDC dc = GetDC(hwnd);
			switch (wParam)
			{
			case VK_RETURN:
				{
					::SetTimer(hwnd, 10, 50, 0);
				}
				break;

			default:
				break;
			}

		}
		break;

	case WM_TIMER:
		{
			switch (wParam)
			{
			case 10:
				{
					if(x < 400)
					{
						x += 2;
						HDC dc = ::GetDC(hwnd);
						ShowBitmap(dc);
						::ReleaseDC(hwnd, dc);
					}
				}
				break;

			default:
				break;
			}
		}
		break;

	case WM_CLOSE:
		{
			DeleteObject(g_h_bitmap_w);
			DeleteObject(g_h_bitmap_b);
			g_hIns = 0;
			::PostQuitMessage(0);
		}
		break;

	default:
		break;
	}
	return ::DefWindowProc( hwnd, uMsg, wParam, lParam);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值