HDC在MSDN中的全称为:The handle of device context。通常,我们都是用来做相应的显示操作。
    
    熟悉WIN32的朋友对于其应该不会陌生,经常采用GetDC,GetWindowDC等等来获取其句柄。而用得最多的,可能就是BeginPaint,如:

  1. case WM_PAINT:
  2. HDC hdc = BeginPaint(hWnd,&ps);
  3. ...
  4. EndPaint(hdc,&ps);
  5. break;
  1. case WM_PAINT:      HDC hdc = BeginPaint(hWnd,&ps);     ...     EndPaint(hdc,&ps);      break;

使用起来非常简单,但如果想将其内容保存为普通的图像文档,可就没那么容易。确切地说,在只知道HDC句柄的情况下,我们是无法保存其内容的;但我们可以剑走偏锋,将HDC的内容写到一个缓存中,然后我们再保存该缓存的内容即可。
   
   听起来很简单,却又像很复杂,不是么?没关系,我们现在一步一步来。
   
   
   首先,我们需要一个HDC的句柄。如同前面所说,你可以有多种方法,比如GetDC,GetWindowDC,甚至是CreateDC。反正呢,你用什么方法我不管,我只要有一个HDC的句柄就好了。
   
   有了HDC的句柄,接下来我们所需要做的是,知道这HDC的大小,也就是宽度和长度。这个不难,我们只要简单地调用GetDeviceCaps,然后参数给予HORZRES或VERTRES即可:

  1. int iWidth = GetDeviceCaps(hdc,HORZRES);
  2. int iHeight = GetDeviceCaps(hdc,VERTRES);
  1. int iWidth = GetDeviceCaps(hdc,HORZRES);    int iHeight = GetDeviceCaps(hdc,VERTRES);

为什么要知道大小呢?因为我们要用它来创建缓存。而这缓存,说白了,其实就是一个BMP格式的数据结构而已。
    
    为了创建这个关键的缓存,我们必须调用CreateDIBSection函数,而该函数形参又用到BITMAPINFOHEADER,所以我们的一切,就先从填充该结构体开始。
    
    该结构体定义如下:

  1. typedef struct tagBITMAPINFO
  2. {
  3. BITMAPINFOHEADER bmiHeader;
  4. RGBQUAD bmiColors[1];
  5. } BITMAPINFO;
  1. typedef struct tagBITMAPINFO    {       BITMAPINFOHEADER bmiHeader;       RGBQUAD bmiColors[1];     } BITMAPINFO;

结构体里面还有一个BITMAPINFOHEADER,其定义如下:

  1. typedef struct tagBITMAPINFOHEADER
  2. {
  3. DWORD biSize;
  4. LONG biWidth;
  5. LONG biHeight;
  6. WORD biPlanes;
  7. WORD biBitCount
  8. DWORD biCompression;
  9. DWORD biSizeImage;
  10. LONG biXPelsPerMeter;
  11. LONG biYPelsPerMeter;
  12. DWORD biClrUsed;
  13. DWORD biClrImportant;
  14. } BITMAPINFOHEADER;
  1. typedef struct tagBITMAPINFOHEADER     {       DWORD biSize;       LONG biWidth;       LONG biHeight;       WORD biPlanes;       WORD biBitCount       DWORD biCompression;       DWORD biSizeImage;       LONG biXPelsPerMeter;       LONG biYPelsPerMeter;       DWORD biClrUsed;       DWORD biClrImportant;     } BITMAPINFOHEADER;

这么多变量,是不是有点头晕?大可不必紧张,其实我们只需要填充其中几个,其它统统置为0即可:

  1. BITMAPINFO bmpInfo = {0};
  2. bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  3. bmpInfo.bmiHeader.biWidth = iWidth;
  4. bmpInfo.bmiHeader.biHeight = iHeight;
  5. bmpInfo.bmiHeader.biPlanes = 1;
  6. bmpInfo.bmiHeader.biBitCount = 24;
  1. BITMAPINFO bmpInfo = {0};    bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);    bmpInfo.bmiHeader.biWidth = iWidth;    bmpInfo.bmiHeader.biHeight = iHeight;    bmpInfo.bmiHeader.biPlanes = 1;    bmpInfo.bmiHeader.biBitCount = 24;

一切从最简单做起,对于BMP而言,最简单的自然是24位位图,这就是为什么biPlanes和biBitCount分别设置为1和24的原因。
    
    填充完BITMAPINFO结构,我们还是不能马上调用CreateDIBSection,因为形参中还有一个HDC。虽然我们可以直接采用已知的HDC句柄,但接下来还要将创建的HBITMAP和HDC相连接,所以我们还是先创建一个缓存DC:

  1. HDC hdcMem = CreateCompatibleDC(hdc);
  1. HDC hdcMem = CreateCompatibleDC(hdc);

