顯示具有 SampleCode 標籤的文章。 顯示所有文章
顯示具有 SampleCode 標籤的文章。 顯示所有文章

2010年2月24日 星期三

CuGLES

class CuGLES : public CuEGL  
{

public:
    void Ortho(double left, double right, double bottom, double top, double Near, double Far);
    void Frustum( double fovy, double aspect, double zNear, double zFar );
    void Viewport(int x, int y, int width, int height);
#if 0
    void DrawArrays(const void *pvlist, const void *pnvlist, const void *ptclist,int stride, int numvertices);
    void DrawElements(const void *pvlist, const void *pnvlist, const void *ptclist,int stride, int numvertices,
        const void *pfaceindex, int numfaceindex);
#endif
    
    CuGLES();
    virtual ~CuGLES();

};


CuGLES::CuGLES()
{

}

CuGLES::~CuGLES()
{

}

#if 0
void CuGLES::DrawArrays(const void *pvlist, const void *pnvlist, const void *ptclist, int stride, int numvertices)
{

    glTexCoordPointer(2, GL_FIXED, stride, ptclist);
    // setup client states
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);    // setup arrays
    // first the vertices
    glVertexPointer(3, GL_FIXED , stride, pvlist);
    glEnableClientState(GL_VERTEX_ARRAY);


    // next the normals
//  glNormalPointer(GL_SHORT, stride, pnvlist);
    glNormalPointer(GL_FIXED , stride, pnvlist);
    glEnableClientState(GL_NORMAL_ARRAY);

    glDrawArrays(GL_TRIANGLES , 0, numvertices);


    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

}


void CuGLES::DrawElements(const void *pvlist, const void *pnvlist, const void *ptclist,int stride, int numvertices,
    const void *pfaceindex, int numfaceindex)
{

    glTexCoordPointer(2, GL_FIXED, stride, ptclist);
    // setup client states
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);


    // setup arrays
    // first the vertices
    glVertexPointer(3, GL_FIXED , stride, pvlist);
    glEnableClientState(GL_VERTEX_ARRAY);


    // next the normals
    glNormalPointer(GL_FIXED , stride, pnvlist);
    glEnableClientState(GL_NORMAL_ARRAY);

    glDrawElements(GL_TRIANGLES , numfaceindex, GL_UNSIGNED_BYTE , pfaceindex);


    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

}
#endif

void CuGLES::Viewport(int x, int y, int width, int height)
{
    glViewport(x,y,width,height);
}

#define PI_     3.14159265358979323846
void CuGLES::Frustum(double fovy, double aspect, double zNear, double zFar)
{
    // 設定投影
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    float right, left, top, bottom;
    top = zNear * tan(fovy * PI_ / 180.0 / 2 );
    bottom = -top;
    right = top * aspect;
    left = -right;

    glFrustumx(EGL_FixedFromFloat(left), EGL_FixedFromFloat(right),
        EGL_FixedFromFloat(bottom), EGL_FixedFromFloat(top),
        EGL_FixedFromFloat(zNear), EGL_FixedFromFloat(zFar) );

}

void CuGLES::Ortho(double left, double right, double bottom, double top, double Near, double Far)
{

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthox(
        EGL_FixedFromFloat(left),
        EGL_FixedFromFloat(right),
        EGL_FixedFromFloat(bottom), 
        EGL_FixedFromFloat(top), 
        EGL_FixedFromFloat(Near), 
        EGL_FixedFromFloat(Far));

}


完全不了解為什麼要繼承, 想不起來.

2010年2月23日 星期二

CuEGL

class CuEGL  
{

    int _red_size;
    int _green_size;
    int _bule_size;
    int _alpha_size;

public:

    // 
    void SwapBuffers();


    // 只要有呼叫 Init() 做初始化 就要呼叫 Exit() 
    // 在這裡 解構會自動呼叫
    void Exit();

    // 初始化 EGL
    // Return:  1 有問題初始化失敗   0: 一切正常
    bool Init(NativeWindowType hWnd);

    CuEGL();
    virtual ~CuEGL();

