2009年12月30日 星期三

CuSocket - create an endpoint for communication

// create an endpoint for communication

CuSocket ClientSocket;
ClientSocket.Socket();
ClientSocket.Connect(lpszHostAddress, nHostPort);


// CuSocket.h


class CuSocket
{
private:
    SOCKET m_hSocket;
public:
    CuSocket(void);
public:
    ~CuSocket(void);

    SOCKET Socket(int nSocketType = SOCK_STREAM);
    int Close(void);

    //enum { SD_SEND = 0, SD_RECEIVE = 1,  SD_BOTH = 2};
    int ShutDown(int nHow = SD_BOTH);

    int Bind(UINT nSocketPort);
    int Listen( int nConnectionBacklog = 5 );
    SOCKET Accept( SOCKADDR *lpSockAddr, int *lpAddrLen );

    int Connect( LPCSTR lpszHostAddress, UINT nHostPort);

    int Receive(void *lpBuf, int nBufLen, int nFlags);
    int Send(const void *lpBuf, int nBufLen, int nFlags);

    BOOL Attach(SOCKET hSocket);
    operator SOCKET() const;
    CuSocket &operator =(CuSocket &socket);

};




// CuSocket.cpp


CuSocket::CuSocket(void)
:m_hSocket(NULL)
{
}

CuSocket::~CuSocket(void)
{
    if( m_hSocket != NULL )
    {
        Close();
    }
}

SOCKET CuSocket::Socket(int nSocketType /* = SOCK_STREAM */ )
{
    this->Close();
    m_hSocket = socket(AF_INET, nSocketType, IPPROTO_TCP);
    return m_hSocket;
}

BOOL CuSocket::Attach(SOCKET hSocket)
{
    this->Close();
    m_hSocket = hSocket;
    return (m_hSocket != NULL);
}

int CuSocket::Close(void)
{
    int error = 0;
    if( m_hSocket != NULL )
    {
        this->ShutDown();
        error = closesocket(m_hSocket);
        m_hSocket = NULL;
    }
    return error;
}

int CuSocket::Bind(UINT nSocketPort)
{
    SOCKADDR_IN SockAddr;
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    SockAddr.sin_port = htons(nSocketPort);

    int error = bind( m_hSocket, (PSOCKADDR)&SockAddr, sizeof(SockAddr) );
    return error;
}

int CuSocket::ShutDown(int nHow /* = SD_BOTH */ )
{
    int error = shutdown( m_hSocket, nHow );
    return error;
}

int CuSocket::Listen( int nConnectionBacklog /* = 5 */ )
{
    int error = listen(m_hSocket, nConnectionBacklog);
    return error;
}

SOCKET CuSocket::Accept( SOCKADDR *lpSockAddr, int *lpAddrLen )
{
    SOCKET hSocket = NULL;
    hSocket = accept( m_hSocket, lpSockAddr, lpAddrLen );
    return hSocket;
}

int CuSocket::Connect( LPCSTR lpszHostAddress, UINT nHostPort)
{
    SOCKADDR_IN ServerAddr;
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons(nHostPort);
    ServerAddr.sin_addr.s_addr = inet_addr( lpszHostAddress );

    int error = connect(m_hSocket, (PSOCKADDR)&ServerAddr, sizeof(ServerAddr));
    return error;
}

CuSocket::operator SOCKET() const
{
    return m_hSocket;
}

CuSocket& CuSocket::operator =(CuSocket &socket)
{
    m_hSocket = socket.m_hSocket;
    return *this;
}

int CuSocket::Receive(void *lpBuf, int nBufLen, int nFlags)
{
    return recv( m_hSocket, static_cast<char *>(lpBuf), nBufLen, nFlags );
}

int CuSocket::Send(const void *lpBuf, int nBufLen, int nFlags)
{
    return send( m_hSocket, static_cast<const char*>(lpBuf), nBufLen, nFlags );
}

CuKeyNameText - retrieves a string that represents the name of a key

// retrieves a string that represents the name of a key

CuKeyNameText KeyNameBySet;
KeyNameBySet.SetScanCode(dwScanCode);
wstring strKeyTextBySet = KeyNameBySet;

CuKeyNameText KeyName(dwScanCode);
wstring strKeyText = KeyName;


// CuKeyNameText.h

class CuKeyNameText
{
    wstring m_strKeyText;
public:
    CuKeyNameText(){};
    CuKeyNameText(DWORD dwScanCode);
    ~CuKeyNameText(){};

    void SetScanCode(DWORD dwScanCode);
    operator wstring() const;
};



// CuKeyNameText.cpp

CuKeyNameText::CuKeyNameText(DWORD dwScanCode)
{
    SetScanCode(dwScanCode);
}

void CuKeyNameText::SetScanCode(DWORD dwScanCode)
{
    LONG lKeyParam = ( dwScanCode << 16 );
    TCHAR szKeyName[16] = L"";
    ::GetKeyNameText(lKeyParam, szKeyName, sizeof(szKeyName));
    m_strKeyText = szKeyName;
}

CuKeyNameText::operator wstring() const
{
    return m_strKeyText;
}


2009年12月29日 星期二

CuDrawText - draws formatted text in the specified rectangle.

//  draws formatted text in the specified rectangle.

CuDrawText textTest;

...

CuRect rt;
GetClientRect(hWnd, &rt);
textTest.SetRect(&rt);

...

textTest.SetText(TEXT("Hi") );

...

CuPaintDC dc(hWnd);
textTest.OnDraw(dc);


// CuDrawText.h

class CuDrawText
{
    CuRect m_rt;
    wstring m_strText;
    UINT m_uFormat;

public:
    CuDrawText(void);
    ~CuDrawText(void);

    void SetRect(  int xLeft,  int yTop,  int xRight,  int yBottom);
    void SetRect( RECT *rt );
    void SetText(LPCTSTR lpszString);
    void SetFormat(UINT uFormat);

    int OnDraw(HDC hdc);
};




// CuDrawText.cpp


CuDrawText::CuDrawText(void)
:m_uFormat(DT_LEFT)
{
}

CuDrawText::~CuDrawText(void)
{
}

void CuDrawText::SetRect(  int xLeft,  int yTop,  int xRight,  int yBottom)
{
    m_rt.SetRect(xLeft, yTop, xRight, yBottom);
}

void CuDrawText::SetRect( RECT *rt )
{
    m_rt = *rt;
}

void CuDrawText::SetText(LPCTSTR lpszString)
{
    m_strText = lpszString;
}

void CuDrawText::SetFormat(UINT uFormat)
{
    m_uFormat = uFormat;
}

int CuDrawText::OnDraw(HDC hdc)
{
    return ::DrawText(hdc, m_strText.c_str(), m_strText.size(), &m_rt, m_uFormat);
}

2009年12月28日 星期一

CuPort - Opens I/O device.

// Opens I/O device.
class CuDevice : public CuPort
{
public:
    CuDevice();
    virtual ~CuDevice();
    virtual void OnRead(BYTE *pByte, int nSize);

};


CuDevice g_device;
DCB g_dcb;

g_device.Open(L"COM2:");
g_device.SetupComm(1024 * 1024 * 2, 2 * 1024);
g_device.GetCommState(&g_dcb);
....
g_device.SetCommState (&g_dcb);

COMMTIMEOUTS CommTimeouts;
g_device.GetCommTimeouts ( &CommTimeouts);
....
g_device.SetCommTimeouts ( &CommTimeouts);
g_device.StardReadThread();


// CuPort.h

class CuPort  
{
    CuWinThread *m_pReadThread;
    
    HANDLE m_hFile;

    int m_nReadBufferSize;
    BYTE *m_pReadBuffer;

public:

    BOOL ClearCommError(LPDWORD lpErrors, LPCOMSTAT lpStat);
    BOOL SetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts);
    BOOL GetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts);
    BOOL GetCommState(LPDCB lpDCB);
    BOOL SetupComm(DWORD dwInQueue, DWORD dwOutQueue);
    BOOL SetCommState(LPDCB lpDCB);
    BOOL Open(LPCTSTR szComPort);
    BOOL Close(void);

    CuPort();
    virtual ~CuPort();
    virtual void OnRead(BYTE *pByte, int nSize){};
    virtual void OnWrite(BYTE *pByte, int nSize);

    BOOL StardReadThread();
    static DWORD ProcessReadThread(LPVOID lpVoid);

