Jump to content

balabuev

Members
  • Content Count

    242
  • Joined

  • Last visited

  • Days Won

    2

Everything posted by balabuev

  1. balabuev

    Creating sub nodes with debugger visualizer

    Also, I've noticed that the strings are different in code editor drop-down and in local variables view: String in code editor drop-down seems to be more complete (like it should be returned from GetReplacementValue). While the string in local variables view seems to be already processed by IDE.
  2. balabuev

    Creating sub nodes with debugger visualizer

    Never tried it myself, but I suspect that you just need to return a string with specific format. Such as "(3, 5, 7)" to show value as array with child elements. Or like "(PropA: 3; PropB: 5)" to show as object with child properties. I may be wrong, of course. Do you looked at the source code of TDebuggerListHelperVisualizer.GetReplacementValue?
  3. This happens (and always was the case) with the following settings:
  4. balabuev

    Delphi WAT of the day

    Task completed:
  5. balabuev

    Object Inspector issue in 10.4.2??

    Then, I don't know, sorry.
  6. 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:
  7. 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.
  8. 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.
  9. 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.
  10. balabuev

    VCL Handling of dpi changes - poor performance

    Those issues in VCL are unfixable.
  11. 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.
  12. 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;
  13. balabuev

    TTreeNode leak when VCL styles are active

    Voted.
  14. 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.
  15. 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
  16. 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.
  17. 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;
  18. 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.
  19. balabuev

    TTreeNode leak when VCL styles are active

    Ohh, no. I can vote if someone will report.
  20. 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.
  21. balabuev

    TTreeNode leak when VCL styles are active

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

    TTreeNode leak when VCL styles are active

    I think similarly.
×