|
Post by Roger Cabo on Jan 10, 2023 15:47:58 GMT 1
Hi everyone, it's strange but it feels like... since win10 or (before at win7 at anytime) the ocx graphics became very slow. It feels like, the OCX draw mechanism is decoupled from D2D. Also creating OCX's by code seems to be very slow.
I will upload an example soon, I create about ~50 control sets in different OCX arrays and it takes about 5 seconds to finish.. I'm running on an AMD X5900 with 64GB 12 core at 4.700Mhz. I cannot believe it's too slow..
Did you experienced the same on your machine? Test OCX Speed.G32 (11.48 KB) _____________________________________________________________________________________________________ 1) It doesn't matter if the OCX already exist previously, creation time takes the same. 2) It's possible to speed up by about 30% when using hide redraw and repaint.. 3) I think, there is anything like a pause function in the creation process internally. Normally the creation process becomes slow as more controls we create. Same with strings etc. But in this case it runs at the same creation speed like a clock.
|
|
webu
Full Member
Posts: 149
|
Post by webu on Jan 10, 2023 22:56:29 GMT 1
1.6 secs!
For example at an old Win7 with Intel Core 2 Duo 2xP8600 2.40 GHz
|
|
|
Post by dragonjim on Jan 11, 2023 12:32:10 GMT 1
3.9 secs Win10 Ryzen 5 2400G 8GB GT730 graphics card (2GB)
That is the time it takes to create over 1,250 common control object windows (if I counted correctly), plus the host window and also updating the timer window. That is not too bad...
GFA creates and manipulates OCXs using the standard Windows APIs and SendMessage so most of the heavy lifting is done by Windows; to speed it up you could try:
1. Using Multithreading, creating up to 50 threads each drawing one section. This may cause problems when redrawing after scrolling, though.
2. Only draw the sections which will be visible, storing information from sections that have been edited but are no longer visible in a array of variants or a UDT array. I have created lists of thousands of sections using this method which scroll and redraw very quickly.
3. Adding items to ComboBoxes is very time consuming: if I comment out the AddItem lines for Termine_Einheiten(i), my system draws the OCXs in only 2.6 secs, so a third of the draw time is actually filling the ComboBoxes. You could get round this by only adding the items when the ComboBox gets focus (if the Combobox starts with a value, just add that one on the initial draw/redraw). The following is a suggestion for the GotFocus sub:
Sub Termine_Einheiten_GotFocus(Index%) If Termine_Einheiten(Index%).ListCount < 2 Local l$ = Trim(Termine_Einheiten(Index%).Text) Termine_Einheiten(Index%).Clear Termine_Einheiten(Index%).AddItem "00:30" Termine_Einheiten(Index%).AddItem "01:00" Termine_Einheiten(Index%).AddItem "01:30" Termine_Einheiten(Index%).AddItem "02:00" Termine_Einheiten(Index%).AddItem "02:30" Termine_Einheiten(Index%).AddItem "03:00" Termine_Einheiten(Index%).AddItem "03:30" Termine_Einheiten(Index%).AddItem "04:00" Termine_Einheiten(Index%).AddItem "04:30" Termine_Einheiten(Index%).AddItem "05:00" Termine_Einheiten(Index%).AddItem "05:30" Termine_Einheiten(Index%).AddItem "06:00" Termine_Einheiten(Index%).AddItem "06:30" Termine_Einheiten(Index%).AddItem "07:00" Termine_Einheiten(Index%).AddItem "07:30" Termine_Einheiten(Index%).AddItem "08:00" Termine_Einheiten(Index%).ListIndex = SendMessage(Termine_Einheiten(Index%).hWnd, CB_FINDSTRING, -1, l$) EndIf EndSub
I hope some of these suggestions are helpful.
|
|
|
Post by Roger Cabo on Jan 11, 2023 22:35:04 GMT 1
Thank you! 2) Yes I think there no no other solution. Further it's possible to draw only about 75 entries (each 180pixel height). If frx3 reach over 16K height than the form crash unfortunately. The 16K pixel in any direction is generally a ugly restriction anyway. I can also draw one event set by graphic commands (Box, text, lines, etc..) When the user clicks I overlay one event ocx set to the correct position. But this is bad anyway, because of the restriction of 16K pixel in any direction. Perhaps I should use only 4 visible Events, and one on top and bottom. When using the slider in upper direction, I draw a event in the invisible area at bottom. Then move the form up. But Im not sure if it's fast enough to use this solution, when the slider is moved rapidly in any direction.
|
|
|
Post by Roger Cabo on Jan 13, 2023 14:03:07 GMT 1
2. Only draw the sections which will be visible, storing information from sections that have been edited but are no longer visible in a array of variants or a UDT array. I have created lists of thousands of sections using this method which scroll and redraw very quickly. Would you so kind and explain it a bit further? Do you mean... change the content of only the maximum visible sections and do not scroll them physically? Then only the contents change? Didn't understand how it could be work with scrolling..
|
|
|
Post by dragonjim on Jan 13, 2023 19:58:17 GMT 1
Below is a very quick example of what I meant.
In this example, the records are simple with just a number and a compass point; the records themselves are 30 pixels in height and are moved up and down by moving the scroll bar of the parent window. To show that changes to records are retained, change a value, scroll it off the screen, then scroll back.
Type Trial - String*14 Description - Int32 No EndType
Dim n%, tr(1 To 500) As Trial For n% = 1 To 500 tr(n%).No = Int(Rnd * 50) + 1 tr(n%).Description = Choose(Int(Rnd * 4) + 1, "North", "South", "East", "West") Next n%
OpenW 1, 10, 10, 400, 600 Win_1.ScrollBars = 2 : Win_1.VScPage = 100 : Win_1.VScStep = 30 : Win_1.VScMax = 500 * 30 - (600 - (Screen.cyFrame * 2) - Screen.cyCaption) + 100 Record_Redraw
Do : Sleep : Until Win_1 Is Nothing
Procedure Record_Redraw Local top% = Win_1.VScPos, bottom% = top% + (600 - (Screen.cyFrame * 2) - Screen.cyCaption), y1%, y2% = 30 For n% = 1 To 500 // Run through records one by one If y1% >= bottom% Or y2% <= top% // If record not visible... If Not IsNothing(txt1(n%)) // ...if record was visible before last scroll... tr(n%).No = Val(txt1(n%).Text) // ...store the number... tr(n%).Description = Trim(txt2(n%).Text) // ...and the description values and... Set txt1(n%) = Nothing // ...destroy the first... Set txt2(n%) = Nothing // ...and second textboxes EndIf Else // Otherwise, if record will be visible... If Not IsNothing(txt1(n%)) // ...if record currently visible... txt1(n%).Move , y1% - top% + 5 // ......move the first... txt2(n%).Move , y1% - top% + 5 // ......and second textboxes accordingly Else // ...otherwise create the textboxes and assign the stored value Ocx TextBox txt1(n%) = Trim(Str(tr(n%).No)), 10, y1% - top% + 5, 40, 15 Ocx TextBox txt2(n%) = Trim(tr(n%).Description), 70, y1% - top% + 5, 200, 15 EndIf EndIf Add y1%, 30 : Add y2%, 30 // Increase to the bounds of the next record Next n% EndProcedure Sub Win_1_VScroll Record_Redraw EndSub
|
|
|
Post by Roger Cabo on Jan 14, 2023 2:36:58 GMT 1
Thanks a lot! Yes now I understand..
|
|