鱼C论坛

 找回密码
 立即注册
查看: 4350|回复: 20

[原创] C语言制作的简单的截屏器

[复制链接]
发表于 2016-6-19 19:02:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 无符号整形 于 2016-6-19 20:09 编辑

这个截屏器简单又粗糙,还有一个小bug,但是它也许能让你研究很久。哈哈~

好吧直接上图上代码,有个小bug,请仔细观察。
gggg.JPG
很粗糙吧!
截图效果:
ggggg.JPG
发现bug了吧。。。还有那个小安仔,还挺好玩的:-)
代码:
  1. #include <windows.h>
  2. #include "resource.h"

  3. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);        //声明用来处理消息的函数
  4. HBITMAP CaptureScreen(LPRECT);
  5. BOOL SaveBmp(HBITMAP, const char*);
  6. HINSTANCE g_hInstance;

  7. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
  8. {
  9.         static TCHAR szAppName[] = TEXT("MyWindow");
  10.         HWND hwnd;
  11.         MSG msg;
  12.         WNDCLASS wndclass;        //声明一个窗口类对象
  13.        
  14.         HMENU hMenu = CreateMenu();
  15.         HMENU hMenuPopup = CreateMenu();
  16.         AppendMenu(hMenuPopup, MF_STRING, 100, "截屏");
  17.         AppendMenu(hMenuPopup, MF_STRING, 101, "另存为");
  18.         AppendMenu(hMenuPopup, MF_STRING, 103, "延时3秒并截屏");
  19.         AppendMenu(hMenu, MF_POPUP, (ULONG_PTR)hMenuPopup, "截屏");
  20.         //以下为窗口类对象wndclass的属性
  21.         wndclass.style = CS_HREDRAW | CS_VREDRAW;                         //窗口样式
  22.         wndclass.lpszClassName = szAppName;                               //窗口类名
  23.         wndclass.lpszMenuName = NULL;                                     //窗口菜单:无
  24.         wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);    //窗口背景颜色
  25.         wndclass.lpfnWndProc = WndProc;                                   //窗口处理函数
  26.         wndclass.cbWndExtra = 0;                                          //窗口实例扩展:无
  27.         wndclass.cbClsExtra = 0;                                          //窗口类扩展:无
  28.         wndclass.hInstance = hInstance;                                   //窗口实例句柄
  29.         wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));               //窗口最小化图标:使用缺省图标
  30.         wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);                 //窗口采用箭头光标

  31.         if (!RegisterClass(&wndclass))
  32.         {    //注册窗口类, 如果注册失败弹出错误提示
  33.                 MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_OK | MB_ICONERROR);
  34.                 return 0;
  35.         }

  36.         hwnd = CreateWindow(                   //创建窗口
  37.                 szAppName,                 //窗口类名
  38.                 TEXT("截图工具"),           //窗口标题
  39.                 WS_OVERLAPPEDWINDOW,       //窗口的风格
  40.                 CW_USEDEFAULT,             //窗口初始显示位置x:使用缺省值
  41.                 CW_USEDEFAULT,             //窗口初始显示位置y:使用缺省值
  42.                 400,             //窗口的宽度:使用缺省值
  43.                 100,             //窗口的高度:使用缺省值
  44.                 NULL,                      //父窗口:无
  45.                 hMenu,                      //子菜单:无
  46.                 hInstance,                 //该窗口应用程序的实例句柄
  47.                 NULL                       //
  48.                 );
  49.         g_hInstance = hInstance;
  50.         ShowWindow(hwnd, iCmdShow);        //显示窗口
  51.         UpdateWindow(hwnd);                //更新窗口

  52.         while (GetMessage(&msg, NULL, 0, 0))        //从消息队列中获取消息
  53.         {
  54.                 TranslateMessage(&msg);                 //将虚拟键消息转换为字符消息
  55.                 DispatchMessage(&msg);                  //分发到回调函数(过程函数)
  56.         }
  57.         return msg.wParam;
  58. }

  59. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  60. {
  61.         HDC hdc, hdcMem;
  62.         static RECT rect;
  63.         static HBITMAP hBitmap;
  64.         static int cx,cy;
  65.         BITMAP bitmap;
  66.         static OPENFILENAME ofn;
  67.         static TCHAR szBuffer[1000] = "";
  68.         static LONG xPos, yPos;
  69.         PAINTSTRUCT ps;
  70.         ofn.lStructSize = sizeof(OPENFILENAME);
  71.         ofn.lpstrFilter = "bmp";
  72.         ofn.lpstrInitialDir = NULL;
  73.         ofn.lpstrFile = szBuffer;
  74.         ofn.nMaxFile = sizeof(szBuffer) / sizeof(*szBuffer);
  75.         ofn.nFilterIndex = 0;
  76.         ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER;

  77.         switch (message)        //处理得到的消息
  78.         {
  79.         case WM_COMMAND:

  80.                 switch (LOWORD(wParam))
  81.                 {
  82.                 case 100:
  83.                         SetCursor(LoadCursor(g_hInstance, IDC_WAIT));
  84.                         MoveWindow(hwnd, 0, 0, 0, 0, 0);
  85.                         ShowWindow(hwnd, SW_HIDE);
  86.                         hBitmap = CaptureScreen(NULL);
  87.                         ShowWindow(hwnd, SW_SHOW);
  88.                         SetCursor(LoadCursor(g_hInstance, IDC_ARROW));
  89.                         MoveWindow(hwnd, 0, 0, 400, 100, 0);
  90.                         MessageBox(hwnd, "已经成功截图", "提醒", MB_OK | MB_ICONINFORMATION );
  91.                         if (!GetSaveFileName(&ofn))
  92.                                 return 0;
  93.                         SaveBmp(hBitmap, szBuffer);
  94.                         break;
  95.                 case 101:
  96.                         if (!GetSaveFileName(&ofn))
  97.                                 return 0;
  98.                         SaveBmp(hBitmap, szBuffer);
  99.                         break;
  100.                 case 103:
  101.                         Sleep(3000);
  102.                                  SetCursor(LoadCursor(g_hInstance, IDC_WAIT));
  103.                                  ShowWindow(hwnd, SW_HIDE);
  104.                                  hBitmap = CaptureScreen(NULL);
  105.                                  ShowWindow(hwnd, SW_SHOW);
  106.                                  SetCursor(LoadCursor(g_hInstance, IDC_ARROW));
  107.                                  MessageBox(hwnd, "已经成功截图", "提醒", MB_OK | MB_ICONINFORMATION);
  108.                                  if (!GetSaveFileName(&ofn))
  109.                                          return 0;
  110.                                  SaveBmp(hBitmap, szBuffer);
  111.                 }
  112.                 return 0;
  113.         case WM_PAINT:
  114.                 hdc = BeginPaint(hwnd, &ps);
  115.                 hdcMem = CreateCompatibleDC(hdc);
  116.                 SelectObject(hdcMem, hBitmap);
  117.                 GetObject(hBitmap, sizeof(BITMAP), &bitmap);
  118.                 cx = bitmap.bmWidth;
  119.                 cy = bitmap.bmHeight;
  120.                 BitBlt(hdcMem, 10, 10, cx, cy, hdc, 0, 0, SRCCOPY);
  121.                 EndPaint(hwnd, &ps);
  122.                 return 0;
  123.         case WM_DESTROY:
  124.                 DeleteObject(hBitmap);
  125.                 PostQuitMessage(0);
  126.                 return 0;
  127.         }
  128.         return DefWindowProc(hwnd, message, wParam, lParam);
  129. }

  130. #ifndef CAPTUREBLT
  131. #define CAPTUREBLT 0x40000000
  132. #endif
  133. HBITMAP CaptureScreen(LPRECT lpRect)//lpRect为NULL时表示全屏幕截图
  134. {
  135.         Sleep(1000);
  136.         HDC      hdc, hdcMem;
  137.         HBITMAP  hemfCopy;
  138.         HWND     hwndScr;
  139.         int      dstcx, dstcy;
  140.         if (lpRect)
  141.         {
  142.                 dstcx = lpRect->right - lpRect->left;
  143.                 dstcy = lpRect->bottom - lpRect->top;
  144.         }
  145.         else
  146.         {
  147.                 dstcx = GetSystemMetrics(SM_CXSCREEN);
  148.                 dstcy = GetSystemMetrics(SM_CYSCREEN);
  149.         }
  150.         if (LockWindowUpdate(hwndScr = GetDesktopWindow()))
  151.         {
  152.                 hdc = GetDCEx(hwndScr, NULL, DCX_CACHE | DCX_LOCKWINDOWUPDATE);
  153.                 hdcMem = CreateCompatibleDC(hdc);
  154.                 if (NULL == hdcMem)
  155.                 {
  156.                         ReleaseDC(hwndScr, hdc);
  157.                         LockWindowUpdate(NULL);
  158.                         return NULL;
  159.                 }
  160.                 hemfCopy = CreateCompatibleBitmap(hdc, abs(dstcx), abs(dstcy));
  161.                 if (NULL == hemfCopy)
  162.                 {
  163.                         DeleteDC(hdcMem);
  164.                         ReleaseDC(hwndScr, hdc);
  165.                         LockWindowUpdate(NULL);
  166.                         return NULL;
  167.                 }
  168.                 SelectObject(hdcMem, hemfCopy);
  169.                 if (lpRect)
  170.                         StretchBlt(hdcMem, 0, 0, abs(dstcx), abs(dstcy),
  171.                         hdc, lpRect->left, lpRect->top, dstcx, dstcy, SRCCOPY | CAPTUREBLT);
  172.                 else
  173.                         BitBlt(hdcMem, 0, 0, dstcx, dstcy,
  174.                         hdc, 0, 0, SRCCOPY | CAPTUREBLT);
  175.                 DeleteDC(hdcMem);
  176.                 ReleaseDC(hwndScr, hdc);
  177.                 LockWindowUpdate(NULL);
  178.                 return hemfCopy;
  179.         }
  180.         return NULL;
  181. }

  182. BOOL SaveBmp(HBITMAP hBitmap, const char *FileName)
  183. {
  184.         HDC     hDC;
  185.         //当前分辨率下每象素所占字节数      
  186.         int     iBits;
  187.         //位图中每象素所占字节数      
  188.         WORD     wBitCount;
  189.         //定义调色板大小,     位图中像素字节大小     ,位图文件大小     ,     写入文件字节数           
  190.         DWORD     dwPaletteSize = 0, dwBmBitsSize = 0, dwDIBSize = 0, dwWritten = 0;
  191.         //位图属性结构           
  192.         BITMAP     Bitmap;
  193.         //位图文件头结构      
  194.         BITMAPFILEHEADER     bmfHdr;
  195.         //位图信息头结构           
  196.         BITMAPINFOHEADER     bi;
  197.         //指向位图信息头结构               
  198.         LPBITMAPINFOHEADER     lpbi;
  199.         //定义文件,分配内存句柄,调色板句柄           
  200.         HANDLE     fh, hDib, hPal, hOldPal = NULL;

  201.         //计算位图文件每个像素所占字节数           
  202.         hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
  203.         iBits = GetDeviceCaps(hDC, BITSPIXEL) *GetDeviceCaps(hDC, PLANES);
  204.         DeleteDC(hDC);
  205.         if (iBits <= 1)
  206.         {
  207.                 wBitCount = 1;
  208.         }
  209.         else if (iBits <= 4)
  210.         {
  211.                 wBitCount = 4;
  212.         }
  213.         else if (iBits <= 8)
  214.         {
  215.                 wBitCount = 8;
  216.         }
  217.         else
  218.         {
  219.                 wBitCount = 24;
  220.         }

  221.         GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
  222.         bi.biSize = sizeof(BITMAPINFOHEADER);
  223.         bi.biWidth = Bitmap.bmWidth;
  224.         bi.biHeight = Bitmap.bmHeight;
  225.         bi.biPlanes = 1;
  226.         bi.biBitCount = wBitCount;
  227.         bi.biCompression = BI_RGB;
  228.         bi.biSizeImage = 0;
  229.         bi.biXPelsPerMeter = 0;
  230.         bi.biYPelsPerMeter = 0;
  231.         bi.biClrImportant = 0;
  232.         bi.biClrUsed = 0;

  233.         dwBmBitsSize = ((Bitmap.bmWidth     *     wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

  234.         //为位图内容分配内存           
  235.         hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));
  236.         lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
  237.         *lpbi = bi;

  238.         //     处理调色板               
  239.         hPal = GetStockObject(DEFAULT_PALETTE);
  240.         if (hPal)
  241.         {
  242.                 hDC = GetDC(NULL);
  243.                 hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
  244.                 RealizePalette(hDC);
  245.         }

  246.         //     获取该调色板下新的像素值           
  247.         GetDIBits(hDC,
  248.                 hBitmap,
  249.                 0,
  250.                 (UINT)Bitmap.bmHeight,
  251.                 (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
  252.                 (BITMAPINFO *)lpbi,
  253.                 DIB_RGB_COLORS);

  254.         //恢复调色板               
  255.         if (hOldPal)
  256.         {
  257.                 SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
  258.                 RealizePalette(hDC);
  259.                 ReleaseDC(NULL, hDC);
  260.         }

  261.         //创建位图文件               
  262.         fh = CreateFile(FileName,
  263.                 GENERIC_WRITE,
  264.                 0,
  265.                 NULL,
  266.                 CREATE_ALWAYS,
  267.                 FILE_ATTRIBUTE_NORMAL,
  268.                 NULL);/*     FILE_FLAG_SEQUENTIAL_SCAN,     NULL);  */

  269.         if (fh == INVALID_HANDLE_VALUE)
  270.         {
  271.                 return     FALSE;
  272.         }

  273.         //     设置位图文件头           
  274.         bmfHdr.bfType = 0x4D42;     //     "BM"           
  275.         dwDIBSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwPaletteSize + dwBmBitsSize;
  276.         bmfHdr.bfSize = dwDIBSize;
  277.         bmfHdr.bfReserved1 = 0;
  278.         bmfHdr.bfReserved2 = 0;
  279.         bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwPaletteSize;
  280.         //     写入位图文件头           
  281.         WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
  282.         //     写入位图文件其余内容           
  283.         WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);
  284.         //清除               
  285.         GlobalUnlock(hDib);
  286.         GlobalFree(hDib);
  287.         CloseHandle(fh);

  288.         return     TRUE;
  289. }