一切准备就绪之后,就调用CreateDIBSection吧:

  1. BYTE *pData = NULL;
  2. hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);
  1. BYTE *pData = NULL;    hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);

pData是分配的一个内存空间,将来用来存储HDC的内容,只不过现在一切都是空的。如果你将这数据保存出来,你会发现一团漆黑。
    
    将HBITMAP和HDC结合:

  1. hOldObj = SelectObject(hdcMem, hBmp);
  1. hOldObj = SelectObject(hdcMem, hBmp);

至此为止,我们前期工作已经准备就绪,我们只需要将HDC的内容用BitBlt绘制到缓存中即可:

  1. BitBlt(hdcMem,
  2. 0,
  3. 0,
  4. iWidth,
  5. iHeight,
  6. hdc,
  7. 0,
  8. 0,
  9. SRCCOPY);
  1. BitBlt(hdcMem,           0,           0,           iWidth,           iHeight,           hdc,           0,           0,           SRCCOPY);

这里其实还有一个小技巧,如果你是想绘制HDC的某个区域,你只需要用StretchBlt替代即可:

  1. StretchBlt(hdcMem,
  2. 0,
  3. 0,
  4. iWidth,
  5. iHeight,
  6. hdc,
  7. rcDC.left,
  8. rcDC.top,
  9. rcDC.right - rcDC.left + 1,
  10. rcDC.bottom - rcDC.top + 1,
  11. SRCCOPY);
  1. StretchBlt(hdcMem,                0,                0,                iWidth,                iHeight,                hdc,                rcDC.left,                rcDC.top,                rcDC.right - rcDC.left + 1,                rcDC.bottom - rcDC.top + 1,                SRCCOPY);

喜欢追究问题的你,也许会发现,在调用该函数之后,pData所指向的内存缓冲区已经改变。是的,没错,这些改变的数据就是我们所需要的。接下来我们所需要做的仅仅是,将这数据按BMP文件的格式,保存下来即可。
    
    BMP文件格式其实很简单,最开始是文件头信息,然后是图片信息,接下来是数据。我们只需要按照这格式,顺序将数据写入即可。
    
    文件头信息和图片信息,微软已经为我们定义好了相应的结构体:
    
    BMP信息:

  1. typedef struct tagBITMAPINFOHEADER
  2. {
  3. DWORD biSize;
  4. LONG biWidth;
  5. LONG biHeight;
  6. WORD biPlanes;
  7. WORD biBitCount
  8. DWORD biCompression;
  9. DWORD biSizeImage;
  10. LONG biXPelsPerMeter;
  11. LONG biYPelsPerMeter;
  12. DWORD biClrUsed;
  13. DWORD biClrImportant;
  14. } BITMAPINFOHEADER;
  1. typedef struct tagBITMAPINFOHEADER     {       DWORD biSize;       LONG biWidth;       LONG biHeight;       WORD biPlanes;       WORD biBitCount       DWORD biCompression;       DWORD biSizeImage;       LONG biXPelsPerMeter;       LONG biYPelsPerMeter;       DWORD biClrUsed;       DWORD biClrImportant;     } BITMAPINFOHEADER;

文件头信息:

  1. typedef struct tagBITMAPFILEHEADER
  2. {
  3. WORD bfType;
  4. DWORD bfSize;
  5. WORD bfReserved1;
  6. WORD bfReserved2;
  7. DWORD bfOffBits;
  8. } BITMAPFILEHEADER;
  1. typedef struct tagBITMAPFILEHEADER     {      WORD bfType;       DWORD bfSize;       WORD bfReserved1;       WORD bfReserved2;       DWORD bfOffBits;     } BITMAPFILEHEADER;

我们首先填充这两个结构体数值:

  1. BITMAPINFOHEADER bmInfoHeader = {0};
  2. bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
  3. bmInfoHeader.biWidth = iWidth;
  4. bmInfoHeader.biHeight = iHeight;
  5. bmInfoHeader.biPlanes = 1;
  6. bmInfoHeader.biBitCount = 24;
  7. //Bimap file header in order to write bmp file
  8. BITMAPFILEHEADER bmFileHeader = {0};
  9. bmFileHeader.bfType = 0x4d42;  //bmp
  10. bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  11. bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)
  1. BITMAPINFOHEADER bmInfoHeader = {0};    bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);    bmInfoHeader.biWidth = iWidth;    bmInfoHeader.biHeight = iHeight;    bmInfoHeader.biPlanes = 1;    bmInfoHeader.biBitCount = 24;        //Bimap file header in order to write bmp file    BITMAPFILEHEADER bmFileHeader = {0};    bmFileHeader.bfType = 0x4d42;  //bmp      bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);    bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)

