|
|
I am trying to figure out why my CEdit box does not appear, even though I've instantiated it to the rectangle (10,70,100,120) just like my buttons. Is it not allowed to be attached to a CFrameWnd?
class MainWindow : public CFrameWnd
{
public:
CButton start;
CButton end;
CEdit textbox;
MainWindow()
{
Create(NULL, "MFC Window");
start.Create("Start", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(10,10,100,30), this, 1);
end.Create("End", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, CRect(10,40,100,60), this, 2);
textbox.Create(ES_READONLY|ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL, CRect(10,70,100,120), this, 3);
}
void ButtonStart();
void ButtonEnd();
void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
void OnLButtonDown(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
void MainWindow::ButtonStart()
{
MessageBox("Start");
}
void MainWindow::ButtonEnd()
{
MessageBox("End");
}
void MainWindow::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (nChar == VK_ESCAPE)
MessageBox("Escape button pressed");
}
void MainWindow::OnLButtonDown(UINT nFlags, CPoint point)
{
MessageBox("Left button clicked");
}
BEGIN_MESSAGE_MAP(MainWindow, CFrameWnd)
ON_BN_CLICKED(1, MainWindow::ButtonStart)
ON_BN_CLICKED(2, MainWindow::ButtonEnd)
ON_WM_KEYDOWN()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
class MyApp : public CWinApp
{
public:
BOOL InitInstance()
{
m_pMainWnd = new MainWindow();
m_pMainWnd->ShowWindow(SW_SHOW);
return TRUE;
}
};
MyApp theApp;
|
|
|
|
|
Cyrilix wrote: textbox.Create(ES_READONLY|ES_LEFT|ES_MULTILINE|ES_AUTOVSCROLL
Wouldn't you need a WS_VISIBLE in the create method for it to show up?
Why is common sense not common?
Never argue with an idiot. They will drag you down to their level where they are an expert.
Sometimes it takes a lot of work to be lazy
|
|
|
|
|
You're right...
Does this have to be specified for every single MFC class? The reason why I have it in the buttons is because I stole it from an example.
|
|
|
|
|
Cyrilix wrote: every single MFC
Only for visible controls and only if you really want to see them.....
Why is common sense not common?
Never argue with an idiot. They will drag you down to their level where they are an expert.
Sometimes it takes a lot of work to be lazy
|
|
|
|
|
...or you can always show them later with ShowWindow()
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
If you don't include the WS_VISIBLE style, the window won't be visible. Crazy, I know.
|
|
|
|
|
Hi,
I use CDC* pDC->DrawText(" number ") in OnDraw() to update text to a frame. I then call InvalidateRect(NULL,FALSE) to display the text. What is the better way of display text without calling InvalidateRect() because OnDraw() with InvalidateRect() slow down application quite a lot. Thanks.
|
|
|
|
|
If you're doing this right you should not have to call InvalidateRect(). OnDraw only gets called when some Rect is alreay invalid, that's why windows generated the WM_PAINT to get you to call OnDraw in the first place. If your text doesn't appear without this then something else is wrong.
I'm not sure what you mean by
gurucplusplus wrote: update text to a frame . With most windows you can call SetWindowText to set the text that's displayed. If this is a custom window class or an owner draw control then DrawText might be right
Nothing is exactly what it seems but everything with seems can be unpicked.
|
|
|
|
|
You're causing recursive repeated calls to OnDraw() by calling InvalidateRect()
from within OnDraw(). That'll certainly slow things down
gurucplusplus wrote: What is the better way of display text without calling InvalidateRect()
Don't call InvalidateRect()!
Mark
-- modified at 14:29 Thursday 7th June, 2007
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
How can I update this text to graphic without calling invalidateRect()?
|
|
|
|
|
When you call DrawText, you ARE updating the text.
You use Invalidate methods to force a repaint from outside of OnPaint/OnDraw.
For example, if the text you are drawing changes as the result of some process in the application
and you want the window updated to reflect the change, then you'd call Invalidate. This will
mark the given area of the window as invalid. On the next WM_PAINT message (which will call
OnDraw() for CViews) you will call DrawText() with the updated text.
I hope that made sense
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
So, If my text drawn changes I have to call invalidateRect to mark invalid for the next WM_PAINT message to update the text. Where should I call invalidaterect then? Not in ondraw()? thanks
|
|
|
|
|
gurucplusplus wrote: If my text drawn changes I have to call invalidateRect to mark invalid for the next WM_PAINT message to update the text. Where should I call invalidaterect then?
Right. If the text characters never change (like pDC->DrawText("Text") then there's no reason
to ever call InvalidateRect() because every time the window needs repainting the text will
just be redrawn.
Now suppose you are drawing the text of a string that changes (pDC->DrawText(str)). The user
does something that causes the value of str to change and you want to reflect that change in the
window. Any time after you change str, call InvalidateRect() to mark the area as invalid. When
the resulting WM_PAINT is received by the window, CView::OnPaint() will call OnDraw(). In your
OnDraw() override, you call pDC->DrawText(str), drawing the new text on the window.
Also remember, WM_PAINT messages are LOW priority (they can get bumped to the back of the message
queue). If you need an instant update, like if the text string is changing as the result of a
timer (like in a clock implementation), then you can add a call to UpdateWindow() right after
the call to InvalidateRect(). This will cause a WM_PAINT to be sent immediately.
Remember that, when responding to WM_PAINT, it is your responsibility to validate the region
of the window that is invalid to prevent repeated WM_PAINT messages. Most of the time this
is done for us by MFC or the default window message handling. So if you invalidate regions of
a window while it's trying to validate it, the WM_PAINT messages keep coming.
If you want to see the recursive action/result of doing this in your OnDraw(), try this in your
OnDraw(). This consumes all the CPU time of one of my processors and renders dialog controls
useless:
Invalidate();
UpdateWindow();
return;
I'm actually surprised it doesn't crash
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
|
|
One way is to use "command enablers"...
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
...
ON_UPDATE_COMMAND_UI(ID_BUTTONID, OnUpdateButton)
...
END_MESSAGE_MAP()
void CMyFrameWnd::OnUpdateButton(CCmdUI* pCmdUI)
{
if (some_condition)
pCmdUI->Enable(TRUE);
else
pCmdUI->Enable(FALSE);
}
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Mark thanks for reply, but I have dialog based application, there is no ON_UPDATE_COMMAND_UI
|
|
|
|
|
Then try in OnPaint.
if (condition)
button->EnableWindow (TRUE);
else
button->EnableWindow (FALSE);
is not the best way, but it will maybe work
NOTE: I have not read the article, so im not sure if I'm saying something catastrofical :P
Greetings.
--------
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
|
|
|
|
|
Well, anytime after a toolbar is created and the buttons are added to it, you can enable and
diable buttons when you need to:
// Disable a button
m_ToolBar.GetToolBarCtrl().EnableButton(ID_BUTTON1, FALSE);
// Enable a button
m_ToolBar.GetToolBarCtrl().EnableButton(ID_BUTTON1, TRUE);
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Mark, many thanks it works , but button was not greyed .
|
|
|
|
|
Romiks wrote: but button was not greyed
Looking at the article, it looks like there's a separate image list for disabled.
Are the images in that image list the same as the regular images?
You could try omitting the last parameter in the call to LoadTrueColorToolBar() - the system
should do its default "greying" for disabled buttons.
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Mark, many thanks for help. I have tried to omit the last parameter, but it doesn't work .
I will try to use CButton instead of tool bar.
|
|
|
|
|
So the buttons diable but they don't look disabled?
Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
|
|
|
|
|
Hi Mark,
If I ommited the last parameter, buttons are not disabled.
|
|
|
|