2008年8月6日 星期三

User defiend windows

http://kevincg.wordpress.com/2008/02/14/不規則視窗-part-ii/

// ==================== 建立形狀 =====================  

// Step 1: 載入影像  
  HBITMAP hBmp = (HBITMAP) LoadImage( AfxGetInstanceHandle(), "Rgn.bmp",IMAGE_BITMAP, 0, 0,LR_LOADFROMFILE );  
   
// Step 2:建立一個 Region, 令紅色為透明色 (transparent)  

  HRGN hRgn = CreateRgnFromFile( hBmp, RGB(255,0,0) );  
  
// Step 3:設定視窗大小與影像大小相同  

  SetWindowPos( NULL, 0, 0, m_dwWidth, m_dwHeight, SWP_NOZORDER | SWP_NOMOVE );  
  
// Step 4:設定視窗的形狀  

  SetWindowRgn( hRgn, TRUE );  

// ==================== End ===================== 

HRGN CreateRgnFromFile( HBITMAP hBmp, COLORREF color )
{
     // get image properties
     BITMAP bmp = { 0 };
     GetObject( hBmp, sizeof(BITMAP), &bmp ); // 取出 hBMP 相關的資訊

     // allocate memory for extended image information
     LPBITMAPINFO bi = (LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
     memset( bi, 0, sizeof(BITMAPINFO) + 8 );
     bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

     // set window size
     m_dwWidth = bmp.bmWidth; // bitmap width
     m_dwHeight = bmp.bmHeight; // bitmap height

     // create temporary dc
     HDC dc = CreateDC( "DISPLAY",NULL,NULL,NULL );
     // get extended information about image (length, compression, length of color table if exist, ...)
      DWORD res = GetDIBits( dc, hBmp, 0, bmp.bmHeight, 0, bi, DIB_RGB_COLORS );
     // allocate memory for image data (colors)
     LPBYTE pBits = new BYTE[ bi->bmiHeader.biSizeImage + 4 ];
     // allocate memory for color table
      if ( bi->bmiHeader.biBitCount == 8 )
     {
          // actually color table should be appended to this header(BITMAPINFO),
          // so we have to reallocate and copy it
         LPBITMAPINFO old_bi = bi;
         // 255 - because there is one in BITMAPINFOHEADER
         bi = (LPBITMAPINFO)new char[ sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD) ];
         memcpy( bi, old_bi, sizeof(BITMAPINFO) );
         // release old header
        delete old_bi;
     }
      // get bitmap info header
      BITMAPINFOHEADER& bih = bi->bmiHeader;
      // get color table (for 256 color mode contains 256 entries of RGBQUAD(=DWORD))
       LPDWORD clr_tbl = (LPDWORD)&bi->bmiColors;
      // fill bits buffer
      res = GetDIBits( dc, hBmp, 0, bih.biHeight, pBits, bi, DIB_RGB_COLORS );
      DeleteDC( dc );

      // shift bits and byte per pixel (for comparing colors)
      LPBYTE pClr = (LPBYTE)&color;
      // swap red and blue components
      BYTE tmp = pClr[0]; pClr[0] = pClr[2]; pClr[2] = tmp;
      // convert color if curent DC is 16-bit (5:6:5) or 15-bit (5:5:5)
      if ( bih.biBitCount == 16 )
     {
           color = ((DWORD)(pClr[0] & 0xf8) >> 3) | // 3
          ((DWORD)(pClr[1] & 0xf8) << rgndataheader_size =" sizeof(RGNDATAHEADER);" add_rects_count =" 40;" bpp =" bih.biBitCount">> 3; // bytes per pixel
      // DIB image is flipped that's why we scan it from the last line
     LPBYTE pColor = pBits + (bih.biHeight - 1) * (bih.biWidth * Bpp);
     DWORD dwLineBackLen = 2 * bih.biWidth * Bpp; // offset of previous scan line
      // (after processing of current)
     DWORD dwRectsCount = bih.biHeight; // number of rects in allocated buffer
     INT i, j; // current position in mask image
     INT first = 0; // left position of current scan line
     // where mask was found
     bool wasfirst = false; // set when mask has been found in current scan line
     bool ismask; // set when current color is mask color

     // allocate memory for region data
     // region data here is set of regions that are rectangles with height 1 pixel (scan line)
    // that's why first allocation is RECTs - number of scan lines in image
    RGNDATAHEADER* pRgnData = 
  (RGNDATAHEADER*)new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
    // get pointer to RECT table
    LPRECT pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
    // zero region data header memory (header part only)
     memset( pRgnData, 0, RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) );
    // fill it by default
    pRgnData->dwSize = RGNDATAHEADER_SIZE;
    pRgnData->iType = RDH_RECTANGLES;

     for ( i = 0; i < j =" 0;" ismask =" (clr_tbl[" ismask =" (*(LPWORD)pColor" ismask =" ((*(LPDWORD)pColor" ismask =" (*(LPDWORD)pColor">nCount++ ] = CRect( first, i, j, i + 1 );
                 // if buffer full reallocate it with more room
                 if ( pRgnData->nCount >= dwRectsCount )
                 {
                       dwRectsCount += ADD_RECTS_COUNT;
                       // allocate new buffer
                        LPBYTE pRgnDataNew = new BYTE[ RGNDATAHEADER_SIZE + dwRectsCount * sizeof(RECT) ];
                       // copy current region data to it
                       memcpy( pRgnDataNew, pRgnData, RGNDATAHEADER_SIZE + pRgnData- >nCount * sizeof(RECT) );
                      // delte old region data buffer
                                            delete pRgnData;
                                             // set pointer to new regiondata buffer to current
                                              pRgnData = (RGNDATAHEADER*)pRgnDataNew;
                                              // correct pointer to RECT table
                                               pRects = (LPRECT)((LPBYTE)pRgnData + RGNDATAHEADER_SIZE);
                                    }
                                    wasfirst = false;
                          }
                           else if ( !wasfirst && ismask ) // set wasfirst when mask is found
                           {
                                      first = j;
                                     wasfirst = true;
                           }
                 }
                 pColor -= dwLineBackLen;
         }
         // release image data
          delete pBits;
         delete bi;

         // create region
         HRGN hRgn = ExtCreateRegion( NULL, RGNDATAHEADER_SIZE + pRgnData->nCount *              sizeof(RECT), (LPRGNDATA)pRgnData );
        // release region data
       delete pRgnData;
 
       return hRgn;
}

