How to do double buffering in C++ Builder 2010? - c++

I have a code that continuously draws lines. The problem is that the lines keep flickering every time form is refreshed. I heard I should use double buffering, but how to do it? I'm using c++ builder 2010. Here is my code:
void __fastcall TForm2::PaintBox1Paint(TObject *Sender)
{
Form2->Refresh();
TPoint P;
::GetCursorPos( &P );
P = ScreenToClient( P );
int XX;
int YY;
if (P.x<240)
{
XX=15;
YY= ((445-P.y)*(XX-P.x)/(240-P.x)+P.y);
}
else if(P.x==240)
{
XX=240;YY=-5;
}
else
{
XX=465;
YY= ((445-P.y)*(XX-P.x)/(240-P.x)+P.y);
}
int delta=2*(445-YY);
this->Canvas->MoveTo(241,445);
this->Canvas->LineTo(XX,YY);
while(0<YY&&YY<480&&YY!=445)
{
XX=abs(480-XX);
YY-=delta;
this->Canvas->LineTo(XX,YY);
}
}

Certainly you need to remove the call to Form2->Refresh. That asks the form to repaint itself immediately. That cannot help.
Secondly, your code handles the OnPaint event of a TPaintBox control. You are expected to paint on the canvas of TPaintBox rather than the form's canvas. Change all references to this->Canvas to instead refer to PaintBox1->Canvas. You may also need to correct the coordinates used to when painting.
Alternatively you could keep your existing code, and remove the paint box altogether. In which case take your current code and attach it to the form's OnPaint handler instead.
As for double buffering, you could let the VCL do it for you. Set the form's DoubleBuffered property to true. That is all you need to do, although be warned that it can have undesirable consequences on the visual appearance of certain control in certain themes. Be alert for any problems.
If you want to do the double buffering your self it is easy enough. Create a TBitmap. Set its size appropriately. Draw your lines to the Canvas of the bitmap. Then draw the bitmap onto the paint box canvas, or the form's canvas.

Related

Change Expand/Collapse icon in wxDataViewCtrl

I want to replace the Expand/Collapse icon with my icons in wxDataViewCtrl.
I am not able to find a way to set my expand/collapse icons.
Is there any API available for the same?
or
Do I need to modify the wxDataViewCtrl source directly? your prior experience can help me.
The main point of having wxDataViewCtrl in the first place is that it wraps the corresponding native control, so changing its look and feel is not supported.
This being said, if you're using its generic implementation, as is always the case under MSW, you can actually change it by defining a custom wxRendererNative-derived class and overriding its DrawTreeItemButton() method. But this would affect all the other controls drawing tree-like buttons, including, obviously, generic wxTreeCtrl itself but also wxPropGrid. Generally speaking I wouldn't recommend doing this.
I do not know whether it is right approach or wrong, Here I found a way to achieve my thing based on VZ.suggestion.
class MyRenderer : public wxDelegateRendererNative
{
public:
MyRenderer() : wxDelegateRendererNative(wxRendererNative::GetDefault()) { }
virtual void DrawTreeItemButton(wxWindow *win,
wxDC& dc,
const wxRect& rect,
int flags = 0)
{
MyCustomCtrl* pWin = dynamic_cast<MyCustomCtrl*>(win->GetParent());
if (pWin != nullptr)
{
// Draw my choice of expand/collapse button.
}
else
{ // Do not affect other controls that are using this drawing.
wxRendererNative::GetDefault().DrawTreeItemButton(win, dc, rect, flags);
}
}
};
This way I can override the
virtual void DrawItemSelectionRect(wxWindow *win,
wxDC& dc,
const wxRect& rect,
int flags)
and many more native drawings.

QToolbar force expand on too many QActions

Hi all is there any way to automatically expand a QToolbar if there is too many QActions in?
Using Qt version 5.4.1 C++11
Ive tried :ui->mainToolBar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred)
But this only expands it horizontally. I need it to expand vertically like the Expand button does.
Always expanding a toolbar vertically is not possible as far as I know (never seen it). A solution would be to add multiple toolbars. This way, you can arrange them one under the other.
What you can try is to add a custom widget to the toolbar that grows horizontally. This was proposed here by using a QScrollArea... Not sure whether this is exactly what you want, but it may work good enough.
This is how you can make a function to expand/retract a QToolbar. Firstly using a Forloop get all the child widgets from the QToolbar. You can use a Bool to lock to only get the first Widget which is the Expanding button/Action.
bool get_first_action{true};
for(QWidget* widget : ui->myToolBar->findChildren<QWidget*>())
{
if(get_first_action)
{
get_first_action = false;
// This is the expanding action!
m_action_expand = widget;
}
}
Or you can do this which is probably a bit safer.
for(QWidget* widget : ui->myToolBar->findChildren<QWidget*>())
{
if(widget->objectName() == "qt_toolbar_ext_button")
{
// This is the expanding action!
m_action_expand = widget;
}
}
Once you have the sneaky expanding action assign it to a member varible
// Make sure to initialize this in the constructor!
// m_action_expand = new QWidget(this // parent)
QWidget* m_action_expand;
Now create a handy function with a good name;
void MainWindow::forceToolbarExpand()
{
// Grab the position of the expanding action/widget
QPointF pos(m_action_expand->pos());
// Create a fake/dummy event that replicates the mouse button press
QMouseEvent event_press(QEvent::MouseButtonPress, pos, Qt::LeftButton,0, 0);
// Create a fake/dummy event that replicates the mouse button release
QMouseEvent event_release(QEvent::MouseButtonRelease, pos, Qt::LeftButton,0, 0);
// These two events together will fire the QAction::Toggled signal.
// Make sure to send the events!
QApplication::sendEvent(m_action_expand, &event_press);
QApplication::sendEvent(m_action_expand, &event_release);
}
And there we have it your QToolbar, if it can be expanded/retracted now will when you call this function. I'm not too sure if you can directly Moc/fake the toggled event but you can try it. I know this method works so yeah.