private:
    void ResizeReadBuffer();

};



// CuPort.cpp

CuPort::CuPort():
m_hFile(INVALID_HANDLE_VALUE)
,m_pReadThread(NULL)
,m_nReadBufferSize(1024)
,m_pReadBuffer(NULL)
{
    ResizeReadBuffer();
}

CuPort::~CuPort()
{
    delete [] m_pReadBuffer;
    Close();
}

BOOL CuPort::Close()
{

    BOOL bResult = FALSE;
    if( m_hFile != INVALID_HANDLE_VALUE )
        bResult = ::CloseHandle (m_hFile);
    m_hFile = INVALID_HANDLE_VALUE;

    if( m_pReadThread )
    {
        m_pReadThread->SuspendThread();
        m_pReadThread->Delete();
    }
    m_pReadThread = NULL;

    return bResult;

}

BOOL CuPort::Open(LPCTSTR szComPort)
{

    Close();

    m_hFile = ::CreateFile(szComPort, GENERIC_READ | GENERIC_WRITE,0, NULL, OPEN_EXISTING, 0, NULL);
    
    return m_hFile == INVALID_HANDLE_VALUE ? FALSE : TRUE;
}

BOOL CuPort::SetCommState(LPDCB lpDCB)
{
    return ::SetCommState( m_hFile, lpDCB); 
}

BOOL CuPort::SetupComm(DWORD dwInQueue, DWORD dwOutQueue)
{
    return ::SetupComm( m_hFile, dwInQueue, dwOutQueue); 
}

BOOL CuPort::GetCommState(LPDCB lpDCB)
{
    return ::GetCommState (m_hFile, lpDCB);
}

BOOL CuPort::GetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts)
{
    return ::GetCommTimeouts(m_hFile, lpCommTimeouts);
}

BOOL CuPort::SetCommTimeouts(LPCOMMTIMEOUTS lpCommTimeouts)
{
    return ::SetCommTimeouts(m_hFile, lpCommTimeouts);
}

BOOL CuPort::ClearCommError(LPDWORD lpErrors, LPCOMSTAT lpStat)
{
    return ::ClearCommError(m_hFile, lpErrors, lpStat );
}

BOOL CuPort::StardReadThread()
{
    m_pReadThread = _BeginThread((_THREADPROC)CuPort::ProcessReadThread, (LPVOID)this);
    return m_pReadThread == NULL ? FALSE : TRUE;
}

void CuPort::OnWrite(BYTE *pByte, int nSize)
{

    if( m_hFile == INVALID_HANDLE_VALUE )
        return;

    DWORD dBytes = 0;

    BYTE *pByteIndex = pByte;

    while( nSize )
    {
        ::WriteFile(m_hFile, pByteIndex, nSize, &dBytes, 0);
        Sleep(1);
        pByteIndex += dBytes;
        nSize -= dBytes;
    }

}

DWORD CuPort::ProcessReadThread(LPVOID lpVoid)
{
    CuPort *pPort = static_cast<CuPort*>(lpVoid);

    static DWORD Errors;
    static COMSTAT ComStat;//COMSTAT;
    static DWORD dBytes = 0;

    while(1)
    {
        do
        {
            Sleep(1);
            ::ReadFile(pPort->m_hFile, pPort->m_pReadBuffer, pPort->m_nReadBufferSize, &dBytes , 0);
        }while( !dBytes );

        // 如果讀的跟預備的BUFFER 一樣大
        // 就把BUFFER 再加大一倍

        pPort->OnRead(pPort->m_pReadBuffer, dBytes );

        if( dBytes ==  pPort->m_nReadBufferSize )
            pPort->ResizeReadBuffer();
    }

    return 0;
}


void CuPort::ResizeReadBuffer()
{
    delete [] m_pReadBuffer;
    m_nReadBufferSize *= 2;
    m_pReadBuffer = new BYTE[m_nReadBufferSize];
}


2009年12月27日 星期日

CuRect - Similar to a Windows RECT structure.

// Similar to a Windows RECT structure. 

CuRect rt;
GetClientRect(hWnd, &rt);

// CuRect.h

class CuRect : public tagRECT
{
    // Constructors
public:
    // uninitialized rectangle
    CuRect() throw();
    // from left, top, right, and bottom
    CuRect(int l, int t, int r, int b) throw();
    // copy constructor
    CuRect(const RECT& srcRect) throw();
    // from a pointer to another rect
    CuRect(LPCRECT lpSrcRect) throw();
    // from a point and size
    CuRect(POINT point, SIZE size) throw();
    // from two points
    CuRect(POINT topLeft, POINT bottomRight) throw();

    // Attributes (in addition to RECT members)

    // retrieves the width
    int Width() const throw();
    // returns the height
    int Height() const throw();
    // returns the size
    CuSize Size() const throw();
    // reference to the top-left point
    CuPoint& TopLeft() throw();
    // reference to the bottom-right point
    CuPoint& BottomRight() throw();
    // const reference to the top-left point
    const CuPoint& TopLeft() const throw();
    // const reference to the bottom-right point
    const CuPoint& BottomRight() const throw();
    // the geometric center point of the rectangle
    CuPoint CenterPoint() const throw();
    // swap the left and right
    void SwapLeftRight() throw();
    static void WINAPI SwapLeftRight(LPRECT lpRect) throw();

    // convert between CuRect and LPRECT/LPCRECT (no need for &)
    operator LPRECT() throw();
    operator LPCRECT() const throw();

    // returns TRUE if rectangle has no area
    BOOL IsRectEmpty() const throw();
    // returns TRUE if rectangle is at (0,0) and has no area
    BOOL IsRectNull() const throw();
    // returns TRUE if point is within rectangle
    BOOL PtInRect(POINT point) const throw();

    // Operations

    // set rectangle from left, top, right, and bottom
    void SetRect(int x1, int y1, int x2, int y2) throw();
    void SetRect(POINT topLeft, POINT bottomRight) throw();
    // empty the rectangle
    void SetRectEmpty() throw();
    // copy from another rectangle
    void CopyRect(LPCRECT lpSrcRect) throw();
    // TRUE if exactly the same as another rectangle
    BOOL EqualRect(LPCRECT lpRect) const throw();

    // Inflate rectangle's width and height by
    // x units to the left and right ends of the rectangle
    // and y units to the top and bottom.
    void InflateRect(int x, int y) throw();
    // Inflate rectangle's width and height by
    // size.cx units to the left and right ends of the rectangle
    // and size.cy units to the top and bottom.
    void InflateRect(SIZE size) throw();
    // Inflate rectangle's width and height by moving individual sides.
    // Left side is moved to the left, right side is moved to the right,
    // top is moved up and bottom is moved down.
    void InflateRect(LPCRECT lpRect) throw();
    void InflateRect(int l, int t, int r, int b) throw();

    // deflate the rectangle's width and height without
    // moving its top or left
    void DeflateRect(int x, int y) throw();
    void DeflateRect(SIZE size) throw();
    void DeflateRect(LPCRECT lpRect) throw();
    void DeflateRect(int l, int t, int r, int b) throw();

    // translate the rectangle by moving its top and left
    void OffsetRect(int x, int y) throw();
    void OffsetRect(SIZE size) throw();
    void OffsetRect(POINT point) throw();
    void NormalizeRect() throw();

    // absolute position of rectangle
    void MoveToY(int y) throw();
    void MoveToX(int x) throw();
    void MoveToXY(int x, int y) throw();
    void MoveToXY(POINT point) throw();

