-
Content Count
1090 -
Joined
-
Last visited
-
Days Won
23
Everything posted by aehimself
-
GDI object leak and overflow when TImageList is on a frame
aehimself replied to aehimself's topic in VCL
The issue is, about 600 frames are opened and closed before the issue detectibly appears. My sanity will give up first than to count each and every TImageList and track their lifetime. Also, any Delphi object leak would be reported by DeLeaker upon application closure. I spent more than a year to get that list clean, so no more unfreed imagelists / TBitmaps 🙂 -
GDI object leak and overflow when TImageList is on a frame
aehimself replied to aehimself's topic in VCL
Yes, it is. My first idea was that the skinning of TcxPageControl caused this (we recently applied some DevExpress skins based on user input) as it was the most recent change with comctrls involvement. My issue is that the ImageList is simply dropped on the innermost frame design-time. It should be created and freed up automatically. If there would be a bug in the Delphi wrapper, it would be visible in my test case, too. The real code contains a cximageList (DevExpress version) but symptoms are exactly the same if I replace it with a simply TImageList. This is why I didn't mention in until now. I doubt it will make any difference, though. -
GDI object leak and overflow when TImageList is on a frame
aehimself replied to aehimself's topic in VCL
I already introduced my boss to D11 when it was released and I personally was the one who said I don't see a reason why we would need to upgrade. Good thing is that I asked him to doublecheck our licensing and we should still be eligible. Will be a funny talk, though 🙂 My personal OCD still hasn't calmed down yet. How come a completely unused TImageList can cause a GDI object leak? Or I'm just looking at the completely wrong direction. That is unfortunately a completely valid option, too. -
GDI object leak and overflow when TImageList is on a frame
aehimself replied to aehimself's topic in VCL
There is a combobox, which is normally pulling those images from the ImageList. I have a hunch that if I get rid of the imagelist and push those bitmaps in resources the issue is solved... it just bugs me that I don't know what is causing the mayhem now. Of course. I tried to replicate everything as close to the real thing as possible. Btw, creating the frames from constructor means inherited... by embedded I meant to add the innermost frame to an outer one from the designer. I suspect the VCL is working correctly, this is why creating and destroying my test frame 100k + times makes no difference. I'm suspecting something funky going on here... like the Z-order TTreeNode leak with styles active or some 3rd party component interference. My knowledge is severely limited in this area though, that's why I need starting points. I'll do a quick search to see if GetDC is called in our custom components / frame code somewhere, but I doubt. The complexity the ancient code is written is pretty basic... data storage is a TStringList 78% of the times 🙂 -
GDI object leak and overflow when TImageList is on a frame
aehimself replied to aehimself's topic in VCL
It is the installation default, which is 10000 decimal. It seems irrelevant though, as if even an abandoned ImageList is on the innermost frame (all code commented out, not used at all, no images in it) will cause the application to have 7500+ GDI objects in about 20 minutes. If I completely remove the ImageList, GDI object count stays top 2500. -
Var firstword = String(Memo1.Text).Trim.Substring(0, String(Memo1.Text).Trim.IndexOf(' ')); Ineffective, but will yield you results 🙂 But as I mentioned, this will work only in some cases. I'd recommend against using such a solution anywhere near production.
-
Patch for Delphi 11 Alexandria available
aehimself replied to PeterPanettone's topic in Delphi IDE and APIs
Seems... you are perfect, too? 🙂 -
This won't work, you have to parse at least a little bit. E.g.: -- This is a very good query /* Just for extra complexity */ SELECT * FROM MyTable is a valid SQL query. Zeos has a SmartOpen property, so you can call .Open even on queries with no resultset returned - although I never tested this. My personal solution is: Function IsOpenQuery(Const inSQL: String): Boolean; Var fword: String; tokenizer: TZTokenizer; token: TZToken; Begin tokenizer := TZTokenizer.Create; fword := ''; Try For token In tokenizer.TokenizeBuffer(inSQL, [toSkipUnknown, toSkipWhitespaces, toSkipComments, toSkipEOF, toUnifyNumbers]) Do If token.TokenType = ttWord Then Begin fword := Copy(token.P, 0, token.L).ToLower; Break; End; Finally FreeAndNil(tokenizer); End; Result := (fword = 'select') Or (fword = 'show') { Or fword.IsEmpty }; End; It uses Zeos's tokenizer for parsing so I don't have to worry about comments and stuff. Although it works, it is still vulnerable to the fact that (probably) there are a lot more statements than SELECT and SHOW, which will return a resultset.
-
https://en.wikipedia.org/wiki/Stockholm_syndrome
-
My thoughts exactly. I saw videos Windows rebooting itself on some live streams and conferences but never happened to me, not even once; and I was testing it from the first Insider build. I also have to admit that Microsoft did a great job around updates (less downtime, torrent-like downloading from Internet and neighboring PCs, active hour detection, etc); whoever says otherwise install Vista or 7 vanilla and try to patch it up to current. I have a feeling that lots of absolute-negative opinions of Windows 10 would flip if only the logo would be Apple instead of Microsoft.
-
Delphi 11.0 has a different form Caption offset than Delphi 10.4
aehimself replied to Tom Mueller's topic in VCL
Form 652. That's a pretty extended hello world collection! -
Calling inherited in Destroy
aehimself replied to pyscripter's topic in RTL and Delphi Object Pascal
I inherit most of my classes from TObject (I have a habit of freeing what I create myself) and ALL of them have inherited calls in constructors and destructors, even if the Create was ReIntroduce-d. There are a MINIMAL amount of cases when this was strictly forbidden - there I did the same what @Dalija Prasnikar did - put it there, comment it out, put a comment why it is commented out. With links, if possible. These just feel empty without inherited calls, even though I know they do nothing. On the other hand, my OCD makes me capitalize almost every instruction (Create, If, Then, Begin, End, Procedure, Function, etc.) so it might be just plain stupid after all 🙂 -
@Fr0sT.Brutal Call me old-fashioned, I'd simply use {$REGION}-s 🙂 Nevertheless yes, this is a valid case. Thanks!
-
Ah, so those are the C header files...?! Basically only the descriptors? Tbh I still don't get why splitting Interface and Implementation would help to avoid code duplication. If you have two units where the implementation section is the same, you can use helpers / a class which does the work / not to have two different units but use only the first one. Take this with a grain of salt, though. I just can not - yet - imagine a scenario where this would be beneficial.
-
Please write to Embarcadero to get a free Delphi 11 edition for Andreas Hausladen
aehimself replied to PeterPanettone's topic in Delphi IDE and APIs
There is nothing fanciful here. There is only a substantial difference between "I have a feeling" and "I know for sure". -
Were there any changes to TZipFile alltogether? I'd love to see native LZMA support and the ability to open some "corrupted" ZIP files too (like what 7Zip does). I have a file which was compressed by a C# code. Delphi either throws a "Invalid central header signature" exception, or manages to open the archive but sees no files in it.
-
I read here on DelphiPraxis that the correct way to get a stack trace for anything is just to extract the stack addresses and translate those back to function names on the developers machine. I could achieve this with the suggestion here and with a custom .map file parser I can get the function names back but unfortunately there's too much trash. I also don't really understand this area, my parser was built by trial-and-error... better to let the experts handle this kind of thing. I know I could alter how DebugEngine actually displays the stack trace but it still needs a .map file (right next to the .exe or integrated as .smap) which is not just making it easier to attack the executable but easily adds ~40% to the size. I guess the question is... does DebugEngine support this already and if no would it be complicated to implement it?
-
I'm using this code called from various places (e.g. WM_SIZE): Procedure TDBGrid.UpdateScrollBar; Var dataset: TZAbstractRODataSet; si: TScrollInfo; Begin dataset := Self.DataSource.DaaSet; If Assigned(dataset) Then Begin If Not dataset.Active Or (dataset.RecordCount <= Self.RowCount - 1) Then ShowScrollBar(Self.Handle, SB_VERT, False) Else Begin ShowScrollBar(Self.Handle, SB_VERT, True); If Win32MajorVersion >= 6 Then SetWindowPos(Self.Handle, 0, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOZORDER Or SWP_NOACTIVATE Or SWP_NOOWNERZORDER Or SWP_NOSENDCHANGING Or SWP_FRAMECHANGED); si.cbSize := sizeof(si); si.nMin := 1; si.nMax := dataset.RecordCount; si.nPos := dataset.RecNo; si.fMask := SIF_POS Or SIF_RANGE; SetScrollInfo(Self.Handle, SB_VERT, si, True); End; End Else ShowScrollBar(Self.Handle, SB_VERT, False); End; This should show the position correctly. To make it actually scroll the dataset, do Procedure TDBGrid.WMHScroll(Var Msg: TWMVScroll); Var dataset: TZAbstractRODataSet; si: TScrollInfo; Begin If (Msg.ScrollCode = SB_THUMBTRACK) Or (Msg.ScrollCode = SB_THUMBPOSITION) Then Begin dataset := Self.DataSource.DataSet; If Assigned(dataset) Then Begin si.cbSize := SizeOf(si); si.fMask := SIF_ALL; If Not GetScrollInfo(Self.Handle, SB_VERT, si) Then RaiseLastOSError; dataset.MoveBy(si.nTrackPos - dataset.RecNo); Msg.Result := 0; End Else inherited; End Else inherited; End; I think these two were necessary. If it doesn't work let me know and I'll check what else I added which changes this behavior. Edit: Misread the question, this still won't scroll while you are dragging. I'll leave the code here anyway - it might be useful for some. Edit-Edit: Extended my code with the suggestion of @Uwe Raabe, now it does update properly while the scrollbar is being dragged. Thank you!
-
I don't know what causes this, but sometimes (even within the same project) this header menu item won't show correctly - neither of the draw methods are called. By experimenting I found out that turning OwnerDraw on on the popup menu itself fixes it on those affected. Anyone has any ideas? How come some menus work correctly without and some required OwnerDraw to call the menu items drawing methods? Edit: Also, assigning an imagelist fixes this, even if no menu items are using any image whatsoever.
-
Delphi 11 Windows XP compatibility tweak
aehimself replied to mitzi's topic in RTL and Delphi Object Pascal
What about Server 2003? Also, most built-in machines are still on XP (older ones can be even on 2k). What I loved about Delphi until now is that if you write the code thoughtfully it runs on Win2k up. And while I can understand the business decision behind this it still hurts a little 🙂 -
Sorry for my previous post being so blunt - I just had different matters to attend to and wanted to leave my comments. With the reappearance the issue is that if the user leaves his PC for half an hour, 30 dialogs will be shown as not even a modal window "blocks" processing further WM_TIMER messages. In these cases I'm usually wrapping the whole OnTimer event in a Timer.Enabled := False; Try [...] Finally Timer.Enabled := True; End; to make sure I'm not rendering my app in an unwanted state. As for the error handling even if this functionality is being used once in a lifetime it worths to add those extra 2-3 lines. Anything is more beautiful than the standard application error dialog 🙂 Just my 2 cents.
-
This code is completely missing error handling and does not consider access sharing and will read only the first line of the message. As an extra if the file is not deleted it will pop back up every 60 seconds. If {$I-}, use ERRORLEVEL to determine if the Reset was successful, if {$I+} swallow (or just politely indicate) the error. Wrap the Reset...ReadLn...Close to a Try-Finally bloc to ensure the file will be closed no matter what. As for access sharing you might want to use TFileStream instead with fmShareDenyNone.
-
@David Duffy I have no XE experience (went to 10.0-10.1 from 7) but you can fall back to the idea of @Lars Fosdal safely: TStyleManager is only used here to extract colors of the currently active style so the header will always "fit in" nicely.
-
Seriously, wtf...
-
Does anyone know what is the name of Delphi's menueditor? I only could find it in FMX but I guess I should be looking at the VCL version. It would be nice to extend it so it is capable of adding header items.