wince에서는 CreateRoundRectRgn()함수가 지원이 안되서 구글 힘을 빌려 만들어 봤습니다. 원본소스는 
http://www.ocera.org/archive/upvlc/public/components/sa-rtl/sa-rtl-2.2-pre2/mw/mwin/winrgn.c
에 있는 일부분을 참고해서 만들었습니다.

 
// TestCEGraphView.h : interface of the CTestCEGraphView class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

#include <vector>

HRGN CreateRoundRectRgn (int left, int top, int right, int bottom, int ellipse_width, int ellipse_height )
{
 HRGN              hrgn = 0;
 int               asq, bsq, d, xd, yd;
 RECT              rect;
 std::vector<RECT> rects;

 if (ellipse_width == 0 || ellipse_height == 0)
  return CreateRectRgn( left, top, right, bottom );

 /* Make the dimensions sensible */
 if (left > right ) { int tmp = left; left = right;  right  = tmp; }
 if (top  > bottom) { int tmp = top;  top  = bottom; bottom = tmp; }

 ellipse_width  = abs(ellipse_width);
 ellipse_height = abs(ellipse_height);

 /* Check parameters */
 if (ellipse_width  > right-left) ellipse_width  = right-left;
 if (ellipse_height > bottom-top) ellipse_height = bottom-top;

 /* Ellipse algorithm, based on an article by K. Porter */
 /* in DDJ Graphics Programming Column, 8/89 */
 asq = ellipse_width  * ellipse_width  / 4; /* a^2 */
 bsq = ellipse_height * ellipse_height / 4; /* b^2 */
 if (asq == 0) asq = 1;
 if (bsq == 0) bsq = 1;
 d  = bsq - asq * ellipse_height / 2 + asq / 4; /* b^2 - a^2b + a^2/4 */
 xd = 0;
 yd = asq * ellipse_height;                     /* 2a^2b */

 rect.left   = left + ellipse_width  / 2;
 rect.right  = right - ellipse_width / 2;

 rects.reserve (ellipse_height);

 /* Loop to draw first half of quadrant */
 while (xd < yd)
 {
  /* if nearest pixel is toward the center */
  if (d > 0) 
  {
   /* move toward center */
   rect.top    = top++;
   rect.bottom = rect.top + 1;
   rects.push_back (rect);

   rect.top    = --bottom;
   rect.bottom = rect.top + 1;
   rects.push_back (rect);

   yd -= 2*asq;
   d  -= yd;
  }
  /* next horiz point */
  rect.left --;       
  rect.right++;
  xd += 2*bsq;
  d  += bsq + xd;
 }

 /* Loop to draw second half of quadrant */
 d += (3 * (asq-bsq) / 2 - (xd+yd)) / 2;
 while (yd >= 0)
 {
  /* next vertical point */
  rect.top    = top++;
  rect.bottom = rect.top + 1;
  rects.push_back (rect);

  rect.top    = --bottom;
  rect.bottom = rect.top + 1;
  rects.push_back (rect);

  /* if nearest pixel is outside ellipse */
  if (d < 0)  
  {
   /* move away from center */
   rect.left --;    
   rect.right++;
   xd += 2*bsq;
   d  += xd;
  }
  yd -= 2*asq;
  d  += asq - yd;
 }

 /* Add the inside rectangle */
 if (top <= bottom)
 {
  rect.top    = top;
  rect.bottom = bottom;
  //rects.push_back (rect);
  rects.insert (rects.begin(), rect);
 }
 
 static int count=0;
 std::vector<RECT>::iterator i;
 for (i=rects.begin(); i!=rects.end(); i++)
 {
  ATLTRACE (_T("[%d]%3d,%3d:%3d,%3d \r\n"), ++count,
   (*i).top,
   (*i).bottom,
   (*i).left,
   (*i).right
   );
 }
 if (rects.empty())
  return NULL;

 RGNDATAHEADER* pRgnData;
 UINT           RgnDataSize;
 UINT           RgnRectCount;
 LPRECT         pRect;

 RgnRectCount = rects.size();
 RgnDataSize  = sizeof(RGNDATAHEADER) + sizeof(RECT)*RgnRectCount;
 pRgnData     = (RGNDATAHEADER*)new BYTE[ RgnDataSize ];
 if (pRgnData==NULL)
  return NULL;

 pRgnData->dwSize         = sizeof(RGNDATAHEADER);
 pRgnData->iType          = RDH_RECTANGLES;
 pRgnData->nCount         = RgnRectCount;
 pRgnData->rcBound.left   = 0;
 pRgnData->rcBound.top    = 0;
 pRgnData->rcBound.right  = 0;
 pRgnData->rcBound.bottom = 0;

 pRect = (LPRECT) ( (LPBYTE) pRgnData + sizeof(RGNDATAHEADER) );

 memcpy (pRect, &*rects.begin(), RgnRectCount*sizeof(RECT));

 hrgn = ExtCreateRegion(NULL, RgnDataSize, (LPRGNDATA)pRgnData);

 delete pRgnData;

 return hrgn;
}

class CTestCEGraphView : public CWindowImpl<CTestCEGraphView>
{
public:
 DECLARE_WND_CLASS(NULL)

 BOOL PreTranslateMessage(MSG* pMsg)
 {
  pMsg;
  return FALSE;
 }

 BEGIN_MSG_MAP(CTestCEGraphView)
  MESSAGE_HANDLER(WM_PAINT, OnPaint)
 END_MSG_MAP()

// Handler prototypes (uncomment arguments if needed):
// LRESULT MessageHandler(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
// LRESULT CommandHandler(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
// LRESULT NotifyHandler(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
 
 LRESULT OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
 { 
  CPaintDC dc(m_hWnd);
  CBrush brush[3];

  brush[0].CreateSolidBrush (RGB(0xff,0x00,0x00));
  brush[1].CreateSolidBrush (RGB(0x00,0xff,0x00));
  brush[2].CreateSolidBrush (RGB(0x00,0x00,0xff));
  
  HRGN hrgn;
  
  hrgn = CreateRoundRectRgn (10,10,200,100,200,200);
  dc.FillRgn (hrgn , brush[0]);
  DeleteObject (hrgn);

  hrgn = CreateRoundRectRgn (10,150,200,250,20,50);
  dc.FillRgn (hrgn , brush[1]);
  DeleteObject (hrgn);

  hrgn = CreateRoundRectRgn (10,300,200,400,20,20);
  dc.FillRgn (hrgn , brush[2]);
  DeleteObject (hrgn);

  return 0;
 }
};

Posted by 셈말짓기 :