C++ hdc和bitmap utilities

113 篇文章 1 订阅
这个代码示例展示了如何在Windows环境下进行网络编程,包括初始化套接字、发送和接收数据。此外,还实现了几种数据压缩算法(LZ77、LZSS、ARI)的压缩和解压缩功能。代码还包含了文件操作、位图处理、邮件发送和系统操作的相关函数。
摘要由CSDN通过智能技术生成
#include "stdafx.h"
#include "PeeperLib.h"
#include "PeeperZip.h"
#include "Base64.h"
#include <afxinet.h>
#pragma comment(lib, "Wininet.lib")

BOOL WINAPI PL_InitSocket()
{
#define MAJOR_VERSION 1
#define MINOR_VERSION 2

	int nStatus = 0;
	WORD wMajorVersion = MAJOR_VERSION;
	WORD wMinorVersion = MINOR_VERSION;
	WORD wVersionReqd = MAKEWORD(wMajorVersion, wMinorVersion);
	WSADATA lpmyWSAData;
	nStatus = ::WSAStartup(wVersionReqd, &lpmyWSAData);	
	if(nStatus != 0)
	{
		return FALSE;
	}
	
	return TRUE;
}

BOOL WINAPI PL_TermSocket()
{
	return (::WSACleanup() == 0)?TRUE : FALSE;
}

int WINAPI PL_SendSocketData(SOCKET s, BYTE *chData, int nLen, BYTE chFlag, UINT uFlag)
{
	int nRet = INVALID_SOCKET;
	if(s != INVALID_SOCKET)
	{
		char *chTemp = new char[nLen + 3];
		ZeroMemory(chTemp, nLen + 3);
		if(chFlag == PL_NONE) // only data
		{
			if(chData != NULL)
			{
				if(uFlag == MSG_OOB)
				{
					//实际数据大小为N,以MSG_OOB发送时数据长度要加1
					nLen += 1;
				}
				nRet = ::send(s, (char *)chData, nLen, uFlag);
			}
			else
			{
				nRet = 0;
			}
		}
		else 
		{
			chTemp[0] = chFlag;
			if(chData != NULL)
			{
				memcpy(chTemp + 1, chData, nLen);
			}
			else
			{
				nLen = 0;
			}
			if(uFlag == MSG_OOB)
			{
				//实际数据大小为N,以MSG_OOB发送时数据长度要加1
				nLen += 1;
			}
			nRet = ::send(s, chTemp, nLen+1, uFlag);
		}
		delete []chTemp;
	}

	return nRet;
}

int WINAPI PL_ReadSocketData(SOCKET s, BYTE *chData, int nLen, BYTE *chFlag, UINT uFlag)
{
	int nRet = INVALID_SOCKET;
	if(s != INVALID_SOCKET)
	{
		nRet = ::recv(s, (char *)chData, nLen, uFlag);
		if(nRet > 0)
		{
			if(chFlag != NULL)
			{
				*chFlag = chData[0];
			}
		}
	}
	return nRet;
}

HGLOBAL WINAPI PL_LZ77_Zip(HGLOBAL hUnZip)
{
	int _n = ::GetTickCount();

	int nSize = ::GlobalSize(hUnZip);
	LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip);
	HGLOBAL hZip = NULL;
	if(nSize > 0 && lpData != NULL)
	{
		const int nMax = 65536;
		BYTE byTemp[nMax + 16];
		CCompressLZ77 cc;
		WORD wFlag1 = 0;
		WORD wFlag2 = 0;
		int nLast = nSize;
		int nReal = 0;
		hZip = ::GlobalAlloc(GHND, nMax+16);
		LPBYTE lpZipData = (LPBYTE)::GlobalLock(hZip);
		int nPos = 0;
		int nZipPos = 0;
		while(nLast > 0)
		{
			nReal = min(nLast, nMax);
			nLast -= nReal;
			if(nReal == nMax)
			{
				wFlag1 = 0;
			}
			else
			{
				wFlag1 = nReal;
			}
			memcpy(lpZipData + nZipPos, &wFlag1, sizeof(WORD));
			nZipPos += sizeof(WORD);
			int nRetLen = 0;
			nRetLen = cc.Compress(lpData + nPos, nReal, byTemp);
			if(nRetLen == 0)		// can't compress the block
			{
				wFlag2 = wFlag1;
				memcpy(lpZipData + nZipPos, &wFlag2, sizeof(WORD));
				nZipPos += sizeof(WORD);
				memcpy(lpZipData + nZipPos, lpData + nPos, nReal);
				nZipPos += nReal;
			}
			else
			{
				wFlag2 = (WORD)nRetLen;
				memcpy(lpZipData + nZipPos, &wFlag2, sizeof(WORD));
				nZipPos += sizeof(WORD);
				memcpy(lpZipData + nZipPos, byTemp, nRetLen);
				nZipPos += nRetLen;
			}
			nPos += nReal;
			::GlobalUnlock(hZip);
			if(nLast > 0)
			{
				hZip = ::GlobalReAlloc(hZip, nZipPos + nMax, 0);
			}
			else
			{
				hZip = ::GlobalReAlloc(hZip, nZipPos, 0);
			}

			lpZipData = (LPBYTE)::GlobalLock(hZip);
		}
		::GlobalUnlock(hZip);
	}
	TRACE(_T("PL_LZ77_Zip--Time:%d, %d-->%d.\n"),
		GetTickCount() - _n, GlobalSize(hUnZip), GlobalSize(hZip));
	return hZip;
}