    EGLDisplay  _eglDisplay;
    EGLConfig   _eglConfig;
    EGLSurface  _eglSurface;
    EGLContext  _eglContext;



};

CuEGL::CuEGL()
{

    _eglDisplay = EGL_NO_DISPLAY;
    _eglConfig;
    _eglSurface = EGL_NO_SURFACE;
    _eglContext = EGL_NO_CONTEXT;

    _red_size = 5;
    _green_size = 6;
    _bule_size = 5;
    _alpha_size = 0;


}

CuEGL::~CuEGL()
{

    if( _eglDisplay != EGL_NO_DISPLAY )
        this->Exit();

}


bool CuEGL::Init(NativeWindowType hWnd)
{

    int buffer_size = _red_size + _green_size + _bule_size + _alpha_size;
    EGLint  attrs[] = {
        EGL_ALPHA_SIZE, _alpha_size,
        EGL_RED_SIZE, _red_size,
        EGL_GREEN_SIZE, _green_size,
        EGL_BLUE_SIZE, _bule_size,
        EGL_BUFFER_SIZE, buffer_size,
        EGL_DEPTH_SIZE, 16,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE};

    EGLint  numConfig;
    LONG        lRet = 1; 

    // NOTE: Theres a bunch of stuff we should be doing to release resources
    //       in the case of failure that we're not bothering with atm

    HDC hdc = GetWindowDC((HWND)hWnd);

    // Get the display device


    _eglDisplay = eglGetDisplay(hdc);

    Assert( _eglDisplay != EGL_NO_DISPLAY, L"CuEGL::Init:\n _eglDisplay == EGL_NO_DISPLAY");

    // Initialize the display
    if (!eglInitialize(_eglDisplay, NULL, NULL))
        {  
            Assert(0, L"CuEGL::Init:\n can't Initialize egl");
            return lRet;

        }

    // Obtain the first configuration with a depth buffer
    if (!eglChooseConfig(_eglDisplay, attrs, &_eglConfig, 1, &numConfig))
        { 
            Assert(0, L"CuEGL::Init:\n can't ChooseConfig");
            return lRet; 
        }

    // Create a surface for the main window
    _eglSurface = eglCreateWindowSurface(_eglDisplay, _eglConfig, (NativeWindowType)hWnd, NULL);
    Assert( _eglSurface != EGL_NO_SURFACE, L"CuEGL::Init:\n _eglSurface == EGL_NO_SURFACE");

    // Create an OpenGL ES context
    _eglContext = eglCreateContext(_eglDisplay, _eglConfig, EGL_NO_CONTEXT, NULL);
    Assert( _eglContext != EGL_NO_CONTEXT, L"CuEGL::Init:\n _eglContext == EGL_NO_CONTEXT");


    // Make the context and surface current
    if (!eglMakeCurrent(_eglDisplay, _eglSurface, _eglSurface, _eglContext))
        {  
            Assert(0, L"CuEGL::Init:\n can't MakeCurrent");
            return lRet; 
        }

    return 0;

}

void CuEGL::Exit()
{

    // Set the current context to nothing
    eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

    // Free any EGL contexts; should be called per context created
    eglDestroyContext(_eglDisplay, _eglContext);

    // Free any EGL surfaces; should be called per surface created
    eglDestroySurface(_eglDisplay, _eglSurface);

    // Terminate any EGL displays; should be called per display initialized
    eglTerminate(_eglDisplay); 

}

void CuEGL::SwapBuffers()
{

    eglSwapBuffers(_eglDisplay, _eglSurface);

}


好舊的碼了~ 如果有更新會在加上去

2010年1月20日 星期三

PHP : CDate

// CDate.php

class CDate {
    
