[代码如下]
编程技巧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()中相应设置<ETO_CLIPPED 和 ETO_OPAQUE>
///
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 ();