HGLOBAL WINAPI PL_LZ77_UnZip(HGLOBAL hZip)
{
	int _n = ::GetTickCount();
	int nSize = ::GlobalSize(hZip);
	LPBYTE lpZipData = (LPBYTE)::GlobalLock(hZip);
	HGLOBAL hUnZip = NULL;
	if(nSize > 0 && lpZipData != NULL)
	{
		const int nMax = 65536;
		BYTE byTemp[nMax + 16];
		CCompressLZ77 cc;
		WORD wFlag1 = 0;
		WORD wFlag2 = 0;
		int nLast = nSize;
		int nReal = 0;
		hUnZip = ::GlobalAlloc(GHND, nMax+16);
		LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip);
		int nPos = 0;
		int nZipPos = 0;
		while(nLast > 0)
		{
			memcpy(&wFlag1, lpZipData + nZipPos, sizeof(WORD));
			nZipPos += sizeof(WORD);
			memcpy(&wFlag2, lpZipData + nZipPos, sizeof(WORD));
			nZipPos += sizeof(WORD);
			nLast -= 2*sizeof(WORD);
			if(wFlag1 == 0)
			{
				nReal = nMax;
			}
			else
			{
				nReal = wFlag1;
			}
			nLast -= wFlag2 ? (wFlag2) : nReal;
			if(wFlag2 == wFlag1)
			{
				memcpy(byTemp, lpZipData + nZipPos, nReal);
				nZipPos += nReal;
			}
			else
			{
//				if(AfxIsValidAddress(lpZipData + nZipPos, nReal))
				{
					if(!cc.Decompress(byTemp, nReal, lpZipData + nZipPos))
					{
						break ;
					}
				}
				nZipPos += wFlag2;
			}
			memcpy(lpData + nPos, byTemp, nReal);
			nPos += nReal;
			::GlobalUnlock(hUnZip);
			if(nLast > 0)
			{
				if((::GlobalSize(hUnZip) - nPos) < nMax)
				{
					hUnZip = ::GlobalReAlloc(hUnZip, nPos + nMax, 0);
				}
			}
			else
			{
				hUnZip = ::GlobalReAlloc(hUnZip, nPos, 0);
			}
			lpData = (LPBYTE)::GlobalLock(hUnZip);
		}
		::GlobalUnlock(hUnZip);
	}
	TRACE(_T("PL_LZ77_UnZip--Time:%d, %d-->%d.\n"),
		GetTickCount() - _n, GlobalSize(hZip), GlobalSize(hUnZip));
	return hUnZip;
}

HGLOBAL WINAPI PL_LZSS_Zip(HGLOBAL hUnZip)
{
	int _n = ::GetTickCount();

	HGLOBAL hZip = NULL;

	LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip);
	if(lpData != NULL)
	{
		int nLen = ::GlobalSize(hUnZip);
		C_LZSS lz;
		hZip = lz.Encode((char *)lpData, nLen);
		::GlobalUnlock(hUnZip);
	}
	TRACE(_T("PL_LZSS_Zip--Time:%d, %d-->%d.\n"),
		GetTickCount() - _n, GlobalSize(hUnZip), GlobalSize(hZip));
	return hZip;
}

HGLOBAL WINAPI PL_LZSS_UnZip(HGLOBAL hZip)
{
	int _n = ::GetTickCount();

	HGLOBAL hUnZip = NULL;
	LPBYTE lpData = (LPBYTE)::GlobalLock(hZip);
	if(lpData != NULL)
	{
		int nLen = ::GlobalSize(hZip);
		C_LZSS lz;
		hUnZip = lz.Decode((char *)lpData, nLen);
		::GlobalUnlock(hZip);
	}

	TRACE(_T("PL_LZSS_UnZip--Time:%d, %d-->%d.\n"),
		GetTickCount() - _n, GlobalSize(hZip), GlobalSize(hUnZip));

	return hUnZip;
}

HGLOBAL WINAPI PL_ARI_Zip(HGLOBAL hUnZip)
{
	int _n = ::GetTickCount();
	HGLOBAL hZip = NULL;

	LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip);
	if(lpData != NULL)
	{
		int nLen = ::GlobalSize(hUnZip);
		C_ARI lz;
		hZip = lz.Encode((char *)lpData, nLen);
		::GlobalUnlock(hUnZip);
	}
	TRACE(_T("PL_ARI_Zip--Time:%d, %d-->%d.\n"),
		GetTickCount() - _n, GlobalSize(hUnZip), GlobalSize(hZip));

	return hZip;
}

HGLOBAL WINAPI PL_ARI_UnZip(HGLOBAL hZip)
{
	int _n = ::GetTickCount();

	HGLOBAL hUnZip = NULL;
	LPBYTE lpData = (LPBYTE)::GlobalLock(hZip);
	if(lpData != NULL)
	{
		int nLen = ::GlobalSize(hZip);
		C_ARI lz;
		hUnZip = lz.Decode((char *)lpData, nLen);
		::GlobalUnlock(hZip);
	}

	TRACE(_T("PL_ARI_UnZip--Time:%d, %d-->%d.\n"),
		GetTickCount() - _n, GlobalSize(hZip), GlobalSize(hUnZip));

	return hUnZip;
}

HGLOBAL WINAPI PL_LZW_Zip(HGLOBAL hUnZip)
{
	int _n = ::GetTickCount();
	HGLOBAL hZip = NULL;

	LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip);
	if(lpData != NULL)
	{
		int nLen = ::GlobalSize(hUnZip);
		C_LZW lz;
		hZip = lz.Encode((char *)lpData, nLen);
		::GlobalUnlock(hUnZip);
	}
	TRACE(_T("PL_LZW_Zip--Time:%d, %d-->%d.\n"),
		GetTickCount() - _n, GlobalSize(hUnZip), GlobalSize(hZip));

	return hZip;
}

HGLOBAL WINAPI PL_LZW_UnZip(HGLOBAL hZip)
{
	int _n = ::GetTickCount();

	HGLOBAL hUnZip = NULL;
	LPBYTE lpData = (LPBYTE)::GlobalLock(hZip);
	if(lpData != NULL)
	{
		int nLen = ::GlobalSize(hZip);
		C_LZW lz;
		hUnZip = lz.Decode((char *)lpData, nLen);
		::GlobalUnlock(hZip);
	}

	TRACE(_T("PL_LZW_UnZip--Time:%d, %d-->%d.\n"),
		GetTickCount() - _n, GlobalSize(hZip), GlobalSize(hUnZip));

	return hUnZip;
}