    // set this rectangle to intersection of two others
    BOOL IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2) throw();

    // set this rectangle to bounding union of two others
    BOOL UnionRect(LPCRECT lpRect1, LPCRECT lpRect2) throw();

    // set this rectangle to minimum of two others
    BOOL SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2) throw();

    // Additional Operations
    void operator=(const RECT& srcRect) throw();
    BOOL operator==(const RECT& rect) const throw();
    BOOL operator!=(const RECT& rect) const throw();
    void operator+=(POINT point) throw();
    void operator+=(SIZE size) throw();
    void operator+=(LPCRECT lpRect) throw();
    void operator-=(POINT point) throw();
    void operator-=(SIZE size) throw();
    void operator-=(LPCRECT lpRect) throw();
    void operator&=(const RECT& rect) throw();
    void operator|=(const RECT& rect) throw();

    // Operators returning CuRect values
    CuRect operator+(POINT point) const throw();
    CuRect operator-(POINT point) const throw();
    CuRect operator+(LPCRECT lpRect) const throw();
    CuRect operator+(SIZE size) const throw();
    CuRect operator-(SIZE size) const throw();
    CuRect operator-(LPCRECT lpRect) const throw();
    CuRect operator&(const RECT& rect2) const throw();
    CuRect operator|(const RECT& rect2) const throw();
    //  CuRect MulDiv(int nMultiplier, int nDivisor) const throw();
};


inline CuRect::CuRect()
{ /* random filled */ }
inline CuRect::CuRect(int l, int t, int r, int b)
{ left = l; top = t; right = r; bottom = b; }
inline CuRect::CuRect(const RECT& srcRect)
{ ::CopyRect(this, &srcRect); }
inline CuRect::CuRect(LPCRECT lpSrcRect)
{ ::CopyRect(this, lpSrcRect); }
inline CuRect::CuRect(POINT point, SIZE size)
{ right = (left = point.x) + size.cx; bottom = (top = point.y) + size.cy; }
inline CuRect::CuRect(POINT topLeft, POINT bottomRight)
{ left = topLeft.x; top = topLeft.y;
right = bottomRight.x; bottom = bottomRight.y; }
inline int CuRect::Width() const
{ return right - left; }
inline int CuRect::Height() const
{ return bottom - top; }
inline CuSize CuRect::Size() const
{ return CuSize(right - left, bottom - top); }
inline CuPoint& CuRect::TopLeft()
{ return *((CuPoint*)this); }
inline CuPoint& CuRect::BottomRight()
{ return *((CuPoint*)this+1); }
inline const CuPoint& CuRect::TopLeft() const
{ return *((CuPoint*)this); }
inline const CuPoint& CuRect::BottomRight() const
{ return *((CuPoint*)this+1); }
inline CuPoint CuRect::CenterPoint() const
{ return CuPoint((left+right)/2, (top+bottom)/2); }
inline void CuRect::SwapLeftRight()
{ SwapLeftRight(LPRECT(this)); }
inline void WINAPI CuRect::SwapLeftRight(LPRECT lpRect)
{ LONG temp = lpRect->left; lpRect->left = lpRect->right; lpRect->right = temp; }
inline CuRect::operator LPRECT()
{ return this; }
inline CuRect::operator LPCRECT() const
{ return this; }
inline BOOL CuRect::IsRectEmpty() const
{ return ::IsRectEmpty(this); }
inline BOOL CuRect::IsRectNull() const
{ return (left == 0 && right == 0 && top == 0 && bottom == 0); }
inline BOOL CuRect::PtInRect(POINT point) const
{ return ::PtInRect(this, point); }
inline void CuRect::SetRect(int x1, int y1, int x2, int y2)
{ ::SetRect(this, x1, y1, x2, y2); }
inline void CuRect::SetRect(POINT topLeft, POINT bottomRight)
{ ::SetRect(this, topLeft.x, topLeft.y, bottomRight.x, bottomRight.y); }
inline void CuRect::SetRectEmpty()
{ ::SetRectEmpty(this); }
inline void CuRect::CopyRect(LPCRECT lpSrcRect)
{ ::CopyRect(this, lpSrcRect); }
inline BOOL CuRect::EqualRect(LPCRECT lpRect) const
{ return ::EqualRect(this, lpRect); }
inline void CuRect::InflateRect(int x, int y)
{ ::InflateRect(this, x, y); }
inline void CuRect::InflateRect(SIZE size)
{ ::InflateRect(this, size.cx, size.cy); }
inline void CuRect::DeflateRect(int x, int y)
{ ::InflateRect(this, -x, -y); }
inline void CuRect::DeflateRect(SIZE size)
{ ::InflateRect(this, -size.cx, -size.cy); }
inline void CuRect::OffsetRect(int x, int y)
{ ::OffsetRect(this, x, y); }
inline void CuRect::OffsetRect(POINT point)
{ ::OffsetRect(this, point.x, point.y); }
inline void CuRect::OffsetRect(SIZE size)
{ ::OffsetRect(this, size.cx, size.cy); }
inline void CuRect::MoveToY(int y)
{ bottom = Height() + y; top = y; }
inline void CuRect::MoveToX(int x)
{ right = Width() + x; left = x; }
inline void CuRect::MoveToXY(int x, int y)
{ MoveToX(x); MoveToY(y); }
inline void CuRect::MoveToXY(POINT pt)
{ MoveToX(pt.x); MoveToY(pt.y); }
inline BOOL CuRect::IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2)
{ return ::IntersectRect(this, lpRect1, lpRect2);}
inline BOOL CuRect::UnionRect(LPCRECT lpRect1, LPCRECT lpRect2)
{ return ::UnionRect(this, lpRect1, lpRect2); }
inline void CuRect::operator=(const RECT& srcRect)
{ ::CopyRect(this, &srcRect); }
inline BOOL CuRect::operator==(const RECT& rect) const
{ return ::EqualRect(this, &rect); }
inline BOOL CuRect::operator!=(const RECT& rect) const
{ return !::EqualRect(this, &rect); }
inline void CuRect::operator+=(POINT point)
{ ::OffsetRect(this, point.x, point.y); }
inline void CuRect::operator+=(SIZE size)
{ ::OffsetRect(this, size.cx, size.cy); }
inline void CuRect::operator+=(LPCRECT lpRect)
{ InflateRect(lpRect); }
inline void CuRect::operator-=(POINT point)
{ ::OffsetRect(this, -point.x, -point.y); }
inline void CuRect::operator-=(SIZE size)
{ ::OffsetRect(this, -size.cx, -size.cy); }
inline void CuRect::operator-=(LPCRECT lpRect)
{ DeflateRect(lpRect); }
inline void CuRect::operator&=(const RECT& rect)
{ ::IntersectRect(this, this, &rect); }
inline void CuRect::operator|=(const RECT& rect)
{ ::UnionRect(this, this, &rect); }
inline CuRect CuRect::operator+(POINT pt) const
{ CuRect rect(*this); ::OffsetRect(&rect, pt.x, pt.y); return rect; }
inline CuRect CuRect::operator-(POINT pt) const
{ CuRect rect(*this); ::OffsetRect(&rect, -pt.x, -pt.y); return rect; }
inline CuRect CuRect::operator+(SIZE size) const
{ CuRect rect(*this); ::OffsetRect(&rect, size.cx, size.cy); return rect; }
inline CuRect CuRect::operator-(SIZE size) const
{ CuRect rect(*this); ::OffsetRect(&rect, -size.cx, -size.cy); return rect; }
inline CuRect CuRect::operator+(LPCRECT lpRect) const
{ CuRect rect(this); rect.InflateRect(lpRect); return rect; }
inline CuRect CuRect::operator-(LPCRECT lpRect) const
{ CuRect rect(this); rect.DeflateRect(lpRect); return rect; }
inline CuRect CuRect::operator&(const RECT& rect2) const
{ CuRect rect; ::IntersectRect(&rect, this, &rect2);
return rect; }
inline CuRect CuRect::operator|(const RECT& rect2) const
{ CuRect rect; ::UnionRect(&rect, this, &rect2);
return rect; }
inline BOOL CuRect::SubtractRect(LPCRECT lpRectSrc1, LPCRECT lpRectSrc2)
{ return ::SubtractRect(this, lpRectSrc1, lpRectSrc2); }

