

HeartWare
-
Content Count
27 -
Joined
-
Last visited
Posts posted by HeartWare
-
-
How does Rapid.TList<STRING> compare to THashSet<STRING> (only for checking if an entry exists in the list or not)? It'll be called thousands of times (the list itself will be pretty small - 5 or 10 entries)
-
I have this contact in India who specializes in Delphi-to-COBOL translations: Ran Slirpa (or Loof Lirpa as he's also known). I can put you in contact with him, if you wish.
-
CONST [ref] is on the surface the same as VAR but it allows a CLASS variable of a descendant to be passed. So where a VAR TObject only allows variables declared as TObject, a CONST [ref] TObject parameter passes a reference (like VAR does) to the instance pointer, but allows all descendants of TObject to be passed in. This eliminates the issue with a typeless VAR to FreeAndNIL also accepting non-classes.
-
1
-
-
23 hours ago, Cristian Peța said:If you open the file with TPNGImage it will raise an exception if the content is not PNG. Not so hard to detect it is not a PNG content.
True, but then you'd have to have the full PNG and JPG decoding library included (as well as all other image formats decoding libraries) instead of just checking the header (which, granted, wouldn't allow you to check if the file is loadable - only that it claims to be what the file extension says).
It all depends on what you really want to check and how extensive the check should be.
-
That won't detect a .PNG file with .JPG content (it will merely detect that it is some form of picture).
-
Something like this (for Image Formats - the ones I detect for):
Quote
FUNCTION ImageFormat(CONST Data : TBytes) : CpuInt;
BEGIN
IF Data.Count<100 THEN
Result:=TImageFormat.Unknown
ELSE IF Data.StartsWith([$89,$50,$4E,$47]) THEN
Result:=TImageFormat.PNG
ELSE IF Data.StartsWith([$FF,$D8,$FF]) AND (Data[6]=$4A) AND (Data[7]=$46) AND (Data[8]=$49) AND (Data[9]=$46) THEN
Result:=TImageFormat.JPG
ELSE IF Data.StartsWith([$42,$4D]) THEN
Result:=TImageFormat.BMP
ELSE IF Data.StartsWith('GIF89') OR Data.StartsWith('GIF87') THEN
Result:=TImageFormat.GIF
ELSE IF Data.Contains('<svg ') THEN // Data.StartsWith('<?xml version="1.0" encoding="UTF-8"') OR Data.StartsWith('<svg ') THEN
Result:=TImageFormat.SVG
ELSE
Result:=TImageFormat.Unknown
END;
Using a TBytes Helper "StartsWith" and "Contains" - but should give you an idea.
Not 100% but enough for my usage, and should allow you to adapt the methodology to your own needs.
-
1
-
-
Unfortunately it's an uphill battle. You can't win. Whatever you do, they will find a way around it, as you cannot differentiate between legal individuals and a mass-request from different IPs. They can hit you from such diverse places as Australia, India, Brazil, Germany and Canada at the same time, and you have no way of knowing if they are from the same person.
Is there a pattern in their requests? Do they go alphabetically? If so, you can do heurestics detection (but they can circumvent this by going random).
You can also limit the speed with which you accept requests (ie. a minimum of 1 min. between requests), but they will soon detect this and space it out to a random value between 1:10 and 1:30, and you risk annoying your legitimate users.
-
1 hour ago, Uwe Raabe said:Yes, upscaling and downscaling by the same factor keeps all values intact (I provided a mathematical proof for that), but downscaling and upscaling does not. That was the main reason for my feature request: RSP-35301 - Option to design in Screen PPI but save in 96 PPI
Ooooh - someone else had the same idea 🙂
-
On 2/23/2024 at 12:38 PM, Cristian Peța said:Yes, but imagine someone with 200% display scale with a magnifying glass trying to adjust something on a form because the form is half the size.
Which is why I suggest a mode that works internally in 96dpi but shows (and allows edit) in the monitor's native DPI. Yes, it will mean that you are restricted to placing components on a 2x2 grid if your monitor is at 200% and the grid will be unsymmetrical if you're at 150%, but since all components will be locked into the same grid, you can still align the positions and sizes.
-
2
-
-
On 2/19/2024 at 3:43 PM, Lars Fosdal said:Not per se. However, the problem is that once you use the DPI aware IDE, the measurements and coordinates in forms are according to your current Windows DPI and scaling settings. Which means that when someone with a different DPI or scaling opens the form, it looks like shit and the changes that someone makes, will again be impacted by their settings. So if two people with two different settings, takes turn in changing a form, you can get a form that keeps on growing or shrinking during the design.
Personally, I would prefer that such a thing doesn't happen - so that I can benefit from HighDPI also in the IDE.
It is not a trivial problem to solve. Pixel perfection becomes very hard once you have to deal with design time as well as runtime scaling.
They should do what we did in our designer. Always work internally (and store) values for 96dpi (100%) in the designer, only scaling it up for display. The issue comes if you scale from (f.ex.) 150% to 200% and then back to 100%. But you can always scale correctly if you go via 100%, ie. to go from 150% to 200%, you go 150% -> 100% -> 200%, then you can always get back to 100%.
That is my wish - An IDE designer mode that works in 100% (96dpi) but scales the visual designer to the monitor's DPI (yes, that will affect your pixel-perfect alignment in 150% during design, but it will be pixel-perfect in whatever scale the final monitor is at, since everything can always be consistently scaled UP from 100% to any DPI). And if your .DFM is stored in 100% values and you start the program on a 150% monitor and then move it to a 200%, it will be scaled back to 100% before being scaled up to 200%. -
1 minute ago, Die Holländer said:I think a language where you can close a modal form without-modalresult being set to mrcancel..
You mean, like Delphi?
-
On 11/10/2023 at 3:06 PM, gkobler said:Download links give "404 Not Found"Now, suddenly, they work...
-
1
-
-
This is the communication log (>> is me sending, << is receiveing)
Quote<< * OK The Microsoft Exchange IMAP4 service is ready. [TQBNADAAUAAyADgAMABDAEEAMAAwADgAMAAuAFMAVwBFAFAAMgA4ADAALgBQAFIATwBEAC4ATwBVAFQATABPAE8ASwAuAEMATwBNAA==] >> C1 CAPABILITY << * CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+ << C1 OK CAPABILITY completed. >> C2 AUTHENTICATE XOAUTH2 dXNlcj1ib3VuY2VAYWRtaW5kLmRrAWF1d******DQyLWM4YzEtNGJhYy1iN2Y1LTQxN2Y4ZmZlOTc0ZAEB << C2 NO AUTHENTICATE failed. >> C3 LOGOUT << * BYE Microsoft Exchange Server IMAP4 server signing off. << C3 OK LOGOUT completed.
-
Thank you very much, Remy. I have now come a bit longer, but it still fails (maybe I'm feeding it the wrong "secret key"). I have this code now:
QuotePROCEDURE TForm141.ConnectBtnClick(Sender: TObject);
VAR
IMAP : TIdIMAP4;
SSL : TIdSSLIOHandlerSocketOpenSSL;
PASS : TIdUserPassProvider;
SASL : TIdSASLXOAuth2;BEGIN
IMAP:=TIdIMAP4.Create(NIL);
TRY
IMAP.Host:=Host.Text;
IMAP.AuthType:=TIdIMAP4AuthenticationType.iatSASL;
SSL:=TIdSSLIOHandlerSocketOpenSSL.Create(IMAP);
IMAP.IOHandler:=SSL;
IMAP.UseTLS:=TIdUseTLS.utUseImplicitTLS;
PASS:=TIdUserPassProvider.Create(IMAP);
PASS.Username:=UserName.Text;
PASS.Password:=SecretKey;
SASL:=TIdSASLXOAuth2.Create(IMAP);
SASL.UserPassProvider:=PASS;
IMAP.SASLMechanisms.Add.SASL:=SASL;
SSL.SSLOptions.SSLVersions:=[TIdSSLVersion.sslvTLSv1_2];
IMAP.Port:=993;
IMAP.Connect;
TRY
Information('Messages: '+IntToStr(IMAP.MailBox.TotalMsgs))
FINALLY
IMAP.Disconnect
END
FINALLY
FreeAndNIL(IMAP)
END
END;but it fails in IdIMAP4.PAS at this line:
Quotefunction PerformSASLLogin_IMAP(ASASL: TIdSASL; AEncoder: TIdEncoder;
ADecoder: TIdDecoder; AClient : TIdIMAP4): Boolean;
const
AOkReplies: array[0..0] of string = (IMAP_OK);
AContinueReplies: array[0..0] of string = (IMAP_CONT);
var
S: String;
AuthStarted: Boolean;
begin
Result := False;
AuthStarted := False;// TODO: use UTF-8 when base64-encoding strings...
if AClient.IsCapabilityListed('SASL-IR') then begin {Do not localize}
if ASASL.TryStartAuthenticate(AClient.Host, AClient.Port, IdGSKSSN_imap, S) then begin
AClient.SendCmd(AClient.NewCmdCounter, 'AUTHENTICATE ' + String(ASASL.ServiceName) + ' ' + AEncoder.Encode(S), [], True); {Do not Localize}
if CheckStrFail(AClient.LastCmdResult.Code, AOkReplies, AContinueReplies) then begin
ASASL.FinishAuthenticate;
Exit; // this mechanism is not supported // <--- Exits here
end;
AuthStarted := True;
end;
end;And ASASL.Service = 'XOAUTH2' and S = 'user=<MailBox@domain>'#1'auth=Bearer <Secret Key>'#1#1 and AClient.LastCmdResult.Code = 'NO'
When I generated my tokens/keys according to Outlook documentation, I got two values. I have tried with both of them, and they both fail at this spot.
Is there a way where I can generate the token needed in code somehow, or do I need to use the value I was given via the online web system?
-
Thank you, Remy.
I have downloaded the files, explicitly added the necessary .PAS files to my project (to force the use of these instead of the Indy10 in my RAD Studio installation), and added the following lines:
QuoteSASL:=TIdSASLXOAuth2.Create(IMAP);
// What do I need to initialize in SASL ?
IMAP.SASLMechanisms.Add.SASL:=SASL;after the "UseTLS" line.
I assume I need to assign something to SASL.UserPassProvider and/or call some of the Autheticate functions. But what should I put into the parameters of the Authenticate calls? Host/Protocol I assume will be outlook.office365.com and 993 (?) but what about "ProtocolName" and what do I send/receive in VirtualResponse? Where do I put the base64 encoded string with user and bearer token? In OnGetAccessToken, I assume?
What final value from SASL should I assign to IMAP.Password after authentication? Or does that happen internally, due to my adding SASL to the IMAP's SASLMechanisms?
Can you help me out, please? 🙂
-
I currently have the following code:
Quoteprocedure TForm141.ConnectBtnClick(Sender: TObject);
VAR
IMAP : TIdIMAP4;
SSL : TIdSSLIOHandlerSocketOpenSSL;BEGIN
IMAP:=TIdIMAP4.Create(NIL);
TRY
SSL:=TIdSSLIOHandlerSocketOpenSSL.Create(IMAP);
IMAP.Host:=Host.Text;
IMAP.Username:=UserName.Text;
IMAP.Password:=Password.Text;
IMAP.IOHandler:=SSL;
IMAP.AuthType:=TIdIMAP4AuthenticationType.iatUserPass;
IMAP.UseTLS:=TIdUseTLS.utUseImplicitTLS;
SSL.SSLOptions.SSLVersions:=[TIdSSLVersion.sslvTLSv1_2];
IMAP.Port:=993;
IMAP.Connect;
TRY
Information('Messages: '+IntToStr(IMAP.MailBox.TotalMsgs))
FINALLY
IMAP.Disconnect
END
FINALLY
FreeAndNIL(IMAP)
END
END;but when I try to connect to Microsoft Office365 (at outlook.office365.com) I can't get it to work (get "LOGIN failed" exception). Is there some other property of the TIdIMAP that I need to set? And what exactly should I put into the UserName/Password fields?
Anyone have some working code that connects to outlook.office365.com using TIdIMAP4 ?
Keld R. Hansen
-
Now that Delphi 11.3 has been released, do you have an estimate on when you'll be able to release a version of your plugin that supports 11.3?
-
On 1/8/2023 at 2:37 AM, David Schwartz said:(If they'd make it so class helpers can inherit previous helpers, then they could simply be published as separate units available to every Delphi user.)
They have, and they can:
TYPE TMyClassHelper = CLASS HELPER(TAncestorHelper) FOR TAncestor
However, RECORD HELPERS cannot be inherited...
-
How do you make a sub-folder to an already existing folder in Favorite branch? Ie. I have a Favorite folder "Utils" under which I want to sub-divide my projects in "GUI" and "CLI", f.ex. When I click the "+" button, it always creates the new folder directly under Favorites. And when I try to Drag'n'Drop it into the correct folder, it just drags it to another position within the Favorites branch.
Also, when I use Drag'n'Drop (after enabling it) from one favorite folder to another, it doesn't operate on the project I'm dragging, but always takes the top one from the source folder.
Also, when Drag'n'Dropping, it should MOVE the project instead of COPYing it (unless you hold down Ctrl when you drag - then it is a COPY operation, as per the standard Windows Drag'n'Drop).
I'm really getting to like this extension, but it still has a few rough edges 🙂
-
7 minutes ago, HeartWare said:When I try to "Close All Files", I get an exception:
[Crash Dump]
and I am unable to continue other than hard-killing BDS.
A possible explanation:
If I have the "Close Welcome screen when opening a new project" enabled, the error occurs. If the Welcome screen is open when I select "Close All Files", it doesn't.
-
When I try to "Close All Files", I get an exception:
[308BDA88]{WP.gksoftPlugin280.bpl} WP.gksoftPlugIn.View.Gksoftplugin.View.TWPFileNotifier.FileNotification (Line 1659, "WP.gksoftPlugIn.View.pas" + 12) + $3
[2F233D50]{EurekaLogCore280.bpl} Especificdelphi.IsCppExceptionCode + $20
[2F3C18DA]{EurekaLogCore280.bpl} Eexceptioninfocpp.ECppException + $35A
[2F3C63E8]{EurekaLogCore280.bpl} Eexceptioninfobcb.EBCPPStdException.GetStdException + $278
[2F3C7BE4]{EurekaLogCore280.bpl} Eexceptioninfollvm.EBCPPStdException.GetStdException + $214
[2F3CA492]{EurekaLogCore280.bpl} Eexceptioninfomsvc.EMSCppStdException.GetStdException + $222
[79A21033]{rtl280.bpl } System.@HandleAnyException (Line 20992, "System.pas" + 13) + $0
[79A29D87]{rtl280.bpl } System.TInterfacedObject.QueryInterface (Line 39725, "System.pas" + 1) + $8
[79A1FF56]{rtl280.bpl } System.TObject.GetInterface (Line 18385, "System.pas" + 7) + $9
[79A29D87]{rtl280.bpl } System.TInterfacedObject.QueryInterface (Line 39725, "System.pas" + 1) + $8
[308BDA19]{WP.gksoftPlugin280.bpl} WP.gksoftPlugIn.View.Gksoftplugin.View.TWPFileNotifier.FileNotification (Line 1650, "WP.gksoftPlugIn.View.pas" + 3) + $7
[79A29D87]{rtl280.bpl } System.TInterfacedObject.QueryInterface (Line 39725, "System.pas" + 1) + $8
[78C52FC5]{coreide280.bpl} IDEServices.TIDEServices.SendFileNotification (Line 5331, "IDEServices.pas" + 😎 + $10
[78C536FA]{coreide280.bpl} IDEServices.FileNotification (Line 5592, "IDEServices.pas" + 1) + $9
[78951B9F]{coreide280.bpl} ProjectGroup.TProjectGroup.BeforeDestruction (Line 920, "ProjectGroup.pas" + 4) + $10
[79A20529]{rtl280.bpl } System.@BeforeDestruction (Line 19336, "System.pas" + 10) + $0
[78951B26]{coreide280.bpl} ProjectGroup.TProjectGroup.Destroy (Line 901, "ProjectGroup.pas" + 0) + $2
[79A1FDF4]{rtl280.bpl } System.TObject.Free (Line 17991, "System.pas" + 1) + $4
[789584F6]{coreide280.bpl} ProjectGroup.TProjectGroupWrapper.Close (Line 2848, "ProjectGroup.pas" + 2) + $5
[00EE7B0F]{bds.exe } AppMain.TAppBuilder.DestroyProjectGroup (Line 2841, "AppMain.pas" + 21) + $9
[00EE7C68]{bds.exe } AppMain.TAppBuilder.CloseProjectGroup (Line 2863, "AppMain.pas" + 4) + $2
[00EE8B49]{bds.exe } AppMain.TAppBuilder.FileCloseAll (Line 3156, "AppMain.pas" + 😎 + $2
[79B349D3]{rtl280.bpl } System.Classes.TBasicAction.Execute (Line 17981, "System.Classes.pas" + 3) + $7
[795CFAC2]{vcl280.bpl } Vcl.ActnList.TCustomAction.Execute (Line 284, "Vcl.ActnList.pas" + 19) + $35
[79B34827]{rtl280.bpl } System.Classes.TBasicActionLink.Execute (Line 17892, "System.Classes.pas" + 2) + $7
[7743664D]{vclactnband280.bpl} Vcl.ActnMenus.TCustomActionMenuBar.ExecAction (Line 1099, "Vcl.ActnMenus.pas" + 6) + $D
[77437F08]{vclactnband280.bpl} Vcl.ActnMenus.TCustomActionMenuBar.TrackMenu (Line 1869, "Vcl.ActnMenus.pas" + 19) + $15
[7743BA5E]{vclactnband280.bpl} Vcl.ActnMenus.TCustomActionMainMenuBar.TrackMenu (Line 3739, "Vcl.ActnMenus.pas" + 5) + $3
[774361CC]{vclactnband280.bpl} Vcl.ActnMenus.TCustomActionMenuBar.CMItemClicked (Line 969, "Vcl.ActnMenus.pas" + 2) + $11
[774361D5]{vclactnband280.bpl} Vcl.ActnMenus.TCustomActionMenuBar.CMItemClicked (Line 970, "Vcl.ActnMenus.pas" + 3) + $4
[795E7F46]{vcl280.bpl } Vcl.Controls.TControl.WndProc (Line 7584, "Vcl.Controls.pas" + 91) + $6
[795ED0F1]{vcl280.bpl } Vcl.Controls.TWinControl.WndProc (Line 10631, "Vcl.Controls.pas" + 170) + $6
[795E7B7C]{vcl280.bpl } Vcl.Controls.TControl.Perform (Line 7362, "Vcl.Controls.pas" + 10) + $8
[795EC6F9]{vcl280.bpl } Vcl.Controls.GetControlAtPos (Line 10332, "Vcl.Controls.pas" + 2) + $78
[795ECF7D]{vcl280.bpl } Vcl.Controls.TWinControl.WndProc (Line 10579, "Vcl.Controls.pas" + 118) + $1D
[795ED0F1]{vcl280.bpl } Vcl.Controls.TWinControl.WndProc (Line 10631, "Vcl.Controls.pas" + 170) + $6
[7743803B]{vclactnband280.bpl} Vcl.ActnMenus.TCustomActionMenuBar.WndProc (Line 1913, "Vcl.ActnMenus.pas" + 25) + $4
[795EC5FC]{vcl280.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 10308, "Vcl.Controls.pas" + 3) + $6
[79B3580C]{rtl280.bpl } System.Classes.StdWndProc (Line 18490, "System.Classes.pas" + 😎 + $0
[7973417F]{vcl280.bpl } Vcl.Forms.TApplication.ProcessMessage (Line 11460, "Vcl.Forms.pas" + 23) + $1
[797341C2]{vcl280.bpl } Vcl.Forms.TApplication.HandleMessage (Line 11490, "Vcl.Forms.pas" + 1) + $4
[79734501]{vcl280.bpl } Vcl.Forms.TApplication.Run (Line 11629, "Vcl.Forms.pas" + 27) + $3
[00F38082]{bds.exe } bds.bds (Line 227, "" + 16) + $2and I am unable to continue other than hard-killing BDS.
-
1 minute ago, HeartWare said:Okay - installed in my v11.2 and it installed okay.
But I can't populate the various branches. I have clicked the "Enable Drag'n'Drop" and can start a drag operation from the plug-in's "Recently Used->Projects" but I can't drop it on the "Favourites" branch (get a "forbidden" stop sign).
How am I supposed to populate the branches if not by D'n'D?
Also, the "+" button above the tree doesn't do anything. How am I to create new branches under the existing ones?
Okay - think I've figured it out. The "Favourites" can't be populated - only branches below that one.
And the "+" cannot create sub-branches other than in Favourites... (ie. not in "Recently Used->Projects").
-
Okay - installed in my v11.2 and it installed okay.
But I can't populate the various branches. I have clicked the "Enable Drag'n'Drop" and can start a drag operation from the plug-in's "Recently Used->Projects" but I can't drop it on the "Favourites" branch (get a "forbidden" stop sign).
How am I supposed to populate the branches if not by D'n'D?
Also, the "+" button above the tree doesn't do anything. How am I to create new branches under the existing ones?
-
It seems like it doesn't work with version 28.0.42600.6491 - is that right?
Which version does it work with?
Class alias for class helper doesn't make class helper visible for compiler.
in RTL and Delphi Object Pascal
Posted · Edited by HeartWare
Fleshed out
Have you tried
unit Unit2;
interface
uses Unit1;
type TControlHelper = class helper(Unit1.TControlHelper) for TControl end;
implementation
end.
(Haven't tried myself, but logically, I think it would work)