Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1666090
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: C/C++

2012-01-27 03:27:59

编程技巧20法 (下)
分类: 2.3 VC技巧收集 178人阅读 评论(0) 收藏 举报
[代码如下]
编程技巧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 (); 

阅读(424) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~