编程技巧20法 (下)

[代码如下]
编程技巧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 ();


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值