复制代码

最激动人心的附件来啦!!!!!!!
截图工具.zip (88.46 KB, 下载次数: 36)
今天省下来3次上传机会,因为我是新鱼油~

好吧888888888

评分

参与人数 5荣誉 +25 鱼币 +25 贡献 +16 收起 理由
小甲鱼 + 5 + 5 + 3 热爱鱼C^_^
zlh + 5 + 5 + 5 感谢楼主无私奉献!
zzk176 + 5 + 5 + 3 这个必须赞
~风介~ + 5 + 5 + 5 支持楼主!
小人 + 5 + 5 热爱鱼C^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-6-19 20:13:41 | 显示全部楼层
说一下,保存时文件名要加上.bmp
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-19 21:12:06 | 显示全部楼层
题目错了,应该是”SDK实现简单截屏功能“才对!@小甲鱼 @兰陵月
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-19 21:13:22 | 显示全部楼层
~风介~ 发表于 2016-6-19 21:12
题目错了,应该是”SDK实现简单截屏功能“才对!@小甲鱼 @兰陵月

这叫VC/VC++
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-19 21:15:54 | 显示全部楼层

没学过VC/VC++
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-19 21:30:34 | 显示全部楼层

好吧-_-||
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-19 22:12:19 | 显示全部楼层
顶一下吧!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-20 09:35:41 | 显示全部楼层
~风介~ 发表于 2016-6-19 21:12
题目错了,应该是”SDK实现简单截屏功能“才对!@小甲鱼 @兰陵月