    function str2time($strStr, $strPattern)
    {
        

       // an array of the valide date characters, see: http://php.net/date#AEN21898
       $arrCharacters = array(
           'd', // day
           'm', // month
           'y', // year, 2 digits
           'Y', // year, 4 digits
           'H', // hours
           'i', // minutes
           's'  // seconds
       );
       // transform the characters array to a string
       $strCharacters = implode('', $arrCharacters);


    
       // splits up the pattern by the date characters to get an array of the delimiters between the date characters
       $arrDelimiters = preg_split('~['.$strCharacters.']~', $strPattern);

       // transform the delimiters array to a string
       $strDelimiters = quotemeta(implode('', array_unique($arrDelimiters)));


    
       // splits up the date by the delimiters to get an array of the declaration
       $arrStr    = preg_split('~[' . $strDelimiters . ']~' , $strStr);
    

       // splits up the pattern by the delimiters to get an array of the used characters
       $arrPattern = preg_split('~['.$strDelimiters.']~', $strPattern);
    
        
       // if the numbers of the two array are not the same, return false, because the cannot belong together
       if (count($arrStr) !== count($arrPattern)) {
           return false;
       }
    
       // creates a new array which has the keys from the $arrPattern array and the values from the $arrStr array
       $arrTime = array();
       for ($i = 0;$i < count($arrStr);$i++) {
           $arrTime[$arrPattern[$i]] = $arrStr[$i];
       }
    
            
       // gernerates a 4 digit year declaration of a 2 digit one by using the current year
       if (isset($arrTime['y']) && !isset($arrTime['Y'])) {
           $arrTime['Y'] = substr(date('Y'), 0, 2) . $arrTime['y'];
       }
    
    
       // if a declaration is empty, it will be filled with the current date declaration
       foreach ($arrCharacters as $strCharacter) {
           if (empty($arrTime[$strCharacter])) {
               $arrTime[$strCharacter] = date($strCharacter);
           }
       }
    
    
       // checks if the date is a valide date
       if (!checkdate($arrTime['m'], $arrTime['d'], $arrTime['Y'])) {
           return false;
       }
    
       // generates the timestamp
       $intTime = mktime($arrTime['H'], $arrTime['i'], $arrTime['s'], $arrTime['m'], $arrTime['d'], $arrTime['Y']);
       // returns the timestamp
    
       return $intTime;
    } // end function str2time
    
}// end class CDate


雖然現在很少人在寫PHP用手動比對時間, 通常都交給SQL去驗證.

2010年1月9日 星期六

CReg - An encapsulation of the Windows registry key.

// An encapsulation of the Windows registry key.  


CReg reg(HKEY_LOCAL_MACHINE, TEXT("Software\\AppName\\"));
string strPath = reg.ValueSZ( "KeyName" );


// CReg.h

class CReg  
{
private:
    HKEY    m_hKey;
    int     m_Index;
    LPBYTE  m_lpbValue; // last value read, if any

public:
    CReg();
    ~CReg();

    BOOL Create(HKEY hkRoot, LPCTSTR pszKey) {
        DWORD dwDisp;
        return ERROR_SUCCESS==RegCreateKeyEx(hkRoot, pszKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &m_hKey, &dwDisp);
    }

    BOOL Open(HKEY hkRoot, LPCTSTR pszKey, REGSAM sam=KEY_READ) {
        return ERROR_SUCCESS==RegOpenKeyEx(hkRoot, pszKey, 0, sam, &m_hKey);
    }

    CReg(HKEY hkRoot, LPCTSTR pszKey) {
        m_hKey = NULL;
        m_Index = 0;
        m_lpbValue = NULL;
        Open(hkRoot, pszKey);
    }



    void MyFree(LPBYTE m_lpbValue) {
        delete [] m_lpbValue;
    }

    LPBYTE MyRgAlloc(int dwLen)
    {
        return new BYTE[dwLen];
    }

    void Reset() { 
        if(m_hKey) RegCloseKey(m_hKey); 
        MyFree(m_lpbValue);
        m_hKey = NULL;
        m_Index = 0;
        m_lpbValue = NULL;
    }

    operator HKEY() { return m_hKey; }

    BOOL IsOK(void) { return m_hKey!=NULL; }


