Hello, I'm wanting to print a circle to a screen, or should I say on a form. Any ideas?

Thanks

I get this error when trying to call a premade function:

g:\University work\Year 2\GUI\Hangman\HangmanDlg.cpp(98): error C2373: 'Ellipse' : redefinition; different type modifiers

Whilst I'm not understanding the code very well, I've gone away and implemented a print function:

void classname::print()
{
BOOL Ellipse(
  HDC hdc,        // handle to DC
  int nLeftRect,  // x-coord of upper-left corner of rectangle
  int nTopRect,   // y-coord of upper-left corner of rectangle
  int nRightRect, // x-coord of lower-right corner of rectangle
  int nBottomRect // y-coord of lower-right corner of rectangle
}
...

print();

Looks like you are trying to call the Ellipse function provided by the Windows API. Then you dont have to redefine it inside the

void classname::print()

function. Just call it like this.

void classname::print
( 
  HDC hdc,        // handle to DC
  int nLeftRect,  // x-coord of upper-left corner of rectangle
  int nTopRect,   // y-coord of upper-left corner of rectangle
  int nRightRect, // x-coord of lower-right corner of rectangle
  int nBottomRect // y-coord of lower-right corner of rectangle
)
{
  Ellipse( hdc, nLeftRect, nTopRect, nRightRect, nBottomRect );
  // Do other stuff you want inside the print function
  //...
}

Then call it like this

classname classobject;
classobject::print( hdc, 10, 100, 30, 140 );

If you get errors, better post the code.

I get one more error:

g:\University work\Year 2\GUI\Hangman\HangmanDlg.cpp(93): error C2065: 'hdc' : undeclared identifier

I've edited the following:

the print protoypte now reads:

void print(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);

implemenation now reads:

void CHangmanDlg::print
( 
  HDC hdc,        // handle to DC
  int nLeftRect,  // x-coord of upper-left corner of rectangle
  int nTopRect,   // y-coord of upper-left corner of rectangle
  int nRightRect, // x-coord of lower-right corner of rectangle
  int nBottomRect // y-coord of lower-right corner of rectangle
)
{
  Ellipse( hdc, nLeftRect, nTopRect, nRightRect, nBottomRect );
}

whilst calling it inside a button which is:

void CHangmanDlg::OnBnClickedCancel()
{
CHangmanDlg::print(hdc, 10, 100, 30, 140 );
	
	OptionsDlg dlg;
	dlg.DoModal();
}

Hmm any ideas?

cheers for your assistnce so far :D

Just do this.

void CHangmanDlg::print
( 
  int nLeftRect,  // x-coord of upper-left corner of rectangle
  int nTopRect,   // y-coord of upper-left corner of rectangle
  int nRightRect, // x-coord of lower-right corner of rectangle
  int nBottomRect // y-coord of lower-right corner of rectangle
)
{
  CDC* pcdc = this->GetDC();
  if ( pcdc)
  {
           pcdc->Ellipse( nLeftRect, nTopRect, nRightRect, nBottomRect );
           if ( this->ReleaseDC( pcdc ) > 0 )
           {
                  // Successfully Released
           }
           else
           {
                  // Error in Releasing Device Context
           }
  }
}
void CHangmanDlg::OnBnClickedCancel()
{
        CHangmanDlg::print(10, 100, 30, 140 );
	OptionsDlg dlg;
	dlg.DoModal();
}

Just do this.

void CHangmanDlg::print
( 
  int nLeftRect,  // x-coord of upper-left corner of rectangle
  int nTopRect,   // y-coord of upper-left corner of rectangle
  int nRightRect, // x-coord of lower-right corner of rectangle
  int nBottomRect // y-coord of lower-right corner of rectangle
)
{
  CDC* pcdc = this->GetDC();
  if ( pcdc)
  {
           pcdc->Ellipse( nLeftRect, nTopRect, nRightRect, nBottomRect );
           if ( this->ReleaseDC( pcdc ) > 0 )
           {
                  // Successfully Released
           }
           else
           {
                  // Error in Releasing Device Context
           }
  }
}
void CHangmanDlg::OnBnClickedCancel()
{
        CHangmanDlg::print(10, 100, 30, 140 );
	OptionsDlg dlg;
	dlg.DoModal();
}

Thanks for the reply, it seems to have done the trick, is they a way of getting a set of co-ordinates on the screen? I want it the fursthers right but a very small cirlce. I've been filling it with some radmon but logical numbers and not getting very far

I also have a few more questions. Can I chose not to fill the circle? so its just an outline? Also can I draw lines with this code? or is that something to do with the paintbrush?

Also can I change the background colour of the entire mfc window? I can't find that in the properities of the dlg box anywhere.

Thanks

John

is they a way of getting a set of co-ordinates on the screen? I want it the fursthers right but a very small cirlce. I've been filling it with some radmon but logical numbers and not getting very far

Sorry but I dont know what you mean. What were the values you used and what do you mean by you didnt get very far? Maybe a problem with the mapping mode. Look for CDC::MapMode()

Can I chose not to fill the circle? so its just an outline? Also can I draw lines with this code? or is that something to do with the paintbrush?

Yes you can. And yes, it has to do with the paintbrush. And I think also with the CPen Object you select. Go through the documentation for CPen and CBrush in MSDN.

Also can I change the background colour of the entire mfc window? I can't find that in the properities of the dlg box anywhere.

Maybe not in Visual C++ 6.0. But I think it was possible in Visual Studio .NET. Anyway do it programmatically. You could probably do it by using the CDC::SetBkColor() method. You will have to search for the COLORREF datatype also.

As regards to question 1 I'm trying to put the circle at a set point on the screen. See here:

www.bsc-coding.com/temp/screenie.png

However I'm finding myself entering different co-ordinates and getting different shapes but none of the desired ones.

As for changing the background color I've located the function which is virtual so I've tried to include my own understanding of implementation which can be as followed:

//optionDlg.cpp file

static COLORREF i = 0x2555555;

..
..
..
COLORREF OptionsDlg::SetBkColor(COLORREF crColor )
{	
	return crColor;
}

but nothing changes I've edited the cancel button to display a message box and the call that SetBkColor but nothing happens... can anyone assist in this dept?

Thanks for your patience, it seems like the msdn is not very clear at explaing things at all! :(

To Change the Background color do this.
Add a protected variable of type CBrush to the Dialog.

e.g.

protected:
	HICON m_hIcon;
	CBrush *brush;

In your Dialog's OnInitDialog function do this intialization.

// TODO: Add extra initialization here
	brush = new CBrush(RGB(0,0,0));

Add a new Handler for the WM_CTLCOLOR event of the Dialog box.
Right click the dialog.
Select Events.
Double CLick WM_CTLCOLOR in the "New Windows Messages/Events" WIndow and select Add Handler and Edit.

At the OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) Function do this.

HBRUSH CBKColorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	//HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	
	// TODO: Change any attributes of the DC here
	
	// TODO: Return a different brush if the default is not desired
 		pDC->SetBkColor(RGB(255, 0, 0));
 		return (HBRUSH)(brush->GetSafeHandle());
}