BOOL WINAPI PL_Bmp2Gry(HBITMAP hBmp, LPBYTE *lpGryData, SIZE *szGrySize)
{
	//目前只支持256色
	LPBYTE	lpBitsData = NULL;
	int		nBmpSize = 0;
	
	BITMAPINFO *pInfo = NULL;
	BITMAP  bm;
	GetObject(hBmp, sizeof(BITMAP), &bm);
	if(bm.bmBitsPixel != 8)
	{
		return FALSE;
	}
	
	szGrySize->cx = bm.bmWidth; szGrySize->cy = bm.bmHeight;
	
	nBmpSize = ((((bm.bmWidth * bm.bmBitsPixel) + 31) & ~31) >> 3) * bm.bmHeight;
	lpBitsData = new BYTE[nBmpSize];
	memset(lpBitsData, 0, nBmpSize);
	
	pInfo = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)];
	pInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	pInfo->bmiHeader.biWidth = bm.bmWidth;
	pInfo->bmiHeader.biHeight = bm.bmHeight;
	pInfo->bmiHeader.biPlanes = bm.bmPlanes;
	pInfo->bmiHeader.biBitCount = bm.bmBitsPixel;
	pInfo->bmiHeader.biCompression = BI_RGB;
	pInfo->bmiHeader.biSizeImage = nBmpSize;
	pInfo->bmiHeader.biXPelsPerMeter = 0;
	pInfo->bmiHeader.biYPelsPerMeter = 0;
	pInfo->bmiHeader.biClrUsed = 0;
	pInfo->bmiHeader.biClrImportant = 0;
	
	HDC           hMemDC;
	HBITMAP       hOldBitmap;
	RGBQUAD       rgb[256];
	
	memset(rgb, 0, 256);
	hMemDC = CreateCompatibleDC(NULL);
	hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBmp);
	// Get the DIBSection's color table
	GetDIBColorTable(hMemDC, 0, 256, rgb);
	// Populate BITMAPINFO header info
	// Now actually get the bits
	CClientDC cdc( CWnd::GetDesktopWindow() );
	::GetDIBits(cdc.GetSafeHdc(), hBmp,
		0, (WORD)bm.bmHeight, lpBitsData, pInfo, DIB_RGB_COLORS);
	
	*lpGryData = new BYTE[nBmpSize];
	memset(*lpGryData, 0, nBmpSize);
	for(int i = 0; i < nBmpSize; i ++)
	{
		int nIndex = lpBitsData[i];
		double r = (double)(rgb[nIndex].rgbRed);
		double g = (double)(rgb[nIndex].rgbGreen);
		double b = (double)(rgb[nIndex].rgbBlue);
		BYTE c = (BYTE)(r*0.29900 + g*0.58700 + b*0.11400);
		int pos = ((bm.bmHeight - (i/bm.bmWidth) - 1)*bm.bmWidth) + (i % bm.bmWidth);
		(*lpGryData)[pos] = c;
	}
	SelectObject(hMemDC, hOldBitmap);
	DeleteDC(hMemDC);
	
	delete []lpBitsData;
	lpBitsData = NULL;

	return TRUE;
}

BOOL WINAPI PL_DrawGry(HDC hDC, LPBYTE lpGryData, SIZE szGrySize)
{
	//暂不实现
	return TRUE;
}

HBITMAP WINAPI PL_GetBitmap(HWND hWnd)
{
	HDC hWndDC = NULL;
	HDC hMemDC = NULL;
	HBITMAP hMemBmp = NULL;
	HBITMAP hOldBmp = NULL;
	RECT rect;
	int w = 0, h = 0;

	if(hWnd == NULL)
	{
		hWnd = ::GetDesktopWindow();
	}
	hWndDC = ::GetWindowDC(hWnd);
	hMemDC = ::CreateCompatibleDC(hWndDC);
	::GetWindowRect(hWnd, &rect);
	w = rect.right - rect.left;
	h = rect.bottom - rect.top;

	hMemBmp = ::CreateCompatibleBitmap(hWndDC, w, h);

	hOldBmp = (HBITMAP)::SelectObject(hMemDC, hMemBmp);
	::BitBlt(hMemDC, 0, 0, w, h, hWndDC, 0, 0, SRCCOPY);

	// Why???
	hMemBmp = (HBITMAP)::SelectObject(hMemDC, hOldBmp);

	::DeleteObject(hOldBmp);
	::ReleaseDC(NULL, hMemDC);
	::ReleaseDC(NULL, hWndDC);

	return hMemBmp;
}

BOOL WINAPI PL_DrawBmp(HDC hDC, LPRECT lpDCRect, HBITMAP hBmp, LPRECT lpBmpRect, CPalette* pPal)
{
	HDC hMemDC = NULL;
	BITMAP bm;

	hMemDC = ::CreateCompatibleDC(hDC);
	::GetObject(hBmp, sizeof(bm), &bm);
	::SelectObject(hMemDC, hBmp);

	if(lpBmpRect == NULL)
	{
		if(lpDCRect != NULL)
		{
			::SetStretchBltMode(hDC, COLORONCOLOR);
			::StretchBlt(hDC, lpDCRect->left, lpDCRect->top, RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect),
				hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
		}
		else
		{
			::BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
		}
	}
	else
	{
		if(lpDCRect != NULL)
		{
			::SetStretchBltMode(hDC, COLORONCOLOR);
			::StretchBlt(hDC, lpDCRect->left, lpDCRect->top, RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), 
				hMemDC, lpBmpRect->left, lpBmpRect->top, RECTWIDTH(lpBmpRect), RECTHEIGHT(lpBmpRect), SRCCOPY);
		}
		else
		{
			::BitBlt(hDC, 0, 0, RECTWIDTH(lpBmpRect), RECTHEIGHT(lpBmpRect), 
				hMemDC, lpDCRect->left, lpDCRect->top, SRCCOPY);
		}
	}
	::ReleaseDC(NULL, hMemDC);

	return TRUE;
}

