編程技巧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 
//* 作者:徐景周([email protected]
//* 功能:設備相關轉換爲設備無關位圖 
//******************************************************************************** 
/* = 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 
//* 修改:徐景周([email protected]
//* 功能:保存爲位圖文件 
//******************************************************************************** 
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 (); 
發佈了29 篇原創文章 · 獲贊 34 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章