inline void CuRect::NormalizeRect()
{
    int nTemp;
    if (left > right)
    {
        nTemp = left;
        left = right;
        right = nTemp;
    }
    if (top > bottom)
    {
        nTemp = top;
        top = bottom;
        bottom = nTemp;
    }
}

inline void CuRect::InflateRect(LPCRECT lpRect)
{
    left -= lpRect->left;       top -= lpRect->top;
    right += lpRect->right;     bottom += lpRect->bottom;
}

inline void CuRect::InflateRect(int l, int t, int r, int b)
{
    left -= l;          top -= t;
    right += r;         bottom += b;
}

inline void CuRect::DeflateRect(LPCRECT lpRect)
{
    left += lpRect->left;   top += lpRect->top;
    right -= lpRect->right; bottom -= lpRect->bottom;
}

inline void CuRect::DeflateRect(int l, int t, int r, int b)
{
    left += l;      top += t;
    right -= r;     bottom -= b;
}

2009年12月26日 星期六

CuHook - HookDLL.dll Adapter

// HookDLL.dll Adapter

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);

CuHook Hook;
Hook.Init(HookProc, WH_KEYBOARD_LL);



// CuHook.h

class CuHook
{
    typedef void (* LPFN_INITHOOK)(HOOKPROC lpfnCallBackHookProc, int idHook);
    LPFN_INITHOOK m_lpfnInitHook;

    typedef void (* LPFN_UNHOOK)(void);
    LPFN_UNHOOK m_lpfnUnHook;

    CuDllManager m_DllManager;

public:
    CuHook(void);
    ~CuHook(void);

    void Init(HOOKPROC lpfnCallBackHookProc, int idHook);
};



// CuHook.cpp

CuHook::CuHook(void)
:m_lpfnInitHook(NULL),
m_lpfnUnHook(NULL)
{
}

CuHook::~CuHook(void)
{
    if( m_lpfnUnHook != NULL )
        m_lpfnUnHook();
}


void CuHook::Init(HOOKPROC lpfnCallBackHookProc, int idHook)
{
    BOOL bLoadDll = m_DllManager.LoadLibrary(L"HookDll.dll");
    Assert( bLoadDll != NULL, TEXT("Don't Find HookDll.dll") );

    m_lpfnInitHook = (LPFN_INITHOOK)m_DllManager.GetProcAddress("InitHook");
    Assert( m_lpfnInitHook != NULL, TEXT("Don't Find function InitHook") );

    m_lpfnUnHook = (LPFN_UNHOOK)m_DllManager.GetProcAddress("UnHook");
    Assert( m_lpfnInitHook != NULL, TEXT("Don't Find function UnHook") );

    if( m_lpfnInitHook != NULL )
        m_lpfnInitHook(lpfnCallBackHookProc, idHook);
}

2009年12月25日 星期五

CuPaintDC - A device-context class.

// A device-context class. 
// A CuPaintDC object can only be used when responding to a WM_PAINT message

CuPaintDC dc(hWnd);
// CuPaintDC.h

class CuPaintDC
{
    HWND m_hWnd;
    HDC m_hDC;
    PAINTSTRUCT m_PS;
public:
    CuPaintDC(HWND hWnd);
public:
    ~CuPaintDC(void);
    operator HDC() const;
};


// CuPaintDC.cpp

CuPaintDC::CuPaintDC(HWND hWnd)
{
    m_hWnd = hWnd;
    m_hDC = BeginPaint(m_hWnd, &m_PS);
}

CuPaintDC::~CuPaintDC(void)
{
    EndPaint(m_hWnd, &m_PS);
}

CuPaintDC::operator HDC() const
{
    return m_hDC;
}

2009年12月23日 星期三

HookDll - installs an application-defined hook procedure into a hook chain.

// installs an application-defined hook procedure into a hook chain.

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam);

typedef void (* LPFN_INITHOOK)(HOOKPROC lpfnCallBackHookProc, int idHook);
LPFN_INITHOOK lpfnInitHook;

typedef void (* LPFN_UNHOOK)(void);
LPFN_UNHOOK lpfnUnHook;

CuDllManager DllManager;
BOOL bLoadDll = DllManager.LoadLibrary(L"HookDll.dll");
lpfnInitHook = (LPFN_INITHOOK)DllManager.GetProcAddress("InitHook");
lpfnUnHook = (LPFN_UNHOOK)DllManager.GetProcAddress("UnHook");
lpfnInitHook(HookProc, WH_MOUSE_LL);

lpfnUnHook();
// HookDll.h

#ifdef HOOKDLL_EXPORTS
#define HOOKDLL_API __declspec(dllexport)
#else
#define HOOKDLL_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif //__cplusplus

    HOOKDLL_API void InitHook(HOOKPROC lpfnCallBackHookProc, int idHook );
    HOOKDLL_API void UnHook(void);

#ifdef __cplusplus
} // extern "C"
#endif //__cplusplus


// HookDll.cpp

#pragma comment(linker,"/SECTION:.MYSEC,RWS")   

#pragma data_seg(".MYSEC") 
HOOKPROC g_lpfnCallBackHookProc = NULL;
HHOOK ghHook = NULL;
#pragma data_seg()  

HMODULE ghModule;

#ifdef _MANAGED
#pragma managed(push, off)
#endif

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
        ghModule = hModule;
        break;
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        UnHook();
        ghHook = NULL;
        break;
    }
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam)
{

    if ( nCode < 0 )
        return ::CallNextHookEx(ghHook, nCode, wParam, lParam);

    if( nCode == HC_ACTION )
    {
        if( g_lpfnCallBackHookProc )
            g_lpfnCallBackHookProc(nCode, wParam, lParam);
    }

    return ::CallNextHookEx(ghHook, nCode, wParam, lParam);

}


HOOKDLL_API void InitHook(HOOKPROC lpfnCallBackHookProc, int idHook )
{
    g_lpfnCallBackHookProc = lpfnCallBackHookProc;
    ghHook = (HHOOK)::SetWindowsHookEx(idHook, HookProc, ghModule ,0);
}


HOOKDLL_API void UnHook(void)
{
    ::UnhookWindowsHookEx(ghHook);
}

CuDllManager - Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).

// Retrieves the address of an exported function or variable from the specified dynamic-link library (DLL).


typedef void (* LPFN_MYFUNCTION)(void);
LPFN_MYFUNCTION lpfnMyFunction;

CuDllManager DllManager;

BOOL bLoadDll = DllManager.LoadLibrary(L"dllfile.dll");
lpfnMyFunction = (LPFN_MYFUNCTION)DllManager.GetProcAddress("MyFunction");

// CuDllManager.h

class CuDllManager
{
private:
    HINSTANCE m_hinstDll;

public:

    virtual FARPROC GetProcAddress(LPCSTR lpProcName);

    virtual void FreeLibrary();
    virtual BOOL LoadLibrary(LPCTSTR szLibrary);

    CuDllManager();
    virtual ~CuDllManager();

};




// CuDllManager.cpp

CuDllManager::CuDllManager()
{
    m_hinstDll = NULL;
}

CuDllManager::~CuDllManager()
{
    FreeLibrary();
}

BOOL CuDllManager::LoadLibrary(LPCTSTR szLibrary)
{
    FreeLibrary();
    m_hinstDll = ::LoadLibrary(szLibrary);
    return (BOOL)m_hinstDll != NULL;
}

void CuDllManager::FreeLibrary()
{
    if( m_hinstDll != NULL )
    {
        ::FreeLibrary(m_hinstDll);
        m_hinstDll = NULL;
    }
}

FARPROC CuDllManager::GetProcAddress(LPCSTR lpProcName)
{
    return ::GetProcAddress(m_hinstDll, lpProcName);
}

2009年12月21日 星期一

CuEventObject - Creates or opens a named or unnamed event object.

// Creates or opens a named or unnamed event object.




// CuEventObject.h


class CuEventObject
{
    HANDLE m_hHandle;

public:
    DWORD WaitForSingleObject(DWORD dwMilliseconds = INFINITE);