    BOOL EnumKey(LPTSTR psz, DWORD dwLen) {
        if(!m_hKey) return FALSE;
        return ERROR_SUCCESS==RegEnumKeyEx(m_hKey, m_Index++, psz, &dwLen, NULL, NULL, NULL, NULL);
    }

    BOOL EnumValue(LPTSTR pszName, DWORD dwLenName, LPTSTR pszValue, DWORD dwLenValue) {
        DWORD dwType;
        if(!m_hKey) return FALSE;
        dwLenValue *= sizeof(TCHAR); // convert length in chars to bytes
        return ERROR_SUCCESS==RegEnumValue(m_hKey, m_Index++, pszName, &dwLenName, NULL, &dwType, (LPBYTE)pszValue, &dwLenValue);
    }

    BOOL ValueSZ(LPCTSTR szName, LPTSTR szValue, DWORD dwLen) 
    {
        if(!m_hKey) return FALSE;
        dwLen *= sizeof(TCHAR); // convert length in chars to bytes
        return ERROR_SUCCESS==RegQueryValueEx(m_hKey, szName, NULL, NULL, (LPBYTE)szValue, &dwLen);
    }

    DWORD ValueBinary(LPCTSTR szName, LPBYTE lpbValue, DWORD dwLen) {
        if(!m_hKey) return FALSE;
        DWORD dwLenWant = dwLen;
        if(ERROR_SUCCESS==RegQueryValueEx(m_hKey, szName, NULL, NULL, lpbValue, &dwLen))
            return dwLen;
        else
            return 0;
    }

    LPCTSTR ValueSZ(LPCTSTR szName)
    {
        if(!m_hKey) return TEXT("");
        DWORD dwLen = 0;
        if( (ERROR_SUCCESS != RegQueryValueEx(m_hKey, szName, NULL, NULL, NULL, &dwLen)) || 
            (dwLen == 0) )
                return TEXT("");
        MyFree(m_lpbValue);
        if( !(m_lpbValue = MyRgAlloc(dwLen)) ||
            (ERROR_SUCCESS != RegQueryValueEx(m_hKey, szName, NULL, NULL, m_lpbValue, &dwLen)) )
                return TEXT("");
        return (LPTSTR)m_lpbValue;
    }

    LPBYTE ValueBinary(LPCTSTR szName) {
        return (LPBYTE)ValueSZ(szName);
    }

    DWORD ValueDW(LPCTSTR szName, DWORD dwDefault=0) {
        if(!m_hKey) return FALSE;
        DWORD dwValue = dwDefault;
        DWORD dwLen = sizeof(DWORD);
        RegQueryValueEx(m_hKey, szName, NULL, NULL, (LPBYTE)&dwValue, &dwLen);
        return dwValue;
    }

    LONG  ValueDW2(LPCTSTR szName, DWORD &dwDefault) {
        if(!m_hKey) return FALSE;
        DWORD dwValue = dwDefault;
        DWORD dwLen = sizeof(DWORD);
        return RegQueryValueEx(m_hKey, szName, NULL, NULL, (LPBYTE)&dwValue, &dwLen);
    }

    BOOL SetSZ(LPCTSTR szName, LPCTSTR szValue, DWORD dwLen) {
        if(!m_hKey) return FALSE;
        return ERROR_SUCCESS==RegSetValueEx(m_hKey, szName, 0, REG_SZ, (LPBYTE)szValue, sizeof(TCHAR)*dwLen);
    }
    
    BOOL SetSZ(LPCTSTR szName, LPCTSTR szValue) {
        return SetSZ(szName, szValue, 1+lstrlen(szValue));
    }

    BOOL SetDW(LPCTSTR szName, DWORD dwValue) {
        if(!m_hKey) return FALSE;
        return ERROR_SUCCESS==RegSetValueEx(m_hKey, szName, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(DWORD));
    }
    
    BOOL SetBinary(LPCTSTR szName, LPBYTE lpbValue, DWORD dwLen) {
        if(!m_hKey) return FALSE;
        return ERROR_SUCCESS==RegSetValueEx(m_hKey, szName, 0, REG_BINARY, lpbValue, dwLen);
    }