Hello, thanks for your reply I got it to paint my background blue..wahoo , howver where theres text or a label the area around it still stays gray. I think I've found a function:

int SetBkMode(
  HDC hdc,      // handle to DC
  int iBkMode   // background mode
);

but not quite sure how to implement it

Modify your WM_CTLCOLOR Handler as below.

HBRUSH CBKColorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	//HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	
	// TODO: Change any attributes of the DC here
	
	// TODO: Return a different brush if the default is not desired
	pDC->SetBkMode( TRANSPARENT) ;
 	return (HBRUSH)(brush->GetSafeHandle());
}

Modify your WM_CTLCOLOR Handler as below.

HBRUSH CBKColorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	//HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	
	// TODO: Change any attributes of the DC here
	
	// TODO: Return a different brush if the default is not desired
	pDC->SetBkMode( TRANSPARENT) ;
 	return (HBRUSH)(brush->GetSafeHandle());
}

since your way wouldnt work either , I've come up with this code which works but still leaves the gray are...

BOOL CHangmanDlg::OnEraseBkgnd(CDC* pDC)
{
	// TODO: Add your message handler code here and/or call default
	if (m_bSubmitPressed)
	{	
		// Set brush to desired background color
		CBrush backBrush(RGB(153,204, 255));

		// Save current brush whilst installing new brush.
		CBrush* pOldBrush = pDC->SelectObject(&backBrush);

		// Discover the rectange to erase.
		CRect rect;
		pDC->GetClipBox(&rect);

		// Copy the brush into that reactange.
		pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(), PATCOPY);

pDC->SetBkMode( TRANSPARENT) ;
		// Reinstate original brush.
		pDC->SelectObject(pOldBrush);

		// Tell system we have done the erasing.
		return TRUE;
	}
	else
	  return CDialog::OnEraseBkgnd(pDC);
}

Pity that it didnt work for you. I just did a test and it worked for me. I edited the code after posting it the first time. Did you update it accordingly?


Add a new Handler for the WM_CTLCOLOR event of the Dialog box.
Right click the dialog.
Select Events.
Double CLick WM_CTLCOLOR in the "New Windows Messages/Events" WIndow and select Add Handler and Edit.

I follow the rest but i can't do this since the option is not valid, its grayed out...

This article has been dead for over six months. Start a new discussion instead.