    BOOL SetEvent();
    BOOL ResetEvent();
    BOOL CreateEvent(TCHAR *szName, BOOL bManualReset = FALSE, BOOL bInitialState = FALSE);
    BOOL CloseHandle();
    operator HANDLE() const;

    CuEventObject();
    CuEventObject(TCHAR *szName);

    // 自動呼叫 CloseHandle();
    virtual ~CuEventObject();
};



// CuEventObject.cpp

CuEventObject::CuEventObject(TCHAR *szName)
:m_hHandle(NULL)
{
    CreateEvent(szName);
}

CuEventObject::CuEventObject()
:m_hHandle(NULL)
{

}

CuEventObject::~CuEventObject()
{
    CloseHandle();
}

CuEventObject::operator HANDLE() const
{
    return m_hHandle;
}

BOOL CuEventObject::CloseHandle()
{
    BOOL bResult = TRUE;
    if(m_hHandle)
        bResult = ::CloseHandle(m_hHandle);
    m_hHandle = NULL;

    return bResult;
}

BOOL CuEventObject::CreateEvent(TCHAR *szName, BOOL bManualReset /*= FALSE*/, BOOL bInitialState /*= FALSE*/)
{

    CloseHandle();
    m_hHandle = ::CreateEvent(NULL, bManualReset, bInitialState, szName);
    return (m_hHandle == NULL);

}
BOOL CuEventObject::ResetEvent()
{
    return ::ResetEvent(m_hHandle);
}

BOOL CuEventObject::SetEvent()
{
    return  ::SetEvent(m_hHandle);
}

DWORD CuEventObject::WaitForSingleObject(DWORD dwMilliseconds /*  = INFINITE */)
{
    return  ::WaitForSingleObject(m_hHandle, dwMilliseconds);
}

CuWinThread - Represents a thread of execution within an application.

// Represents a thread of execution within an application. 

// CuWinThread.h

typedef UINT (__cdecl  *_THREADPROC)(LPVOID);

// global helpers for threads
class CuWinThread;

CuWinThread* _BeginThread(_THREADPROC pfnThreadProc, LPVOID pParam,
    int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0,
    DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);

class CuWinThread  
{
public:
    BOOL CreateThread(DWORD dwCreateFlags = 0, UINT nStackSize = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);

    // only valid while running
    HANDLE m_hThread;       // this thread's HANDLE
    DWORD m_nThreadID;      // this thread's ID
    BOOL m_bAutoDelete;     // enables 'delete this' after thread termination

    LPVOID m_pThreadParams; // generic parameters passed to starting function
    _THREADPROC m_pfnThreadProc;

    CuWinThread();
    CuWinThread(_THREADPROC pfnThreadProc, LPVOID pParam);

// Operations
    DWORD SuspendThread();
    DWORD ResumeThread();
    BOOL SetThreadPriority(int nPriority);

// Implementation
    void CommonConstruct();
    virtual ~CuWinThread();

    // 'delete this' only if m_bAutoDelete == TRUE
    virtual void Delete();

};


inline DWORD CuWinThread::ResumeThread()
    { Assert(m_hThread != NULL, _T("CuWinThread::ResumeThread m_hThread != NULL") ); return ::ResumeThread(m_hThread); }
inline DWORD CuWinThread::SuspendThread()
    { Assert(m_hThread != NULL, _T("CuWinThread::SuspendThread m_hThread != NULL")) ; return ::SuspendThread(m_hThread); }
inline BOOL CuWinThread::SetThreadPriority(int nPriority)
    { Assert(m_hThread != NULL, _T("CuWinThread::SetThreadPriority m_hThread != NULL")); return ::SetThreadPriority(m_hThread, nPriority); }



// CuWinThread.cpp

struct _THREAD_STARTUP
{
    // following are "in" parameters to thread startup
    //_THREAD_STATE* pThreadState;    // thread state of parent thread
    CuWinThread* pThread;    // CWinThread for new thread
    DWORD dwCreateFlags;    // thread creation flags

    HANDLE hEvent;          // event triggered after success/non-success
    HANDLE hEvent2;         // event triggered after thread is resumed

    // strictly "out" -- set after hEvent is triggered
    BOOL bError;    // TRUE if error during startup
};

DWORD __cdecl _ThreadEntry(void* pParam)
{

    _THREAD_STARTUP* pStartup = (_THREAD_STARTUP*)pParam;
    Assert(pStartup != NULL, _T("_ThreadEntry::\npStartup != NULL"));
    Assert(pStartup->pThread != NULL, _T("_ThreadEntry::\npStartup->pThread != NULL"));
    Assert(pStartup->hEvent != NULL, _T("_ThreadEntry::\npStartup->hEvent != NULL"));
    Assert(!pStartup->bError, _T("_ThreadEntry::\n!pStartup->bError"));

    CuWinThread* pThread = pStartup->pThread;
    
    // pStartup is invlaid after the following
    // SetEvent (but hEvent2 is valid)
    HANDLE hEvent2 = pStartup->hEvent2;

    // allow the creating thread to return from CWinThread::CreateThread
    Verify(::SetEvent(pStartup->hEvent), _T(""));

    // wait for thread to be resumed
    Verify(::WaitForSingleObject(hEvent2, INFINITE) == WAIT_OBJECT_0, _T(""));
    ::CloseHandle(hEvent2);

    // first -- check for simple worker thread
    DWORD nResult = 0;
    if (pThread->m_pfnThreadProc != NULL)
    {
        nResult = (*pThread->m_pfnThreadProc)(pThread->m_pThreadParams);
    }

    pThread->Delete();

    // allow C-runtime to cleanup, and exit the thread
    ::ExitThread(nResult);
    return 0;

}


CuWinThread* _BeginThread(_THREADPROC pfnThreadProc, LPVOID pParam,
    int nPriority /* = THREAD_PRIORITY_NORMAL */, UINT nStackSize /* = 0 */,
    DWORD dwCreateFlags /* = 0 */, LPSECURITY_ATTRIBUTES lpSecurityAttrs /* = NULL*/ )
{

    Assert(pfnThreadProc != NULL, _T(""));

    CuWinThread* pThread = new CuWinThread(pfnThreadProc, pParam);
    Assert(pThread != NULL , _T("_BeginThread:: pThread == NULL"));

    if (!pThread->CreateThread(dwCreateFlags|CREATE_SUSPENDED, nStackSize,
        lpSecurityAttrs))
    {
        pThread->Delete();
        return NULL;
    }

    Verify(pThread->SetThreadPriority(nPriority) , _T(""));
    if (!(dwCreateFlags & CREATE_SUSPENDED))
        Verify(pThread->ResumeThread() != (DWORD)-1, _T(""));

    return pThread;

}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CuWinThread::CuWinThread()
{

    m_pThreadParams = NULL; 
    m_pfnThreadProc = NULL;

    CommonConstruct();

}

CuWinThread::CuWinThread(_THREADPROC pfnThreadProc, LPVOID pParam)
{

    m_pThreadParams = pParam;
    m_pfnThreadProc = pfnThreadProc;

    CommonConstruct();

}

CuWinThread::~CuWinThread()
{

    // free thread object
    if (m_hThread != NULL)
        CloseHandle(m_hThread);

}



void CuWinThread::CommonConstruct()
{

    m_hThread = NULL;
    m_nThreadID = 0;
    m_bAutoDelete = TRUE;

}


void CuWinThread::Delete()
{
    // delete thread if it is auto-deleting
    if (m_bAutoDelete)
        delete this;
}

