Solved

Non-Rectangular Windows using MFC

Posted on 1998-03-11
7
403 Views
Last Modified: 2013-12-03
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 );

}
      

      

0
Comment
Question by:danchandran
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
7 Comments
 
LVL 32

Accepted Solution

by:
jhance earned 100 total points
ID: 1411899
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
 

Author Comment

by:danchandran
ID: 1411900

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

Expert Comment

by:jhance
ID: 1411901
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
Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

 
LVL 32

Expert Comment

by:jhance
ID: 1411902
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
 
LVL 32

Expert Comment

by:jhance
ID: 1411903
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
 

Author Comment

by:danchandran
ID: 1411904
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
 

Expert Comment

by:luketaylor
ID: 1411905
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

Featured Post

SharePoint Admin?

Enable Your Employees To Focus On The Core With Intuitive Onscreen Guidance That is With You At The Moment of Need.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…

717 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question