将HDC保存为BMP文件
HDC在MSDN中的全称为:The handle of device context。通常,我们都是用来做相应的显示操作。
熟悉WIN32的朋友对于其应该不会陌生,经常采用GetDC,GetWindowDC等等来获取其句柄。而用得最多的,可能就是BeginPaint,如:
- case WM_PAINT:
- HDC hdc = BeginPaint(hWnd,&ps);
- ...
- EndPaint(hdc,&ps);
- break;
- case WM_PAINT: HDC hdc = BeginPaint(hWnd,&ps); ... EndPaint(hdc,&ps); break;
使用起来非常简单,但如果想将其内容保存为普通的图像文档,可就没那么容易。确切地说,在只知道HDC句柄的情况下,我们是无法保存其内容的;但我们可以剑走偏锋,将HDC的内容写到一个缓存中,然后我们再保存该缓存的内容即可。
听起来很简单,却又像很复杂,不是么?没关系,我们现在一步一步来。
首先,我们需要一个HDC的句柄。如同前面所说,你可以有多种方法,比如GetDC,GetWindowDC,甚至是CreateDC。反正呢,你用什么方法我不管,我只要有一个HDC的句柄就好了。
有了HDC的句柄,接下来我们所需要做的是,知道这HDC的大小,也就是宽度和长度。这个不难,我们只要简单地调用GetDeviceCaps,然后参数给予HORZRES或VERTRES即可:
- int iWidth = GetDeviceCaps(hdc,HORZRES);
- int iHeight = GetDeviceCaps(hdc,VERTRES);
- int iWidth = GetDeviceCaps(hdc,HORZRES); int iHeight = GetDeviceCaps(hdc,VERTRES);
为什么要知道大小呢?因为我们要用它来创建缓存。而这缓存,说白了,其实就是一个BMP格式的数据结构而已。
为了创建这个关键的缓存,我们必须调用CreateDIBSection函数,而该函数形参又用到BITMAPINFOHEADER,所以我们的一切,就先从填充该结构体开始。
该结构体定义如下:
- typedef struct tagBITMAPINFO
- {
- BITMAPINFOHEADER bmiHeader;
- RGBQUAD bmiColors[1];
- } BITMAPINFO;
- typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO;
结构体里面还有一个BITMAPINFOHEADER,其定义如下:
- 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;
- 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即可:
- BITMAPINFO bmpInfo = {0};
- bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmpInfo.bmiHeader.biWidth = iWidth;
- bmpInfo.bmiHeader.biHeight = iHeight;
- bmpInfo.bmiHeader.biPlanes = 1;
- bmpInfo.bmiHeader.biBitCount = 24;
- 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:
- HDC hdcMem = CreateCompatibleDC(hdc);
- HDC hdcMem = CreateCompatibleDC(hdc);
一切准备就绪之后,就调用CreateDIBSection吧:
- BYTE *pData = NULL;
- hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);
- BYTE *pData = NULL; hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);
pData是分配的一个内存空间,将来用来存储HDC的内容,只不过现在一切都是空的。如果你将这数据保存出来,你会发现一团漆黑。
将HBITMAP和HDC结合:
- hOldObj = SelectObject(hdcMem, hBmp);
- hOldObj = SelectObject(hdcMem, hBmp);
至此为止,我们前期工作已经准备就绪,我们只需要将HDC的内容用BitBlt绘制到缓存中即可:
- BitBlt(hdcMem,
- 0,
- 0,
- iWidth,
- iHeight,
- hdc,
- 0,
- 0,
- SRCCOPY);
- BitBlt(hdcMem, 0, 0, iWidth, iHeight, hdc, 0, 0, SRCCOPY);
这里其实还有一个小技巧,如果你是想绘制HDC的某个区域,你只需要用StretchBlt替代即可:
- StretchBlt(hdcMem,
- 0,
- 0,
- iWidth,
- iHeight,
- hdc,
- rcDC.left,
- rcDC.top,
- rcDC.right - rcDC.left + 1,
- rcDC.bottom - rcDC.top + 1,
- SRCCOPY);
- 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信息:
- 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;
- 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;
文件头信息:
- typedef struct tagBITMAPFILEHEADER
- {
- WORD bfType;
- DWORD bfSize;
- WORD bfReserved1;
- WORD bfReserved2;
- DWORD bfOffBits;
- } BITMAPFILEHEADER;
- typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER;
我们首先填充这两个结构体数值:
- 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)
- 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)
接下来的事情,估计大家都轻车熟路了。创建文件,然后写入数据,保存,完毕。
- 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);
- 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);
文章的最后,是参考源代码:
- #ifdef UNICODE
- #ifndef TSTRING
- #define TSTRING std::wstring
- #endif
- #else
- #ifndef TSTRING
- #define TSTRING std::string
- #endif
- #endif
- BOOL 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 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)
- 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 information
- bmpInfo.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 data
- hdcMem = CreateCompatibleDC(hdc);
- if(hdcMem == NULL)
- {
- goto EXIT;
- }
- //Get the data from the memory DC
- hBmp = 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 DC
- sizeImg.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;
- }
- #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,只需要简单地调用:
- HDC hdc = GetDC(NULL);
- WriteBmp(TEXT("//NAND//DCSave.bmp"));
- ReleaseDC(NULL,hdc);
- HDC hdc = GetDC(NULL); WriteBmp(TEXT("//NAND//DCSave.bmp")); ReleaseDC(NULL,hdc);
如果想保存HDC的某一个部分,同样也很简单:
- HDC hdc = GetDC(NULL);
- RECT rcDC = {0,0,100,100};
- WriteBmp(TEXT("//NAND//DCSavePart.bmp"),rcDC);
- ReleaseDC(NULL,hdc);
- HDC hdc = GetDC(NULL); RECT rcDC = {0,0,100,100}; WriteBmp(TEXT("//NAND//DCSavePart.bmp"),rcDC); ReleaseDC(NULL,hdc);
这个函数还能做到一个很有意思的功能,就是截取屏幕。对于屏幕来说,也是一个HDC,我们只要获取屏幕的HDC句柄,剩下的就没有什么难度了:
- HDC hdc = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
- WriteBmp(TEXT("//NAND//ScreenCapture.BMP"),hdc);
- DeleteDC(hdc);
将HDC保存为BMP文件的更多相关文章
- [原]将BITMAPINFO保存成bmp文件,以及渲染到设备
/* class Image { public: Image() = delete; Image(const uint32_t& _w, const uint32_t& _h) :w( ...
- 使用ffmpeg将BMP图片编码为x264视频文件,将H264视频保存为BMP图片,yuv视频文件保存为图片的代码
ffmpeg开源库,实现将bmp格式的图片编码成x264文件,并将编码好的H264文件解码保存为BMP文件. 实现将视频文件yuv格式保存的图片格式的測试,图像格式png,jpg, gif等等測试均O ...
- OpenGL(十) 截屏并保存BMP文件
BMP文件格式 BMP图像又称为Bitmap(位图),是Windows系统中广泛采用的图像格式.BMP文件的数据按照从文件头开始的先后顺序分为四个部分: 我们一般见到的图像以24位图像为主,即R.G. ...
- 1.1.0-学习Opencv与MFC混合编程之---全屏截图,保存为BMP图像(并增加快捷键)
源代码:http://download.csdn.net/detail/nuptboyzhb/3961677 Ø 添加全屏截图菜单项,菜单项的属性如下; Ø 为该菜单项建立类向导. 编辑消息处理函 ...
- 【VC++技术杂谈006】截取电脑桌面并将其保存为bmp图片
本文主要介绍如何截取电脑桌面并将其保存为bmp图片. 1. Bmp图像文件组成 Bmp是Windows操作系统中的标准图像文件格式. Bmp图像文件由四部分组成: (1)位图头文件数据结构,包含Bmp ...
- 图像预处理第9步:存为.bmp文件
//图像预处理第9步:将最终标准化后的字符图像分为单个单个的HDIB保存,并存为.bmp文件 void CChildView::OnImgprcToDibAndSave() { unsigned ch ...
- BMP文件解析
目录 BMP文件简介 BMP文件格式 位图头 位图信息 调色板 位图数据 C语言代码 获取文件大小 获取文件尺寸 获取文件偏移量 读取文件数据示例 一个问题 完整程序 BMP文件简介 BMP(全称Bi ...
- 二维码图片以字符串的形式保存DB,已文件流显示页面上
以下是生成二维码的方法,我只用其中一个方法 这个需要引用ZXing.DLL 链接:https://pan.baidu.com/s/1mCTwHiAm_awtsPcibAotZw 提取码:ufp6 pu ...
- [ATL/WTL]_[中级]_[保存CBitmap到文件-保存屏幕内容到文件]
场景: 1. 在做图片处理时,比方放大后或加特效后须要保存CBitmap(HBITMAP)到文件. 2.截取屏幕内容到文件时. 3.不须要增加第3方库时. 说明: 这段代码部分来自网上.第一次学atl ...
随机推荐
- distributor之Interrupt Set/Clear-Active Registers, GICD_IS/CACTIVERn
set active寄存器.顾名思义就是把一个中断置为active状态,clear active寄存器就是清除active状态,在这里我们有必要说明一下中断状态的一些概念: active状态:假设此时 ...
- uva 10404 Bachet's Game(完全背包)
题目连接:10404 - Bachet's Game 题目大意:由一堆石子, 给出石子的总数, 接下来由stan和ollie两个人玩游戏,给出n, 在给出n种取石子的方法(即为每次可取走石子的数量), ...
- hdu 4612 Warm up 双连通缩点+树的直径
首先双连通缩点建立新图(顺带求原图的总的桥数,事实上因为原图是一个强连通图,所以桥就等于缩点后的边) 此时得到的图类似树结构,对于新图求一次直径,也就是最长链. 我们新建的边就一定是连接这条最长链的首 ...
- C++数组与指针
指向数组元素的指针 一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址.指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中) ...
- IOS 表视图(UITableVIew)的使用方法(7)表视图的编辑功能(拖拉调整排序位置)
除了每个单元行左边的删除和新增图标,UITableView还支持在单元行的右侧显示一个供用户拖拉调整排序位置的控件. 不过如果要显示此控件,UITableView的数据源需要实现以下的方法. -(vo ...
- android screenOrientation
Activity: android:screenOrientation 横(landscape)竖(portrait)屏显示. 如果想让它一直是横屏显示的话,xml:android:screenOri ...
- 关于地址的理解 C++
#include <iostream> using namespace std; int main(){ ; int* ptr; ptr=&a; cout<<& ...
- discuz_style_default.xml修改
首先我们需要在template/文件夹下新建一个yourstyle文件夹放置模板文件,然后复制default下的discuz_style_default.xml,重命名为discuz_style_你的 ...
- 【在网页中获取截图数据】Chrome和Firefox下的实战经验
[转载自我在segmentfault的专栏:https://segmentfault.com/a/1190000004584071] 最近在实现一个功能,需求如下: 前提:当前页面无弹窗 页面任意位置 ...
- BZOJ 1718: [Usaco2006 Jan] Redundant Paths 分离的路径( tarjan )
tarjan求边双连通分量, 然后就是一棵树了, 可以各种乱搞... ----------------------------------------------------------------- ...