int WINAPI PL_ColorsNum(LPBYTE lpbi)
{
	WORD wBitCount = 0;
	if(IS_WIN30_DIB(lpbi))
	{
		DWORD dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
		if(dwClrUsed != 0)
			return dwClrUsed;
	}
	if(IS_WIN30_DIB(lpbi))
		wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
	else
		wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;

	switch (wBitCount)
	{
		case 1:
			return 2;

		case 4:
			return 16;

		case 8:
			return 256;

		default:
			return 0;
	}
}

int WINAPI PL_DIBWidth(LPBYTE lpDIB)
{
	LPBITMAPINFOHEADER lpbmi;
	LPBITMAPCOREHEADER lpbmc;

	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lpbmc = (LPBITMAPCOREHEADER)lpDIB;

	if (IS_WIN30_DIB(lpDIB))
		return lpbmi->biWidth;
	else
		return lpbmc->bcWidth;
}

int WINAPI PL_DIBHeight(LPBYTE lpDIB)
{
	LPBITMAPINFOHEADER lpbmi;
	LPBITMAPCOREHEADER lpbmc;

	lpbmi = (LPBITMAPINFOHEADER)lpDIB;
	lpbmc = (LPBITMAPCOREHEADER)lpDIB;

	if (IS_WIN30_DIB(lpDIB))
		return lpbmi->biHeight;
	else
		return lpbmc->bcHeight;
}

int WINAPI PL_PaletteSize(LPBYTE lpbi)
{
   if(IS_WIN30_DIB(lpbi))
	  return (WORD)(::PL_ColorsNum(lpbi)*sizeof(RGBQUAD));
   else
	  return (WORD)(::PL_ColorsNum(lpbi)*sizeof(RGBTRIPLE));
}

HDIB WINAPI PL_BmpToDIB(HBITMAP hBitmap, HPALETTE hPal, int nBits)
{
    BITMAP              bm;
    BITMAPINFOHEADER    bi;
    LPBITMAPINFOHEADER  lpbi;
    DWORD               dwLen;
    HANDLE              hDIB, h;
    HDC                 hDC;
    WORD                biBits;

    if(!hBitmap)
        return NULL;

    if(!GetObject(hBitmap, sizeof(bm), (LPSTR)&bm))
        return NULL;
    if (hPal == NULL)
        hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
    biBits = bm.bmPlanes * bm.bmBitsPixel;
    if (biBits <= 1)
        biBits = 1;
    else if (biBits <= 4)
        biBits = 4;
    else if (biBits <= 8)
        biBits = 8;
    else
        biBits = 24;
	if(nBits != -1)
	{
		if(nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24)
		{
			biBits = nBits;
		}
	}
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bm.bmWidth;
    bi.biHeight = bm.bmHeight;
    bi.biPlanes = 1;
    bi.biBitCount = biBits;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;
    dwLen = bi.biSize + PL_PaletteSize((LPBYTE)&bi);

    hDC = GetDC(NULL);
    hPal = SelectPalette(hDC, hPal, FALSE);
    RealizePalette(hDC);
    hDIB = GlobalAlloc(GHND, dwLen);
    if (!hDIB)
    {
      SelectPalette(hDC, hPal, TRUE);
      RealizePalette(hDC);
      ReleaseDC(NULL, hDC);
      return NULL;
    }
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
    *lpbi = bi;
    GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, NULL, (LPBITMAPINFO)lpbi,
        DIB_RGB_COLORS);
    bi = *lpbi;
    GlobalUnlock(hDIB);

    if (bi.biSizeImage == 0)
        bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
    dwLen = bi.biSize + PL_PaletteSize((LPBYTE)&bi) + bi.biSizeImage;

    if (h = GlobalReAlloc(hDIB, dwLen, 0))
        hDIB = h;
    else
    {
        GlobalFree(hDIB);
        hDIB = NULL;
        SelectPalette(hDC, hPal, TRUE);
        RealizePalette(hDC);
        ReleaseDC(NULL, hDC);
        return NULL;
    }
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
    if (GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, (LPSTR)lpbi +
            (WORD)lpbi->biSize + PL_PaletteSize((LPBYTE)lpbi), (LPBITMAPINFO)lpbi,
            DIB_RGB_COLORS) == 0)
    {
        GlobalUnlock(hDIB);
        hDIB = NULL;
        SelectPalette(hDC, hPal, TRUE);
        RealizePalette(hDC);
        ReleaseDC(NULL, hDC);
        return NULL;
    }

    bi = *lpbi;
    GlobalUnlock(hDIB);
    SelectPalette(hDC, hPal, TRUE);
    RealizePalette(hDC);
    ReleaseDC(NULL, hDC);

    return (HDIB) hDIB;
}

BOOL WINAPI PL_CreateDIBPalette(HDIB hDIB, CPalette* pPal)
{
	LPLOGPALETTE lpPal = NULL;
	HANDLE hLogPal = NULL;
	HPALETTE hPal = NULL;
	int i;                   // loop index
	WORD wNumColors;         // number of colors in color table
	LPSTR lpbi;              // pointer to packed-DIB
	LPBITMAPINFO lpbmi;      // pointer to BITMAPINFO structure (Win3.0)
	LPBITMAPCOREINFO lpbmc;  // pointer to BITMAPCOREINFO structure (old)
	BOOL bWinStyleDIB;       // flag which signifies whether this is a Win3.0 DIB
	BOOL bResult = FALSE;
	
	if (hDIB == NULL)
		return FALSE;
	
	lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
	
	lpbmi = (LPBITMAPINFO)lpbi;
	
	lpbmc = (LPBITMAPCOREINFO)lpbi;
	
	wNumColors = ::PL_ColorsNum((LPBYTE)lpbi);
	
	if (wNumColors != 0)
	{
		hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
			+ sizeof(PALETTEENTRY) * wNumColors);
		
		if (hLogPal == 0)
		{
			::GlobalUnlock((HGLOBAL) hDIB);
			return FALSE;
		}
		
		lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal);
		
		lpPal->palVersion = PALVERSION;
		lpPal->palNumEntries = (WORD)wNumColors;
		
		bWinStyleDIB = IS_WIN30_DIB(lpbi);
		for (i = 0; i < (int)wNumColors; i++)
		{
			if (bWinStyleDIB)
			{
				lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
				lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
				lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
				lpPal->palPalEntry[i].peFlags = 0;
			}
			else
			{
				lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
				lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
				lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
				lpPal->palPalEntry[i].peFlags = 0;
			}
		}
		
		bResult = pPal->CreatePalette(lpPal);
		::GlobalUnlock((HGLOBAL) hLogPal);
		::GlobalFree((HGLOBAL) hLogPal);
	}
	
	::GlobalUnlock((HGLOBAL) hDIB);
	
	return bResult;
}