BOOL CuWinThread::CreateThread(DWORD dwCreateFlags, UINT nStackSize, LPSECURITY_ATTRIBUTES lpSecurityAttrs)
{

    Assert(m_hThread == NULL, _T("CreateThread::m_hThread == NULL"));  // already created?

    // setup startup structure for thread initialization
    _THREAD_STARTUP startup; 
    
    memset(&startup, 0, sizeof(startup));
    startup.pThread = this;
    startup.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    startup.hEvent2 = ::CreateEvent(NULL, TRUE, FALSE, NULL);
    startup.dwCreateFlags = dwCreateFlags;
    if (startup.hEvent == NULL || startup.hEvent2 == NULL)
    {

        Assert(0, _T("Warning: CreateEvent failed in CWinThread::CreateThread.\n"));
        //TRACE(traceAppMsg, 0, "Warning: CreateEvent failed in CWinThread::CreateThread.\n");
        if (startup.hEvent != NULL)
            ::CloseHandle(startup.hEvent);
        if (startup.hEvent2 != NULL)
            ::CloseHandle(startup.hEvent2);
        return FALSE;
    }


    // create the thread (it may or may not start to run)
    m_hThread = ::CreateThread(lpSecurityAttrs, nStackSize,  //REVIEW
        (LPTHREAD_START_ROUTINE)&_ThreadEntry,  &startup, dwCreateFlags | CREATE_SUSPENDED, (PDWORD)&m_nThreadID);

    if (m_hThread == NULL)
        return FALSE;

    // start the thread just for MFC initialization
    Verify(ResumeThread() != (DWORD)-1, _T(""));
    Verify(::WaitForSingleObject(startup.hEvent, INFINITE) == WAIT_OBJECT_0, _T(""));
    ::CloseHandle(startup.hEvent);

    // if created suspended, suspend it until resume thread wakes it up
    if (dwCreateFlags & CREATE_SUSPENDED)
        Verify(::SuspendThread(m_hThread) != (DWORD)-1, _T(""));

    // if error during startup, shut things down
    if (startup.bError)
    {
        Verify(::WaitForSingleObject(m_hThread, INFINITE) == WAIT_OBJECT_0, _T(""));
        ::CloseHandle(m_hThread);
        m_hThread = NULL;
        ::CloseHandle(startup.hEvent2);
        return FALSE;
    }

    // allow thread to continue, once resumed (it may already be resumed)
    ::SetEvent(startup.hEvent2);

    return TRUE;
}



2009年12月18日 星期五

Filter of the Internet cache - CuUrlCacheFilter

// Filter of the Internet cache

string GetCacheIconFile( string &strUrl )
{
    CuUrlCacheFilter UrlCacheFilter;
    return UrlCacheFilter.OnGetCacheFile(".ico", strUrl.c_str());
}

// CuUrlCacheFilter.h

class CuUrlCacheFilter
{
    CuUrlCacheEntry m_UrlCacheEntry;

public:
    CuUrlCacheFilter(void);
    ~CuUrlCacheFilter(void);

public:
    string OnGetCacheFile(LPCTSTR szFilter = TEXT(".jpg") , LPCTSTR szURL = TEXT("") ); 

private:
    BOOL IsFilter( LPCTSTR lpszSource, LPCTSTR lpszFilter );
    BOOL IsFilterLocalFile( INTERNET_CACHE_ENTRY_INFO * lpEntry, LPCTSTR szFilter );
    BOOL IsFilterURL(INTERNET_CACHE_ENTRY_INFO * lpEntry, LPCTSTR szURL);

};


// CuUrlCacheFilter.cpp

CuUrlCacheFilter::CuUrlCacheFilter(void)
{
    m_UrlCacheEntry.ProcessEnumCacheEntry();
}

CuUrlCacheFilter::~CuUrlCacheFilter(void)
{
}

string CuUrlCacheFilter::OnGetCacheFile(LPCTSTR szFilter , LPCTSTR szURL  )
{

    string strResult;
    INTERNET_CACHE_ENTRY_INFO* lpEntry = NULL;
    for( int i = 0 ; i < m_UrlCacheEntry.size() ; i++ )
    {
        lpEntry = m_UrlCacheEntry.at(i);
        if(  IsFilterLocalFile( lpEntry, szFilter) && IsFilterURL(lpEntry, szURL) )
        {
            strResult = lpEntry->lpszLocalFileName;
            break;
        }
    }

    return strResult;
}


BOOL CuUrlCacheFilter::IsFilter( LPCTSTR lpszSource, LPCTSTR lpszFilter )
{
    if( lpszSource == NULL )
        return FALSE;

    string strTempFile(lpszSource);
    size_t found = strTempFile.find(lpszFilter);

    return ( found != string::npos );
}

BOOL CuUrlCacheFilter::IsFilterURL(INTERNET_CACHE_ENTRY_INFO * lpEntry, LPCTSTR szURL)
{
    return IsFilter(lpEntry->lpszSourceUrlName , szURL);
}

BOOL CuUrlCacheFilter::IsFilterLocalFile( INTERNET_CACHE_ENTRY_INFO * lpEntry, LPCTSTR szFilter )
{ 
    return IsFilter(lpEntry->lpszLocalFileName , szFilter);
}

Enumeration of the Internet cache - CuUrlCacheEntry

// Enumeration of the Internet cache.

CuUrlCacheEntry UrlCacheEntry;
UrlCacheEntry.ProcessEnumCacheEntry();

INTERNET_CACHE_ENTRY_INFO* lpEntry = NULL;
for( int i = 0 ; i < UrlCacheEntry.size() ; i++ )
{
    lpEntry = UrlCacheEntry.at(i);
}

// CuUrlCacheEntry.h

class CuUrlCacheEntry
{
    HANDLE m_hEnumHandle;
    vector<INTERNET_CACHE_ENTRY_INFO*> m_vecCacheEntryInfo;

public:
    CuUrlCacheEntry(void);
    ~CuUrlCacheEntry(void);

    UINT size(){ return m_vecCacheEntryInfo.size(); };
    INTERNET_CACHE_ENTRY_INFO* at(UINT i){ return m_vecCacheEntryInfo.at(i); };

public:
    void ProcessEnumCacheEntry();

private:
    HANDLE FindFirstEntry( LPCTSTR lpszUrlSearchPattern,  LPINTERNET_CACHE_ENTRY_INFO lpFirstCacheEntryInfo, LPDWORD lpcbCacheEntryInfo );
    BOOL FindNextEntry( LPINTERNET_CACHE_ENTRY_INFO lpNextCacheEntryInfo, LPDWORD lpcbCacheEntryInfo );
    BOOL FindCloseUrlCache();

    void Clear();
    BOOL CacheFirstEntry();
    BOOL CacheNextEntry();

};


// CuUrlCacheEntry.cpp

CuUrlCacheEntry::CuUrlCacheEntry(void)
:m_hEnumHandle(NULL)
{
}

CuUrlCacheEntry::~CuUrlCacheEntry(void)
{
    FindCloseUrlCache();
    this->Clear();
}

void CuUrlCacheEntry::ProcessEnumCacheEntry()
{

    BOOL bResult = CacheFirstEntry();
    if( bResult == FALSE )
        return;
    do 
    {
        bResult = CacheNextEntry();
    } while (bResult);

    FindCloseUrlCache();
}



HANDLE CuUrlCacheEntry::FindFirstEntry( LPCTSTR lpszUrlSearchPattern,  LPINTERNET_CACHE_ENTRY_INFO lpFirstCacheEntryInfo, LPDWORD lpcbCacheEntryInfo )
{
    FindCloseUrlCache();
    this->Clear();

    m_hEnumHandle = ::FindFirstUrlCacheEntry(lpszUrlSearchPattern, lpFirstCacheEntryInfo, lpcbCacheEntryInfo );
    return m_hEnumHandle;
}


BOOL CuUrlCacheEntry::FindNextEntry( LPINTERNET_CACHE_ENTRY_INFO lpNextCacheEntryInfo, LPDWORD lpcbCacheEntryInfo )
{
    return ::FindNextUrlCacheEntry(m_hEnumHandle, lpNextCacheEntryInfo, lpcbCacheEntryInfo  );
}


BOOL CuUrlCacheEntry::FindCloseUrlCache( )
{
    BOOL bResult = ::FindCloseUrlCache( m_hEnumHandle );
    m_hEnumHandle = NULL;
    return bResult;
}

