-
Content Count
1089 -
Joined
-
Last visited
-
Days Won
23
Posts posted by aehimself
-
-
2 minutes ago, Dalija Prasnikar said:There is new option in Options -> User Interface -> Theme Manager called Toggle style to match Windows Light and Dark mode. It is checked by default and that setting overrides any other custom settings. You need to uncheck that option before you can use custom theme settings.
If you want to edit registry directly under Theme key, this new option is called ToggleTheme (DWORD) and its value should be set to 0
By mistake I already discovered this option and disabled it. It shows as off in Dephi IDE and ToggleTheme in Registry values stores 0. Still, color values in Editor \ Highlight \ * are being reset to the values of the scheme selected.
-
So I started to experiment with Delphi 10.4. When we switched to 10.3, I immediately installed the VS code color theme (https://blog.grijjy.com/2017/12/29/alternative-dark-editor-themes-for-delphi-10-2-2/) via the Migration Tool as I think it's the most eye-friendly scheme - plus I got used to it already.
My issue is that Delphi 10.4 simply does not want to accept this. I tried to manually update the values in Registry but as soon as the IDE restarts they are being overwritten. Does anyone know where Delphi 10.4 stores the saved color schemes? I would try to create a new one and set it as a default for my dark theme; I just don't know where to put them 🙂
-
4 hours ago, dummzeuch said:I have so far implemented DFS, simply because it was the easiest. It takes a very long time (about 60 seconds in my test scenario).
Before I try to implement BFS: Has anybody ever compared the performance of these approaches on Windows + network shares?
Give TDirectory.GetFiles (System.IOUtils) a try. It drastically improved the time it took to discover everything compared to my recursive FindFirst / FindNext in my backup application.
-
It's fixed now. At the time of the original post my Edge reported it unsafe too, but now it goes there without an issue.
-
My preference is to have as low amount of files in my built applications as possible. Therefore I usually include the admin area.
I really do dislike the pure "it depends" answers, but here yes, it depends on lots of different factors, including security, end-user needs and of course your own personal preference.
Security, because the admin area might contain references you don't want an average "Hacker Henry" to see with a decompiler, not even as assembly code.
End user needs, as for 3 checkboxes and a language selector the user might find it disturbing having to navigate somewhere else.
Personal preference - which codebase is easier for you to maintain? Multiple applications with less code, or one application with more?
And these are just the first ones which pop up in my mind, so treat this list as severely incomplete 🙂
-
1 hour ago, Kas Ob. said:I saw this behaviour few times, it does happen with PNG and virtual image lists, couldn't track it to specific reason.
This makes no sense to me. I was in the belief that a code either works or not. Unless if it's a problem with TDBImage and/or VCL of course; but that is out of my reach anyway.
If I can manage to reproduce the issue somehow, I will attempt to fix it with DIBNeeded and will not forget to share the result.
-
@Kas Ob. Often the experience gathered during the journey is more valuable than reaching your destination. Noone will actually see that I worked on this component, but I'm richer with a bit of knowledge. Yes, I would be more than willing to check your idea, however...
Today, when I restored the faulty TJPEGImage assignments, it simply started to work...?! Noone else touched this code, the image is the same. Yesterday it was an empty white rectangle, today the image shows up...
-
If any future visitor is wondering, a simple
Picture.Assign(DataLink.Field);
solved the problem, there was no need for a middle TJPEGImage. It's still a mystery for me though, why it is not working with a TJPEGImage and working without. Especially since they were all loaded correctly.
Especially since the above works fine with a normal TImage, but not from inside a TDBImage descendant.
-
1 hour ago, Uwe Raabe said:You should be aware that assigning to TPicture.Graphic will create an internal copy of the source (see TPicture.SetGraphic), so you get a memory leak with the above code.
I know. This is why I am attempting to get rid of it.
1 hour ago, Uwe Raabe said:Not refreshing the display may have a different cause.
Well, it is working if we are leaking TJPEGImages, which I find really strange. Also attempting to Self.Invalidate / Self.Repaint / Self.Refresh after loading the picture makes no difference.
-
Good idea. Commented the .Free out:
jpeg := TJPEGImage.Create; Try jpeg.Assign(DataLink.Field); Picture.Assign(jpeg); Finally // jpeg.Free; End;
Bad thing is, it still does not work (picture isn't shown) and it leaks a TBitmapImage, a TJPEGImage, a TBitmap, a TJPEGData and a TMemoryStream object upon destruction 😞
-
Yep. As I'm .nil-ing that, it'd throw an AV. The loading has been re-written, and is now:
Picture.Assign(jpeg);
-
Hello,
I'm in the process of fixing some unusual amount of memory leaks and code errors in a legacy codebase. We have a custom TDBImage descendant, which was leaking TJPEGImages like there's no tomorrow.
The code used to look like this:
constructor TMyDBImage.Create(AOwner: TComponent); begin […] Picture.Graphic := TJPEGImage.Create; […] end; procedure TMyDBImage.DataChange(Sender: TObject); begin Picture.Graphic := TJPEGImage.Create; FPictureLoaded := False; if FAutoDisplay and (DataSource.DataSet.State <> dsInactive) then LoadPicture; end; procedure TMyDBImage.LoadPicture(ARefreshDataSet: Boolean = False); begin […] if not DataSource.DataSet.EOF and DataLink.Field.IsBlob then Picture.Graphic.Assign(DataLink.Field) else Picture.Graphic := TJPEGImage.Create; // Empty picture end;
I guess they wanted to clear the image, so I changed all those TJPEGImage.Create-s with a simple nil assignments (Picture.Graphic := nil). I also changed the loading mechanism:
procedure TMyDBImage.LoadPicture(ARefreshDataSet: Boolean = False); Var jpeg: TJPEGImage; begin [...] if not DataSource.DataSet.EOF and DataLink.Field.IsBlob then Begin jpeg := TJPEGImage.Create; Try jpeg.Assign(DataLink.Field); Picture.Assign(jpeg); // Picture.Bitmap.Assign(jpeg); This does not work either Finally jpeg.Free; End; End else Picture.Graphic := nil; // Empty picture end;
The leaks are gone, but the picture is not shown in the component. I already confirmed that "jpeg" is filled correctly (stop with debugger, execute a .SaveToFile and check the result) but I can not really make the DBimage's Picture to load it. Based on my previous codes the Picture.Bitmap.Assign should be fine; I guess in this case it's the nil assignment of the .Graphic property which is not letting it to work?
Where is my logic wrong?
Thanks!
-
Procedure TAEMultiSQLMainForm.ConnectionClick(inSender: TObject); Var ts: TTabSheet; sqf: TSQLConnectionFrame; s: String; Begin s := (inSender As TMenuItem).Caption; ts := TTabSheet.Create(Display); ts.Caption := s; ts.ImageIndex := 1; ts.PageControl := Display; sqf := TSQLConnectionFrame.Create(ts, Settings.Connections[s], Log); sqf.Parent := ts; RecolorSQLFrame(ts); Display.ActivePage := ts; ChangeFocus; sqf.ReconnectButton.Click; End;
This is the code snipplet I use in a tabbed SQL browser to open a new connection; which is also a frame. I am creating a tabsheet and a frame without a name and never got an error concerning component names. That's the only reason I asked.
-
On 5/5/2020 at 11:39 PM, dummzeuch said:we don't need no fchking brainf*ck or whitespace.
Came just to say it reminds me of BrainF*ck. You were faster though 🙂
-
On 5/5/2020 at 6:38 PM, Tntman said:for i := 0 to 10 do begin randNumb := Random(9900); messageList[randNumb] := TListBoxItem.Create(Self);
Based on your luck, you can leak 10 TListBoxItem obects with one run. Don't do this. Just because it did not fail during debugging, it might fail in real life.
Random(9900) will give you a number between 0 and 9899, leaving the last one (#9900) unused 100% of the times. Consider using Random(High(messageList) + 1) instead of a burned-in number; so if you decide to resize your array later on - you only have to do it at one place.
On 5/5/2020 at 6:38 PM, Tntman said:TFrame1.Create(Self).Name := IntToStr(randNumb); with TFrame1(FindComponent(IntToStr(randNumb))) do
If you really like With that much, you can just say
With TFrame1.Create(Self) Do Begin Name := IntToStr(randNumb); [...] End;
Burning CPU cycles for FindComponent is completely useless, if you just created that object. I'd use a local variable here, but that's only my taste.
As for the rest of your fears - they are all valid. I guess @David Heffernan has an alert set up if you write SetLength(myArray, Length(myArray) + 1) anywhere, as he will appear and tell you that it is a REALLY bad practice. Indexing will also never automatically shrink, items will not be moved - you have to do it manually if you want to...
... oooor instead of an array you can say
messageList: TObjectList<TListBoxItem>; [...] messageList := TObjectList<TListBoxItem>.Create(True);
...this way you will get an automatically expanding and shrinking list, which will automatically .Free your object if you delete it from the list.
With this, the above With block could be replaced by...
Var index: Integer; Begin index := messageList.Add(TListBoxItem.Create(Self)); messageList[a].Name := xxx; [...]
which looks cleaner imo.
P.s.: Is there a purpose you are naming dynamically created objects? I never ever had to do it so far; thus can not imagine a reason why I'd need to do so.
-
1
-
-
8 minutes ago, Tntman said:its more for myself to learn more
In this case I keep my mouth shut - this is how we all experiment and learn at the end. I still do dislike custom notifications, though 🙂
10 minutes ago, Tntman said:Yes , in my app user can toggle on / off if he wants to get custom notifications.
Custom, as in notifications at all; or custom-themed notifications? People using computers nowadays are lazy. We don't want to flip a switch if we expect the program to know to keep quiet. Furthermore, if I already set "Quiet hours in Cortana"....
You can add a button like "Don't show notifications when [Insert currently active window title] is active". At least you have to click once, then never again.
I'm cursed to write my own - even - experimenting apps with my own comfort in sight. If I cannot do it with a feature I want to see in a finished product, it's a no-go for me.
P.s.: yes, I have hundreds of unfinished test projects 😞
-
9 hours ago, Sherlock said:I shut it down every day. Have done so since... well, always. You just can't get windows to behave as expected unless it's been freshly rebooted.
So. Damn. True.
I'll always smile on the EULA of Win2k, which clearly stated that it's not an error-prone operating system and therefore it's not recommended for appliances such as in airplanes or rocket guidance.
But - as always - you'll always find gems. Once one of our customer called us and said that they "found" a running server under a desk in a closed-down section of the building. If my memory is correct, it had Windows 2003 installed and when we checked it it was up for 3,5 years straight. Easy without any real tasks, though.
-
12 hours ago, Tntman said:The way how i solved this is to make form without border with animations and display it in corner of the screen .. Add timer and on timer finish display closing animation, i have not found any better other method
I am against custom notifications. I disliked MSN messenger, early Outlook (2003 era, maybe; can't recall) now Viber and all the others doing this as it completely breaks a computers look-and-feel. Especially since later OSes have their native notification system.
I half-implemented this once, but soon I realized that it's not that easy. A notification only worth it if it's above everything else on your screen - except some situations: you'll have to check for full-screen apps (gaming, video); possibly add DnD intervals and maybe allow the user that if a specific application is running - don't show anything. What happens if your notification covers the native notification or vice versa...? Would be nice to have some syncing to make sure it never happens.
That's a lot of extra work, and the OS already knows it all.
-
1
-
-
A VPN is overkill in my opinion; a simple port forwarding is sufficient. Even if you have dynamic IP addresses there are free / cheap solutions to tie that to a domain name (just google for free dynamic dns). But as @Tom Chamberlain mentioned, it is a REALLY bad idea to directly expose a database to the Internet, so definitely do use a REST-like server in between.
-
Do you get the same leak report if you don't debug the code, just let it to run?
It should not be the case, but try to call VarClear on the variant before exiting, and finalizing the array.
-
5 hours ago, Magno said:Yep, but I think the helper with setting nil before is not so handy, but it is ok. This is the way, as I have spoken.
I'm not saying there's something wrong with this type of helpers (I have close to the same at work) it's just an "inconvenient" - or should I say unusual - format to follow. And - as @Attila Kovacs mentioned and your example shows - you have to be careful; as there's no way (according to my knowledge) in Delphi to see if a TObject is initialized or not.
-
1
-
-
13 minutes ago, RTollison said:_KeyValue := bintoAscii(dmspCreate.adsAcuLocks1.FieldbyName('KeyValue').AsBytes);
if (_keyValue[1] = #0) then
_keyValue := bintoStr(dmspCreate.adsAcuLocks1.FieldbyName('KeyValue').AsBytes);The first and the third example starts with 0x30 so bintoStr will not be called, but the byte array seems to be binary; not ASCII. If you are sure that the field always contains binary data, drop BinToAscii and call BinToStr only.
-
BinToHex should work, but you can give this a try:
Function MyBinToHex(inBinary: TArray<Byte>): String; Var b: Byte; Begin Result := '0x'; For b In inBinary Do Result := Result + IntToHex(Ord(b), 2); End;
..,in older Delphi's:
Function MyBinToHex(inBinary: Array Of Byte): String; Var a: Integer; Begin Result := '0x'; For a := Low(inBinary) To High(inBinary) Do Result := Result + IntToHex(Ord(b), 2); End;
-
Talking about a virtual environment, especially Xen; I'd give the how-to written by @Dalija Prasnikar a shot:
https://dalijap.blogspot.com/2019/05/disable-delphi-rio-ide-theme.html
There were multiple reported painting issues solved by disabling theming of the IDE.
Your RAD Studio 10.4 Sydney issues
in General Help
Posted
This was my plan all along, I just did not see the "Custom themes" subkey 🙂 Thank you, @Lars Fosdal; this method works like a charm!