接下来的事情,估计大家都轻车熟路了。创建文件,然后写入数据,保存,完毕。

  1. HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  2. DWORD dwWrite = 0;
  3. WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
  4. WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);
  5. WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);
  6. CloseHandle(hFile);
  1. HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);    DWORD dwWrite = 0;    WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);    WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);    WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);    CloseHandle(hFile);

文章的最后,是参考源代码:

  1. #ifdef UNICODE
  2. #ifndef TSTRING
  3. #define TSTRING std::wstring
  4. #endif
  5. #else
  6. #ifndef TSTRING
  7. #define TSTRING std::string
  8. #endif
  9. #endif
  10. BOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg);
  11. BOOL WriteBmp(const TSTRING &strFile,HDC hdc);
  12. BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC);
  13. BOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg)
  14. {
  15. BITMAPINFOHEADER bmInfoHeader = {0};
  16. bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
  17. bmInfoHeader.biWidth = sizeImg.cx;
  18. bmInfoHeader.biHeight = sizeImg.cy;
  19. bmInfoHeader.biPlanes = 1;
  20. bmInfoHeader.biBitCount = 24;
  21. //Bimap file header in order to write bmp file
  22. BITMAPFILEHEADER bmFileHeader = {0};
  23. bmFileHeader.bfType = 0x4d42;  //bmp
  24. bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
  25. bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)
  26. HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  27. if(hFile == INVALID_HANDLE_VALUE)
  28. {
  29. return FALSE;
  30. }
  31. DWORD dwWrite = 0;
  32. WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
  33. WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);
  34. WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);
  35. CloseHandle(hFile);
  36. return TRUE;
  37. }
  38. BOOL WriteBmp(const TSTRING &strFile,HDC hdc)
  39. {
  40. int iWidth = GetDeviceCaps(hdc,HORZRES);
  41. int iHeight = GetDeviceCaps(hdc,VERTRES);
  42. RECT rcDC = {0,0,iWidth,iHeight};
  43. return WriteBmp(strFile,hdc,rcDC);
  44. }
  45. BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC)
  46. {
  47. BOOL bRes = FALSE;
  48. BITMAPINFO bmpInfo = {0};
  49. BYTE *pData = NULL;
  50. SIZE sizeImg = {0};
  51. HBITMAP hBmp = NULL;
  52. std::vector<BYTE> vtData;
  53. HGDIOBJ hOldObj = NULL;
  54. HDC hdcMem = NULL;
  55. //Initilaize the bitmap information
  56. bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  57. bmpInfo.bmiHeader.biWidth = rcDC.right - rcDC.left;
  58. bmpInfo.bmiHeader.biHeight = rcDC.bottom - rcDC.top;
  59. bmpInfo.bmiHeader.biPlanes = 1;
  60. bmpInfo.bmiHeader.biBitCount = 24;
  61. //Create the compatible DC to get the data
  62. hdcMem = CreateCompatibleDC(hdc);
  63. if(hdcMem == NULL)
  64. {
  65. goto EXIT;
  66. }
  67. //Get the data from the memory DC
  68. hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);
  69. if(hBmp == NULL)
  70. {
  71. goto EXIT;
  72. }
  73. hOldObj = SelectObject(hdcMem, hBmp);
  74. //Draw to the memory DC
  75. sizeImg.cx = bmpInfo.bmiHeader.biWidth;
  76. sizeImg.cy = bmpInfo.bmiHeader.biHeight;
  77. StretchBlt(hdcMem,
  78. 0,
  79. 0,
  80. sizeImg.cx,
  81. sizeImg.cy,
  82. hdc,
  83. rcDC.left,
  84. rcDC.top,
  85. rcDC.right - rcDC.left + 1,
  86. rcDC.bottom - rcDC.top + 1,
  87. SRCCOPY);
  88. vtData.resize(sizeImg.cx * sizeImg.cy * 3);
  89. memcpy(&vtData[0],pData,vtData.size());
  90. bRes = WriteBmp(strFile,vtData,sizeImg);
  91. SelectObject(hdcMem, hOldObj);
  92. EXIT:
  93. if(hBmp != NULL)
  94. {
  95. DeleteObject(hBmp);
  96. }
  97. if(hdcMem != NULL)
  98. {
  99. DeleteDC(hdcMem);
  100. }
  101. return bRes;
  102. }
  1. #ifdef UNICODE#ifndef TSTRING#define TSTRING std::wstring#endif#else#ifndef TSTRING#define TSTRING std::string#endif#endifBOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg);BOOL WriteBmp(const TSTRING &strFile,HDC hdc);BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC);BOOL WriteBmp(const TSTRING &strFile,const std::vector<BYTE> &vtData,const SIZE &sizeImg) { BITMAPINFOHEADER bmInfoHeader = {0};bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);bmInfoHeader.biWidth = sizeImg.cx;bmInfoHeader.biHeight = sizeImg.cy;bmInfoHeader.biPlanes = 1;bmInfoHeader.biBitCount = 24;//Bimap file header in order to write bmp fileBITMAPFILEHEADER bmFileHeader = {0};bmFileHeader.bfType = 0x4d42;  //bmp  bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if(hFile == INVALID_HANDLE_VALUE){return FALSE;}DWORD dwWrite = 0;WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);CloseHandle(hFile);return TRUE;} BOOL WriteBmp(const TSTRING &strFile,HDC hdc){int iWidth = GetDeviceCaps(hdc,HORZRES);int iHeight = GetDeviceCaps(hdc,VERTRES);RECT rcDC = {0,0,iWidth,iHeight};return WriteBmp(strFile,hdc,rcDC);}BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC){BOOL bRes = FALSE;BITMAPINFO bmpInfo = {0};BYTE *pData = NULL;SIZE sizeImg = {0};HBITMAP hBmp = NULL;std::vector<BYTE> vtData;HGDIOBJ hOldObj = NULL;HDC hdcMem = NULL;//Initilaize the bitmap informationbmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);bmpInfo.bmiHeader.biWidth = rcDC.right - rcDC.left;bmpInfo.bmiHeader.biHeight = rcDC.bottom - rcDC.top;bmpInfo.bmiHeader.biPlanes = 1;bmpInfo.bmiHeader.biBitCount = 24;//Create the compatible DC to get the datahdcMem = CreateCompatibleDC(hdc);if(hdcMem == NULL){goto EXIT;}//Get the data from the memory DChBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);if(hBmp == NULL){goto EXIT;}hOldObj = SelectObject(hdcMem, hBmp);//Draw to the memory DCsizeImg.cx = bmpInfo.bmiHeader.biWidth;sizeImg.cy = bmpInfo.bmiHeader.biHeight;StretchBlt(hdcMem,0,0,sizeImg.cx,sizeImg.cy,hdc,rcDC.left,rcDC.top,rcDC.right - rcDC.left + 1,rcDC.bottom - rcDC.top + 1,SRCCOPY);vtData.resize(sizeImg.cx * sizeImg.cy * 3);memcpy(&vtData[0],pData,vtData.size());bRes = WriteBmp(strFile,vtData,sizeImg);SelectObject(hdcMem, hOldObj);EXIT:if(hBmp != NULL){DeleteObject(hBmp);}if(hdcMem != NULL){DeleteDC(hdcMem);}return bRes;}

