help needed displaying text
-
Hi sorry for the long code snippet...i didnt know where the error could possibly be thus the long extract.;p..anyway the code below attempts to draw 2 axes and label them.However, both x&y axis label appears twice.One set with a smaller font and right escapement, the other set with bigger font and failed escapement(the text is not rotated). Does anyone know why?I've flipped through books but nothing seemed wrong to me.
CPen axisPen (PS_SOLID, 2, RGB(0,0,0)); CFont axisXFnt,axisYFnt; CPen *pOldPen; CFont *pOldFont; LOGFONT lf; TEXTMETRIC tm; int fontSize=8; ZeroMemory(&lf, sizeof(lf)); lstrcpy(lf.lfFaceName,"Arial"); lf.lfHeight=fontSize; axisXFnt.CreateFontIndirect(&lf); pDC->GetTextMetrics(&tm); int charWidth = tm.tmAveCharWidth; m_AxisXName="Values"; m_AxisYName="Time"; pOldPen = pDC->SelectObject(&axisPen); //draw x-axis pDC->MoveTo(m_origin); pDC->LineTo(m_endPoint); //draw y-axis pDC->MoveTo(m_origin); pDC->LineTo(m_endPoint2); pDC->SelectObject(pOldPen); //label x-axis pOldFont = (CFont*) pDC->SelectObject(&axisXFnt); pDC->SetTextAlign(TA_CENTER|TA_BOTTOM); pDC->TextOut((graphRect.Width() / 2) - ((m_AxisXName.GetLength() / 3)*charWidth),graphRect.top+15,m_AxisXName); //label y-axis lf.lfEscapement=900; axisYFnt.CreateFontIndirect(&lf); pDC->SelectObject(&axisYFnt); pDC->SetTextAlign(TA_BOTTOM|TA_CENTER); pDC->TextOut(graphRect.left+10,((graphRect.Height() / 2) + ((m_AxisYName.GetLength() / 3)*charWidth)),m_AxisYName); pDC->SelectObject(pOldFont);
-forgive me, im a newb- -
Hi sorry for the long code snippet...i didnt know where the error could possibly be thus the long extract.;p..anyway the code below attempts to draw 2 axes and label them.However, both x&y axis label appears twice.One set with a smaller font and right escapement, the other set with bigger font and failed escapement(the text is not rotated). Does anyone know why?I've flipped through books but nothing seemed wrong to me.
CPen axisPen (PS_SOLID, 2, RGB(0,0,0)); CFont axisXFnt,axisYFnt; CPen *pOldPen; CFont *pOldFont; LOGFONT lf; TEXTMETRIC tm; int fontSize=8; ZeroMemory(&lf, sizeof(lf)); lstrcpy(lf.lfFaceName,"Arial"); lf.lfHeight=fontSize; axisXFnt.CreateFontIndirect(&lf); pDC->GetTextMetrics(&tm); int charWidth = tm.tmAveCharWidth; m_AxisXName="Values"; m_AxisYName="Time"; pOldPen = pDC->SelectObject(&axisPen); //draw x-axis pDC->MoveTo(m_origin); pDC->LineTo(m_endPoint); //draw y-axis pDC->MoveTo(m_origin); pDC->LineTo(m_endPoint2); pDC->SelectObject(pOldPen); //label x-axis pOldFont = (CFont*) pDC->SelectObject(&axisXFnt); pDC->SetTextAlign(TA_CENTER|TA_BOTTOM); pDC->TextOut((graphRect.Width() / 2) - ((m_AxisXName.GetLength() / 3)*charWidth),graphRect.top+15,m_AxisXName); //label y-axis lf.lfEscapement=900; axisYFnt.CreateFontIndirect(&lf); pDC->SelectObject(&axisYFnt); pDC->SetTextAlign(TA_BOTTOM|TA_CENTER); pDC->TextOut(graphRect.left+10,((graphRect.Height() / 2) + ((m_AxisYName.GetLength() / 3)*charWidth)),m_AxisYName); pDC->SelectObject(pOldFont);
-forgive me, im a newb-Some notes: When rotating a font, you also need to set the lfOrientation = 900 in the LOGFONT structure. Personally, I never rely on the GDI o correctly position text for me. I use GetTextExtent() and calculate the exact position the text should be displayed and pass the start coordinates in to TextOut(). Drawing twice: Is this being done in an OnDraw() function? If it is you need to call Validate() or use a CPaintDC() oobject which automatically validates the client area after the DC is released. Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003
-
Some notes: When rotating a font, you also need to set the lfOrientation = 900 in the LOGFONT structure. Personally, I never rely on the GDI o correctly position text for me. I use GetTextExtent() and calculate the exact position the text should be displayed and pass the start coordinates in to TextOut(). Drawing twice: Is this being done in an OnDraw() function? If it is you need to call Validate() or use a CPaintDC() oobject which automatically validates the client area after the DC is released. Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003
thks I didnt know how to use GetTextExtent().I'll read up on it. Anyway the codes are contained in a function of a separate class which are called by the OnPaint() function of my CDialog class. Is it counted? When should i call Validate() then? Anyway do u know the difference between Validate() and InValidate()? once again,thks
-
thks I didnt know how to use GetTextExtent().I'll read up on it. Anyway the codes are contained in a function of a separate class which are called by the OnPaint() function of my CDialog class. Is it counted? When should i call Validate() then? Anyway do u know the difference between Validate() and InValidate()? once again,thks
If its in your on paint and your not using a CPaintDC object then you must call Validate() at the end of the procedure otherewise windows will send you another WM_PAINT message, and then another until the area is validated or is obscured completely by another window. CPaintDC does a validate() call for you automatically in its destructor, but if your using GetDC()/ReleaseDC() in the OnPaint, you need to call it. Validate() syas to windows, this window is upto date and does not need to be-redrawn Invalidate() says to windows that this window (or a rectangle of it) needs to be re-drawn. Windows will queue a WM_PAINT message for the window which had an invalidate() call on it. GetTextExtent() is a function to be called on the DC
CString text = "I want to know my length!";
CSize textSize = pDC->GetTextExtent(text, text.GetLength());textSize.cx = length of text in pixels for the current output font textSize.cy = Height of text in pixels for the current output font With this info you could centre you text using
CRect window;
GetWindowRect(&window);
x = (window.Width() - textSize.cx) / 2;
y = 500; // or whateverpDC->TextOut(x, y, text, text.GetLength());
Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003
-
If its in your on paint and your not using a CPaintDC object then you must call Validate() at the end of the procedure otherewise windows will send you another WM_PAINT message, and then another until the area is validated or is obscured completely by another window. CPaintDC does a validate() call for you automatically in its destructor, but if your using GetDC()/ReleaseDC() in the OnPaint, you need to call it. Validate() syas to windows, this window is upto date and does not need to be-redrawn Invalidate() says to windows that this window (or a rectangle of it) needs to be re-drawn. Windows will queue a WM_PAINT message for the window which had an invalidate() call on it. GetTextExtent() is a function to be called on the DC
CString text = "I want to know my length!";
CSize textSize = pDC->GetTextExtent(text, text.GetLength());textSize.cx = length of text in pixels for the current output font textSize.cy = Height of text in pixels for the current output font With this info you could centre you text using
CRect window;
GetWindowRect(&window);
x = (window.Width() - textSize.cx) / 2;
y = 500; // or whateverpDC->TextOut(x, y, text, text.GetLength());
Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003
-
If its in your on paint and your not using a CPaintDC object then you must call Validate() at the end of the procedure otherewise windows will send you another WM_PAINT message, and then another until the area is validated or is obscured completely by another window. CPaintDC does a validate() call for you automatically in its destructor, but if your using GetDC()/ReleaseDC() in the OnPaint, you need to call it. Validate() syas to windows, this window is upto date and does not need to be-redrawn Invalidate() says to windows that this window (or a rectangle of it) needs to be re-drawn. Windows will queue a WM_PAINT message for the window which had an invalidate() call on it. GetTextExtent() is a function to be called on the DC
CString text = "I want to know my length!";
CSize textSize = pDC->GetTextExtent(text, text.GetLength());textSize.cx = length of text in pixels for the current output font textSize.cy = Height of text in pixels for the current output font With this info you could centre you text using
CRect window;
GetWindowRect(&window);
x = (window.Width() - textSize.cx) / 2;
y = 500; // or whateverpDC->TextOut(x, y, text, text.GetLength());
Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003
-
i tried Validate(pDC) and this->Validate(). All of them gave me the same error msg(undeclared identifier)... Should i place it before or after ReleaseDC() anyway? thks.
Ooops, sorry its:
ValidateRect()
:-O:-O:-O Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003 -
Ooops, sorry its:
ValidateRect()
:-O:-O:-O Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003 -
it's ok;) i called ValidateRect(graphRect) jus before ReleaseDC()...where graphRect is a CRect...is that right?
Thats should work ik. But just 1 small possible danger. If the update rectangle for the WM_PAINT call (which comes in a PAINTSTRUCT) is slightly larger than your graphRect then this could cause additional WM_PAINT messages to be sent to you. I usually do:
void X::OnPaint()
{
CDC pDC = GetDC();
// paint stuff
pDC_>ReleaseDC();
CPaintDC dc; // construct/destructs and validates the paint region
}Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003
-
Thats should work ik. But just 1 small possible danger. If the update rectangle for the WM_PAINT call (which comes in a PAINTSTRUCT) is slightly larger than your graphRect then this could cause additional WM_PAINT messages to be sent to you. I usually do:
void X::OnPaint()
{
CDC pDC = GetDC();
// paint stuff
pDC_>ReleaseDC();
CPaintDC dc; // construct/destructs and validates the paint region
}Roger Allen Sonork 100.10016 Were you different as a kid? Did you ever say "Ooohhh, shiny red" even once? - Paul Watson 11-February-2003
i put "CPaintDC dc" but an error was returned stating no appropriate default constructor available, so i tried "CPaintDC dc(this)" n it complied successfully but it wiped out all i've drawn earlier. here's my code... void CGrapDlg::OnPaint() { CWnd* graphFrame = (CWnd*)GetDlgItem(IDC_GRAPH_FRAME); CDC* pDC = graphFrame->GetDC(); plotGraph.Plot(pDC); ReleaseDC(pDC); CPaintDC dc(this); } have a nice weekend n thks :-D