|
截屏代码网上有很多,不过,这里代码很简单,看一眼,浪费不了多少时间。功能:
1、直接按F3截全屏,
2、按住Shift键,同时按鼠标左键拖动选择要截屏的区域,松开即选定。所选区域坐标,在控制台窗口标题有显示。
选定后可松开shift, 并可移动窗口不遮盖选择区域。然后按F2截取到文件。文件保存在程序所在目录,文件名为截取的日期时间.bmp
3. 新建控制台程序,代码复制粘贴,编译即可。有空在里面淘金吧。无废码。
- #include "stdafx.h"
- #include <iostream>
- #include <iomanip>
- #include <fstream>
- #include <Windows.h>
- using namespace std;
- namespace cutscreen {
- POINT currpt = { 0,0 }, lastpt = { 0,0 };
- HPEN hpen = NULL;
- BOOL boSel = FALSE;
- HWND hWndDesktop;
- HDC hdcScreen = NULL;
- HDC hdcMem = NULL;
- HBITMAP hbitmap;
- HBITMAP hOldBitmap;
- DWORD lastTick;
- BYTE* pBitmapData=NULL;
- BITMAPINFO *pbmi;
- int nMaxXScreen, nMaxYScreen;
- void Prepare();
- void Save(BOOL boFullScreen);
- void Quit();
- void GetInput();
- void Adjust();
- };
- using namespace cutscreen;
- int main()
- {
- hWndDesktop = GetDesktopWindow();
- SetConsoleTitle(L"截取屏幕");
- wcout.imbue(locale("chs"));
- wcout << L"按住Shift和鼠标左键,拖动鼠标选择区域" << endl;
- wcout << L"选择好按F2自动截取到文件。" << endl;
- wcout << L"无需选择按F3自动全屏。" << endl;
- wcout << L"按ESC退出" << endl;
- Prepare();
- while(1){
- short key = GetAsyncKeyState(VK_ESCAPE);
- if (key & 0x8000) break;
- GetInput();
- SleepEx(1, TRUE);
- }
- Quit();
- return 0;
- }
- void cutscreen::GetInput() {
- POINT pt;
- short key, key1;
- GetCursorPos(&pt);
- key = GetAsyncKeyState(VK_LBUTTON);
- key1 = GetAsyncKeyState(VK_SHIFT);
- if (key1 & 0x8000) {
- if((key & 0x8000)) {
- if (!boSel) {
- lastpt = pt;
- currpt = pt;
- boSel = TRUE;
- }
- //擦先前划线
- HDC hdc = GetDC(hWndDesktop);
- SetROP2(hdc, R2_NOTXORPEN);
- SelectObject(hdc, GetStockObject(NULL_BRUSH));
- SelectObject(hdc, hpen);
- Rectangle(hdc, lastpt.x, lastpt.y, currpt.x, currpt.y);
- ReleaseDC(hWndDesktop, hdc);
- currpt = pt;
- }
- else
- {
- if (boSel) {
- currpt = pt;
- Adjust();
- }
- boSel = FALSE;
- }
- }
- //绘选择框
- HDC hdc = GetDC(hWndDesktop);
- SelectObject(hdc, GetStockObject(NULL_BRUSH));
- SelectObject(hdc, hpen);
- Rectangle(hdc, lastpt.x, lastpt.y, currpt.x, currpt.y);
- ReleaseDC(hWndDesktop,hdc);
- //标题显示选择区域
- TCHAR szMsg[MAX_PATH];
- wsprintf(szMsg, L"截取屏幕(%d,%d)-(%d,%d)", lastpt.x, lastpt.y, currpt.x, currpt.y);
- SetConsoleTitle(szMsg);
- //截取选择区域
- key = GetAsyncKeyState(VK_F2);
- if (key & 0x8000) {
- DWORD thisTick = GetTickCount();
- if (thisTick - lastTick > 1000) {
- Save(FALSE);
- lastTick = GetTickCount();
- }
- }
- //截取全屏
- key = GetAsyncKeyState(VK_F3);
- if (key & 0x8000) {
- DWORD thisTick = GetTickCount();
- if (thisTick - lastTick > 1000) {
- Save(TRUE);
- lastTick = GetTickCount();
- }
- }
- }
- void cutscreen::Prepare() {
- hpen = CreatePen(PS_SOLID, 1, RGB(255,0, 0));
- lastTick = GetTickCount();
- //不能静态分配,因为32位biCompression==BI_BITFIELDS时bmiColors有3个DWORD颜色掩码
- //不分配多余空间会导致内存分配后,已有数据错位混乱
- pbmi =(BITMAPINFO*) new BYTE[sizeof(BITMAPINFO) + 3 * sizeof(DWORD)];
- //建立桌面兼容设备
- hdcScreen = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
- hdcMem = CreateCompatibleDC(hdcScreen);
- //只能建DDB兼容位图,不能用DIB位图
- nMaxXScreen = GetDeviceCaps(hdcScreen, HORZRES);
- nMaxYScreen = GetDeviceCaps(hdcScreen, VERTRES);
- hbitmap = CreateCompatibleBitmap(hdcScreen, nMaxXScreen, nMaxYScreen);
- hOldBitmap = (HBITMAP)SelectObject(hdcMem, hbitmap);
- }
- //调整选择区域为正矩形
- void cutscreen::Adjust() {
- int t;
- if (currpt.x < lastpt.x)
- {
- t = currpt.x;
- currpt.x = lastpt.x;
- lastpt.x = t;
- }
- if (currpt.y < lastpt.y)
- {
- t = currpt.y;
- currpt.y = lastpt.y;
- lastpt.y = t;
- }
- }
- void cutscreen::Save(BOOL boFullScreen) {
- int x, y, w, h;
- if (boFullScreen) {
- x = 0;
- y = 0;
- w = nMaxXScreen,
- h = nMaxYScreen;
- }
- else {
- x = lastpt.x;
- y = lastpt.y;
- w = currpt.x - lastpt.x;
- h = currpt.y - lastpt.y;
- }
- if (w <= 0 || h <= 0) return;
- //复制全屏幕
- DWORD dwRop = SRCCOPY | CAPTUREBLT;
- BOOL bRet = BitBlt(hdcMem, 0, 0, w, h, hdcScreen,0,0, dwRop);
- //SetStretchBltMode(memdc, HALFTONE);
- //StretchBlt(memdc, 0, 0, w, h, hdcscreen, x, y, w, h, SRCCOPY | CAPTUREBLT);
- //获取内存位图数据的大小
- ZeroMemory(pbmi, sizeof(BITMAPINFO));
- pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- int ret = GetDIBits(hdcMem, hbitmap, 0, nMaxYScreen, NULL, (BITMAPINFO*)pbmi, DIB_RGB_COLORS);
- if (ret < 1) {
- wcout << L"获取内存数据大小不成功!" << endl;
- return;
- }
- //分配内存位图数据的大小
- pBitmapData = new BYTE[pbmi->bmiHeader.biSizeImage];
- //读取内存位图数据
- ret = GetDIBits(hdcMem, hbitmap, 0, nMaxYScreen,(LPVOID)pBitmapData, (BITMAPINFO*)pbmi, DIB_RGB_COLORS);
- if (ret < 1) {
- wcout << L"无法读取内存保存数据!" << endl;
- return;
- }
- //按时间产生文件名
- SYSTEMTIME st;
- GetLocalTime(&st);
- TCHAR FileName[MAX_PATH];
- wsprintf(FileName, L"scr%.4d%.2d%.2d%.2d%.2d%.2d.bmp",
- st.wYear,
- st.wMonth,
- st.wDay,
- st.wHour,
- st.wMinute,
- st.wSecond
- );
- wstring sfilename = FileName;
- wcout << L"输出文件:" << sfilename.c_str()<<L"输出区域 ("<< x <<L","<<y <<L"-"<<(x+w)<<","<<(y+h)<<L")"<< endl;
- #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
- //位图存盘计算对齐位图宽度,WIDTHBYTES参数=原宽度*8
- int newWidth = WIDTHBYTES(w * 8);
- int nPitch = newWidth * 3;
- //填位图文件头
- BITMAPFILEHEADER bfh;
- ZeroMemory(&bfh, sizeof(bfh));
- bfh.bfType = (WORD)(*(WORD*)&"BM");
- bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
- bfh.bfSize = bfh.bfOffBits + nPitch * h;
- //填位图信息头,-h,数据颠倒存放,画图看才会是正的
- BITMAPINFOHEADER bih;
- ZeroMemory(&bih, sizeof(bih));
- bih.biBitCount = 24;
- bih.biHeight = -h;
- bih.biWidth = newWidth;
- bih.biPlanes = 1;
- bih.biCompression = BI_RGB;
- bih.biSize = sizeof(BITMAPINFOHEADER);
- //大小必须是按对齐的大小
- bih.biSizeImage = nPitch * h;
- //写位图文件
- ofstream ofile(sfilename.c_str(), ios::out | ios::binary);
- if (!ofile) {
- wcout << sfilename.c_str() << L" 不能写!错误码=" << GetLastError() << endl;
- return;
- }
- ofile.write((char*)&bfh, sizeof(BITMAPFILEHEADER));
- ofile.write((char*)&bih, sizeof(BITMAPINFOHEADER));
- int srcBytesPixel = pbmi->bmiHeader.biBitCount/8;
- int srcPitch = pbmi->bmiHeader.biWidth*srcBytesPixel;
- //注意屏幕上位图坐标是正的,内存数据是颠倒地,
- for (int i = nMaxYScreen - y;i>nMaxYScreen -(y + h);i--) {
- for (int j = x;j < x+newWidth;j++) {
- RGBTRIPLE rgb;
- rgb.rgbtBlue = pBitmapData[i*srcPitch + j*srcBytesPixel + 0];
- rgb.rgbtGreen = pBitmapData[i*srcPitch + j*srcBytesPixel + 1];
- rgb.rgbtRed = pBitmapData[i*srcPitch + j*srcBytesPixel + 2];
- ofile.write((char*)&rgb, 3);
- }
- }
- ofile.close();
- if (pBitmapData) delete[]pBitmapData;
- wcout << L"done!" << endl;
- }
- void cutscreen::Quit() {
- DeleteObject(hpen);
- if(pbmi) delete[]pbmi;
- SelectObject(hdcMem, hOldBitmap);
- DeleteDC(hdcMem);
- DeleteDC(hdcScreen);
- DeleteObject(hbitmap);
- }
复制代码

|
评分
-
查看全部评分
上一篇: MFC六大核心机制下一篇: Visual Studio项目清理(批处理)
|