    BOOL SetMultiSZ(LPCTSTR szName, LPCTSTR lpszValue, DWORD dwLen) {
        return ERROR_SUCCESS==RegSetValueEx(m_hKey, szName, 0, REG_MULTI_SZ, (LPBYTE)lpszValue, sizeof(TCHAR)*dwLen);
    }

    BOOL DeleteValue(LPCTSTR szName) {
        if(!m_hKey) return FALSE;
        return ERROR_SUCCESS==RegDeleteValue(m_hKey, szName);
    }

    BOOL DeleteKey(LPCTSTR szName) {
        if(!m_hKey) return FALSE;
        return ERROR_SUCCESS==RegDeleteKey(m_hKey, szName);
    }
};


// CReg.cpp

CReg::CReg()
{
        m_hKey = NULL;
        m_Index = 0;
        m_lpbValue = NULL;
}

CReg::~CReg()
{
    if(m_hKey) 
        RegCloseKey(m_hKey); 
    MyFree(m_lpbValue);
}

2010年1月7日 星期四

CuSize - Similar to the Windows SIZE structure

// Similar to the Windows SIZE structure

// CuSize.h

class CuSize : public tagSIZE
{
public:

// Constructors
    // construct an uninitialized size
    CuSize() throw();
    // create from two integers
    CuSize(int initCX, int initCY) throw();
    // create from another size
    CuSize(SIZE initSize) throw();
    // create from a point
    CuSize(POINT initPt) throw();
    // create from a DWORD: cx = LOWORD(dw) cy = HIWORD(dw)
    CuSize(DWORD dwSize) throw();

// Operations
    BOOL operator==(SIZE size) const throw();
    BOOL operator!=(SIZE size) const throw();
    void operator+=(SIZE size) throw();
    void operator-=(SIZE size) throw();
    void SetSize(int CX, int CY) throw();

// Operators returning CuSize values
    CuSize operator+(SIZE size) const throw();
    CuSize operator-(SIZE size) const throw();
    CuSize operator-() const throw();

// Operators returning CuPoint values
    CuPoint operator+(POINT point) const throw();
    CuPoint operator-(POINT point) const throw();

// Operators returning CuRect values
    CuRect operator+(const RECT* lpRect) const throw();
    CuRect operator-(const RECT* lpRect) const throw();
};

inline CuSize::CuSize()
    { /* random filled */ }
inline CuSize::CuSize(int initCX, int initCY)
    { cx = initCX; cy = initCY; }
inline CuSize::CuSize(SIZE initSize)
    { *(SIZE*)this = initSize; }
inline CuSize::CuSize(POINT initPt)
    { *(POINT*)this = initPt; }
inline CuSize::CuSize(DWORD dwSize)
    {
        cx = (short)LOWORD(dwSize);
        cy = (short)HIWORD(dwSize);
    }
inline BOOL CuSize::operator==(SIZE size) const
    { return (cx == size.cx && cy == size.cy); }
inline BOOL CuSize::operator!=(SIZE size) const
    { return (cx != size.cx || cy != size.cy); }
inline void CuSize::operator+=(SIZE size)
    { cx += size.cx; cy += size.cy; }
inline void CuSize::operator-=(SIZE size)
    { cx -= size.cx; cy -= size.cy; }
inline void CuSize::SetSize(int CX, int CY)
    { cx = CX; cy = CY; }   
inline CuSize CuSize::operator+(SIZE size) const
    { return CuSize(cx + size.cx, cy + size.cy); }
inline CuSize CuSize::operator-(SIZE size) const
    { return CuSize(cx - size.cx, cy - size.cy); }
inline CuSize CuSize::operator-() const
    { return CuSize(-cx, -cy); }
inline CuPoint CuSize::operator+(POINT point) const
    { return CuPoint(cx + point.x, cy + point.y); }
inline CuPoint CuSize::operator-(POINT point) const
    { return CuPoint(cx - point.x, cy - point.y); }
inline CuRect CuSize::operator+(const RECT* lpRect) const
    { return CuRect(lpRect) + *this; }
