Solved

Non-Rectangular Windows using MFC

Posted on 1998-03-11
7
379 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
  • 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
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This article describes how to programmatically preset the "Pages per Sheet" option that's available with most printer drivers.   This setting lets you do "n-Up" printing, where two, four, or more pages are printed on each sheet of paper. If your …
This article surveys and compares options for encoding and decoding base64 data.  It includes source code in C++ as well as examples of how to use standard Windows API functions for these tasks. We'll look at the algorithms — how encoding and decodi…
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…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

746 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now