Non-Rectangular Windows using MFC

I am new to MFC programming, and I am trying to create an elliptical window
that displays some text at the center.  I derived my main window from the CWnd
class and overrode OnCreate, and called CWnd::SetWindowRgn to set it to a
an elliptic region.  But  it does not appear to do anything.  I just see a title bar,
and nothing else.    Following is the code segment.
Thanks,
daniel

//
// RgnDemo.h
//

class CMyApp : public CWinApp
{
public:
      BOOL InitInstance();
};


class CMainWindow : public CWnd
{
public:
      CMainWindow();

protected:
      virtual void PostNcDestroy();

      afx_msg int OnCreate(LPCREATESTRUCT);
      afx_msg void OnPaint();

      DECLARE_MESSAGE_MAP()
};


//
// RgnDemo.cpp
//

#include <afxwin.h>
#include "RgnDemo.h"

CMyApp myApp;

BOOL CMyApp::InitInstance()
{
      m_pMainWnd = new CMainWindow();
      m_pMainWnd->ShowWindow(m_nCmdShow);
      m_pMainWnd->UpdateWindow();
      return TRUE;
}

// CMainWindow message map and member functions

BEGIN_MESSAGE_MAP(CMainWindow, CWnd)
      ON_WM_PAINT()
      ON_WM_CREATE()
END_MESSAGE_MAP()


CMainWindow::CMainWindow()
{
      CString strWndClass = AfxRegisterWndClass(
            CS_VREDRAW | CS_HREDRAW, myApp.LoadStandardCursor(IDC_ARROW),
            (HBRUSH)(COLOR_3DFACE+1),
            myApp.LoadStandardIcon(IDI_APPLICATION));

      CreateEx(0,strWndClass,"Region Demo", WS_VISIBLE,
            CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
            NULL,NULL);
}

void CMainWindow::PostNcDestroy()
{
      delete this;
}

int CMainWindow::OnCreate(LPCREATESTRUCT lpcs)
{
      CRgn rgn;

      if ( CWnd::OnCreate(lpcs) == -1 )
            return -1;

      rgn.CreateEllipticRgn(0,0,500,500);

      SetWindowRgn(rgn, TRUE);

      return 0;
}


void CMainWindow::OnPaint()
{
      CRect rect;

      GetClientRect(&rect);

      CString strTemp;
      strTemp.Format("Width:%d, Ht:%d", rect.Width, rect.Height);
      MessageBox(strTemp,"Dimensions",MB_OK);

      CPaintDC dc(this);
      dc.DrawText("Round Window", -1, &rect,
                        DT_SINGLELINE | DT_CENTER | DT_VCENTER );

}
      

      

danchandranAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
jhanceConnect With a Mentor Commented:
Here is a modified version of what you posted that creates a round window on my screen, draws the background in grey, and write out the text:

// MyWnd.cpp : implementation file
//

#include "stdafx.h"
#include "NewParent.h"
#include "MyWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// MyWnd

MyWnd::MyWnd()
{
}

MyWnd::~MyWnd()
{
}


BEGIN_MESSAGE_MAP(MyWnd, CWnd)
      //{{AFX_MSG_MAP(MyWnd)
      ON_WM_CREATE()
      ON_WM_PAINT()
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// MyWnd message handlers

int MyWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
      if (CWnd::OnCreate(lpCreateStruct) == -1)
            return -1;
      
      // TODO: Add your specialized creation code here

      if ( CWnd::OnCreate(lpCreateStruct) == -1 )
            return -1;

      rgn.CreateEllipticRgn(0,0,500,500);

      SetWindowRgn(rgn, TRUE);

      return 0;
}

void MyWnd::OnPaint()
{
      CPaintDC dc(this); // device context for painting

      // TODO: Add your message handler code here
      CRect rect;

      GetClientRect(&rect);

      CBrush *myBrush = new CBrush;
      myBrush->CreateSolidBrush(RGB(128,128,128));

      dc.FillRect(&rect, myBrush);
      delete myBrush;

      CString strTemp;
      //strTemp.Format("Width:%d, Ht:%d", rect.Width, rect.Height);
      //MessageBox(strTemp,"Dimensions",MB_OK);


      dc.DrawText("Round Window", -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER );

      // Do not call CWnd::OnPaint() for painting messages
}






It gets called like this:

      CWnd *myWnd = new MyWnd;
      if(!myWnd->CreateEx(
            0,
            AfxRegisterWndClass(0),
            "MyWindowName",
            WS_OVERLAPPEDWINDOW,
            0, 0, 500, 500,
            NULL,
            NULL,
            NULL
      )){
            AfxMessageBox("ERROR: CreateEx() failed!", MB_OK);
            delete myWnd;
            return;
      }
      myWnd->ShowWindow(SW_NORMAL);
0
 
danchandranAuthor Commented:

Could also post your header files "NewParent.h" and "MyWnd.h"?
And also point out  why my code does not work?
Thanks,
daniel
0
 
jhanceCommented:
MyWnd.h:

class MyWnd : public CWnd
{
// Construction
public:
      MyWnd();

// Attributes
public:

// Operations
public:

// Overrides
      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(MyWnd)
      //}}AFX_VIRTUAL

// Implementation
public:
      virtual ~MyWnd();

      // Generated message map functions
protected:
      CRgn rgn;
      //{{AFX_MSG(MyWnd)
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      afx_msg void OnPaint();
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};

0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
jhanceCommented:
NewParentDlg.h:

class CNewParentDlg : public CDialog
{
// Construction
public:
      CNewParentDlg(CWnd* pParent = NULL);      // standard constructor

// Dialog Data
      //{{AFX_DATA(CNewParentDlg)
      enum { IDD = IDD_NEWPARENT_DIALOG };
            // NOTE: the ClassWizard will add data members here
      //}}AFX_DATA

      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CNewParentDlg)
      protected:
      virtual void DoDataExchange(CDataExchange* pDX);      // DDX/DDV support
      //}}AFX_VIRTUAL

// Implementation
protected:
      HICON m_hIcon;

      // Generated message map functions
      //{{AFX_MSG(CNewParentDlg)
      virtual BOOL OnInitDialog();
      afx_msg void OnPaint();
      afx_msg HCURSOR OnQueryDragIcon();
      virtual void OnOK();
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};
0
 
jhanceCommented:
All I did was to use the MFC App Wizard to make a MFC dialog application.  I then used the Class Wizard to add a handler to the OK button in the default dialog.  I put the "new MyWnd" stuff in the OnOK function in my dialog.  The rest is basically your code with some extra stuff thrown in to make sure the background of the window gets drawn.  Otherwise, it's hard to see the window itself as the edges to show up.
0
 
danchandranAuthor Commented:
I think I found the problem with my code.  I had rgn defined
as a local variable in the OnCreate message handler.  Making
it a protected member of the CMainWindow class made it work.

Thanks for your post.
daniel
0
 
luketaylorCommented:
Thanks, the CRgn really is the business,
it seems like we can build windows with
holes etc.

I was just wondering (if the code already
exists) as anyone written window dragging
code, for windows with no bar etc ? My
efforts so far leave a trail behind the
window as it moves.

Luke

Actualy that code must be in the MFC source
somewhere, any suggestions where to look?

0
All Courses

From novice to tech pro — start learning today.