Jump to content

balabuev

Members
  • Content Count

    238
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by balabuev

  1. balabuev

    Object Inspector issue in 10.4.2??

    Then, I don't know, sorry.
  2. balabuev

    Object Inspector issue in 10.4.2??

    Try to uninstall third-party stuff. Like Cnpack/Gexperts... Also your object instector looks strange. I have no horizontal lines:
  3. balabuev

    Object Inspector issue in 10.4.2??

    Non-standard property editors are installed. More technically (if anyone interested) this happens when a property editor implements ICustomPropertyDrawing interface but does not implement more recently introduced ICustomPropertyDrawing80 interface.
  4. balabuev

    VCL Handling of dpi changes - poor performance

    My point is that from all things, happening during rescaling of a form, the most resource consuming are SetWindowPos calls, which are called from SetBounds, which are themselfs called from different places, including AlignControls. Drawing and especially async invalidation takes much less resources and time, imho. So, when we speak about form rescaling performance, we can denote it as O(n), where n - is mostly the number of SetWindowPos calls. To trace how many times SetWindowPos is actually called we can use WM_WINDOWPOSCHANGED event handlers on child controls. So, given very simple example with a single TPanel control, aligned with alClient on a form, I see three SetWindowPos on each dpi boundary cross: procedure TPanel.WMWindowPosChanged(var M: TWMWindowPosChanged); var cr: TRect; begin if (M.WindowPos.flags and SWP_NOSIZE) = 0 then begin Winapi.Windows.GetWindowRect(Handle, cr); OutputDebugString(PChar('WMWindowPosChanged: ' + cr.Width.ToString + ',' + cr.Height.ToString)); end; inherited; end; As seen from the events log the child panel is repositioned three times, and each time its size is set to different value: 638 * 380 510 * 304 640 * 382 So, in this particular case three times more work is done, than it actually required. Test project: dpi_test.zip PS: Looking more generally at this issue I have to conclude that layouting should be asynchronous. The concept of async layouting is a some kind of replacement of the global BeginUpdate/EndUpdate mentioned earlier. But, this will be too big and breaking change for VCL. And moreover, this is almost impossible for native Windows controls, such as TEdit, TListBox, etc.
  5. balabuev

    VCL Handling of dpi changes - poor performance

    In my demo on a form full of different controls this line is not executed at all.
  6. balabuev

    VCL Handling of dpi changes - poor performance

    Those issues in VCL are unfixable.
  7. Sorting of replacement patterns (by length, desc) seems to me an overkill. As @Attila Kovacs already proposed, input patterns already have their natural order in array - so this order should be respected. This will be more flexible, and fast.
  8. Here is my small idea. Not perfect, has limitations, I guess, but usable {$POINTERMATH ON} const GUESS_MASK = 32 - 1; procedure BuildGuess(AGuess: PByte; const aOld: array of string); var pi, j: Integer; begin FillChar(AGuess^, GUESS_MASK + 1, 0); for pi := 0 to High(aOld) do begin j := Ord(aOld[pi][1]) and GUESS_MASK; if AGuess[j] = 0 then AGuess[j] := pi + 1 else AGuess[j] := 255; end; end; function Equals(S1, S2: PChar; ACount: Integer): Boolean; var i: Integer; begin for i := 0 to ACount - 1 do begin if S1[i] <> S2[i] then Exit(False); end; Result := True; end; function MyReplace(const S: string; const aOld, aNew: array of string): string; label L; var lnt: Integer; pcnt: Integer; c, eof: PChar; p: PChar; pi, j: Integer; pln: Integer; off: Integer; guess: array[0..GUESS_MASK] of Byte; begin pln := 0; lnt := Length(S); pcnt := Length(AOld); BuildGuess(@guess, aOld); SetLength(Result, lnt * 2); c := Pointer(S); eof := c + lnt; off := PChar(Pointer(Result)) - c; while c <> eof do begin pi := guess[Ord(c^) and GUESS_MASK]; if pi <> 0 then begin if pi <> 255 then begin Dec(pi); pln := aOld[pi].Length; if (c^ = aOld[pi][1]) and Equals(c, Pointer(aOld[pi]), pln) then goto L; end else begin pi := 0; while pi <> pcnt do begin pln := aOld[pi].Length; if (c^ = aOld[pi][1]) and Equals(c, Pointer(aOld[pi]), pln) then goto L; Inc(pi); end; end; end; c[off] := c^; Inc(c); Continue; L: Inc(c, pln); Dec(off, pln); pln := aNew[pi].Length; p := Pointer(aNew[pi]); for j := 0 to pln - 1 do c[off + j] := p[j]; Inc(off, pln); end; SetLength(Result, @c[off] - PChar(Pointer(Result))); end;
  9. balabuev

    TTreeNode leak when VCL styles are active

    Voted.
  10. No library used, just a simplest implementation of hash map. Use it as you need. I'm hearing about this the first time ever, and it seems to me very strange. Also, a single hash map can be organized on top of TDataLine user objects without any additional objects (via additng Next and Hash fields directly to TDataLine). Two maps, however will need another one pair of such properties, which is not so graceful, but also possible, if we speak about the extreme case. I've only tested with 100k items. I can see the effect. However, it's not clear for me why this happens.
  11. Here is my try. I've changed a lot in existing code (mentioned early comparers, equality comparers, etc.). Also, I've replaced returned string type in functions by PString, just because otherwise string handling takes too much time and algorythms comparison becomes not interesting. As well I've added my own minimalistic implementation of hash maps (not universal). mapstest.zip
  12. balabuev

    Developer Express gave up on FMX

    FMX is no way to go. What is more, controls are ususally developed for more than just one latest IDE version. So, what is matter, whether in some reasonably old IDE version FMX works good and is actually popular.
  13. I think this is a: passed by reference (1*) pointer variable, which will point (2*) to array of pointers (3*) to libvlc_media_track_t structs. type PTracks = ^TTracks; TTracks = array[0..1024] of ^libvlc_media_track_t; function libvlc_media_tracks_get(p_md: libvlc_media_t_ptr; var tracks: PTracks): LongWord; cdecl; procedure libvlc_media_tracks_release(tracks: PTracks; i_count: LongWord); cdecl; procedure GetTracks; var tracks: PTracks; cnt: Integer; track: libvlc_media_track_t; begin cnt := libvlc_media_tracks_get(FVLCMIntf, tracks); try for i := 0 to cnt - 1 do begin track := tracks[i]^; DoSomething(track); end; finally libvlc_media_tracks_release(tracks, cnt); end; end;
  14. balabuev

    TTreeNode leak when VCL styles are active

    Not really works, because enqueued via ForceQueue tasks are not executed after the main form close. So, need to replace it with some explicit implementation: type TScrollingStyleHook = class(TMouseTrackControlStyleHook) public type //... TAsyncDeletion = class private class var FItems: TList; class procedure FreeItems; public class destructor Destroy; class procedure FreeAsync(O: TObject); end; //... end; class destructor TScrollingStyleHook.TAsyncDeletion.Destroy; begin TThread.RemoveQueuedEvents(nil, FreeItems); FreeItems; end; class procedure TScrollingStyleHook.TAsyncDeletion.FreeAsync(O: TObject); begin if FItems = nil then begin FItems := TList.Create; TThread.ForceQueue(nil, FreeItems); end; FItems.Add(O); end; class procedure TScrollingStyleHook.TAsyncDeletion.FreeItems; var itm: TObject; begin if FItems <> nil then begin for itm in FItems do TObject(itm).Free; FreeAndNil(FItems); end; end; This version works fine.
  15. balabuev

    TTreeNode leak when VCL styles are active

    Ohh, no. I can vote if someone will report.
  16. balabuev

    TTreeNode leak when VCL styles are active

    It's looks like carefully hidden stuff, but PostMessage is there: class procedure TThread.Synchronize(...); begin //... if Assigned(WakeMainThread) then WakeMainThread(SyncProcPtr.SyncRec.FThread); //... end; procedure TApplication.WakeMainThread(Sender: TObject); begin PostMessage(Handle, WM_NULL, 0, 0); end; procedure TApplication.WndProc(var Message: TMessage); begin //... WM_NULL: CheckSynchronize; // Executes accumulated tasks. //... end; There simply no other ways, main thread executes message loop infinitely.
  17. balabuev

    TTreeNode leak when VCL styles are active

    AFAIK, this internally executed in the context of the main thread (via PostMessage).
  18. balabuev

    TTreeNode leak when VCL styles are active

    I think similarly.
  19. balabuev

    TTreeNode leak when VCL styles are active

    Yes, something like this. However, I'll still prefer to leave DoRemoveControl as is, and deal with TScrollingStyleHook.Destroy instead to defer the destruction of two TScrollWindow objects only. And, since TScrollWindow objects (controls) uses CreateParented constructor, which utilizes ParentWindow property (instead of Parent property), they cannot be occasionnaly destroyed by their parents. So, this simplifies the task a bit, and we can ommit usual book keeping involving FreeNotification, etc. procedure FreeScrollWindowAsync(W: TScrollingStyleHook.TScrollWindow); begin if W.HandleAllocated then begin ShowWindow(W.Handle, SW_HIDE); TThread.ForceQueue(nil, procedure begin W.Free; end); end else W.Free; end; destructor TScrollingStyleHook.Destroy; begin FInitingScrollBars := True; if FVertScrollWnd <> nil then begin FVertScrollWnd.StyleHook := nil; FreeScrollWindowAsync(FVertScrollWnd); end; if FHorzScrollWnd <> nil then begin FHorzScrollWnd.StyleHook := nil; FreeScrollWindowAsync(FHorzScrollWnd); end; FInitingScrollBars := False; inherited; end;
  20. balabuev

    TTreeNode leak when VCL styles are active

    I've replaced the treeview with a frame to remove the mess with the second pair of unneeded scrollbar windows. I've simulated some resource allocation on WM_CREATE in a frame, which is then freed on WM_DESTROY, similar to tree view. Run the demo. Switch to any VCL Style. Press "Bring to front" button. Close the form Source.zip
  21. balabuev

    TTreeNode leak when VCL styles are active

    I think, csDestroying flag cannot be used also, because it is set in any situation: Form as a whole is destroyed Or, the control only is destroyed by the user.
  22. balabuev

    TTreeNode leak when VCL styles are active

    I need some time to modify our demo to show this in one simple step. The problem is that we have currently four scrollbar windows, from which only two belong to list view (other two belong to tree view). This hides the bug, when they are not in the needed specific order relative to each other.
×