Thread: Non-Rectangle Window

  1. #1
    Registered User
    Join Date
    Dec 2002
    Posts
    15

    Question Non-Rectangle Window

    Hi Guys,

    I have tried to do a seach but I may be asking the wrong thing. Basically I am trying to find information on how do you make an application window look not like a standard window.

    Applications I can think of off the top of my head that are like this is Windows Media Player, QuickTime Player.

    Thanks for any info you can provide!

  2. #2
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    SetWindowRgn() is how you can accomplish this. Basically you create a bitmap that serves as the dialog window. I actually came across this great function on the web a long time back that simplifies the whole thing for you... I'll post it...
    Here's the function:
    Code:
    HRGN DIBToRgn(HBITMAP hBmp, COLORREF BkColor, BOOL Direct)
    {
      // use to return the handle of the HGRN
        HRGN hRgn = NULL;          
      #define MAX_ALLOC_RECTS  100
      //the difference of the color
      COLORREF  Tolerance=0x00101010;
      if (hBmp)
      {
        //creat the dib to save the dc
        HDC hMemDC = CreateCompatibleDC(NULL);    
        if (hMemDC)
        {
          BITMAP bm;
          //get the info of the bitmap
          GetObject(hBmp, sizeof(bm), &bm);  
    
          BITMAPINFOHEADER BmpInfoh = {          //the struct of the bitmap
              sizeof(BITMAPINFOHEADER),      // biSize
              bm.bmWidth,          // biWidth;
              bm.bmHeight,          // biHeight;
              1,            // biPlanes;
              32,            // biBitCount
              BI_RGB,            // biCompression;
              0,            // biSizeImage;
              0,            // biXPelsPerMeter;
              0,            // biYPelsPerMeter;
              0,            // biClrUsed;
              0            // biClrImportant;
          };
          //design a void point to point to the bitmap
          LPVOID pBit32; 
          //creat a DIB
          HBITMAP hDib32 = CreateDIBSection(hMemDC, 
              (BITMAPINFO *)&BmpInfoh, 
              DIB_RGB_COLORS, &pBit32, NULL, 0);
          if (hDib32)
          {
            //copy dib to DC
            HBITMAP hOldib32 = (HBITMAP)SelectObject(hMemDC, hDib32);
            // create a DC to save orgin bitmap
            HDC hDC = CreateCompatibleDC(hMemDC);
            if (hDC)
            {
              BITMAP bm32;
              // get the new 34 bit Dib size
              GetObject(hDib32, sizeof(bm32), &bm32);
              //make sure the 32Dib's every line pilex's is 4 's times
              while (bm32.bmWidthBytes % 4)
                bm32.bmWidthBytes++;
              //copy the orginal dib to DC
              HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
              //copy dib to memory DC
              BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
              DWORD MaxRects = MAX_ALLOC_RECTS;
              SYSTEM_INFO  Sysinfo;
              //get memory size
              GetSystemInfo(&Sysinfo);
              //make a stack which can chang big
              //alloct memory
              HANDLE hRcData=HeapCreate(HEAP_GENERATE_EXCEPTIONS,Sysinfo.dwPageSize, 0);
              RGNDATA * pRcData=(RGNDATA*)HeapAlloc(hRcData,HEAP_ZERO_MEMORY,
                sizeof(RGNDATAHEADER)+sizeof(RECT)*MaxRects);
               //fill the the RGNDATA struck
              pRcData->rdh.dwSize = sizeof(RGNDATAHEADER);
              pRcData->rdh.iType = RDH_RECTANGLES;
              pRcData->rdh.nCount = pRcData->rdh.nRgnSize = 0;
              SetRect(&pRcData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
                         BYTE hr,hg,hb,lr,lg,lb;
              switch(BkColor)
              {
              case RGB(255,255,255):  //if the bkcolor is white
                hr = GetRValue(BkColor);
                hg = GetGValue(BkColor);
                hb = GetBValue(BkColor);
                lr = min(0xff, hr - GetRValue(Tolerance));
                lg = min(0xff, hg - GetGValue(Tolerance));
                lb = min(0xff, hb - GetBValue(Tolerance));
                break;
              case RGB(0,0,0):  //if the bkcolor is black
                lr = GetRValue(BkColor);
                lg = GetGValue(BkColor);
                lb = GetBValue(BkColor);
                hr = min(0xff, lr + GetRValue(Tolerance));
                hg = min(0xff, lg + GetGValue(Tolerance));
                hb = min(0xff, lb + GetBValue(Tolerance));
                break;
              default:    //if the bkcolor is other color
                Tolerance=0x111111;
                lr =max(0, GetRValue(BkColor)-GetRValue(Tolerance));
                lg = max(0,GetGValue(BkColor)-GetGValue(Tolerance));
                lb = max(0,GetBValue(BkColor)-GetBValue(Tolerance));
                hr=min(0xff,GetRValue(BkColor)+GetRValue(Tolerance));
                hg=min(0xff,GetGValue(BkColor)+GetGValue(Tolerance));
                hb=min(0xff,GetBValue(BkColor)+GetBValue(Tolerance));
                break;
              }
              // Get the bit point and do the search
              BYTE *pBits = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
              for (int y = 0; y < bm.bmHeight; y++)
              {
                for (int x = 0; x < bm.bmWidth; x++)
                {
                  int x0 = x;
                  DWORD *pColor = (DWORD *)pBits + x;
                  BYTE dr,dg,db;
                  while (x < bm.bmWidth)
                  {
                    dr=GetRValue(*pColor);
                    dg=GetGValue(*pColor);
                    db=GetBValue(*pColor);
    
                    if ((dr>= lr && dr<= hr)&&(dg>=lg&&dg<=hg)&&(db>=lb&&db<=hb))
                    {
                      if(Direct)
                        break;
                      else
                      {
                        pColor++;
                        x++;
                      }
                      }
                    else if(Direct)
                    {
                      pColor++;
                      x++;
                    }
                    else
                      break;
    
                  }
                  if (x > x0)
                  {
                    if (pRcData->rdh.nCount >= MaxRects)
                    {
                      MaxRects += MAX_ALLOC_RECTS;
                      //re alloc the stack
                      pRcData=(RGNDATA*)HeapReAlloc(
                      hRcData,HEAP_ZERO_MEMORY,pRcData, 
                      sizeof(RGNDATAHEADER)+sizeof(RECT)*MaxRects);
                    }
                    RECT *pr = (RECT *)&pRcData->Buffer;
                    SetRect(&pr[pRcData->rdh.nCount], x0, y, x, y+1);
                    pRcData->rdh.rcBound.left = x0;
                    pRcData->rdh.rcBound.top = y;
                    pRcData->rdh.rcBound.right = x;
                    pRcData->rdh.rcBound.bottom = y+1;
                    pRcData->rdh.nCount++;
    
                    if (pRcData->rdh.nCount == 3000)
                    {  
                      HRGN tmphRgn = ExtCreateRegion(NULL,
                      sizeof(RGNDATAHEADER) + (sizeof(RECT) * MaxRects),
                      pRcData);
                      if (hRgn)
                      {
                        CombineRgn(hRgn, hRgn, tmphRgn, RGN_OR);
                        DeleteObject(tmphRgn);
                      }
                      else
                        hRgn = tmphRgn;
                      pRcData->rdh.nCount = 0;
                      SetRect(&pRcData->rdh.rcBound, 
                      MAXLONG, MAXLONG, 0, 0);
                    }
                  }
                }
    
                // search next line
                pBits -= bm32.bmWidthBytes;
              }
              HRGN tmphRgn = ExtCreateRegion(NULL, 
                  sizeof(RGNDATAHEADER) + (sizeof(RECT) * MaxRects), pRcData);
              if (hRgn)
              {
                CombineRgn(hRgn, hRgn, tmphRgn, RGN_OR);
                DeleteObject(tmphRgn);
              }
              else
                hRgn = tmphRgn;
              // make a rect ,use this rect xor to the  BkColor
              //then we can get the rect we want
              if(!Direct)
              {
                HRGN hRect=CreateRectRgn(0,0,bm.bmWidth,bm.bmHeight);
                                    if(hRect)
                {
                  CombineRgn(hRgn,hRgn,hRect,RGN_XOR);
                  DeleteObject(hRect);
                }
                  else
                  return NULL;
              }
              //release the memory
              HeapFree(hRcData,HEAP_NO_SERIALIZE,pRcData);
              SelectObject(hDC, holdBmp);
              DeleteDC(hDC);
              DeleteObject(holdBmp);
            }
            SelectObject(hMemDC,hOldib32);
            DeleteDC(hMemDC);
            DeleteObject(hOldib32);
            DeleteObject(hDib32);
          }
          else
            DeleteDC(hMemDC);
        }
      }
      return hRgn;
    }
    Then call this somewhere in your initialization:
    Code:
      m_hBmp = (HBITMAP)LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDB_MAIN), IMAGE_BITMAP, 0, 0,L R_CREATEDIBSECTION);
      m_hClientRgn = CreateEllipticRgn(33, 34, 34, 35);
      m_hWndRgn = DIBToRgn(m_hBmp, 0xff00ff, FALSE);
      if(m_hWndRgn)
        SetWindowRgn(m_hWndRgn,TRUE);
    Also look into overriding OnEraseBkgnd() and OnNcHitTest():
    Code:
    BOOL CSkinTestDlg::OnEraseBkgnd(CDC* pDC) 
    {
      if(m_hBmp)
      {
        BITMAP bm;
        GetObject(m_hBmp,sizeof(bm),&bm);
        HDC hMemdc=CreateCompatibleDC(pDC->m_hDC); 
        if(hMemdc)
        {
           HBITMAP hOldBmp=(HBITMAP)SelectObject(hMemdc,m_hBmp);
           if(hOldBmp)
           {
             BitBlt(pDC->m_hDC,0,0,bm.bmWidth,bm.bmHeight,hMemdc,0,0,SRCCOPY);
             SelectObject(hMemdc,hOldBmp);
             DeleteDC(hMemdc);
             DeleteObject(hOldBmp);
             return TRUE;
           }
           else
           DeleteDC(hMemdc);
        }
      }
      return CDialog::OnEraseBkgnd(pDC);
    }
    
    
    UINT CSkinTestDlg::OnNcHitTest(CPoint point) 
    {
      return HTCAPTION;//always say our mouse is on the caption (title bar) area
    }
    Hope this helps.
    Last edited by LuckY; 04-09-2003 at 02:30 PM.

  3. #3
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    Additionally, it may interest you to search for the CButtonST class (try google). It's a CButton derived class that displays flat buttons with a bitmap that can change when your mouse is over it. Neat stuff.

  4. #4
    Enforcer
    Guest
    WOW!

    Thanks a ton I didn't expect this much info!

  5. #5

  6. #6
    JamiraQwery
    Guest
    Does this help?

  7. #7
    JamiraQwery
    Guest
    Does this help?

    This is how I've always done it:

    ******************************
    HRGN hrgn;

    //Create a region of the shape you want to use

    hrgn = CreateEllipticRgn(Variables for region size and curve);

    SetWindowRgn(hwnd, hrgn, 1);

    ******************************

    Now your window will be the shape and size of the region you defined!! That easy!!

    Of course there's a lot more to explore here. But that should be an experience best left to your very capable self!!

    I think I found this solution (if memory serves) on Flipcode.com

    I hope it helps you!!

    Cheers!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Just starting Windows Programming, School me!
    By Shamino in forum Windows Programming
    Replies: 17
    Last Post: 02-22-2008, 08:14 AM
  2. WM_CAPTION causing CreateWindowEx() to fail.
    By Necrofear in forum Windows Programming
    Replies: 8
    Last Post: 04-06-2007, 08:23 AM
  3. 6 measly errors
    By beene in forum Game Programming
    Replies: 11
    Last Post: 11-14-2006, 11:06 AM
  4. OpenGL Window
    By Morgul in forum Game Programming
    Replies: 1
    Last Post: 05-15-2005, 12:34 PM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM