C++项目 18-11-21-截图工具

1.整体

1.开发工具

vs2012

2.语言

C++

2.了解带窗口的应用程序

1.做一个带窗口的应用程序

Win32:就是Windows API(函数)
MFC :类库,对Windows API的一种封装

3.编写程序

1.创建Win32项目(不选中创建空项目)

2._tWinMain 是程序的入口函数

3.函数: MyRegisterClass()

注册窗口类,窗口的样子由该函数决定
wcex.lpfnWndProc = WndProc; // 窗口过程函数

4.函数: InitInstance(HINSTANCE, int)

目的: 保存实例句柄并创建主窗口(用于创建窗口)
注释: 在此函数中,我们在全局变量中保存实例句柄并创建和显示主程序窗口。
其中有 CreateWindow(类名称,窗口的标题,窗口弹出的样式,。。。。。。),本次改变窗口弹出的方式为WS_POPUP

5.显示窗口

ShowWindow(hWnd, nCmdShow);				// 第二个参数表示窗口的大小样式,可以修改为SW_MAXMIZE
UpdateWindow(hWnd);

6.CALLBACK 函数

系统调用,当有消息时就调用该函数。

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)			// message 是消息ID,用于表示鼠标左键点击、键盘按键等等消息
	{
   

	// 里面用于处理一些感兴趣的消息
	case WM_LBUTTONDOWN:
		MessageBox(hWnd, L"左键按下", L"info", MB_OK);
		break;

	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择:
		switch (wmId)
		{
   
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:							// 屏幕绘制消息
		hdc = BeginPaint(hWnd, &ps);
		// TODO: 在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

4.设计思想流程

0.让窗口全屏

1步.hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUP, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
2步.ShowWindow(hWnd, nCmdShow); // 第二个参数表示窗口的大小样式,可以修改为SW_MAXMIZE
3步.wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MY1121); // 在窗口上不显示菜单栏

1.需要获取整个图像

1.首先创建一个 ScreenCapture 函数,用来保存获取到的图像
1.首先创建一个桌面的 DC; HDC dis_dc = ::CreateDC(L"DISPLAY", 0, 0, 0); // 创建一个DC ,DISPLAY 表示桌面,与桌面相关
2.获取整个桌面的大小(分辨率);
screen_w = GetDeviceCaps(dis_dc, HORZRES); // 整个桌面水平的大小
screen_h = GetDeviceCaps(dis_dc, VERTRES); // 整个桌面垂直的大小
3.获取桌面截图;
g_src_men_dc = CreateCompatibleDC(dis_dc); // 创建一个兼容性的dc(内存DC),与桌面的dc相关的
4.模拟一张画布出来;
HBITMAP h_bitmap = CreateCompatibleBitmap(dis_dc, screen_w, screen_h);
5.将画布选入dc
SelectObject(g_src_men_dc, h_bitmap);
6.将桌面画到画布上
BitBlt(g_src_men_dc, 0, 0, screen_w, screen_h, dis_dc, 0, 0, SRCCOPY); // 整个桌面已经被画到了mem_dc中

2.将图像放到窗口上

1.需要进入 CALLBACK 函数,在 WM_PAINT 消息中进行“搬运”截图到窗口的工作;
2.将整个桌面放到了全屏的窗口上面
BitBlt(hdc, 0, 0, screen_w, screen_h, g_src_men_dc, 0, 0, SRCCOPY);
3.在进行创建窗口的时候就进行 ScreenCapture 函数的调用(即创建截图的图像)

3.在窗口上画出矩形

1.需要通过鼠标左键按下进行记录矩形的左和上坐标,通过鼠标左键弹起记录矩形的右和下坐标,因此定义一个全局的 RECT 类型的变量 rect,RECT 是一个结构体
2.需要在 WM_PAINT 消息里进行绘制矩形,绘制矩形使用的时函数 Rectangle ,参数分别为 hdc、矩形的左、上、右、下坐标,一共有五个参数。
3.当完成此步骤后,可以在按下鼠标左键后到松开后在窗口上画出白底的矩形框;
4.改变矩形框的颜色,使其透明,需要在 CALLBACK 函数中定义一个新的画刷,使用 LOGBRUSH 声明一个新的画刷,并定义 brush.lbStyle = BS_NULL,在定义一个画刷句柄 HBRUSH h_brush = CreateBrushIndirect(&brush),就可生成透明的画刷;
5.改变完画刷为透明之后,在 WM_PAINT 消息中进行选择画刷,是声明的透明的画刷被选中,使用 SelectObject 函数进行选择画刷。
6.当前步骤完成后可以进行透明矩形的绘制,但是矩形的边框仍为黑色,若想改变矩形边框的颜色,需要进行 笔 的创建,
使用 LOGPEN pen 创建一个笔,
之后使用 POINT pt 来保存矩形边框的粗细,设置 pt.x = pt.y = 2,即设置矩形边框为2个像素的粗细,
pen.lopnColor = 0x0000FFFF 表示选择矩形的边框为 绿色(0000FFFF 是绿色的十六进制表示),
pen.lopnStyle = PS_SOLID 表示绘制矩形的边框为 实线,
pen.lopnWidth = pt 表示绘制的矩形的边框的粗细为 2个像素,
生成笔的句柄:HPEN h_pen = CreatePenIndirect(&pen);
最后在 WM_PAINT 消息处理下选择笔,使用 SelectObject(hdc, h_pen) 来选择笔,进行绘制自定义颜色、粗细、边框风格的矩形。
7.在进行完第6步之后,可以得到 绿色、实线、透明的矩形。

4.保存画出来的矩形

1.添加窗口可以处理鼠标双击的样式,需要在 注册窗口类 在设置窗口时对窗口的样式(style)进行设置,添加一条 CS_DBLCLKS 样式。
2.在 CALLBACK 的消息处理中添加 WM_LBUTTONDBLCLK 鼠标双击消息检测机制,用来复制选中区域;
3.编写复制鼠标选中区域的函数 CopyBitmap2CipBoarD ,
1.首先需要复制矩形框内的内容,计算矩形框的宽和高;
2.获取桌面 dc:HDC h_scr_dc = ::CreateDC(L"DISPLAY", 0, 0, 0);
3.创建内存 dc:HDC mem_dc = CreateCompatibleDC(h_scr_dc);
4.模拟画布:HBITMAP bmp = CreateCompatibleBitmap(h_scr_dc, width, height);
5.将画布选入笔中:HBITMAP old_map = (HBITMAP)SelectObject(mem_dc, bmp);
6.将矩形画到内存dc中:BitBlt(mem_dc, 0, 0, width, height, h_scr_dc, rect.left, rect.top, SRCCOPY);
7.将旧的画布放到新的画布中:HBITMAP new_map = (HBITMAP)SelectObject(mem_dc, old_map);
8.将 new_map 复制到粘贴板中:SetClipboardData(CF_BITMAP, new_map);
4.在鼠标双击消息处理中调用 CopyBitmap2CipBoarD,但是需要注意,鼠标左键双击会包含单击的过程,因此需要对单击和双击进行区分,我们使用 双击 的操作是在选中矩形之后,因此可以定义一个全局的变量来记录是否选中了矩形:BOOL is_select = FALSE,该值默认为假;当我们未选中矩形的时候执行 单击 操作,并将 is_select 修改为真;当我们选中矩形后执行 双击 操作,并修改 is_select 的值为假;
5.在 4 过程中,我们需要进行 鼠标左键是否按下 的检测,当鼠标左键按下并且矩形未被选中的时候,我们才可以进行矩形区域的选择,进而双击的时候进行矩形的复制(将矩形区域复制到粘贴板上),因此需要引入一个全局变量记录是否鼠标按键以按下:BOOL is_down = FALSE,默认值为假,当鼠标左键单击时修改为真,当选中矩形后修改为假;
6.5步执行完之后可以将选中的矩形框复制进剪贴板当中;

5.基本完成,需要改进的地方

1.没有被选中的地方需要变灰
2.被选中的地方应该变亮
3.最好是窗口不要出现,以快捷键的方式来做(全局的钩子)(也就是添加快捷键)
4.鼠标移动的时候,矩形框能够跟着变化
5.加上一个托盘(就是红蜘蛛一直存在的地方的图标)

5.创建出来的空 Win32 应用程序(创建时不选中 空项目)

// 1111.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "1111.h"

#define MAX_LOADSTRING 100

// 全局变量:
HINSTANCE hInst;								// 当前实例
TCHAR szTitle[MAX_LOADSTRING];					// 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];			// 主窗口类名

// 此代码模块中包含的函数的前向声明:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
   
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值