[代码如下]
编程技巧20法 (下)
发布时间:
11. 如 何 判 断 当 前 操 作 系 统 的 版 本
//------------------------------------------------------------------------------------------------
//判断操作系统涵数及变量,jingzhou xu
typedef enum tagWin32SysType
{
Windows32s ,
WindowsNT3 ,
Windows95 ,
Windows98 ,
WindowsME ,
WindowsNT4 ,
Windows2000 ,
WindowsXP
}
Win32SysType ;
//判断操作系统涵数及变量,jingzhou xu
Win32SysType IsShellSysType ()
{
Win32SysType ShellType ;
DWORD winVer ;
OSVERSIONINFO * osvi ;
winVer = GetVersion ();
if (winVer < 0x80000000 )
{
/*NT */
ShellType = WindowsNT3 ;
osvi = (OSVERSIONINFO * )malloc (sizeof (OSVERSIONINFO ));
if (osvi != NULL )
{
memset (osvi , 0 , sizeof (OSVERSIONINFO ));
osvi -> dwOSVersionInfoSize = sizeof (OSVERSIONINFO );
GetVersionEx (osvi );
if (osvi -> dwMajorVersion == 4L )ShellType = WindowsNT4 ;
else if (osvi -> dwMajorVersion == 5L && osvi -> dwMinorVersion == 0L )ShellType = Windows2000 ;
else if (osvi -> dwMajorVersion == 5L && osvi -> dwMinorVersion == 1L )ShellType = WindowsXP ;
free (osvi );
}
}
else if (LOBYTE (LOWORD (winVer ))< 4 )
ShellType = Windows32s ;
else
{
ShellType = Windows95 ;
osvi = (OSVERSIONINFO * )malloc (sizeof (OSVERSIONINFO ));
if (osvi != NULL )
{
memset (osvi , 0 , sizeof (OSVERSIONINFO ));
osvi -> dwOSVersionInfoSize = sizeof (OSVERSIONINFO );
GetVersionEx (osvi );
if (osvi -> dwMajorVersion == 4L && osvi -> dwMinorVersion == 10L )ShellType = Windows98 ;
else if (osvi -> dwMajorVersion == 4L && osvi -> dwMinorVersion == 90L )ShellType = WindowsME ;
free (osvi );
}
}
return ShellType ;
}
//------------------------------------------------------------------------------------------------
12. 如 何 在 指 定 矩 形 框 内 水 平 / 垂 直 显 示 多 行 文 字
///////////////////////////////////////////////////////
//说明:
// 在矩形框中水平或垂直显示多行文字,jingzhou xu.
// lMode: 排列方式,0:水平方式; 1:垂直对齐
// lHori: 水平对齐方式, 0:左对齐; 1:居中; 2:右对齐; 3:自定义
// lVert: 垂直对齐方式, 0:顶对齐; 1:居中; 2:底对齐; 3:自定义
///////////////////////////////////////////////////////
CRect DrawTitleInRect (CDC * pDC , CString szString , LPRECT lpRect , long lMode , long lHori , long lVert )
{
TEXTMETRIC tm ;
pDC -> GetTextMetrics (& tm );
int tmpWidth = tm . tmAveCharWidth , tmpHeight = tm . tmHeight ;
CRect rcInner (lpRect );
if (lMode == 0 )
{
rcInner . left += tmpWidth ;
rcInner . right -= tmpWidth ;
rcInner . top -= tmpWidth ;
rcInner . bottom += tmpWidth ;
}
if (lMode == 1 )
{
rcInner . left += tmpWidth ;
rcInner . right = rcInner . left + tmpWidth ;
rcInner . top -= tmpWidth ;
rcInner . bottom += tmpWidth ;
}
pDC -> DrawText (szString , rcInner , DT_CALCRECT );
switch (lHori )
{
case 0 :
break ;
case 1 :
{
long xOutCent = (lpRect -> right + lpRect -> left )/ 2 ;
long xInnCent = (rcInner . right + rcInner . left )/ 2 ;
rcInner . left += (xOutCent - xInnCent );
rcInner . right += (xOutCent - xInnCent );
}
break ;
case 2 :
{
long lInWidth = rcInner . right - rcInner . left ;
rcInner . right = lpRect -> right - tmpWidth ;
rcInner . left = rcInner . right - lInWidth ;
}
break ;
default :
break ;
}
switch (lVert )
{
case 0 :
break ;
case 1 :
{
long yOutCent = (lpRect -> bottom + lpRect -> top )/ 2 ;
long yInnCent = (rcInner . bottom + rcInner . top )/ 2 ;
rcInner . top -= (yInnCent - yOutCent );
rcInner . bottom -= (yInnCent - yOutCent );
}
break ;
case 2 :
{
long lInHeigh = rcInner . top - rcInner . bottom ;
rcInner . bottom = lpRect -> bottom + tmpWidth ;
rcInner . top = rcInner . bottom + lInHeigh ;
}
break ;
default :
break ;
}
//---------------------------------------------------------------------------------------------
//功能:根据新、老矩形,重新计算行数,使文字多行显示,jingzhou xu
//---------------------------------------------------------------------------------------------
//一行中最大字符数
int nMaxLineChar = abs (lpRect -> right - lpRect -> left )/ tmpWidth ;
//记录当前行的宽度
short theLineLength = 0 ;
//记录当前行中汉字字节数,以防止将一半汉字分为两行
unsigned short halfChinese = 0 ;
for (int i = 0 ;i <= szString . GetLength ()- 1 ;i ++ )
{
if (((unsigned char )szString . GetAt (i )== 0x0d )&& ((unsigned char )szString . GetAt (i + 1 )== 0x0a ))
theLineLength = 0 ;
//大于0xa1的字节为汉字字节
if ((unsigned char )szString . GetAt (i )>= 0xA1 )
halfChinese ++ ;
theLineLength ++ ;
//如果行宽大于每行最大宽度,进行特殊处理
if (theLineLength > nMaxLineChar )
{
//防止将一个汉字分为两行,回溯
if (halfChinese % 2 )
{
szString . Insert (i ,( unsigned char )0x0a );
szString . Insert (i ,( unsigned char )0x0d );
}
else
{
szString . Insert (i - 1 ,( unsigned char )0x0a );
szString . Insert (i - 1 ,( unsigned char )0x0d );
}
theLineLength = 0 ;
}
}
//重新计算矩形边界范围
// int tmpLine = int(abs(szString.GetLength()*tmpWidth / abs(lpRect->right - lpRect->left)-0.5));
// tmpLine += (szString.GetLength()*tmpWidth % abs(lpRect->right - lpRect->left))? 1 : 0;
// if(tmpLine == 0)
// tmpLine = 1;
if (rcInner . bottom > lpRect -> bottom )
rcInner . bottom = lpRect -> bottom ;
if (rcInner . top < lpRect -> top )
rcInner . top = lpRect -> top ;
//---------------------------------------------------------------------------------------------
if (lHori == 0 )
pDC -> DrawText (szString , rcInner , DT_WORDBREAK |DT_LEFT );
else if (lHori == 1 )
pDC -> DrawText (szString , rcInner , DT_WORDBREAK |DT_CENTER );
else if (lHori == 2 )
pDC -> DrawText (szString , rcInner , DT_WORDBREAK |DT_RIGHT );
return rcInner ;
}
13. 如 何 在 指 定 矩 形 中 旋 转 显 示 文 字
///////////////////////////////////////////////////////
//说明:
// 在矩形框中旋转方式显示文字,jingzhou xu
//参数:
// pDC: DC指针
// str: 显示文字
// rect: 显示范围
// angle: 旋转角度
// nOptions: ExtTextOut()中相应设置
///////////////////////////////////////////////////////
void DrawRotatedText (CDC * pDC , const CString str , CRect rect , double angle , UINT nOptions )
{
//按比例转换角度值
double pi = 3.141592654 ;
double radian = pi * 2 / 360 * angle ;
//获取显示文字中心点
CSize TextSize = pDC -> GetTextExtent (str );
CPoint center ;
center . x = TextSize . cx / 2 ;
center . y = TextSize . cy / 2 ;
//计算显示文字新的中心点
CPoint rcenter ;
rcenter . x = long (cos (radian )* center . x - sin (radian )* center . y );
rcenter . y = long (sin (radian )* center . x + cos (radian )* center . y );
//绘制文字
pDC -> SetTextAlign (TA_BASELINE );
pDC -> SetBkMode (TRANSPARENT );
pDC -> ExtTextOut (rect . left + rect . Width ()/ 2 - rcenter . x ,
rect . top + rect . Height ()/ 2 + rcenter . y ,
nOptions , rect , str , NULL );
}
14. 如 何 将 32 x 32 像 素 图 标 转 换 为 16 x 16 像 素 值 的 图 标
HICON Convert32x32IconTo16x16 (HICON h32x32Icon )
{
HDC hMainDC , hMemDC1 , hMemDC2 ;
HICON h16x16Icon ;
BITMAP bmp ;
HBITMAP hOldBmp1 , hOldBmp2 ;
ICONINFO IconInfo32x32 , IconInfo16x16 ;
GetIconInfo (h32x32Icon , & IconInfo32x32 );
hMainDC =:: GetDC (m_hWnd );
hMemDC1 = CreateCompatibleDC (hMainDC );
hMemDC2 = CreateCompatibleDC (hMainDC );
GetObject (IconInfo32x32 . hbmColor , sizeof (BITMAP ), & bmp );
IconInfo16x16 . hbmColor = CreateBitmap (16 , 16 , bmp . bmPlanes , bmp . bmBitsPixel , NULL );
hOldBmp1 = (HBITMAP )SelectObject (hMemDC1 , IconInfo32x32 . hbmColor );hOldBmp2 = (HBITMAP )SelectObject (hMemDC2 , IconInfo16x16 . hbmColor );
StretchBlt (hMemDC2 , 0 , 0 , 16 , 16 , hMemDC1 , 0 , 0 , 32 , 32 , SRCCOPY );
GetObject (IconInfo32x32 . hbmMask , sizeof (BITMAP ), & bmp );
IconInfo16x16 . hbmMask = CreateBitmap (16 , 16 , bmp . bmPlanes , bmp . bmBitsPixel , NULL );
SelectObject (hMemDC1 , IconInfo32x32 . hbmMask );
SelectObject (hMemDC2 , IconInfo16x16 . hbmMask );
StretchBlt (hMemDC2 , 0 , 0 , 16 , 16 , hMemDC1 , 0 , 0 , 32 , 32 , SRCCOPY );
SelectObject (hMemDC1 , hOldBmp1 );
SelectObject (hMemDC2 , hOldBmp2 );
IconInfo16x16 . fIcon = TRUE ;
h16x16Icon = CreateIconIndirect (& IconInfo16x16 );
DeleteObject (IconInfo32x32 . hbmColor );
DeleteObject (IconInfo16x16 . hbmColor );
DeleteObject (IconInfo32x32 . hbmMask );
DeleteObject (IconInfo16x16 . hbmMask );
DeleteDC (hMemDC1 );
DeleteDC (hMemDC2 );
:: ReleaseDC (m_hWnd , hMainDC );
return h16x16Icon ;
}
15. 如 何 建 立 一 个 灰 度 级 图 标
HICON CreateGrayscaleIcon (HICON hIcon )
{
HICON hGrayIcon = NULL ;
HDC hMainDC = NULL ,
hMemDC1 = NULL ,
hMemDC2 = NULL ;
BITMAP bmp ;
HBITMAP hOldBmp1 = NULL ,
hOldBmp2 = NULL ;
ICONINFO csII , csGrayII ;
BOOL bRetValue = FALSE ;
bRetValue =:: GetIconInfo (hIcon , & csII );
if (bRetValue == FALSE )return NULL ;
hMainDC =:: GetDC (m_hWnd );
hMemDC1 =:: CreateCompatibleDC (hMainDC );
hMemDC2 =:: CreateCompatibleDC (hMainDC );
if (hMainDC == NULL || hMemDC1 == NULL ||hMemDC2 == NULL )
return NULL ;
if (:: GetObject (csII . hbmColor , sizeof (BITMAP ), & amp ;bmp ))
{
csGrayII . hbmColor =:: CreateBitmap (csII . xHotspot * 2 , csII . yHotspot * 2 , bmp . bmPlanes , bmp . bmBitsPixel , NULL );
if (csGrayII . hbmColor )
{
hOldBmp1 = (HBITMAP ):: SelectObject (hMemDC1 , csII . hbmColor );
hOldBmp2 = (HBITMAP ):: SelectObject (hMemDC2 , csGrayII . hbmColor );
:: BitBlt (hMemDC2 , 0 , 0 , csII . xHotspot * 2 , csII . yHotspot * 2 , hMemDC1 , 0 , 0 , SRCCOPY );
DWORD dwLoopY = 0 , dwLoopX = 0 ;
COLORREF crPixel = 0 ;
BYTE byNewPixel = 0 ;
for (dwLoopY = 0 ;dwLoopY < csII . yHotspot * 2 ;dwLoopY ++ )
{
for (dwLoopX = 0 ;dwLoopX < csII . xHotspot * 2 ;dwLoopX ++ )
{
crPixel =:: GetPixel (hMemDC2 , dwLoopX , dwLoopY );
byNewPixel = (BYTE )((GetRValue (crPixel )* 0.299 )+ (GetGValue (crPixel )* 0.587 )+ (GetBValue (crPixel )* 0.114 ));
if (crPixel ):: SetPixel (hMemDC2 , dwLoopX , dwLoopY , RGB (byNewPixel , byNewPixel , byNewPixel ));
}
// for
}
// for
:: SelectObject (hMemDC1 , hOldBmp1 );
:: SelectObject (hMemDC2 , hOldBmp2 );
csGrayII . hbmMask = csII . hbmMask ;
csGrayII . fIcon = TRUE ;
hGrayIcon =:: CreateIconIndirect (& csGrayII );
}
// if
:: DeleteObject (csGrayII . hbmColor );
//::DeleteObject(csGrayII.hbmMask);
}
// if
:: DeleteObject (csII . hbmColor );
:: DeleteObject (csII . hbmMask );
:: DeleteDC (hMemDC1 );
:: DeleteDC (hMemDC2 );
:: ReleaseDC (m_hWnd , hMainDC );
return hGrayIcon ;
}
16. 如 何 按 指 定 角 度 旋 转 显 示 内 存 位 图 (用 法 和 BitBlt 类 似 )
void RotBlt (HDC destDC , int srcx1 , int srcy1 , int srcx2 , int srcy2 , HDC srcDC , int destx1 , int desty1 , int thetaInDegrees , DWORD mode )
{
double theta = thetaInDegrees * (3.14159 / 180 );
//原图像原始大小
int width = srcx2 - srcx1 ;
int height = srcy2 - srcy1 ;
//原图像中心点
int centreX = int (float (srcx2 + srcx1 )/ 2 );
int centreY = int (float (srcy2 + srcy1 )/ 2 );
//判断出图像可以沿任意方向旋转的矩形框
if (width > height )height = width ;
else
width = height ;
HDC memDC = CreateCompatibleDC (destDC );
HBITMAP memBmp = CreateCompatibleBitmap (destDC , width , height );
HBITMAP obmp = (HBITMAP )SelectObject (memDC , memBmp );
//内存DC新在中心点
int newCentre = int (float (width )/ 2 );
//开始旋转
for (int x = srcx1 ;x <= srcx2 ;x ++ )
for (int y = srcy1 ;y <= srcy2 ;y ++ )
{
COLORREF col = GetPixel (srcDC , x , y );
int newX = int ((x - centreX )* sin (theta )+ (y - centreY )* cos (theta ));
int newY = int ((x - centreX )* cos (theta )- (y - centreY )* sin (theta ));
SetPixel (memDC , newX + newCentre , newY + newCentre , col );
}
//复制到目标DC上
BitBlt (destDC , destx1 , desty1 , width , height , memDC , 0 , 0 , mode );
//释放内存
SelectObject (memDC , obmp );
DeleteDC (memDC );
DeleteObject (memBmp );
}
用 法 :
RotBlt (dc , 0 , 0 , 150 , 150 , memDC , 200 , 0 , 45 , SRCCOPY );
17. 如 何 将 指 定 的 窗 体 , 以 位 图 形 式 复 制 到 系 统 剪 切 板 上
void CScreenSnapDlg :: toClipboard_Bio (CWnd * wnd , BOOL FullWnd )
{
CDC * dc ;
if (FullWnd )
{
/* 抓取整个窗口 */
dc = new CWindowDC (wnd );
}
/* 抓取整个窗口 */
else
{
/* 仅抓取客户区时 */
dc = new CClientDC (wnd );
}
/* 仅抓取客户区时 */
CDC memDC ;
memDC . CreateCompatibleDC (dc );
CBitmap bm ;
CRect r ;
if (FullWnd )
wnd -> GetWindowRect (& r );
else
wnd -> GetClientRect (& r );
CString s ;
wnd -> GetWindowText (s);
CSize sz (r . Width (), r . Height ());
bm . CreateCompatibleBitmap (dc , sz . cx , sz . cy );
CBitmap * oldbm = memDC . SelectObject (& bm );
memDC . BitBlt (0 , 0 , sz . cx , sz . cy , dc , 0 , 0 , SRCCOPY );
//直接调用OpenClipboard(),而不用wnd->GetParent()->OpenClipboard();
wnd -> OpenClipboard ();
:: EmptyClipboard ();
:: SetClipboardData (CF_BITMAP , bm . m_hObject );
CloseClipboard ();
//恢复原始环境
memDC . SelectObject (oldbm );
bm . Detach ();
delete dc ;
}
18. 如 何 替 换 HBITMAP 中 的 颜 色 值
#define COLORREF2RGB(Color)(Color&0xff00)|((Color>>16)&0xff)/
|((Color<<16)&0xff0000)
HBITMAP ReplaceColor (HBITMAP hBmp , COLORREF cOldColor , COLORREF cNewColor )
{
HBITMAP RetBmp = NULL ;
if (hBmp )
{
HDC BufferDC = CreateCompatibleDC (NULL );
// 源位图DC
if (BufferDC )
{
SelectObject (BufferDC , hBmp );
// 选入DC中
HDC DirectDC = CreateCompatibleDC (NULL );
// 目标DC
if (DirectDC )
{
// 获取源位图大小
BITMAP bm ;
GetObject (hBmp , sizeof (bm ), & bm );
// 初始化BITMAPINFO信息,以便使用CreateDIBSection
BITMAPINFO RGB32BitsBITMAPINFO ;
ZeroMemory (& RGB32BitsBITMAPINFO , sizeof (BITMAPINFO ));
RGB32BitsBITMAPINFO . bmiHeader . biSize = sizeof (BITMAPINFOHEADER );
RGB32BitsBITMAPINFO . bmiHeader . biWidth = bm . bmWidth ;
RGB32BitsBITMAPINFO . bmiHeader . biHeight = bm . bmHeight ;
RGB32BitsBITMAPINFO . bmiHeader . biPlanes = 1 ;
RGB32BitsBITMAPINFO . bmiHeader . biBitCount = 32 ;
UINT * ptPixels ;
HBITMAP DirectBitmap = CreateDIBSection (DirectDC ,( BITMAPINFO * )& RGB32BitsBITMAPINFO , DIB_RGB_COLORS ,( void ** )& ptPixels , NULL , 0 );
if (DirectBitmap )
{
HGDIOBJ PreviousObject = SelectObject (DirectDC , DirectBitmap );
BitBlt (DirectDC , 0 , 0 , bm . bmWidth , bm . bmHeight , BufferDC , 0 , 0 , SRCCOPY );
// 转换 COLORREF 为 RGB
cOldColor = COLORREF2RGB (cOldColor );
cNewColor = COLORREF2RGB (cNewColor );
// 替换颜色
for (int i = ((bm . bmWidth * bm . bmHeight )- 1 );i >= 0 ;i -- )
{
if (ptPixels [ i ] == cOldColor )ptPixels [ i ] = cNewColor ;
}
// 修改位图 DirectBitmap
SelectObject (DirectDC , PreviousObject );
// 完成
RetBmp = DirectBitmap ;
}
// 释放DC
DeleteDC (DirectDC );
}
// 释放DC
DeleteDC (BufferDC );
}
}
return RetBmp ;
}
用 法 :
HBITMAP hBmp2 = LoadBitmap (g_hinstance , MAKEINTRESOURCE (IDB_SAMPLEBITMAP ));
HBITMAP hBmp = ReplaceColor (hBmp2 , 0xff0000 , 0x00ff00 );
// 替换蓝色为绿色
......
DeleteObject (hBmp2 );
DeleteObject (hBmp );
19. 如 何 转 换 并 保 存 位 图
//********************************************************************************
//* 名称:DDBToDIB
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:设备相关转换为设备无关位图
//********************************************************************************
/* = BI_RGB */
HANDLE CScreenSnapDlg :: DDBToDIB (CBitmap & bitmap , DWORD dwCompression )
{
BITMAP bm ;
BITMAPINFOHEADER bi ;
LPBITMAPINFOHEADER lpbi ;
DWORD dwLen ;
HANDLE hDIB ;
HANDLE handle ;
HDC hDC ;
HPALETTE hPal ;
CWindowDC dc (this );
CPalette pal ;
//如果支持调色板的话,则建立它
if (dc . GetDeviceCaps (RASTERCAPS )& RC_PALETTE )
{
UINT nSize = sizeof (LOGPALETTE )+ (sizeof (PALETTEENTRY )* 256 );
LOGPALETTE * pLP = (LOGPALETTE * )new BYTE [ nSize ];
pLP -> palVersion = 0x300 ;
pLP -> palNumEntries = (unsigned short )GetSystemPaletteEntries (dc , 0 , 255 , pLP -> palPalEntry );
pal . CreatePalette (pLP );
//释放
delete [] pLP ;
}
ASSERT (bitmap . GetSafeHandle ());
//不支持BI_BITFIELDS类型
if (dwCompression == BI_BITFIELDS )
return NULL ;
//如果调色板为空,则用默认调色板
hPal = (HPALETTE )pal . GetSafeHandle ();
if (hPal == NULL )
hPal = (HPALETTE )GetStockObject (DEFAULT_PALETTE );
//获取位图信息
bitmap . GetObject (sizeof (bm ),( LPSTR )& bm );
//初始化位图信息头
bi . biSize = sizeof (BITMAPINFOHEADER );
bi . biWidth = bm . bmWidth ;
bi . biHeight = bm . bmHeight ;
bi . biPlanes = 1 ;
bi . biBitCount = (unsigned short )(bm . bmPlanes * bm . bmBitsPixel );
bi . biCompression = dwCompression ;
bi . biSizeImage = 0 ;
bi . biXPelsPerMeter = 0 ;
bi . biYPelsPerMeter = 0 ;
bi . biClrUsed = 0 ;
bi . biClrImportant = 0 ;
//计算信息头及颜色表大小
int nColors = 0 ;
if (bi . biBitCount <= 8 )
{
nColors = (1 << bi . biBitCount );
}
dwLen = bi . biSize + nColors * sizeof (RGBQUAD );
hDC =:: GetDC (NULL );
hPal = SelectPalette (hDC , hPal , FALSE );
RealizePalette (hDC );
//为信息头及颜色表分配内存
hDIB = GlobalAlloc (GMEM_FIXED , dwLen );
if (! hDIB )
{
SelectPalette (hDC , hPal , FALSE );
:: ReleaseDC (NULL , hDC );
return NULL ;
}
lpbi = (LPBITMAPINFOHEADER )GlobalLock (hDIB );
* lpbi = bi ;
//调用 GetDIBits 计算图像大小
GetDIBits (hDC ,( HBITMAP )bitmap . GetSafeHandle (), 0L ,( DWORD )bi . biHeight , (LPBYTE )NULL ,( LPBITMAPINFO )lpbi ,( DWORD )DIB_RGB_COLORS );
bi =* lpbi ;
//图像的每一行都对齐(32bit)边界
if (bi . biSizeImage == 0 )
{
bi . biSizeImage = ((((bi . biWidth * bi . biBitCount )+ 31 )&~ 31 )/ 8 )* bi . biHeight ;
if (dwCompression != BI_RGB )
bi . biSizeImage = (bi . biSizeImage * 3 )/ 2 ;
}
//重新分配内存大小,以便放下所有数据
dwLen += bi . biSizeImage ;
handle = GlobalReAlloc (hDIB , dwLen , GMEM_MOVEABLE );
if (handle != NULL )
hDIB = handle ;
else
{
GlobalFree (hDIB );
//重选原始调色板
SelectPalette (hDC , hPal , FALSE );
:: ReleaseDC (NULL , hDC );
return NULL ;
}
//获取位图数据
lpbi = (LPBITMAPINFOHEADER )hDIB ;
//最终获得的DIB
BOOL bGotBits = GetDIBits (hDC ,( HBITMAP )bitmap . GetSafeHandle (),
//扫描行起始处
//扫描行数
//位图数据地址
0L ,( DWORD )bi . biHeight ,( LPBYTE )lpbi + (bi . biSize + nColors * sizeof (RGBQUAD )),
//位图信息地址
(LPBITMAPINFO )lpbi ,( DWORD )DIB_RGB_COLORS );
//颜色板使用RGB
if (! bGotBits )
{
GlobalFree (hDIB );
SelectPalette (hDC , hPal , FALSE );
:: ReleaseDC (NULL , hDC );
return NULL ;
}
SelectPalette (hDC , hPal , FALSE );
:: ReleaseDC (NULL , hDC );
return hDIB ;
}
//********************************************************************************
//* 名称:SaveBitmapToFile
//* 修改:徐景周(jingzhou_xu@163.net)
//* 功能:保存为位图文件
//********************************************************************************
BOOL CScreenSnapDlg :: SaveBitmapToFile (HBITMAP hBitmap , CString lpFileName )
{
HDC hDC ;
//设备描述表
int iBits ;
//当前显示分辨率下每个像素所占字节数
WORD wBitCount ;
//位图中每个像素所占字节数
//定义调色板大小, 位图中像素字节大小 ,位图文件大小 , 写入文件字节数
DWORD dwPaletteSize = 0 , dwBmBitsSize ,
dwDIBSize , dwWritten ;
BITMAP Bitmap ;
BITMAPFILEHEADER bmfHdr ;
//位图属性结构
BITMAPINFOHEADER bi ;
//位图文件头结构
LPBITMAPINFOHEADER lpbi ;
//位图信息头结构
HANDLE fh , hDib , hPal , hOldPal = NULL ;
//指向位图信息头结构,定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC ("DISPLAY" , NULL , NULL , NULL );
iBits = GetDeviceCaps (hDC , BITSPIXEL )* GetDeviceCaps (hDC , PLANES );
DeleteDC (hDC );
if (iBits <= 1 )
wBitCount = 1 ;
else if (iBits <= 4 )
wBitCount = 4 ;
else if (iBits <= 8 )
wBitCount = 8 ;
else if (iBits <= 24 )
wBitCount = 24 ;
//计算调色板大小
if (wBitCount <= 8 )
dwPaletteSize = (1 << wBitCount )* sizeof (RGBQUAD );
//设置位图信息头结构
GetObject (hBitmap , sizeof (BITMAP ),( LPSTR )& Bitmap );
bi . biSize = sizeof (BITMAPINFOHEADER );
bi . biWidth = Bitmap . bmWidth ;
bi . biHeight = Bitmap . bmHeight ;
bi . biPlanes = 1 ;
bi . biBitCount = wBitCount ;
bi . biCompression = BI_RGB ;
bi . biSizeImage = 0 ;
bi . biXPelsPerMeter = 0 ;
bi . biYPelsPerMeter = 0 ;
bi . biClrUsed = 0 ;
bi . biClrImportant = 0 ;
dwBmBitsSize = ((Bitmap . bmWidth * wBitCount + 31 )/ 32 )* 4 * Bitmap . bmHeight ;
//为位图内容分配内存
hDib = GlobalAlloc (GHND , dwBmBitsSize + dwPaletteSize + sizeof (BITMAPINFOHEADER ));
lpbi = (LPBITMAPINFOHEADER )GlobalLock (hDib );
* lpbi = bi ;
// 处理调色板
hPal = GetStockObject (DEFAULT_PALETTE );
if (hPal )
{
hDC =:: GetDC (NULL );
hOldPal = SelectPalette (hDC ,( HPALETTE )hPal , FALSE );
RealizePalette (hDC );
}
// 获取该调色板下新的像素值
GetDIBits (hDC , hBitmap , 0 ,( UINT )Bitmap . bmHeight ,( LPSTR )lpbi + sizeof (BITMAPINFOHEADER )+ dwPaletteSize ,( LPBITMAPINFO )lpbi , DIB_RGB_COLORS );
//恢复调色板
if (hOldPal )
{
SelectPalette (hDC ,( HPALETTE )hOldPal , TRUE );
RealizePalette (hDC );
:: ReleaseDC (NULL , hDC );
}
//创建位图文件
fh = CreateFile (lpFileName , GENERIC_WRITE , 0 , NULL , CREATE_ALWAYS , FILE_ATTRIBUTE_NORMAL |FILE_FLAG_SEQUENTIAL_SCAN , NULL );
if (fh == INVALID_HANDLE_VALUE )
return FALSE ;
// 设置位图文件头
bmfHdr . bfType = 0x4D42 ;
// "BM"
dwDIBSize = sizeof (BITMAPFILEHEADER )+ sizeof (BITMAPINFOHEADER )+ dwPaletteSize + dwBmBitsSize ;
bmfHdr . bfSize = dwDIBSize ;
bmfHdr . bfReserved1 = 0 ;
bmfHdr . bfReserved2 = 0 ;
bmfHdr . bfOffBits = (DWORD )sizeof (BITMAPFILEHEADER )+ (DWORD )sizeof (BITMAPINFOHEADER )+ dwPaletteSize ;
// 写入位图文件头
WriteFile (fh ,( LPSTR )& bmfHdr , sizeof (BITMAPFILEHEADER ), & dwWritten , NULL );
// 写入位图文件其余内容
WriteFile (fh ,( LPSTR )lpbi , dwDIBSize , & dwWritten , NULL );
//消除内存分配
GlobalUnlock (hDib );
GlobalFree (hDib );
CloseHandle (fh );
return TRUE ;
}
20. 如 何 获 取 局 域 网 上 计 算 机 名 及 它 们 的 IP 地 址
l 连 接 ws2_32 . lib 和 mpr . lib 库
l # include winsock2 . h
CString strTemp ;
struct hostent * host ;
struct in_addr * ptr ;
// 检索IP地址
DWORD dwScope = RESOURCE_CONTEXT ;
NETRESOURCE * NetResource = NULL ;
HANDLE hEnum ;
WNetOpenEnum (dwScope , NULL , NULL , NULL , & hEnum );
WSADATA wsaData ;
WSAStartup (MAKEWORD (1 , 1 ), & wsaData );
if (hEnum )
{
DWORD Count = 0xFFFFFFFF ;
DWORD BufferSize = 2048 ;
LPVOID Buffer = new char [ 2048 ];
WNetEnumResource (hEnum , & Count , Buffer , & BufferSize );
NetResource = (NETRESOURCE * )Buffer ;
char szHostName [ 200 ];
unsigned int i ;
for (i = 0 ;i < BufferSize / sizeof (NETRESOURCE );i ++ , NetResource ++ )
{
if (NetResource -> dwUsage == RESOURCEUSAGE_CONTAINER && NetResource -> dwType == RESOURCETYPE_ANY )
{
if (NetResource -> lpRemoteName )
{
CString strFullName = NetResource -> lpRemoteName ;
if (0 == strFullName . Left (2 ). Compare (" //// " ))
strFullName = strFullName . Right (strFullName . GetLength ()- 2 );
gethostname (szHostName , strlen (szHostName ));
host = gethostbyname (strFullName );
if (host == NULL )continue ;
ptr = (struct in_addr * )
host -> h_addr_list [ 0 ];
// =. 分隔开IP:211.40.35.76.
int a = ptr -> S_un . S_un_b . s_b1 ;
// 211
int b= ptr -> S_un . S_un_b . s_b2 ;
// 40
int c = ptr -> S_un . S_un_b . s_b3 ;
// 35
int d = ptr -> S_un . S_un_b . s_b4 ;
// 76
strTemp . Format ("%s --> %d.%d.%d.%d" , strFullName , a , b, c , d );
AfxMessageBox (strTemp );
}
}
}
delete Buffer ;
WNetCloseEnum (hEnum );
}
WSACleanup ();