已经好久没弄C了,以后温故知新了再献丑,哈哈~

我现在全身心都在汇编~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-20 12:00:48 | 显示全部楼层
兰陵月 发表于 2016-6-20 09:35
已经好久没弄C了,以后温故知新了再献丑,哈哈~

我现在全身心都在汇编~~

是不是反编译软件看不懂啊?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-20 18:07:09 | 显示全部楼层
666,我以前也想弄一个,没弄成,要把代码好好的研究一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-20 18:57:31 | 显示全部楼层
求版主们加精
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-20 21:57:36 | 显示全部楼层
自己顶一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-21 01:08:34 | 显示全部楼层
不错不错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-21 11:21:23 | 显示全部楼层
无符号整形 发表于 2016-6-20 12:00
是不是反编译软件看不懂啊?

不是,只是为了更加灵活运用windows32汇编,然后再研究下64汇编~达到较为熟练的程序~

当然最终目的为了逆向~

C肯定还是要搞的~只是暂时放下~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-21 11:25:01 | 显示全部楼层
8086汇编下,当前屏幕显示的是0b800以后的字节~

windows下,C下肯定是有类似的空间保存屏幕的二进制内容~

你这个截屏是不是先保存二进制内容,再显示出来~类似这样的原理?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-21 17:55:57 | 显示全部楼层
兰陵月 发表于 2016-6-21 11:25
8086汇编下,当前屏幕显示的是0b800以后的字节~

windows下,C下肯定是有类似的空间保存屏幕的二进制内容 ...

没学过8086汇编,但是可以告诉你:
先截图
然后保存到文件
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-21 19:38:40 | 显示全部楼层
无符号整形 发表于 2016-6-21 17:55
没学过8086汇编,但是可以告诉你:
先截图
然后保存到文件

我就是说的截图的过程,图也是二进制数据组成的,截图就是把排列好的二进制数据保存下来,然后再显示出来~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-21 20:51:55 | 显示全部楼层
兰陵月 发表于 2016-6-21 19:38
我就是说的截图的过程,图也是二进制数据组成的,截图就是把排列好的二进制数据保存下来,然后再显示出来 ...

嗯嗯是的⊙▽⊙
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-22 11:50:59 | 显示全部楼层
大家对代码有什么问题可以回复哦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-6-24 11:53:27 | 显示全部楼层
顶一下因为没人
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-6 07:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表