LPBYTE WINAPI PL_DIBBits(LPBYTE lpbi)
{
	return (lpbi + *(LPDWORD)lpbi + ::PL_PaletteSize(lpbi));
}

BOOL WINAPI PL_DrawDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, 
					   LPRECT lpDIBRect, CPalette* pPal)
{
	LPSTR    lpDIBHdr;
	LPSTR    lpDIBBits;
	BOOL     bSuccess = FALSE;
	HPALETTE hPal = NULL;
	HPALETTE hOldPal = NULL;
	
	if(hDIB == NULL)
		return -1;
	lpDIBHdr  = (LPSTR)::GlobalLock((HGLOBAL) hDIB);
	lpDIBBits = (LPSTR)::PL_DIBBits((LPBYTE)lpDIBHdr);
	
	if(pPal != NULL)
	{
		hPal = (HPALETTE) pPal->m_hObject;
		hOldPal = ::SelectPalette(hDC, hPal, TRUE);
	}

	if(lpDIBRect == NULL)
	{
		if(lpDCRect != NULL)
		{
			::SetStretchBltMode(hDC, COLORONCOLOR);
			
			bSuccess = ::StretchDIBits(hDC, lpDCRect->left, lpDCRect->top,
				RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), 0, 0, 
				PL_DIBWidth((LPBYTE)lpDIBHdr), PL_DIBHeight((LPBYTE)lpDIBHdr),
				lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY);
		}
		else
		{
			bSuccess = ::SetDIBitsToDevice(hDC, 0, 0,
				PL_DIBWidth((LPBYTE)lpDIBHdr), PL_DIBHeight((LPBYTE)lpDIBHdr),
				0, 0, 0, PL_DIBHeight((LPBYTE)lpDIBHdr),
				lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS);
		}
	}
	else
	{
		if(lpDCRect != NULL)
		{
			::SetStretchBltMode(hDC, COLORONCOLOR);
	
			bSuccess = ::StretchDIBits(hDC, lpDCRect->left, lpDCRect->top,
				RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect),
				lpDIBRect->left, lpDIBRect->top, 
				RECTWIDTH(lpDIBRect), RECTHEIGHT(lpDIBRect),
				lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY);

		}
		else
		{
			bSuccess = ::SetDIBitsToDevice(hDC, 0, 0,
				RECTWIDTH(lpDIBRect), RECTHEIGHT(lpDIBRect),
				0, 0, 0, RECTHEIGHT(lpDIBRect),
				lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS);

		}
	}

	::GlobalUnlock((HGLOBAL)hDIB);
	if (hOldPal != NULL)
	{
		::SelectPalette(hDC, hOldPal, TRUE);
	}
	
	return bSuccess;
}

SIZE WINAPI PL_GetScreenSize()
{
	SIZE sz;
	sz.cx = ::GetSystemMetrics(SM_CXSCREEN);
	sz.cy = ::GetSystemMetrics(SM_CYSCREEN);
	return sz;
}

void WINAPI PL_MouseMove(POINT point)
{
	::SetCursorPos(point.x, point.y);
}

void WINAPI PL_MouseLButtonDown(POINT point, BOOL bMove)
{
	if(bMove)
	{
		::PL_MouseMove(point);
	}
	::mouse_event(MOUSEEVENTF_LEFTDOWN, point.x, point.y, 0, 0);
}

void WINAPI PL_MouseLButtonUp(POINT point, BOOL bMove)
{
	if(bMove)
	{
		::PL_MouseMove(point);
	}
	::mouse_event(MOUSEEVENTF_LEFTUP, point.x, point.y, 0, 0);
}

void WINAPI PL_MouseRButtonDown(POINT point, BOOL bMove)
{
	if(bMove)
	{
		::PL_MouseMove(point);
	}
	::mouse_event(MOUSEEVENTF_RIGHTDOWN, point.x, point.y, 0, 0);
}

void WINAPI PL_MouseRButtonUp(POINT point, BOOL bMove)
{
	if(bMove)
	{
		::PL_MouseMove(point);
	}
	::mouse_event(MOUSEEVENTF_RIGHTUP, point.x, point.y, 0, 0);
}

void WINAPI PL_MouseLButtonDblClk(POINT point, BOOL bMove)
{
	if(bMove)
	{
		::PL_MouseMove(point);
	}
	::PL_MouseLButtonDown(point);
	::PL_MouseLButtonUp(point);
	::PL_MouseLButtonDown(point);
	::PL_MouseLButtonUp(point);
}

void WINAPI PL_MouseRButtonDblClk(POINT point, BOOL bMove)
{
	if(bMove)
	{
		::PL_MouseMove(point);
	}
	::PL_MouseRButtonDown(point);
	::PL_MouseRButtonUp(point);
	::PL_MouseRButtonDown(point);
	::PL_MouseRButtonUp(point);
}

void WINAPI PL_KeyDown(UINT uChar, UINT uFlag)
{
	::keybd_event((BYTE)uChar, (BYTE)uChar, 0, 0);
}

