-
Content Count
1089 -
Joined
-
Last visited
-
Days Won
23
Posts posted by aehimself
-
-
@yonojoy Sure, go ahead. You might also want to consider @Renate Schaaf's version, which is an installable component and therefore works at design time as well.
-
When experimenting with a new component I suggest a "barebone" example first. One control on the form, setting up and connecting in FormCreate.
I'm not going to recreate your form layout and filter out the essentials I'm sorry... I already showed how I'm doing it and it works fine.
Also keep in mind that by importing the MsTscAx control you are effectively using the current version available in your Windows setup: it can / might / surely will differ between versions, editions and even patch levels.
-
The first window warns about "invalidity" of certificate and approval of access for a specific function (drive mapping maybe?). You will not be able to bypass this (you can ignore the certificate so the warning only comes back once the cert is renewed).
The second one you can bypass by specifying the username and password.
This is how my tabbed remote access application sets up MsTscAx controls for RDP connections:
If Self.Credential <> nil Then Begin If Not Self.Credential.DomainName.IsEmpty Then _rdp.Domain := Self.Credential.DomainName; If Not Self.Credential.UserName.IsEmpty Then _rdp.UserName := Self.Credential.UserName; If Not Self.Credential.Password.IsEmpty Then _rdp.AdvancedSettings7.ClearTextPassword := Self.Credential.Password; End;
I suggest you check all the .AdvancedSettingsxxx options. There are plenty of tasty settings there to fulfill your needs.
-
The caption isn't truncated, only the display is clipped:
procedure TForm1.FormCreate(Sender: TObject); Const MYTEXT = '<RHINOSTRING English="Exploding this mesh will create %d individual meshes. This may be more than your system can safely manage using the available memory. You can use Weld to make the mesh explode into fewer pieces, or see Help for more information.\n\nClick OK to proceed with Explode, or Cancel to leave the mesh as is.[[24836]]" Localized="Exploding this mesh will create %d individual meshes. This may be more than your system can safely manage using the available memory. You can use Weld to make the mesh explode into fewer pieces, or see Help for more information.\n\nClick OK to proceed with Explode, or Cancel to leave the mesh as is.[[24836]]" />'; begin ListView1.Items.Add.Caption := MYTEXT; ShowMessage(MYTEXT.Length.ToString + sLineBreak + ListView1.Items[0].Caption.Length.ToString); end;
Shows 661 and 661 respectively.
The reason seems to be a WinApi limitation:
https://stackoverflow.com/questions/19881409/tlistview-add-600-characters-on-item-caption
-
Does TJSonSerializer work with TObjectList and TObjectDictionary already? As far as I remember this is why I started to (de)serialize objects manually back around Delphi 10.4 but would love to automate things finally :)
-
For a while I used this unit to detect the OS version and edition. For a while it is unmaintained though and could use some refactoring for sure.
As @David Heffernan mentioned you must include a mainfest file as a resource in your application, otherwise OS detection will return false information due to compatibility modes.
-
I read a tip here on DelphiPraxis back in 10.x that disabling the Welcome screen altogether greatly improves stability. Since then that's the first thing I do after a Delphi installation and the IDE is rock solid since then.
You get an AV if you click on the Welcome screen settings in Options, but that's a sacrifice I'm willing to live with :)
-
I'm using this code for alternating colors:
Procedure TDBGrid.DrawColumnCell(Const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); Var dataset: TDataSet; {$IFDEF HIDECOLLINESIFEMPTY} colline: Boolean; {$ENDIF} editcolor: TColor; hidefocus: Boolean; Begin dataset := Self.DataSource.DataSet; // This method is only being called on DATA cells, which only happens if there is a dataset connected. Therefore, no // need to perform an assigned check here. {$IFDEF HIDECOLLINESIFEMPTY} colline := True; {$ENDIF} hidefocus := Not (csDesigning In Self.ComponentState) And (gdSelected In State) And Not Self.Focused; If (dgMultiSelect In Self.Options) And (Self.SelectedRows.CurrentRowSelected) Then Begin End Else If dataset.IsEmpty Then Begin {$IFDEF HIDECOLLINESIFEMPTY} colline := False; {$ENDIF} editcolor := TStyleManager.ActiveStyle.GetStyleColor(scEdit); Self.Canvas.Brush.Color := editcolor; Self.Canvas.Font.Color := editcolor; End Else // This code imitates the highlight of the whole row even if RowSelect is disabled. Note that it needs MultiSelect to be enabled! // If Not (gdSelected In State) And grid.SelectedRows.CurrentRowSelected Then // grid.Canvas.Brush.Color := clHighLight // Else If (dataset.RecNo Mod 2 = 0) And ((State = []) Or hidefocus) Then Self.Canvas.Brush.Color := TStyleManager.ActiveStyle.GetStyleColor(scButtonDisabled) Else If (dataset.RecNo Mod 2 = 1) And hidefocus Then Self.Canvas.Brush.Color := TStyleManager.ActiveStyle.GetStyleColor(scEdit); If hidefocus Then Self.Canvas.Brush.Color := TStyleManager.ActiveStyle.GetStyleColor(scCategoryButtonsGradientBase); {$IFDEF HIDECOLLINESIFEMPTY} If HIDECOLLINESIFEMPTY And colline And Not (dgColLines In Self.Options) Then Self.Options := Self.Options + [dgColLines] Else If HIDECOLLINESIFEMPTY And Not colline And (dgColLines In Self.Options) Then Self.Options := Self.Options - [dgColLines]; {$ENDIF} inherited; Self.DefaultDrawColumnCell(Rect, DataCol, Column, State); End;
Supports VCL styles and works fine for a couple of years now.
I used the "lazy" technique. Save this as uDBGrid.pas, add is to the uses clause of your form and in the declaration change "grdMyDBGrid: TDBGrid;" to "grdMyDBGrid: uDBGrid.TDBGrid". Since the class name is the same no modification in the dfm is necessary.
Drawback is, it only works runtime. And it's hacky.
-
1
-
-
1 hour ago, bobD said:Because a TFDConnection connects very quickly, but takes a long time to fail, and it's annoying to sit and wait
I never personally used FireDac, but doesn't it have a configurable timeout property?
If no, what you can do is to attempt to connect in a background thread. Use your local connection until DB connection succeeded then simply swap them out and sync changes.
-
14 minutes ago, bobD said:So the connection attempt would fail and the program would fall over to the local db. It would just take longer.
Why to have any additional checks then...? When you initiate a connection to a host name / fqdn, name resolution is done automatically by the DB client library.
Just attempt a connection to your database server. If that fails for any reason, fall back to the local DB.
-
5 hours ago, Brian Evans said:There are network profiles in Windows which can be Private, Public or Domain. Normally your home network would be Private and anytime you go elsewhere it would be Public (discovery disabled) or Domain. You could check what the active connection is. Or just key off the active profile name for what network settings your application should use.
This check will trigger on all networks, which are set to private which is probably not a desired behavior. While these will work, OP's solution will be a different design pattern.
What if you put the code in a separate DLL, which you are not distributing; and lives only on your home dev PC?
-
When you are trying to detect your home network, don't rely on a successful (reverse) DNS lookup. I usually ping my home router (using fqdn) but even better, attempt a connection to a well-known service. However I only use this method to decide if VPN should be fired up or not; it's better to set up your DNS properly so tools will work from inside and outside.
If you are keen to go this way I found these two snipplets in my codebase:
Function LookupHostName(inIP: String): String; Var host: PHostEnt; addr: Integer; dat: TWSAData; Begin Result := ''; WSAStartup($0101, dat); Try addr := inet_addr(PAnsiChar(AnsiString(inIP))); host := GetHostByAddr(@addr, 4, PF_INET); If host <> nil Then Result := String(host.h_name); Finally WSACleanup; End; End;
This one was abandoned halfway as no variables seem to be declared:
Write('Attempting to resolve ' + HostName + '...'); If WSAStartup($0101, wsdata) = 0 Then Try tmp := GetHostByName(PAnsiChar(HostName)); If tmp <> nil Then Begin tmpin.sin_addr.S_addr := LongInt(PLongInt(tmp^.h_addr_list^)^); IPAddress := inet_ntoa(tmpin.sin_addr); WriteLn(IPAddress); End; Finally WSACleanup; End;
May I ask why your program needs to behave different from a specific network? There might be a better way than relying on simple checks, which might trigger in places you don't want them to.
-
The basic ones (label, edit, memo, etc.) are self-explanatory. For the rest I'm usually creating an empty project, dropping one of the components on the form and start experimenting in what I can do with it.
-
I had one situation when VCL styles flickered a lot, and that was if they were on an anchored / aligned panel and the form was being resized. Setting .ParentBackround := False on the panel solved this though.
-
In theory, you can use XP... I'd love to give it a spin and see if the latest Delphi runs fine or not :)
-
Windows 11 moved further away from privacy, prefers "innovation" noone asked for over functionality and requires way too much hardware just to sit on the desktop, doing nothing.
I'm eyeing Windows 10 IoT Enterprise LTSC. Price is not that high and you get a fully functional and debloated WIndows 10, supported until 2035.
Until then I hope a Delphi IDE will be released for Linux :)
-
Long story short - if you don't have to, don't. I am forced to use it at work and the only positive thing I can say about it is even XE7 runs on it without issues.
-
Antivirus exclusion? If only specific bds.exe-s are set (not the whole Program Files\Embarcadero\Studio folder) your real time scanner can and will affect build times.
-
I personally used MySQL for my projects and a bit of MsSQL server. I advise against FireBird and Oracle, my personal experience shows you'll have extra issues to keep an eye on.
On Windows servers my suggestion is MsSQL, on Linux MariaDB. That way updates / patches are included in the regular process.
-
Unfortunately that is true. If the old version running, it will stay that way until it is closed.
At least you can make sure that the new instances are the updated version :)
-
35 minutes ago, corneliusdavid said:sometimes they leave it running at the end of the day which locks the app from being updated.
I'm not sure because we are talking about a network share, but renaming the file and placing the new .exe (with the same name) might still work. A lot of us use this technique in updating our applications.
-
1 minute ago, maumsti said:That being said, if a malicious actor has already gained access to the network, their primary goal would likely not be just shutting down applications but rather compromising systems, exfiltrating data, or escalating privileges...
With this I completely agree. Meaningful attacks (and their mitigation) are out of the scope of this project however (especially if we are somewhat "controlling" endpoints) we should do our part in cybersecurity :)
-
Include some security. The first glance there's nothing stopping me from shutting down all your programs if I get into your network.
Are you sure you need to keep a TCP connection up with each agent? UDP would be a lot more practical, plus you could do the discovery with a simple broadcasted message.
-
The only benefit I see here is the usage of data aware controls.
A Dataset descendant is never going to be as efficient in storage or manipulation as arrays are. Also keep in mind that you are doubling the resources used every time you are cloning a Dataset, which - by your own words - is already pretty large.
To simplify/standardize I would create my custom data storage class with thread safe access and then look into DataBinding or writing my own helpers to display the data in this storage. If speed is not an issue you also can use an indexed TFileStream to cut back on memory requirements.
programmatically determine the edition of RAD Studio 12.3
in Delphi IDE and APIs
Posted
As this information might be useful I added TAEIDEVersion.Edition and TAEIDEVersion.ExecutableVersion to my installed version / instance detection component. Tested with TAEDelphiVersion, seems to return correct values.