一共有三个WriteBmp函数,使用上非常简单。
    
    比如,我想保存一个HDC,只需要简单地调用:

  1. HDC hdc = GetDC(NULL);
  2. WriteBmp(TEXT("//NAND//DCSave.bmp"));
  3. ReleaseDC(NULL,hdc);
  1. HDC hdc = GetDC(NULL);    WriteBmp(TEXT("//NAND//DCSave.bmp"));    ReleaseDC(NULL,hdc);

如果想保存HDC的某一个部分,同样也很简单:

  1. HDC hdc = GetDC(NULL);
  2. RECT rcDC = {0,0,100,100};
  3. WriteBmp(TEXT("//NAND//DCSavePart.bmp"),rcDC);
  4. ReleaseDC(NULL,hdc);
  1. HDC hdc = GetDC(NULL);    RECT rcDC = {0,0,100,100};    WriteBmp(TEXT("//NAND//DCSavePart.bmp"),rcDC);    ReleaseDC(NULL,hdc);

这个函数还能做到一个很有意思的功能,就是截取屏幕。对于屏幕来说,也是一个HDC,我们只要获取屏幕的HDC句柄,剩下的就没有什么难度了:

  1. HDC hdc = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
  2. WriteBmp(TEXT("//NAND//ScreenCapture.BMP"),hdc);
  3. DeleteDC(hdc);