void WINAPI PL_KeyUp(UINT uChar, UINT uFlag)
{
	::keybd_event((BYTE)uChar, (BYTE)uChar, KEYEVENTF_KEYUP, 0);
}

BOOL WINAPI PL_GetHostName(char *chIP, char *chName)
{
	BOOL bRet = FALSE;
	char chTemp[256];
	hostent* pEnt = NULL;
	ZeroMemory(chTemp, 256);
	int nRet = ::gethostname(chTemp, 256);
	if(nRet == 0)
	{
		if(AfxIsValidAddress(chName, strlen(chTemp)))
		{
			strcpy(chName, chTemp);
			bRet = TRUE;
		}
		if(AfxIsValidAddress(chIP, 16))
		{
			pEnt = ::gethostbyname(chTemp);
			if(pEnt)
			{
				sprintf(chIP, "%d.%d.%d.%d", 
					BYTE(pEnt->h_addr_list[0][0]), BYTE(pEnt->h_addr_list[0][1]),
					BYTE(pEnt->h_addr_list[0][2]), BYTE(pEnt->h_addr_list[0][3]));
				bRet = TRUE;
			}
			else
			{
				bRet = FALSE;
			}
		}
	}
	return bRet;
}

int WINAPI PL_ExecuteCommand(char *chCommandLine)
{
	return ::WinExec(chCommandLine, SW_NORMAL);
}

void WINAPI PL_LockDesktop(BOOL bLock)
{
	::ShowCursor(!bLock);
	::SystemParametersInfo(SPI_SETFASTTASKSWITCH, (int)(!bLock), NULL, 0);
	::SystemParametersInfo(SPI_SCREENSAVERRUNNING, (int)bLock, NULL, 0);
	::EnableWindow(::GetDesktopWindow(), !bLock);
}

BOOL WINAPI PL_ExitWindow(UINT uFlag)
{
	HANDLE hToken = NULL;
	TOKEN_PRIVILEGES tkp;
	BOOL fResult = FALSE;
	if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
	{
		if(LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid))
		{
			tkp.PrivilegeCount = 1;
			tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
			if(AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0))
			{
				return ::ExitWindowsEx(uFlag, 0);
			}
		}
	}
	
	return ::ExitWindowsEx(uFlag, 0);
}

void WINAPI PL_Send_CtrlAltDel()
{
	::PL_KeyDown(VK_CONTROL, 0);
	::PL_KeyDown(VK_MENU, 0);
	::PL_KeyDown(VK_DELETE, 0);
	::Sleep(2000);
	::PL_KeyUp(VK_CONTROL, 0);
	::PL_KeyUp(VK_MENU, 0);
	::PL_KeyUp(VK_DELETE, 0);
}

BOOL WINAPI PL_CopyFileClient(CString strIP, UINT uPort, char *chSrc, 
							  BOOL bSend, HWND hNotifyWnd)
{
	BOOL bRet = FALSE;
	CSocket sckClient;
	CFile file;
	do
	{
		if(bSend)
		{
			bRet = file.Open(chSrc, CFile::modeRead);
		}
		else
		{
			bRet = file.Open(chSrc, CFile::modeCreate | CFile::modeWrite);
		}
		if(!bRet)
		{
			break ;
		}
		bRet = sckClient.Create();
		if(!bRet)
		{
			break ;
		}
		bRet = sckClient.Connect(strIP, uPort);
		if(!bRet)
		{
			break ;
		}
		BYTE *chFileData = new BYTE[PL_SOCKET_MAXBYTES+1];
		char chData[10];
		int nSize = 0;
		if(bSend)
		{
			nSize = file.GetLength();
			int nRead = nSize;
			ZeroMemory(chData, 10);
			memcpy(chData, &nSize, sizeof(int));
			int nRet = sckClient.Send(chData, sizeof(int));
			if(nRet <= 0)
			{
				bRet = FALSE;
				break ;
			}
			while(nRead > 0)
			{
				int n1 = min(nRead, PL_SOCKET_MAXBYTES);
				int n2 = file.Read(chFileData, n1);
				nRead -= n2;
				nRet = sckClient.Send(chFileData, n2);
				if(nRet <= 0)
				{
					bRet = FALSE;
					break ;
				}
				if(hNotifyWnd != NULL)
				{
					int nProgress = (int)(((float)(nSize - nRead))*100.0f/((float)nSize));
					::PostMessage(hNotifyWnd, PL_PEEPER_NOTIFY_COPYFILE, 
						(WPARAM)nProgress, NULL);
				}
				bRet = TRUE;
			}
		}
		else
		{
			char chData[10];
			ZeroMemory(chData, 10);
			nSize = 0;
			int nRet = sckClient.Receive(chData, 10);//读文件大小
			if(nRet <= 0)
			{
				bRet = FALSE;
				break ;
			}
			nSize = *((int*)(chData));
			if(nSize <= 0)
			{
				bRet = FALSE;
				break ;
			}
			BYTE *chFileData = new BYTE[PL_SOCKET_MAXBYTES+1];
			int nWrite = 0;
			while(nWrite < nSize)
			{
				nRet = sckClient.Receive(chFileData, PL_SOCKET_MAXBYTES);
				if(nRet <= 0)
				{
					bRet = FALSE;
					break ;
				}
				file.Write(chFileData, nRet);
				nWrite += nRet;
				if(hNotifyWnd != NULL)
				{
					int nProgress = (int)(((float)nWrite)*100.0f/((float)nSize));
					::PostMessage(hNotifyWnd, PL_PEEPER_NOTIFY_COPYFILE, 
						(WPARAM)nProgress, NULL);
				}
				bRet = TRUE;
			}
		}
		delete []chFileData;
		if(!bRet) // 送文件数据出错.
		{
			break ;
		}
	}while(0);
	if(sckClient.m_hSocket !=	INVALID_SOCKET)
	{
		sckClient.Close();
	}
	if(file.m_hFile != CFile::hFileNull)
	{
		file.Close();
	}

	return bRet;
}

