Integrated Application Platform › Forums › General › Display issues with adding/removing from VertConrol
- This topic has 7 replies, 2 voices, and was last updated 12 years, 1 month ago by
amckinlay.
-
AuthorPosts
-
April 16, 2011 at 9:11 pm #697
emilevanpassel
ParticipantI was in Suneido working with VertControl, adding and removing elements. I noticed that when objects are added there is something happening in the screen that is not related to the part where the VertControl is located. I think it is because Construct is building some GUI element here on screen, to add it to the VertControl. The result is a flickering in the screen which is very noticable. Is there a way that this visual build up of the elements can be done off-screen, or made invisible in some way? Hiding the VertControl element does not matter, the elements that I add are still visibly constructed on-screen.
A good example I think is the use of the RepeatControl.April 16, 2011 at 10:25 pm #833amckinlay
KeymasterI agree the flickering is annoying. I guess I have just got used to it!
I think this is coming from the .WindowRefresh() in Group (parent of Vert and Horz) Insert and Remove
Because of stretchable controls and fill, adding or removing (or resizing) a control can cause non-local changes, so the layout for the entire window has to be recalculated. Of course, most of the time only certain parts of the window actually change.
WindowBase.Refresh does combine multiple refreshes to reduce the flickering.
The refresh ends up calling Resize on each control which usually ends up in Hwnd.Resize that calls SetWindowPos. But it still flickers even if I change this to not call SetWindowPos if the size is the same.
Now that I look at it, I’m not sure where the flickering is actually coming from.
If you are using FieldControl is has a .Repaint() in .SetBgndColor which is probably unnecessary when called by New. But commenting it out doesn’t help.
The SWP.NOCOPYBITS in Hwnd.Resize is suspicious, but again commenting it out doesn’t help.
The CS.REDRAW in the Window class definitions in Init also caught my eye, but removing it didn’t help.
It seems like something is erasing and redrawing the whole window, but I can’t find where that would be coming from.
Sorry, I am stumped. I wrote most of this code, but it was a long time ago!
Anyone else have any ideas?
April 17, 2011 at 5:08 pm #834emilevanpassel
ParticipantI noticed when I commented out the WindowRefresh, that on the top of the screen the elements that needed to be inserted were drawn, before inserting them. The situation is like this:
1. In the lower left corner of the screen is a RepeatControl, that is automatically filled with data from a query. The query is stripped and the various parts are inserted into the RepeatControl, showing attributes, data and options like ‘equal to’, ‘less than’, etc.
2. When the RepeatControl is filled, I see that the FieldControls that are inserted into the RepeatControl are drawn on the top of the screen, being followed by a screen redraw.
3. When the WindowRefresh is commented out, I notice that the FieldControl on top of the screen contains the data that is finally inserted into the RepeatControl, but the FieldControl has a very different shape. It is about 4 times higher and 4 times larger then when it is inserted into the RepeatControl.What it seems to me is that the Control method Construct is building the FieldControl, then resizes it, fits it into the RepeatControl and then forces a WindowRefresh to wipe out the FieldControl that was build up in the top of the screen. Although I don’t know the details of the GUI creation…
April 17, 2011 at 7:12 pm #835amckinlay
KeymasterThat makes sense.
When it creates the control (via Hwnd.CreateWindow) it does not know the final size or position – this is determined by the layout Recalc
So it creates it at an arbitrary position and size and then the first Resize adjusts the position and size.
This works fine when you are constructing the whole window at once because you only see the final result. But not so good with dynamically creating controls.
I’m still not sure why it’s actually getting painted with the original (wrong) position/size. I thought painting wasn’t done till you returned to the message loop and processed paint messages. Unless you call UpdateWindow, but I do not think it is getting called.
Maybe what we should be doing is creating the controls without WS.VISIBLE and then making them visible after the first Resize (SetWindowPos)
I made this simple test:
Window(Controller
{
Xmin: 800
Ymin: 600
Controls: (Vert (Button Add))
On_Add()
{ .Vert.Insert(.Vert.Tally(), #(Field)) }
})It flickers. If I add this in Hwnd.CreateWindow just before CreateWindowEx
.show = (style & WS.VISIBLE) is WS.VISIBLE
style &= ~WS.VISIBLEand add this in Hwnd.Resize just before SetWindowPos
if .show
{
.SetVisible(true)
.show = false
}Now my simple test does not flicker ๐ But RepeatControl still flickers ๐ Maybe something to do with it using WndPaneControl ?
WARNING: Be careful modifying Hwnd or similar code. For example, if you make a syntax error you can crash the Suneido UI. I usually Dump() just before making these kinds of changes. Then if you crash you can restore with suneido -load
April 20, 2011 at 1:35 pm #836emilevanpassel
ParticipantI also think that the PaneControl is causing the problems in RepeatControl. I am trying to make a RepeatControl that will work without the PaneControl. Thanks for the information.
I also read on the website that maybe .Net would be used in the future. Does it mean that MFC will be thrown out then?
April 20, 2011 at 2:06 pm #837emilevanpassel
ParticipantJust had some idea that could work and it seems to work very fine…
What I saw in Hwnd is that CreateWindow defaults x and y to 0. I changed this to make y default to 3000. This seems a bit strange, but it works. No more flickering in VertControl, RepeatControl, etc. Makes display more friendly on the eyes ๐
Of course the setting y = 3000 is a bit extreme, but it works. Maybe a negative value also works. In the past, working with C++ on BeOS, I used off-screen area to construct display elements. I never realised that under Windows this could also be done.
April 20, 2011 at 4:38 pm #838amckinlay
KeymasterNice idea! I’ll try it.
Note: When you have multiple monitors, some of them can be at negative coordinates (but that is screen coordinates, not window coordinates)
My modifications were not a good solution – they cause problems with some things e.g. ListView in QueryView
Technically, suneido/stdlib isn’t using MFC, it is just using the Win32 api (like MFC does).
It would be an interesting project to rewrite Suneido in .NET, but it took me a couple of years to do the Java rewrite, and .NET would probably be comparable. Maybe there is some way to allow the current suneido.exe to call .NET code (similiar to the current dll interface used to call Win32 api’s).
April 20, 2011 at 4:44 pm #839amckinlay
KeymasterPS. Part of the reason for the WndPane might have been to get the tab order.
-
AuthorPosts
- You must be logged in to reply to this topic.