void CuUrlCacheEntry::Clear()
{

    TCHAR* szBuffer = NULL;
    vector<INTERNET_CACHE_ENTRY_INFO*>::iterator iter;
    for( iter = m_vecCacheEntryInfo.begin() ; iter < m_vecCacheEntryInfo.end() ; iter++)
    {
        szBuffer = (TCHAR*)(*iter);
        delete [] szBuffer;
    }

    m_vecCacheEntryInfo.clear();

}

BOOL CuUrlCacheEntry::CacheFirstEntry()
{

    DWORD dwEntrySize = 0;

    BOOL bResult = (BOOL)FindFirstEntry(NULL, NULL, &dwEntrySize);
    if( (GetLastError() == ERROR_INSUFFICIENT_BUFFER) )
    {   
        INTERNET_CACHE_ENTRY_INFO * lpEntry = (INTERNET_CACHE_ENTRY_INFO * )new TCHAR[dwEntrySize];
        bResult = (BOOL)FindFirstEntry(NULL, lpEntry, &dwEntrySize);
        m_vecCacheEntryInfo.push_back(lpEntry);
    }

    return bResult;
}

BOOL CuUrlCacheEntry::CacheNextEntry()
{

    DWORD dwEntrySize = 0;

    BOOL bResult = (BOOL)FindNextEntry(NULL, &dwEntrySize);
    if( (GetLastError() == ERROR_INSUFFICIENT_BUFFER) )
    {   
        INTERNET_CACHE_ENTRY_INFO * lpEntry = (INTERNET_CACHE_ENTRY_INFO * )new TCHAR[dwEntrySize];
        bResult = FindNextEntry(lpEntry, &dwEntrySize);
        m_vecCacheEntryInfo.push_back(lpEntry);
    }

    return bResult;
}


CuEnvironmentString - Changing Environment Variables

// Changing Environment Variables

CuEnvironmentString envString( szPath );
string strPath(envString);

// CuEnvironmentString.h

class CuEnvironmentString
{
    string m_strString;
public:
    CuEnvironmentString(void);
    CuEnvironmentString(string str);
    ~CuEnvironmentString(void);

public:
    void OnDo( string &str );
    operator string() const;

private:
    BOOL HaveEnvironmentVariable( string &str );
    string GetEnvironmentVariable( string &str );
    string ExplodeEnironmentVariable( string &str, size_t ops = 0 );
    string SubStrToIndexChar( string &str, char ch, size_t pos = 0 );
};


// CuEnvironmentString.cpp

CuEnvironmentString::CuEnvironmentString(void)
{
}

CuEnvironmentString::~CuEnvironmentString(void)
{
}

CuEnvironmentString::CuEnvironmentString(string str)
{
    OnDo(str);
}

void CuEnvironmentString::OnDo( string &str )
{

    m_strString.clear();
    if( !HaveEnvironmentVariable(str) )
    {
        m_strString = str;
        return;
    }

    size_t pos = 0;
    string strNotEnv;
    string strEnv;
    do 
    {
        strNotEnv = SubStrToIndexChar( str, '%', pos);
        m_strString += strNotEnv;
        pos += strNotEnv.size() + 1;

        strEnv = SubStrToIndexChar( str, '%', pos);
        m_strString += this->GetEnvironmentVariable(strEnv);
        pos += strEnv.size() + 1;

    } while ( pos < str.size() );

}

string CuEnvironmentString::SubStrToIndexChar( string &str, char ch, size_t pos/* = 0 */)
{
    string strResult;       
    if( pos > str.size() )
        return strResult;

    size_t found = str.find( '%' , pos);
    strResult = str.substr( pos, found - pos );

    return strResult;
}

string CuEnvironmentString::GetEnvironmentVariable( string &str )
{
    TCHAR newEnv[MAX_PATH +1];
    DWORD res = ::GetEnvironmentVariable( str.c_str(), newEnv, MAX_PATH );
    string strResult;
    if( res != 0 )
        strResult = newEnv;
    return strResult;
}

string CuEnvironmentString::ExplodeEnironmentVariable( string &str, size_t ops /* = 0*/ )
{

    size_t found_first = str.find( '%' , ops );
    size_t found_second = str.find( '%' , found_first + 1);

    string strResult;
    if( found_first != string::npos && found_second != string::npos )
        strResult = str.substr (found_first + 1, found_second - 1);

    return strResult;

}

BOOL CuEnvironmentString::HaveEnvironmentVariable( string &str )
{
    string strResult = ExplodeEnironmentVariable(str);
    return (!strResult.empty());
}

CuEnvironmentString::operator string() const
{ return string(m_strString.begin(), m_strString.end()); }

2009年12月17日 星期四

ExpandEnvironmentStrings - Changing Environment Variables

// Changing Environment Variables
int _ExpandEnvironmentStrings( LPTSTR pText )
{
    TCHAR* p1 = _tcschr( pText, _T('%') );
    if( p1 == NULL )
        return -1;

    TCHAR* p2 = _tcschr( p1 +1, _T('%') );
    if( p2 == NULL )
        return -1;

    TCHAR provi[MAX_PATH +1];
    provi[0] = TCHAR(0);
    TCHAR env[MAX_PATH +1];
    p1 = pText;
    TCHAR* d = provi;
    while( *p1 != TCHAR(0) )
    {
        if( *p1 != _T('%') )
        {
            *d++ = *p1++;
            continue;
        }

        // find %
        p2 = _tcschr( p1 +1, _T('%') );
        if( p2 == NULL )
            return -1;

        lstrcpyn( env, p1 +1, int(p2 - p1) );
        TCHAR newEnv[MAX_PATH +1];
        DWORD res = ::GetEnvironmentVariable( env, newEnv, MAX_PATH );
        if( res > 0 )
        {
            lstrcpy( d, newEnv );
            d += lstrlen( newEnv );
        }
        p1 = p2 +1;
    }
    *d = TCHAR(0);

    if( lstrlen( provi ) != 0 )
    {
        lstrcpy( pText, provi );
    }

    return 0;
}


Explode ini File -- CuIniFile

//Explode ini File

CuIniFile IniFile;
IniFile.OpenFile(szFilename);
string strURL = IniFile.GetValue("InternetShortcut", "URL");


// CuIniFile.h

class CuINIItem
{
public:
    string m_Key;
    string m_Value;
};

class CuINIStatment
{
public:
    string m_Name;
    vector<CuINIItem> m_vecItem;
};

//  有使用分號 ';' 的那一行, 會直接將整行試為註解, 不管分號是不是在第一個字元
class CuIniFile
{
    vector<CuINIStatment> m_vecStatment;

public:
    CuIniFile(void);
    ~CuIniFile(void);

public:
    int OpenFile(LPCTSTR szFileName);
    string GetValue( string strStatment, string strKey);

    CuINIStatment *FindStatment( string strStatmentName );
    CuINIItem *FindItem( CuINIStatment *pStatment, string strItemName );

private:
    string GetStatment(string &str);
    BOOL IsStatmentLine(string &str);
    BOOL IsMemoLine(string &str);
    void CreateNewStatment( string &str );
    void CreateNewItem( string &str );
};


// CuIniFile.cpp

CuIniFile::CuIniFile(void)
{
}

CuIniFile::~CuIniFile(void)
{
}


int CuIniFile::OpenFile(LPCTSTR szFileName)
{
    CuStringList StrList;
    StrList.OpenFile(szFileName);

    string strTemp;
    for( int i = 0 ; i < StrList.size() ; i++ )
    {
        strTemp = StrList.at(i);
        if( IsMemoLine(strTemp) )
            continue;

        if( IsStatmentLine(strTemp) )
            CreateNewStatment(strTemp);
        else
            CreateNewItem(strTemp);
    }

    return 0;
}

CuINIStatment *CuIniFile::FindStatment( string strStatmentName )
{
    vector<CuINIStatment>::iterator iter =  m_vecStatment.begin();
    for( ; iter < m_vecStatment.end(); iter++ )
    {
        if( (*iter).m_Name == strStatmentName ) 
            return &(*iter);
    }

    return NULL;
}