将HDC保存为BMP文件的更多相关文章

  1. [原]将BITMAPINFO保存成bmp文件,以及渲染到设备

    /* class Image { public: Image() = delete; Image(const uint32_t& _w, const uint32_t& _h) :w( ...

  2. 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码

    ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件. 实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均O ...

  3. OpenGL(十) 截屏并保存BMP文件

    BMP文件格式 BMP图像又称为Bitmap(位图),是Windows系统中广泛采用的图像格式.BMP文件的数据按照从文件头开始的先后顺序分为四个部分: 我们一般见到的图像以24位图像为主,即R.G. ...

  4. 1.1.0-学习Opencv与MFC混合编程之---全屏截图,保存为BMP图像(并增加快捷键)

    源代码:http://download.csdn.net/detail/nuptboyzhb/3961677 Ø  添加全屏截图菜单项,菜单项的属性如下; Ø  为该菜单项建立类向导. 编辑消息处理函 ...

  5. 【VC++技术杂谈006】截取电脑桌面并将其保存为bmp图片

    本文主要介绍如何截取电脑桌面并将其保存为bmp图片. 1. Bmp图像文件组成 Bmp是Windows操作系统中的标准图像文件格式. Bmp图像文件由四部分组成: (1)位图头文件数据结构,包含Bmp ...

  6. 图像预处理第9步:存为.bmp文件

    //图像预处理第9步:将最终标准化后的字符图像分为单个单个的HDIB保存,并存为.bmp文件 void CChildView::OnImgprcToDibAndSave() { unsigned ch ...

  7. BMP文件解析

    目录 BMP文件简介 BMP文件格式 位图头 位图信息 调色板 位图数据 C语言代码 获取文件大小 获取文件尺寸 获取文件偏移量 读取文件数据示例 一个问题 完整程序 BMP文件简介 BMP(全称Bi ...

  8. 二维码图片以字符串的形式保存DB,已文件流显示页面上

    以下是生成二维码的方法,我只用其中一个方法 这个需要引用ZXing.DLL 链接:https://pan.baidu.com/s/1mCTwHiAm_awtsPcibAotZw 提取码:ufp6 pu ...

  9. [ATL/WTL]_[中级]_[保存CBitmap到文件-保存屏幕内容到文件]

    场景: 1. 在做图片处理时,比方放大后或加特效后须要保存CBitmap(HBITMAP)到文件. 2.截取屏幕内容到文件时. 3.不须要增加第3方库时. 说明: 这段代码部分来自网上.第一次学atl ...

随机推荐

  1. API和DLL

    API API(Application Programming Interface,应用编程接口)其实就是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的 API 而使操作系统去执行应用 ...

  2. ZOJ 3080 ChiBi(spfa)

    ZOJ Problem Set - 3080 ChiBi Time Limit: 5 Seconds      Memory Limit: 32768 KB watashi's mm is so pr ...

  3. zoj 3710 Friends

    #include<stdio.h> #include<string.h> ][],h; int main(int argc, char* argv[]) { int t,i,n ...

  4. Android的selector 背景选择器

    关于listview和button都要改变android原来控件的背景,在网上查找了一些资料不是很全,所以现在总结一下android的selector的用法.首先android的selector是在d ...

  5. jmeter 通过ant集成到jenkins

    jmeter可以通过ant自动执行测试脚本,然后集成到jenkins上,并发送测试报告 1.下载安装ant 2.将jmeter安装包extras文件夹里ant-jemter-1.1.1.jar 复制到 ...

  6. python自学笔记(六)二进制与位移

    一.二进制 a = 1 bin(a)-->ob1  #python内置方法 ob 表示二进整型制格式 二.难缠符号 1.位移二进制的位 >> 右位移,想象成 切肉切去最后一位 例如 ...

  7. 2013年末、2014年初合辑——关于c语言的进阶学习

    太过于慵懒了,一个多月没有来自己的园子播种了.还是给自己找找借口吧,十二月末备战期末考试也是自己没心情码文字的理由吧,一月份理所当然地进入考试周,回家后做了个小手术也是客观上让自己不能静下心来回顾知识 ...

  8. Vim键盘布局

     Vim键盘布局 用Linux的朋友一定会使用到Vim这个文本编辑器,它是由Vi发展而来的编辑器,其具有代码补齐.编译.错误跳转等丰富的功能,非常适合编程.对于修改Linux配置文件它更是你不二的选择 ...

  9. 国内BI工具/报表工具厂商简介

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  10. xbox360版本之分

    2005-11-22 发售精简版 (Core):白色 / 无硬盘 / 主板代号 Xenon(现已停产) 2005-11-22 发售豪华版 (Premium):白色 / 20 GB 硬盘 / 主板代号 ...