-
Content Count
3000 -
Joined
-
Last visited
-
Days Won
135
Everything posted by Remy Lebeau
-
Can the packages setup be updated for ICS in new versions?
Remy Lebeau replied to Geoffrey Smith's topic in ICS - Internet Component Suite
That is the approach that Indy took a long time ago. It has a master database of its units and their characteristics, and then there is a Package Generator app that reads in that database and spits out DPK files (no DPROJ, CBPROJ, or GROUPPROJ files at this time) for all of the supported compiler versions (well, not all of them, as the app hasn't been updated in a long time - packages for modern compiler versions have largely just been copied from earlier versions and edited by hand). -
Yes. Unfortunately, it still would have been a big update, since OpenSSL basically redesigned their API in v1.1.0. All of the structures were changed, and many functions were either renamed or dropped. So, while making the existing SSLIOHandler component be more version-aware to support both pre-1.1.0 and post-1.1.0 libraries would have been ideal, the API changes really warranted new SSLIOHandler components to keep the two API designs separate. But, to be fair, I wasn't involved in the development of the new components, so I couldn't say if the new design is actually overkill or not.
-
TIdSNTP, and Indy in general, does not connect you to the Internet. You have to already be connected beforehand. It would be more accurate to say that you are using TIdSNTP to connect to a remote time server that is accessible over the Internet. What type of exception are you seeing, exactly? What does it say? Please be more specific.
-
None taken, and yes, there are several PRs that have been pending for too long. But, during that time, there have also been several other user-submitted PRs and non-PR changes alike that have been merged. So, it is not like I'm ignoring everything that gets submitted to me. Regarding the PRs that are still pending, most of them were not ready-to-merge as-is at the time they were submitted, which is why I didn't just blindly merge them. Looking at them now, I can probably merge the smaller ones soon, but if the "big" PR you are referring to is the OpenSSL 1.1+ one, that is a HUGE PR to merge - 246 changed files, and 200 comments/commits trying to iron out its issues. I haven't reviewed its code in full yet.
-
Well, not exactly the same. Keep in mind that keybd_event() (and mouse_event(), too) can only inject 1 event at a time into the input queue, thus other events from other sources could interweave in between the synthetic events. That may have subtle side-effects. Wherever SendInput() is designed to inject multiple events atomically into the queue, thus no interweaving can happen anymore.
-
The value you are passing to the last (cbSize) parameter of SendInput() is wrong. It wants you to give it the size of a single TInput, but you are giving it the full size of your entire array instead. You are also using the wrong TInput field inside of the array. Since you are sending virtual key codes and not hardware scan codes, you should be using the TInput.ki.wVk field rather than the TInput.ki.wScan field. Try this instead: class procedure TRoutinesEx.ShiftTab; var Inputs: array[0..3] of TInput; begin ZeroMemory(@Inputs, SizeOf(Inputs)); Inputs[0].Itype := INPUT_KEYBOARD; Inputs[0].ki.wVk := VK_SHIFT; Inputs[1].Itype := INPUT_KEYBOARD; Inputs[1].ki.wVk := VK_TAB; Inputs[2].Itype := INPUT_KEYBOARD; Inputs[2].ki.dwFlags := KEYEVENTF_KEYUP; Inputs[2].ki.wVk := VK_TAB; Inputs[3].Itype := INPUT_KEYBOARD; Inputs[3].ki.dwFlags := KEYEVENTF_KEYUP; Inputs[3].ki.wVk := VK_SHIFT; SendInput(Length(Inputs), Inputs[0], SizeOf(TInput)); end;
-
Tab (and arrows) is reserved for focus navigation by default, that is true. But, if you want to handle it yourself, you can request it from the OS so it arrives as normal messages. For instance, by intercepting WM_GETDLGCODE to return DLGC_WANTTAB. Some child controls have properties to handle this for you, but TForm does not, so you have to implement it manually.
-
Indy does not implement OAuth at this time, that is true. There are open tickets for adding that feature. However, Indy does work fine with GMail if you enable 2FA and use an app-specific password. Indy has WIP support for OpenSSL 1.1+/TLS 1.3 in this GitHub pull request: https://github.com/indySockets/indy/pull/299 Indy's official GitHub repo has the latest version: https://github.com/IndySockets/Indy/ Indy is still supported (by me). Though, development of new feature for it tends to be a bit on the slow side, for a number of reasons, namely that I'm a sole developer, I don't have a lot of free time, I don't have a working IDE right now, etc etc etc. However, Indy is open-source, users are always free and encouraged to submit new code. Most don't, though.
-
What do you mean?
-
Cross platform HTTP client with proxy support?
Remy Lebeau replied to softtouch's topic in Network, Cloud and Web
Indy's support for OpenSSL 1.1+/TLS 1.3 is a WIP that is available in this pull request: https://github.com/IndySockets/Indy/pull/299 Correct, Indy does not support platform-specific implementations at this time. Delphi's native HTTP client libraries do, though. Did you report that to Embarcadero? Note that Indy is not specifically tied to OpenSSL exclusively. That is just Indy's default SSL/TLS library since it is cross-platform, but you can use any other library you want, all you need is a TIdSSLIOHandlerSocketBase-derived class that wraps the library's API. Some 3rd party SSL/TLS libraries provide such a class, but for others you will have to write (or find) your own class. There are only a handful of virtual methods that need to be implemented (namely, to handle the handshake, to read/write data, etc). -
TIdServerIOHandlerSSLOpenSSL root certficate error
Remy Lebeau replied to Sid D's topic in Delphi IDE and APIs
I can't answer that. I have very little experience working with certificates. -
How to Convert curl command line to Delphi code using IndyHttp or THttpClient.
Remy Lebeau replied to amit's topic in Network, Cloud and Web
The original curl request of this discussion thread uses the "-F" parameter, whereas your request uses the "-d" parameter instead. If you read curl's documentation, the "-F" parameter sends an HTTP "multipart/form-data" request, whereas the "-d" parameter sends an HTTP "application/x-www-form-urlencoded" request. The TIdHTTP.Post() method has separate overloads for those types of requests. Your code is using the wrong overload. You need to use the overload that takes a TStrings, not a TIdMultipartFormDataStream, eg: Result := False; IdHTTP := TIdHTTP.Create(nil); try //'curl https://api.dropbox.com/oauth2/token \ -d code=<AUTHORIZATION_CODE> \ -d grant_type=authorization_code \ -u <APP_KEY>:<APP_SECRET>' ssl := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP); ssl.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2]; ssl.SSLOptions.Mode := TidSSLMode.sslmUnassigned; ssl.SSLOptions.VerifyMode := []; ssl.SSLOptions.VerifyDepth := 0; //ssl.OnStatusInfoEx := __IdSSLIOHandlerSocketOpenSSL1StatusInfoEx; IdHTTP.HandleRedirects := True; IdHTTP.IOHandler := ssl; IdHTTP.Request.BasicAuthentication := True; IdHTTP.Request.Username := 'MY_APP_KEY'; IdHTTP.Request.Password := 'MY_APP_SECRET'; try Params := TStringList.Create; try Params.Add('code=MY_AUTH_CODE'); Params.Add('grant_type=authorization_code'); aStatus := IdHTTP.Post('https://api.dropbox.com/oauth2/token', Params); Result := True; finally Params.Free; end; except on E: EIdHTTPProtocolException do begin aStatus := ErrorResult(IdHTTP.ResponseText); end; end; (**) finally IdHTTP.Free; end; -
TIdServerIOHandlerSSLOpenSSL root certficate error
Remy Lebeau replied to Sid D's topic in Delphi IDE and APIs
How are you configuring the SSLIOHandler? Does the Windows service have permission to access the certificate file? -
Duplicate of
-
Are you using TIdFTP in Active mode (TIdFTP.Passive=False, which is the default) or in Passive mode (TIdFTP.Passive=True)? Different modes use different timeouts, but since you are setting them all, you certainly should be getting a timeout error one way or the other. However, your try..except is catching only exceptions derived from EIdSocketError, but for instance EIdAcceptTimeout (which TIdFTP raises in Active mode if the server doesn't connect to TIdFTP within the ListenTimeout interval) is not derived from EIdSocketError. In the code you have shown, I don't really see a need to have the try..except differentiate which type of exception is raised. It should be catching all of them. You are also not synchronizing with the UI thread when accessing your UI controls. Try something more like this instead: constructor TLoadThread.Create; begin inherited Create(True); FreeOnTerminate := True; end; procedure TLoadThread.Execute; begin try Form2.FTP1.Connect; try Form2.Ftp1.Get('file1.txt', TPath.Combine(TPath.GetTempPath, 'file1.txt'), True, False); Form2.Ftp1.Get('file2.txt', TPath.Combine(TPath.GetTempPath, 'file2.txt'), True, False); finally Form2.FTP1.Disconnect; end; except on e: Exception do begin TThread.Synchronize(nil, procedure begin if e is EIdSocketError then Form2.AddToMemo('Error: ' + IntToStr(EIdSocketError(e).LastError) + ' ' + e.Message) else Form2.AddToMemo('Error: ' + e.Message); end ); end; end; end; procedure TForm2.ThreadTerminated(Sender: TObject); begin xThread := nil; Loading := False; AddToMemo('Thread Terminated'); end; procedure TForm2.FTP1Status(ASender: TObject; const AStatus: TIdStatus; const AStatusText: string); begin TThread.Queue(nil, procedure begin AddToMemo(AStatusText); end ); end; procedure TForm2.AddToMemo(const AMsg: string); begin Memo1.Lines.Add(DateTimeToStr(Now()) + ' ' + AMsg); end; Alternatively, you can move your exception logging to the thread's OnTerminate event handler instead, eg: constructor TLoadThread.Create; begin inherited Create(True); FreeOnTerminate := True; end; procedure TLoadThread.Execute; begin Form2.FTP1.Connect; try Form2.Ftp1.Get('file1.txt', TPath.Combine(TPath.GetTempPath, 'file1.txt'), True, False); Form2.Ftp1.Get('file2.txt', TPath.Combine(TPath.GetTempPath, 'file2.txt'), True, False); finally Form2.FTP1.Disconnect; end; end; procedure TForm2.ThreadTerminated(Sender: TObject); var exc: Exception; begin xThread := nil; Loading := False; if TThread(Sender).FatalException <> nil then begin exc := Exception(TThread(Sender).FatalException); if exc is EIdSocketError then AddToMemo('Error: ' + IntToStr(EIdSocketError(exc).LastError) + ' ' + e.Message) else AddToMemo('Error: ' + e.Message); end; AddToMemo('Thread Terminated'); end; procedure TForm2.FTP1Status(ASender: TObject; const AStatus: TIdStatus; const AStatusText: string); begin TThread.Queue(nil, procedure begin AddToMemo(AStatusText); end ); end; procedure TForm2.AddToMemo(const AMsg: string); begin Memo1.Lines.Add(DateTimeToStr(Now()) + ' ' + AMsg); end;
-
Indy does have some binaries in its OpenSSL-binaries GitHub repo, but it currently has only .DLLs for Windows, .SO's for Android, and static .A's for iOS, there are no .DYLIB's for macOS, sorry.
-
WideString.c_bstr() operation in 11.2
Remy Lebeau replied to Roger Cigol's topic in RTL and Delphi Object Pascal
What is the exact problem you are having? Can you provide an example? Passing a BSTR (which is already a pointer type to begin with) by value for an [in] parameter is very different than passing a pointer to a BSTR for an [in,out]/[out] parameter. The WideString::c_str() method will work fine for the former case, but you can't use it in the latter case, you would have to use WideString::operator& instead. Not without seeing the actual code you are having trouble with. -
It will not be available in 11.3, which is already in beta. It is too soon to speculate about 12.0.
-
I don't know, as I'm not a macOS developer. However, TLS 1.2 was added to OpenSSL in v1.0.1, so v1.0.0 will not suit your needs. That is because Indy's default SSLIOHandler only supports OpenSSL up to v1.0.2. To use OpenSSL v1.1.0 or later, you will have to install and use the work-in-progress SSLIOHandler that is found on this Pull Request in Indy's GitHub repo (as it hasn't been reviewed and merged into the main code yet).
-
There is no ETA on when Indy 11 will be released. Work on it has been slow for several years, but there has been work on it nonetheless. There is an Indy11-preparation branch in Indy 10's GitHub repo whose code is expected to eventually become Indy 11, but it is not quite ready for release yet.
-
In which case, I wouldn't even bother with calling Application.Terminate(), just skip calling Application.Run() instead: begin Application.Initialize; Application.ShowMainForm := False; Application.CreateForm(TfrmMainForm, frmMainForm); if frmMainForm.DoWeShowTheForm then begin Application.ShowMainForm := True; Application.Run; end; end.
-
Application.Terminate() calls PostQuitMessage() internally: // ----- Form1 ---- uses Unit2; procedure TForm1.FormCreate(Sender: TObject); begin Application.Terminate; end; procedure TForm1.Button1Click(Sender: TObject); begin Form2 := TForm2.Create(self); end; // ----- Form2 ---- procedure TForm2.FormCreate(Sender: TObject); begin Application.Terminate; end; No need for using OnClose/caFree when Form1 is the Owner of Form2, since Application.Terminate()/PostQuitMessage() is asynchronous, so the Form1 and Form2 objects will still be created, Form1 will take ownership of Form2, and then the Application object will destroy the Form1 object, and thus the Form2 object, when the Application object is destroyed after the quit message makes Application.Run() exit.
-
Need inline InterfacedObjects to be freed?
Remy Lebeau replied to emileverh's topic in RTL and Delphi Object Pascal
Note that such usage is demonstrated in Embarcadero's documentation, though it is not explicitly called out as being a requirement: https://docwiki.embarcadero.com/RADStudio/en/Inline_Variable_Declaration procedure Test99; begin // some code if (something) then begin var Intf: IInterface = GetInterface; // Intf.AddRef // <-- HERE! var MRec: TManagedRecord = GetMRecValue; // MRec.Create + MRec.Assign UseIntf(Intf); UseMRec(MRec); end; // Intf.Release and MRec.Destroy are implicitly called at end of scope // more code end; // no additional cleanup -
Only while the control is actively processing a paint operation invoked by the OS - ie, during a WM_PAINT or NM_CUSTOMDRAW or equivalent window message. Before the control's virtual Paint() method is called, or its public OnPaint/OnDraw... events are fired, both allowing user code to handle custom drawing, the relevant control properties are assigned to the Canvas. Outside of an active paint operation, the Canvas's properties are not guaranteed to match the control's properties, and likely will be defaults instead.
-
Access class fields and properties with RTTI
Remy Lebeau replied to pyscripter's topic in RTL and Delphi Object Pascal
AFAIK, yes, it is still the case.