GLUT animation with glutPostRedisplay

Is there any difference between calling glutPostRedisplay() at the end of my display function and using an idle function callback that does nothing but call my display function? I have seen both ways used in examples and cannot tell the difference by observation.
A main loop generally looks like this:
Process and handle events
calling stuff like glutKeyboardFunc/glutMouseFunc.
Advance/update 3D state (physics/animation etc)
typically in glutIdleFunc
Re-draw the scene if needed
use glutDisplayFunc
glutPostRedisplay simply sets a flag, that tells glut to call the display callback on the next loop iteration. It doesn't actually call display [1] [2].
If you have a game, which always updates every frame this might not be that useful. Maybe if you're alt-tabbed or dragging the window you don't need to be calling display. Or you might be frame limiting by dropping frames (although I'd suggest this).
void idle()
{
...
animatedThing.value += deltaTime
glutPostRedisplay(); //scene is always changing. always call display
}
Having a "dirty" flag becomes more useful when you don't need to re-render continuously. Maybe in something like a 3D modelling package where there isn't any animation and you only move the camera occasionally. Or a GUI where you only need to update when you hover and click on stuff.
void mousedown(int button, int state, int x, int y)
{
if (clickedGUI(x, y))
glutPostRedisplay();
}
void idle()
{
...
if (myKeys[MOVE_VIEW_FORWARD])
{
view.z -= deltaTime;
glutPostRedisplay();
}
}
Anyway, to answer your question, no, there's probably not much difference. However...
I'd put the glutPostRedisplay in idle as above. Calling from within display works but gives up some control you might want later. It's essentially this:
bool shouldDraw = true;
while (1)
{
// check events, input etc
// idle/update state
if (shouldDraw)
{
shouldDraw = false;
// draw
shouldDraw = true;
}
}
I also wouldn't call display from idle from a design perspective as it removes some control from glut. For example if there's a case where glut needs to override the post-redisplay (not that I know of one) it won't be able to.

CStatic does not invalidate every time its text is changed

I am trying to dynamically change the text of a CStatic control. My member variable is called mStatic of the type CStatic. I have changed the ID to IDC_MYSTATIC instead of IDC_STATIC.
I am calling mStatic.SetWindowText("asdfasdf") when I want to change the text of the control. I do this periodically in a timer.
Now I have the problem that the previous text is not erased after I call the SetWindowText(). It just keeps piling up until I get a mess on the screen.
The parent window has the layered property with a bitmap background. I have also set the color_key property so a certain color of the bitmap is viewed as transparent (I.e. It will not be drawn and will let mouse messages through). The mStatic control is drawn on the parts not transparent, that have a bitmap background.
Why isn't the window invalidating?
Had the same issue. The following code fixed it:
mStatic.SetWindowText("New text");
CRect rect;
mStatic.GetWindowRect(&rect);
ScreenToClient(&rect);
InvalidateRect(&rect);
UpdateWindow();
Perhaps your static text control have a SS_SIMPLE style enabled. You can check style flags on resource file or using GetStyle().
Static control with SS_SIMPLE style displays text faster, but also - as MSDN describes -
"SS_SIMPLE static controls do not clear the control's display area when displaying text. If a shorter string is displayed, the part of the original string that is longer than the new shorter string is displayed."
Clear SS_SIMPLE from style flags and CStatic will behave 'normally'.
This knowledge base support article describes the same problem when the SetWindowText() call is made from another thread. Is that what your timer is doing?
If so the solution could simply be to:
mStatic.SetWindowText("asdfasdf");
CRect clientRect;
mStatic.GetClientRect(clientRect);
mStatic.InvalidateRect(clientRect);
As mentioned by others already, a static control doesn't necessarily erase its background prior to drawing the text.
I find it a much better solution to subclass the static control and force the invalidation of the control from there. This enables one to easily implement it on all static texts with transparent background, without having to do extra calls to invalidate the control from its parent class.
One way to catch a change of the control's text from within the control itself is to react to the WM_SETTEXT message and force the invalidation from there:
int CStaticT::OnSetText(LPCTSTR text)
{
LRESULT res = Default();
Invalidate();
UpdateWindow();
return res;
}
Here is a brief example, extracted from one of my classes, of how such a subclassed control could look like:
//////////////////////////////////////////////////////////////////////////
// Header
//////////////////////////////////////////////////////////////////////////
class CStaticT : public CStatic
{
DECLARE_DYNAMIC(CStaticT)
public:
CStaticT();
virtual ~CStaticT();
protected:
afx_msg int OnSetText(LPCTSTR text);
DECLARE_MESSAGE_MAP()
private:
BOOL m_InitialSet;
};
//////////////////////////////////////////////////////////////////////////
// Implementation
//////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CStaticT, CStatic)
CStaticT::CStaticT()
{
m_InitialSet = FALSE;
}
CStaticT::~CStaticT()
{
}
BEGIN_MESSAGE_MAP(CStaticT, CStatic)
ON_WM_SETTEXT()
END_MESSAGE_MAP()
int CStaticT::OnSetText(LPCTSTR text)
{
LRESULT res = Default();
// I've noticed issues when this forces the invalidation
// of the static control before the parent's background
// is painted completely.
// This is a cheap workaround, skipping the initial setting
// of the text by the subclassing call.
// You have to test if this works out for your environment.
if (!m_InitialSet)
{
m_InitialSet = TRUE;
return res;
}
// Force of the invalidation
Invalidate();
UpdateWindow();
return res;
}

Is there any function that removes icon, using visual studio 6.0?

I couldn't find any function which removes a loaded icon. Please help me:))
Or is there any other function which makes an icon hidden such as setVisible(false), or delete?
if(GetDlgItem (IDC_BUTTON1)->IsWindowEnabled())
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
dc.DrawIcon(DT_CENTER,DT_CENTER, m_hIcon);
}
if(GetDlgItem (IDC_BUTTON1)->IsWindowEnabled()==0) //disabled
{ dc.SetTextColor(RGB(192,192,192));
m_hIcon = AfxGetApp()->RemoveIcon(IDI_ICON1);//HERE! // I try another icon
//which is null, however it didn't work because it is transparent.
}
Instead of painting another icon when the button is disabled, either draw a rectangle using a null pen and a brush of the background colour or just invalidate the icon-rectangle with bErase as TRUE when you disable the button
This code is a bit strange, especially since you don't give us any context. What is dc, a device context? Is this code inside of a OnPaint message handler function? And either way, why are you drawing the icon manually instead of letting the button control do it automatically?
The simpler approach is to monitor the enabled state of the control by listening for WM_ENABLE messages via the OnEnable member function, and calling the SetIcon member function to update the button's icon. This way, the button control keeps track of the icon, so there's no need to keep it in a member variable (m_hIcon). And removing an icon is as simple as setting it to display a null icon. There's no need or all of these ugly hacks, like using a second transparent icon, or drawing over the icon with a solid color rectangle.
Sample code, where CMyButton extends CButton:
void CMyButton::OnEnable(BOOL bEnable)
{
CButton::OnEnable(bEnable); // call the base class
if (bEnable)
{
// The button was enabled, so load and set the icon.
const HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
this->SetIcon(hIcon);
}
else
{
// The button was disabled.
// First, retrieve the current icon from the button.
const HICON hIcon = this->GetIcon();
// Then, remove the icon from the button by setting a null icon.
this->SetIcon(NULL);
// Finally, delete the original icon to prevent memory leaks.
::DestroyIcon(hIcon);
}
}
It is, of course, possible to do it your way inside of the OnPaint function, if you absolutely must (though this is poor design). The trick is that the icon only gets drawn if the code to draw it gets executed. Otherwise, no icon gets drawn. The base class will not draw an icon.
So all you need is:
void CMyWindow::OnPaint()
{
CPaintDC dc(this);
const CWnd* pBtn = GetDlgItem(IDC_BUTTON1);
if (pBtn->IsWindowEnabled())
{
m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
dc.DrawIcon(DT_CENTER, DT_CENTER, m_hIcon);
// make sure that you delete m_hIcon when the window is destroyed!
}
else
{
// Do not draw the icon here!
// But write whatever other code you want, like...
dc.SetTextColor(RGB(192,192,192));
}
}
Obviously this tactic will only work if your code is inside of the OnPaint function, but that is where you should do all of your drawing. Otherwise it will be lost whenever the window is repainted. For a demonstration, just try minimizing the window or moving it off the screen. Force a repaint by calling CWnd::Invalidate, followed by CWnd::UpdateWindow (or alternatively `CWnd::RedrawWindow).