CuINIItem *CuIniFile::FindItem( CuINIStatment *pStatment, string strItemName )
{
    vector<CuIniFile> &IniItem =  pStatment->m_vecItem;
    vector<CuIniFile>::iterator iter = IniItem.begin();

    for( ; iter < IniItem.end(); iter++ )
    {
        if( (*iter).m_Key == strItemName )
            return &(*iter);
    }

    return NULL;
}

string CuIniFile::GetValue( string strStatment, string strKey)
{

    CuINIStatment *pStatment = FindStatment(strStatment);
    if( pStatment == NULL )
        return "";

    CuINIItem *pItem = FindItem(pStatment , strKey);
    if( pItem == NULL )
        return "";

    return pItem->m_Value;

}

BOOL CuIniFile::IsMemoLine(string &str)
{
    size_t found = str.find( ';' );
    return ( found == 0 );
}

string CuIniFile::GetStatment(string &str)
{

    size_t found_first = str.find( '[' );
    size_t found_second = str.find( ']' , found_first);

    string strStatment;
    if( found_first != string::npos && found_second != string::npos )
        strStatment =  str.substr(found_first + 1, found_second - found_first - 1);

    return strStatment;
}

BOOL CuIniFile::IsStatmentLine(string &str)
{
    string strStatmentKey = GetStatment(str);
    return (!strStatmentKey.empty());
}

void CuIniFile::CreateNewStatment( string &str )
{
    CuINIStatment Statment;
    Statment.m_Name = GetStatment(str);
    m_vecStatment.push_back(Statment);
}   


void CuIniFile::CreateNewItem( string &str )
{

    size_t found = str.find('=');
    if( found == string::npos )
        return;

    string strKey = str.substr(0, found);
    string strValue = str.substr( found + 1 , str.size());

    CuINIItem Item;
    Item.m_Key = strKey;
    Item.m_Value = strValue;
    m_vecStatment[ m_vecStatment.size() - 1 ].m_vecItem.push_back(Item);
}


Explode File to String List

// Explode File to String List

OpenFile(LPCTSTR szFileName)
{
    CuStringList StrList;
    StrList.OpenFile(szFileName);

    string strTemp;
    for( int i = 0 ; i < StrList.size() ; i++ )
    {
        strTemp = StrList.at(i);
    }
}

// CuStringList.h

class CuStringList
{

    vector<string> m_vecString;
public:
    CuStringList(void);
public:
    ~CuStringList(void);
public:
    
    int OpenFile( LPCTSTR szFileName );

    int size(void){ return m_vecString.size(); }
    string at(int n){ return m_vecString.at(n); }

private:
    void ExplodeFile( BYTE * pBuffer, UINT nBufferSize );

};

// CuStringList.cpp

CuStringList::CuStringList(void)
{
}

CuStringList::~CuStringList(void)
{
}

void CuStringList::ExplodeFile( BYTE * pBuffer , UINT nBufferSize)
{

    int nResult;
    char szTempBuffer[1024] = {0};
    int nszTempIndex = 0;

    for( int i = 0 ; i < nBufferSize ; i++ )
    {
        nResult = pBuffer[i];
        if( nResult != 13 && nResult != 10 )
        {
            szTempBuffer[nszTempIndex++] = nResult;
            continue;
        }

        szTempBuffer[nszTempIndex] = '\0';
        m_vecString.push_back(szTempBuffer);
        nszTempIndex = 0;

    }
}

int CuStringList::OpenFile(LPCTSTR szFileName)
{

    CuFile f;
    BOOL bResult = f.Open(szFileName, TEXT("r"));
    Assert(bResult != 0, const_cast<LPTSTR>(szFileName));

    // GetFileSize 太大的話 應該會配不出記憶體
    BYTE *pBuffer = new BYTE[ f.GetFileSize() + 2];
    Assert(pBuffer != 0, TEXT("not enough memory CuStringList::OpenFile"));

    f.Read((void*)pBuffer,  f.GetFileSize());
    ExplodeFile(pBuffer, f.GetFileSize() );

    delete [] pBuffer;
    return TRUE;
}


CuHttp.cpp

CuHttp::CuHttp(void)
:m_nPageSize(0)
{
}

CuHttp::~CuHttp(void)
{
}

string CuHttp::GetPage( const TCHAR *szHttpUrl )
{

    CuInternetSession Session;
    CuInternetFile *pFile = Session.OpenUrl(szHttpUrl, NULL, 0 );

    string strResultPage;
    const UINT nBufferSize = 4096;
    BYTE bBuffer[nBufferSize];

    DWORD dwRead = 0;
    m_nPageSize = dwRead;
    do 
    {
        dwRead = pFile->Read( (void*)bBuffer, nBufferSize - 1);
        bBuffer[dwRead] = '\0';
        strResultPage += (char*)bBuffer;
        m_nPageSize += dwRead;
    } while ( dwRead );

    delete pFile;

    return strResultPage;

} 

CuHttp.h

class CuHttp
{
    UINT m_nPageSize;

public:
    CuHttp(void);
    ~CuHttp(void);

public:
    string GetPage( const TCHAR *szHttpUrl );

};

Use CuHttp Get Page

CuHttp Http;
string strPage = Http.GetPage(strHttpUrl.c_str());

CuInternetSession.cpp

CuInternetSession::CuInternetSession(
                  LPCTSTR lpszAgent /*= NULL*/,
                  DWORD dwAccessType/* = INTERNET_OPEN_TYPE_DIRECT*/,
                  LPCTSTR lpszProxyName/* = NULL*/,
                  LPCTSTR lpszProxyBypass/* = NULL*/,
                  DWORD dwFlags/* = 0*/
                  )

{
    m_hSession = InternetOpen(lpszAgent, dwAccessType, lpszProxyName, lpszProxyBypass, dwFlags);
}

CuInternetSession::~CuInternetSession(void)
{

    ::InternetCloseHandle(m_hSession);

}

CuInternetFile * CuInternetSession::OpenUrl( LPCTSTR lpszUrl, LPCTSTR lpszHeaders, 
        DWORD dwHeadersLength, DWORD dwFlags,  DWORD_PTR dwContext)
{

    HINTERNET hFile = ::InternetOpenUrl( m_hSession, lpszUrl, lpszHeaders, 
        dwHeadersLength, dwFlags, dwContext );

    CuInternetFile* pFile = new CuInternetFile( hFile );

    return  pFile;
}


2009年12月16日 星期三

CuInternetFile.cpp

2009年12月15日 星期二

CuInternetSession.h

class CuInternetSession
{
    HINTERNET m_hSession;
public:

    CuInternetSession(
        LPCTSTR lpszAgent = NULL,
        DWORD dwAccessType = INTERNET_OPEN_TYPE_DIRECT,
        LPCTSTR lpszProxyName = NULL,
        LPCTSTR lpszProxyBypass = NULL,
        DWORD dwFlags = 0
    );
    ~CuInternetSession(void);

public:
    CuInternetFile * OpenUrl(
        LPCTSTR lpszUrl,
        LPCTSTR lpszHeaders,
        DWORD dwHeadersLength,
        DWORD dwFlags = INTERNET_FLAG_DONT_CACHE,
        DWORD_PTR dwContext = 0
    );

};

CuInternetFile.h


class CuInternetFile 
{
    HINTERNET m_hFile;
public:

    CuInternetFile(HINTERNET hFile);
    ~CuInternetFile(void);

public:
    virtual int Read( void* lpBuffer, int nCount );
    virtual void Close();
};

GetFile From Internet HttpUrl

void TestInternetSession( const TCHAR *szHttpUrl , const TCHAR *szSaveFileName)
{

    DWORD dwSize;
    TCHAR szHead[] = _T("Accept: */*\r\n\r\n");
    VOID * szTemp[25];


    CuInternetSession Session;
    CuInternetFile *pFile = Session.OpenUrl(szHttpUrl, szHead, lstrlen (szHead) );

    BYTE bBuffer[4096];
    DWORD dwRead = pFile->Read( (void*)bBuffer, 4096);

    CuFile f;
    f.Open(szSaveFileName, _T("wb"));
    f.Write((void*)bBuffer, dwRead);

    delete pFile;

}