C++: SendMessage 的使用方式

http://brain.wordpress.com/2008/01/16/sendmessage/

2008年8月5日 星期二

__stdcall ,__cdecl的區別

http://kevincg.wordpress.com/2006/06/19/__stdcall-__cdecl的區別/

2008年7月21日 星期一

ListCtrl in MFC

//======毛毛介紹 listctrl =====================
http://blog.csdn.net/handsomerun/archive/2006/04/13/662462.aspx

2008年7月9日 星期三

CFileDialog in MFC

Search File Sample

/************ using WIN32 API **************/
HANDLE hSearch;
CString path_name;
bool bFinished = false;
WIN32_FIND_DATA find_data;

m_curpath = path_name.Left(path_name.GetLength()-strlen("kghost.exe"));
path_name = m_curpath + "*.txt";
hSearch = FindFirstFile(path_name, &find_data);
if( hSearch==INVALID_HANDLE_VALUE )
return;

while( bFinished==false )
{
CString str = find_data.cFileName;
...
if( !FindNextFile(hSearch, &find_data) )
bFinished = true;
}
FindClose(hSearch);
/****************************************/
其中
WIN32_FIND_DATA
typedef struct _WIN32_FIND_DATA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
TCHAR cFileName[ MAX_PATH ];
TCHAR cAlternateFileName[ 14 ];
} WIN32_FIND_DATA, *PWIN32_FIND_DATA;

2008年7月8日 星期二

Performance Tuning of Code

http://www.newlc.com/performance-tuning-code