I'm making a plug-in for a program and when faced with the options on how to create a window inside the program with the same style as the program window i opted for using the MFC classes:CDC, CRect, CPen,etc and then using DrawFrameControl i was able to design a simplified version of what i want.
The question now is: i created a close,minimize,etc buttons. But how will i add events to what i have drawn?
I searched online and haven't found a solution, that why i'm asking you guys
Thank you
Here is the code for what i've drawn so far:
CDC dc;
dc.Attach(hdc);
CButton but;
CBrush green(COLOR_GREEN);
CBrush white(COLOR_WHITE);
CRect rect=GetRadarArea();
CRect rect2=GetChatArea();
CPoint ptdown,ptup;
rect.bottom=rect2.top;
rect.TopLeft().x=rect.BottomRight().x-180;
//AddScreenObject (1,"Cenas",rect,true,"nice") ;
//but.Create("Undo",BS_PUSHBUTTON,rect,hdc,MYBUTTONID);
dc.FillRect(&rect,&green);
CRect rect3; //Closebutton
rect3.TopLeft().x=rect.BottomRight().x-10;
rect3.TopLeft().y=rect.TopLeft().y;
rect3.BottomRight().x=rect.BottomRight().x;
rect3.BottomRight().y=rect.TopLeft().y+10;
dc.DrawFrameControl(&rect3,DFC_CAPTION,DFCS_CAPTIONCLOSE);
CRect rect4; //Minimize button
rect4.top=rect3.top;
rect4.bottom=rect3.bottom;
rect4.TopLeft().x=rect3.TopLeft().x-10;
rect4.BottomRight().x=rect3.BottomRight().x-10;
dc.DrawFrameControl(&rect4,DFC_CAPTION,DFCS_CAPTIONMIN);
CRect rect5;
rect5.top=rect3.top;
rect5.bottom=rect3.bottom;
rect5.TopLeft().x=rect.TopLeft().x;
rect5.BottomRight().x=rect3.BottomRight().x;
dc.SetTextColor(COLOR_WHITE);
dc.DrawText("FL Changes List",rect5,DT_CENTER);
CPen pen1 ( 0, 0.2, COLOR_WHITE) ;
dc.SelectObject(&pen1);
dc.MoveTo(rect.TopLeft().x,rect5.BottomRight().y);
dc.LineTo(rect.BottomRight().x,rect5.BottomRight().y);
Add message handlers for WM_LBUTTONDOWN and WM_LBUTTONUP. When you get a click compare the click location to the pseudo-button location(s) to determine if a button was hit.
Related
I am having a property sheet wizard which consists of three buttons Back,Next,Cancel as default at the right bottom corner.Do we have any possibility of moving those wizard buttons towards it's left to the center bottom of the sheet (exactly to the sheet center at the bottom,in detail those buttons should move towards their left to the center of the sheet)?
The short answer is yes. You'll need to derive your own CPropertySheet class and override OnInitDialog () to move the buttons. You need to use the IDs ID_WIZNEXT and ID_WIZBACK to get a pointer to the actual buttons. Once you have the pointer, you can move the buttons just like you would any other control using CWnd::MoveWindow. Here's some sample code (lacking error checking)...
CWnd* pWnd = GetDlgItem(ID_WIZBACK);
CRect rect(0, 0, 0, 0);
pWnd->GetWindowRect(&rect);
rect.OffsetRect(-50, 0);
ScreenToClient(&rect);
pWnd->MoveWindow(&rect);
I am developing MFC based SDI application using CFormView class in VC++. My problem is that I need to load image when the dialog initially appears. How to place image in an SDI application..I know for dialog based applications it can be done using OnInitDialog application.But for SDI application there is no such function. I tried placing the image using OnInitialUpdate() and OnPaint() function. But it failed..What should I do to place the image to dialog when it first appears? Please Help
Thanks in advance
Code as I placed in OnInitialUpdate()
void CECUSimulatorView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
hBitmap = LoadImage(0,_T("F:/ECUSimulator/ECUSimulator_New/res/LedOff.bmp"), IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
ImageLoading();
}
Code for the function ImageLoading()
void CECUSimulatorView::OnInitialUpdate()
{
HDC hDC, hDCToDisplay = NULL;
hDC = CreateCompatibleDC(hDCToDisplay);
SelectObject(hDC,hBitmap);
hDCToDisplay = ::GetDC(m_picture.m_hWnd);
m_picture.GetWindowRect(&picRect);
BitBlt(hDCToDisplay,0 , 0, (picRect.right - picRect.left), (picRect.bottom -picRect.top), hDC, 0 ,0 ,SRCCOPY);
DeleteDC(hDC);
DeleteDC(hDCToDisplay);
}
Here
HANDLE hBitmap;
CStatic m_picture; //Picture Control
CRect picRect; //Picture Control Rect
I removed the code from OnInitialUpdate() and placed it in OnPaint() function as follows:
void CECUSimulatorView::OnPaint()
{
CPaintDC dc(this); // device context for painting
hBitmap = LoadImage(0,_T("F:/ECUSimulator/ECUSimulator_New/res/LedOff.bmp"), IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
ImageLoading();
}
Calling LoadImage() in OnInitialUpdate() is ok, the actual painting needs to be done in one of the two following ways:
a) in CECUSimulatorView::OnDraw() -- easier, but may introduce flickering
b) override the OnPaint() function of the m_picture control using ClassWizard and draw the picture there
[the comments in the previous answer was getting very extended, hence a new answer]
a) derive a new class (say CMyPicture) based on CStatic, change m_picture to this new class
b) in CMyPicture, create a handler for WM_PAINT, this will normally be called CMyPicture::OnPaint()
c) change your ImageLoading() function to take a CDC *pDC as parameter and use this DC to render the image
d)
void CMyStatic::OnPaint(void)
{ CPaintDC dc(this);
ImageLoading(&dc); // or even move the painting logic here
}
NOTE: you can load the image in OnInitialUpdate(), no need to load it each time you are painting
An example (for a dialog, but the painting logic should not be affected) in this SO Answer.
I found the answer for my problem.
I used CBitmap class as follows:
CBitmap m_bBitmap1;
In OnInitialUpdate() I wrote as follows :
m_bBitmap1.LoadBitmapW(IDB_BITMAP1);
In OnPaint() I wrote as follows:
m_picture.SetBitmap(m_bBitmap1);
Wherever(In which all functions)need to load image just call the above line of code in corresponding functions..
I'm a little new to using MFC and VC++ as such, but I'm doing this as part of a Course and i Have to stick to VC++.
http://www.cprogramming.com/tutorial/game_programming/same_game_part1.html
This is the tutorial I have been following to make a simple samegame. However when i try to display score, the score is getting displayed Underneath or outside my application window, even though I've displayed score before calling updateWindow(). I've tried various methods but I am kinda lost here.
Here is the code I'm using to Display the score:
void CSameGameView::updateScore()
{
CSameGameDoc* pDoc = GetDocument();
CRect rcClient, rcWindow;
GetClientRect(&rcClient);
GetParentFrame()->GetWindowRect(&rcWindow);
int nHeightDiff = rcWindow.Height() - rcClient.Height();
rcScore.top=rcWindow.top + pDoc->GetHeight() * pDoc->GetRows() + nHeightDiff;
rcScore.left=rcWindow.left + 50;
rcScore.right=rcWindow.left + pDoc->GetWidth() - 50;
rcScore.bottom=rcScore.top + 20;
CString str;
double points = Score::getScore();
str.Format(_T("Score: %0.2f"), points);
HDC hDC=CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL);
COLORREF clr = pDoc->GetBoardSpace(-1, -1); //this return background colour
pDC->FillSolidRect(&rcScore, clr);
DrawText(hDC, (LPCTSTR) str, -1, (LPRECT) &rcScore, DT_CENTER);
}
Thank you for any help and I'm sorry if the question doesn't make sense or in ambiguous.
There are several problems with your code:
1. The hDC you are creating is going to have coordinates relative to the desktop window. To paint text in your window, use CClientDC like this: CClientDC dc(this); (see http://msdn.microsoft.com/en-US/library/s8kx4w44%28v=vs.80%29.aspx)
2. The code you have will leak a DC every time the function is called. The method in #1 will fix that.
3. Your paint code should be done in the CView::OnDraw. There you get a DC passed to you and you don't have to worry about creating one with CClientDC. Set the variables you want to draw (e.g. your points or score), store them as class members and draw them in CView::OnDraw.
Don't do the drawing in your updateScore method.
Make sense? Hang in there!
I am trying to make a paint application in MFC using visul basic c++ 6.0 i have already created a window using Create function and also have created a toolbar with a tool line but i am stuck on how to code for the line because the function i know goes like d.lineTo(x,y) and d.Moveto(x2,y2) but it comes under the line function how do i use OnLButtonDown to Trap the co-ordiantes or is there any other way i can draw a line ..? any help will be useful
have a look at the MFC Scribble tutorial :
http://msdn.microsoft.com/en-us/library/aa716527%28v=vs.60%29.aspx)
It will get you started on how to handling mouse click and mouse move and drawing.
M.
Ok, you're going to have to override several member functions to do this. I've outlined an approach below. My example below deals with a single line-drawing operation (from mouse down, to mouse up). An exercise for you, is to make it so that once you've done one, you can then do another at a different place. It's easy, btw!
CWnd::OnLButtonDown(UINT _flags, CPoint _pt);
CWnd::OnLButtonUp(UINT _flags, CPoint _pt);
CWnd::OnMouseMove(UINT _flags, CPoint _pt);
CWnd::OnPaint()
Apologies if some of these function signatures are wrong! Add some members to your window class:
// at the top of your file
#include <vector>
// in your class
typedef std::vector<POINT> PointVector;
PointVector m_Points;
CYourWnd::OnLButtonDown(UINT _flags, CPoint _pt);
{
// NOTE: For more than one set of drawing, this will be different!
m_Points.clear();
m_Points.push_back(POINT(_pt.x, _pt.y));
}
CYourWnd::OnMouseMove(UINT _flags, CPoint _pt);
{
if(_flags & MK_LBUTTON)
{
const POINT& last(m_Points.back());
if(_pt.x != last.x || _pt.y != last.y)
{
m_Points.push_back(POINT(_pt.x, _pt.y));
Invalidate();
}
}
}
CYourWnd::OnPaint()
{
CPaintDC dc(this);
CRect rcClient; GetClientRect(&rc);
FillSolidRect(&rcClient, RGB(255, 255, 255));
if(m_Points.size())
{
dc.MoveTo(m_Points[0].x, m_Points[0].y);
for(PointsVector::size_type p(1);
p < m_Points.size();
++p)
dc.LineTo(m_Points[p].x, m_Points[p].y);
}
}
Obviously, this is crude and gives you a single drawing operation. Once you click the left button down again, it erases what you've done. So, once you have this working:
Make it so you can draw an unlimited amount of lines. You could accomplish this in several ways such as an additional container (to store vectors), or even drawing-operation classes that you can store in a single vector and then execute.
This solution may well flicker. How might you stop this? Perhaps OnEraseBkgnd holds the clue...
How about more colours?
All signs point towards creating some drawing-classes that encapsulate this for you, but I hope this has got you started.
I'm trying to draw a CSpinButtonCtrl as a buddy of an edit box in Windows 7. When my CEdit window is 12 dialog units high, the spin buttons are scaled really badly and the top border is clipped off.
This looks pretty ugly. How can I get around this, or must I restrict my CEdit controls to be 14 dialog units high?
My controls are declared thusly:
EDITTEXT IDC_LOWER_EDIT,51,20,63,12,ES_MULTILINE | ES_WANTRETURN,WS_EX_RIGHT
CONTROL "",IDC_LOWER_SPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,104,17,11,12
I've tried resizing using MoveWindow, but that doesn't help. Any ideas?
I found the code for changing the width
CWnd* pWnd = GetDlgItem( IDC_SPIN1 );
CRect rect;
pWnd->GetWindowRect( &rect );
ScreenToClient( &rect );
rect.right += 5 ; // make 5 pixels wider
pWnd->MoveWindow(&rect) ;
Put it in the OnInitDialog().
I think I would go for #2 - are you that pressed for screen space?
Another option is: leave it unattached (remove UDS_ALIGNRIGHT) and place it right next to the edit control.