BOOL WINAPI PL_CopyFileServer(UINT uPort, char *chDes, BOOL bSend, HWND hNotifyWnd)
{
	BOOL bRet = FALSE;
	CFile file;
	CSocket sckServer;
	CSocket sckClient;
	do
	{
		if(!bSend)
		{
			bRet = file.Open(chDes, CFile::modeCreate | CFile::modeWrite);
		}
		else
		{
			bRet = file.Open(chDes, CFile::modeRead);
		}
		if(!bRet)
		{
			break ;
		}
		bRet = sckServer.Create(uPort);
		if(!bRet)
		{
			break ;
		}
		bRet = sckServer.Listen();
		if(!bRet)
		{
			break ;
		}
		bRet = sckServer.Accept(sckClient);
		if(!bRet)
		{
			break ;
		}
		char chData[10];
		BYTE *chFileData = new BYTE[PL_SOCKET_MAXBYTES+1];
		int nSize = 0;
		if(!bSend)
		{
			ZeroMemory(chData, 10);
			int nRet = sckClient.Receive(chData, 10);//读文件大小
			if(nRet <= 0)
			{
				bRet = FALSE;
				break ;
			}
			nSize = *((int*)(chData));
			if(nSize <= 0)
			{
				bRet = FALSE;
				break ;
			}
			int nWrite = 0;
			while(nWrite < nSize)
			{
				nRet = sckClient.Receive(chFileData, PL_SOCKET_MAXBYTES);
				if(nRet <= 0)
				{
					bRet = FALSE;
					break ;
				}
				file.Write(chFileData, nRet);
				nWrite += nRet;
				if(hNotifyWnd != NULL)
				{
					int nProgress = (int)(((float)nWrite)*100.0f/((float)nSize));
					::PostMessage(hNotifyWnd, PL_PEEPER_NOTIFY_COPYFILE, 
						(WPARAM)nProgress, NULL);
				}
				bRet = TRUE;
			}
		}
		else
		{
			nSize = file.GetLength();
			int nRead = nSize;
			ZeroMemory(chData, 10);
			memcpy(chData, &nSize, sizeof(int));
			int nRet = sckClient.Send(chData, sizeof(int));
			if(nRet <= 0)
			{
				bRet = FALSE;
				break ;
			}
			while(nRead > 0)
			{
				int n1 = min(nRead, PL_SOCKET_MAXBYTES);
				int n2 = file.Read(chFileData, n1);
				nRead -= n2;
				nRet = sckClient.Send(chFileData, n2);
				if(nRet <= 0)
				{
					bRet = FALSE;
					break ;
				}
				if(hNotifyWnd != NULL)
				{
					int nProgress = (int)(((float)(nSize - nRead))*100.0f/((float)nSize));
					::PostMessage(hNotifyWnd, PL_PEEPER_NOTIFY_COPYFILE, 
						(WPARAM)nProgress, NULL);
				}
				bRet = TRUE;
			}
		}
		delete []chFileData;
	}while(0);
	if(sckClient.m_hSocket != INVALID_SOCKET)
	{
		sckClient.Close();
	}
	if(sckServer.m_hSocket != INVALID_SOCKET)
	{
		sckServer.Close();
	}
	if(file.m_hFile != CFile::hFileNull)
	{
		file.Close();
	}

	return bRet;
}

BOOL WINAPI PL_DeleteFile(char *chFileName)
{
	BOOL bRet = FALSE;
	DWORD dwFlag = ::SetFileAttributes(chFileName, FILE_ATTRIBUTE_NORMAL);
	if(dwFlag != 0xFFFFFFFF)
	{
		bRet = ::DeleteFile(chFileName);
	}

	return bRet;
}

BOOL WINAPI PL_MoveFile(char *chSrcFileName, char *chDesFileName)
{
	BOOL bRet = FALSE;
	DWORD dwFlag = ::SetFileAttributes(chSrcFileName, FILE_ATTRIBUTE_NORMAL);
	if(dwFlag != 0xFFFFFFFF)
	{
		bRet = ::MoveFile(chSrcFileName, chDesFileName);
	}

	return bRet;
}

BOOL WINAPI PL_SendMail(CString strSMTP, CString strFrom, 
						CString strTo, CString strSubject, CString strBody)
{
	BOOL bRet = FALSE;
	CSocket sckSmtp;
	if(sckSmtp.Create())
	{
		char chMonth[][12] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", 
			"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
		SYSTEMTIME sm;
		::GetLocalTime(&sm);
		CString strDate;
		//                  日  月  年    时  分  秒  
		strDate.Format(_T("%02d %s %02d %02d:%02d:%02d"), 
			sm.wDay, chMonth[sm.wMonth-1], sm.wYear%100, 
			sm.wHour, sm.wMinute, sm.wSecond);
		char chTemp[1024];

		int nRet = -1;
		if(sckSmtp.Connect(strSMTP, 25))
		{
			do
			{
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//欢迎用户
				
				TCHAR local_host[80];
				ZeroMemory(local_host, 80*sizeof(TCHAR));
				::gethostname(local_host, 80);
				CString strUser = CString(local_host);

				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "HELO %s\r\n", strUser);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//mail from
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "MAIL FROM: <%s>\r\n", strFrom);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//rcpt to
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "RCPT TO: <%s>\r\n", strTo);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//Data
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "DATA\r\n");
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//信件内容
				//时间
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "Date: %s\r\n", strDate);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//From
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "From:%s\r\n", strFrom);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//To
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "To:%s\r\n", strTo);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//CC
				//			ZeroMemory(chTemp, 1024);
				//			sprintf(chTemp, "CC:%s\r\n", strCC);
				//			sckSmtp.Send(chTemp, strlen(chTemp));
				//Subject
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "Subject:%s\r\n", strSubject);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//内容
				int nLen = strBody.GetLength() + 5;
				char *chBody = new char[nLen];
				ZeroMemory(chBody, nLen);
				sprintf(chBody, "%s\r\n", strBody);
				nRet = sckSmtp.Send(chBody, strlen(chBody));
				delete []chBody;
				if(nRet < 0)
					break ;
				//结束
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, ".\r\n");
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//退出
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "QUIT\r\n");
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				bRet = TRUE;
			}while(0);
		}
		sckSmtp.Close();
	}

	return bRet;
}

