1.Win32复习
1.Win32内容
包括 句柄 ,API(接口函数),消息宏。
2.画刷之类的称为 GDI。
3. HDC 与 HWND 称为用户对象。
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);
}