inline CuRect CuSize::operator-(const RECT* lpRect) const
    { return CuRect(lpRect) - *this; }

2010年1月1日 星期五

CuPoint - A 2-D point, similar to Windows POINT structure.

// CuPoint - A 2-D point, similar to Windows POINT structure.

class CuPoint : public tagPOINT
{
public:
// Constructors

    // create an uninitialized point
    CuPoint() throw();
    // create from two integers
    CuPoint(int initX, int initY) throw();
    // create from another point
    CuPoint(POINT initPt) throw();
    // create from a size
    CuPoint(SIZE initSize) throw();
    // create from an LPARAM: x = LOWORD(dw) y = HIWORD(dw)
    CuPoint(LPARAM dwPoint) throw();


// Operations

// translate the point
    void Offset(int xOffset, int yOffset) throw();
    void Offset(POINT point) throw();
    void Offset(SIZE size) throw();
    void SetPoint(int X, int Y) throw();

    BOOL operator==(POINT point) const throw();
    BOOL operator!=(POINT point) const throw();
    void operator+=(SIZE size) throw();
    void operator-=(SIZE size) throw();
    void operator+=(POINT point) throw();
    void operator-=(POINT point) throw();

// Operators returning CuPoint values
    CuPoint operator+(SIZE size) const throw();
    CuPoint operator-(SIZE size) const throw();
    CuPoint operator-() const throw();
    CuPoint operator+(POINT point) const throw();

// Operators returning CuSize values
    CuSize operator-(POINT point) const throw();

// Operators returning CuRect values
    CuRect operator+(const RECT* lpRect) const throw();
    CuRect operator-(const RECT* lpRect) const throw();
};


inline CuPoint::CuPoint()
    { /* random filled */ }
inline CuPoint::CuPoint(int initX, int initY)
    { x = initX; y = initY; }
inline CuPoint::CuPoint(POINT initPt)
    { *(POINT*)this = initPt; }
inline CuPoint::CuPoint(SIZE initSize)
    { *(SIZE*)this = initSize; }
inline CuPoint::CuPoint(LPARAM dwPoint)
    {
        x = (short)LOWORD(dwPoint);
        y = (short)HIWORD(dwPoint);
    }
inline void CuPoint::Offset(int xOffset, int yOffset)
    { x += xOffset; y += yOffset; }
inline void CuPoint::Offset(POINT point)
    { x += point.x; y += point.y; }
inline void CuPoint::Offset(SIZE size)
    { x += size.cx; y += size.cy; }
inline void CuPoint::SetPoint(int X, int Y)
    { x = X; y = Y; }
inline BOOL CuPoint::operator==(POINT point) const
    { return (x == point.x && y == point.y); }
inline BOOL CuPoint::operator!=(POINT point) const
    { return (x != point.x || y != point.y); }
inline void CuPoint::operator+=(SIZE size)
    { x += size.cx; y += size.cy; }
inline void CuPoint::operator-=(SIZE size)
    { x -= size.cx; y -= size.cy; }
inline void CuPoint::operator+=(POINT point)
    { x += point.x; y += point.y; }
inline void CuPoint::operator-=(POINT point)
    { x -= point.x; y -= point.y; }
inline CuPoint CuPoint::operator+(SIZE size) const
    { return CuPoint(x + size.cx, y + size.cy); }
inline CuPoint CuPoint::operator-(SIZE size) const
    { return CuPoint(x - size.cx, y - size.cy); }
inline CuPoint CuPoint::operator-() const
    { return CuPoint(-x, -y); }
inline CuPoint CuPoint::operator+(POINT point) const
    { return CuPoint(x + point.x, y + point.y); }
inline CuSize CuPoint::operator-(POINT point) const
    { return CuSize(x - point.x, y - point.y); }
inline CuRect CuPoint::operator+(const RECT* lpRect) const
    { return CuRect(lpRect) + *this; }
inline CuRect CuPoint::operator-(const RECT* lpRect) const
    { return CuRect(lpRect) - *this; }

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月21日 星期一

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月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;
}