BOOL WINAPI PL_SendMail2(CString strSMTP, CString strFrom, CString strAuth, 
							  CString strPass, CString strTo, CString strSubject, 
							  CString strBody)
{
	BOOL bRet = FALSE;
	CSocket sckSmtp;
	if(sckSmtp.Create())
	{
		char chMonth[][12] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", 
			"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
		SYSTEMTIME sm;
		::GetLocalTime(&sm);
		CString strDate;
		//                  日  月  年    时  分  秒  
		strDate.Format(_T("%02d %s %02d %02d:%02d:%02d"), 
			sm.wDay, chMonth[sm.wMonth-1], sm.wYear%100, 
			sm.wHour, sm.wMinute, sm.wSecond);
		char chTemp[1024];

		int nRet = -1;
		if(sckSmtp.Connect(strSMTP, 25))
		{
			do
			{
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "334", 3) != 0 &&
				   strncmp(chTemp, "235", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//欢迎用户
				
				char local_host[80];
				ZeroMemory(local_host, 80);
				DWORD dwLen = 80;
				GetUserName(local_host, &dwLen);

				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "EHLO %s\r\n", local_host);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "334", 3) != 0 &&
				   strncmp(chTemp, "235", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				// auto login
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "AUTH LOGIN\r\n");
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "334", 3) != 0 &&
				   strncmp(chTemp, "235", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				// verify user(Base64)
				CBase64 cb;
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "%s\r\n", cb.Encode(strAuth.GetBuffer(0), strAuth.GetLength()));
				strAuth.ReleaseBuffer();
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;

				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "334", 3) != 0 &&
				   strncmp(chTemp, "235", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				// verify password
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "%s\r\n", cb.Encode(strPass.GetBuffer(0), strPass.GetLength()));
				strPass.ReleaseBuffer();
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;

				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "334", 3) != 0 &&
				   strncmp(chTemp, "235", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;

				//mail from
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "MAIL FROM: <%s>\r\n", strFrom);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "334", 3) != 0 &&
				   strncmp(chTemp, "235", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//rcpt to
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "RCPT TO: <%s>\r\n", strTo);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "334", 3) != 0 &&
				   strncmp(chTemp, "235", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//Data
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "DATA\r\n");
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "334", 3) != 0 &&
				   strncmp(chTemp, "235", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//信件内容
				//时间
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "Date: %s\r\n", strDate);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//From
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "From:%s\r\n", strFrom);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//To
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "To:%s\r\n", strTo);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//CC
				//			ZeroMemory(chTemp, 1024);
				//			sprintf(chTemp, "CC:%s\r\n", strCC);
				//			sckSmtp.Send(chTemp, strlen(chTemp));
				//Subject
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "Subject:%s\r\n", strSubject);
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//内容
				int nLen = strBody.GetLength() + 5;
				char *chBody = new char[nLen];
				ZeroMemory(chBody, nLen);
				sprintf(chBody, "%s\r\n", strBody);
				nRet = sckSmtp.Send(chBody, strlen(chBody));
				delete []chBody;
				if(nRet < 0)
					break ;
				//结束
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, ".\r\n");
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				//接收信息
				ZeroMemory(chTemp, 1024);
				nRet = sckSmtp.Receive(chTemp, 1024);
				if(nRet < 0)
					break ;
				if(strncmp(chTemp, "220", 3) != 0 &&
				   strncmp(chTemp, "250", 3) != 0 &&
				   strncmp(chTemp, "334", 3) != 0 &&
				   strncmp(chTemp, "235", 3) != 0 &&
				   strncmp(chTemp, "354", 3) != 0 &&
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功
					break ;
				//退出
				ZeroMemory(chTemp, 1024);
				sprintf(chTemp, "QUIT\r\n");
				nRet = sckSmtp.Send(chTemp, strlen(chTemp));
				if(nRet < 0)
					break ;
				bRet = TRUE;
			}while(0);
		}
		sckSmtp.Close();
	}

	return bRet;
}

BOOL WINAPI PL_DetectInternetConnect(CString strHTTP)
{
	BOOL bRet = FALSE;
	HINTERNET hSession = NULL;
	hSession = ::InternetOpen(_T("peeper"), PRE_CONFIG_INTERNET_ACCESS, NULL, NULL, 0);
	if(hSession)
	{
		HINTERNET hHTTPSession = ::InternetOpenUrl(hSession,
			strHTTP, NULL, 0, INTERNET_FLAG_RELOAD, 0);
		if(hHTTPSession)
		{
			bRet = TRUE;
			::InternetCloseHandle(hHTTPSession);
		}
		::InternetCloseHandle(hSession);
	}
	return bRet;
}

HGLOBAL WINAPI PL_ReadDataFromFile(CString strFile)
{
	HGLOBAL hData = NULL;
	CFile file;
	if(file.Open(strFile, CFile::modeRead))
	{
		int nLen = file.GetLength();
		hData = ::GlobalAlloc(GHND, nLen);
		if(hData != NULL)
		{
			LPVOID lpData = ::GlobalLock(hData);
			file.ReadHuge(lpData, nLen);
			GlobalUnlock(hData);
		}
		file.Close();
	}
	return hData;
}

BOOL WINAPI PL_WriteDataToFile(CString strFile, HGLOBAL hData)
{
	BOOL bRet = FALSE;
	CFile file;
	if(file.Open(strFile, CFile::modeCreate | CFile::modeWrite))
	{
		if(hData != NULL)
		{
			int nLen = ::GlobalSize(hData);
			LPVOID lpData = ::GlobalLock(hData);
			file.WriteHuge(lpData, nLen);
			GlobalUnlock(hData);
			bRet = TRUE;
		}
		file.Close();
	}
	return bRet;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值