Jump to content

Remy Lebeau

Members
  • Content Count

    2337
  • Joined

  • Last visited

  • Days Won

    95

Everything posted by Remy Lebeau

  1. Remy Lebeau

    Internet time sync - with some timeout

    That would require moving the routine into a separate process or COM object that can then run elevated.
  2. I assume, then, that gettimeofday() is failing? That might be related to this: https://github.com/IndySockets/Indy/issues/245 Thanks. I'll look into incorporating TTimeZone into Indy. There are quite a number of code fragments that can make use of it. What issue is that? Is it an Indy issue, or just a Delphi issue?
  3. Remy Lebeau

    Internet time sync - with some timeout

    But WHERE is it hanging exactly? You need to determine that. Is it on the actual transmission of the request packet? On the receiving of the response packet? On the setting of the PC clock? Your code is calling only 1 method (SyncTime), but that method does multiple things internally, so there are multiple points of failure. Have you tried to use a packet sniffer, like Wireshark, to make sure the SNTP request is actually being sent, and an SNTP response is being received? That is because SNTP runs over UDP, so there is no connection, like you are thinking of. A UDP socket can be "connected" to a remote peer by assigning the peer's IP address statically to the UDP socket, thus sends/receives via that socket will interact only with that particular IP. But that is optional. Your code is not calling the TIdSNTP.Connect() method to establish such a static association, which is why you are not seeing the OnConnected/OnDisconnected events being fired. By default, TIdSNTP will simply write a datagram to the network and then wait for a responding datagram to come back from any peer to TIdSNTP's sending port, which is usually fine in most cases.
  4. That means Indy's IdGlobal.OffsetFromUTC() and/or IdGlobalProtocols.TimeZoneBias() function is returning a time zone offset of 0.0. So, either the function(s) are failing to query the OS for the correct time zone, or the time zone is actually being reported as UTC. You are going to have to debug into Indy's code to see which is actually the case. No. The local time zone is always queried dynamically. It just happens to be coming back as offset 0 in your situation. I can't answer that without more details about what exactly is failing.
  5. Remy Lebeau

    Main Form appearing issue..

    That is wrong. The PopupParent should be the AudioForm instead, since it is the one invoking the print dialog. There is only 1 good reason to ever do that - if you want the AudioForm to be a top-level window (acting as a sibling of the MainForm, so either Form could appear on top of the other at any time) with its own button on the Taskbar. Otherwise, without that code, the AudioForm would by default be owned by the TApplication window (when Application.ShowMainFormOnTaskbar=false) or the MainForm window (when Application.ShowMainFormOnTaskbar=true), and thus would not have a Taskbar button, and would always appear on top of its owner, never underneath it.
  6. Remy Lebeau

    New to Json

    No, it is not, as the code in question is not creating any new JSON objects, only reading them. The framework will do all of the necessary creations for you while parsing the JSON string. It is not necessary in this example at all. If you were creating a new JSON document, THEN you would have to create new objects as needed. Only the root object returned by ParseJSONValue() needs to be freed explicitly. The rest of the objects in the document are owned by the root object and will be freed automatically when the root object is freed.
  7. Remy Lebeau

    How to .Free a non-modal form?

    No. You have to reset it manually. Unless the parent form needs to reset its FNonModalForm variable, in which case you would need to move the OnClose handler to the parent form instead, eg: procedure TForm1.Button1Click(Sender: TObject); begin if FNonModalForm = nil then begin FNonModalForm := TForm2.Create(Self); FNonModalForm.OnClose := NonModalFormClosed; end; FNonModalForm.Show; end; procedure TForm1.NonModalFormClosed(Sender: TObject; var Action; TCloseAction); begin FNonModalForm := nil; Action := caFree; end;
  8. Remy Lebeau

    Using Indy with Xero API

    Do you mean your WebBroker server is sending back a 200 response to your clients? That is likely because you are not reporting any error to WebBroker, so it thinks the client's request is successful. If TIdHTTP receives a HTTP "400 Bad Request" response, it will raise an EIdHTTPProtocolException exception, unless you explicitly tell it not to. But, you are swallowing ALL exceptions raised by TIdHTTP, so WebBroker won't know about them. Your exception handler should either re-raise any caught exception, or at least populate WebBroker's Response with an appropriate error code and content. Does the body content of Xero's response say WHY the request is bad? I suspect it is because of the issue below... That is not what BasicAuthentication means. Setting that property to False tells TIdHTTP that it is not allowed to fallback to using HTTP's "BASIC" authentication scheme if a more appropriate scheme is not selected, after TIdHTTP has looked at a response's "WWW-Authenticate" header, matched it to any registered TIdAuthentication classes, and fired its On(Select)Authorization events to allow you to customize the handling. Since you are using the TIdHTTP.Request.CustomHeaders property to provide authentication credentials manually, you are responsible for ensuring the proper formatting of that data. Which, if Xero is really expecting BASIC authentication, as your code suggests, then your credential data is NOT being formatted properly. That could easily cause a 400 error. BASIC does not use url-encoding at all. And even if it did, your formatted string would still be malformed, as it lacks the required 'Basic ' prefix. For proper BASIC formatting, you would need to change this: tempString := StringReplace(UrlEncode(sClientID + ':' + sClientSecret),#$D#$A, '', [rfReplaceAll]); To this instead: // TIdEncoderMIME is Indy's Base64 encoder tempString := 'Basic ' + TIdEncoderMIME.EncodeString(sClientID + ':' + sClientSecret, IndyTextEncoding_UTF8); But, if Xero really expects BASIC authentication, you don't need to use the CustomHeaders property for that, as TIdHTTP has built-in support for BASIC. Simply set BasicAuthentication to True, and then set the TIdHTTP.Request.UserName and TIdHTTP.Request.Password properties as needed. Let TIdHTTP handle the formatting of the request's "Authorization" header for you: my_http.Request.BasicAuthentication := True; my_http.Request.UserName := sClientID; my_http.Request.Password := sClientSecret;
  9. Remy Lebeau

    Retrieving gmail email with TIDPop3

    POP3 will work for Gmail, in that you can connect and download emails, but it just may not work the way you are expecting a typical POP3 server to behave. See: Read Gmail messages on other email clients using POP Gmail’s POP3 behavior
  10. Remy Lebeau

    Retrieving gmail email with TIDPop3

    Why POP3 and not IMAP? GMail's POP3 implementation is a bit of an oddball, it does not exhibit standard POP3 behaviors. This is described in GMail's POP3 documentation. This is why I question your choice to use POP3 to begin with. More precisely, it tells you that you have 274 emails that have not been downloaded via POP3 yet. Once you have downloaded a Gmail email via POP3, you can't access it again via POP3, even if it still exists in the Inbox. In your Gmail settings, you have to specify what you want Gmail to do with emails that have been downloaded via PO3.
  11. Remy Lebeau

    Creating custom file groupings

    The IDE just knows that PAS/CPP and DFM files are related to each other, so it groups them together automatically based on matching unit/file names. AFAIK, there is no registration/API you can use to do this kind of grouping for other types of files.
  12. "Best" is a bit subjective. What you describe could be the EASIEST way, but not necessarily the BEST or FASTEST way. An alternative that doesn't involve spawning a separate process or using any file I/O would be to use NtQuerySytemInformation(SystemHandleInformation) instead to find open handles that belong to your process, and then resolve which files they refer to. See Enumerating opened handles from a process. Yes, it is more work to code for, but it may be much more efficient in the long run.
  13. True. However, when using Process Monitor, the user can see WHEN the file is being opened by his app in real-time. Maybe he can match that up to a specific operation the app is performing at that time, and then he can track down the code behind that operation to see if it is leaking the file handle.
  14. Remy Lebeau

    Converting C struct to Delphi

    Then the C struct should use an untyped pointer to begin with. Since the EXE can't make use of the pointer anyway, it is just for the DLL's private use. So the DLL can open a file and store the FILE* (or whatever) in the pointer, then cast it back when needing to access the file again. The EXE shouldn't have any knowledge about HOW the DLL accesses the file. Seems like a waste of effort to port the C code twice to two separate and unrelated languages. Some Roku devices already support H.264. And there are some existing 3rd party solutions for streaming RTSP to Roku.
  15. Remy Lebeau

    Installing Community Edition (error 500)

    Looks like someone forgot to notify Support that Embarcadero's community forums are now dead.
  16. Remy Lebeau

    Converting C struct to Delphi

    The C code is likely using a FILE* stream to read/write MP4E_track_t data from/to a media file on disk. In Delphi, you can use TFileStream for that same purpose.
  17. Remy Lebeau

    A Strange thing with TImage

    Since the TImage.Picture property is operating correctly at run-time, this sounds like it is just a design-time issue. I'm guessing that maybe a 3rd party package has registered its own design-time editor for TPicture that is interfering with the IDE's native TPicture editor. I would suggest turning off all non-essential packages and see if the problem goes away. If you can't solve the design-time issue, there is a run-time workaround. You can store the PNG in the app's resources at compile-time, then use a TResourceStream to load it into the TImage.Picture at run-time via TPicture.LoadFromStream() or TPngImage.LoadFromStream(). At least that way you don't have to distribute the PNG as a separate file.
  18. Remy Lebeau

    Marking Forum as Read - Doesn't

    What I do is on each visit to this site, I click on "Unread Content" that is available at the top of every page, open any new messages that look interesting, and then click on "Mark site read" at the bottom of the list. I haven't had any problems with old messages popping up as unread after I have read/marked them.
  19. Remy Lebeau

    Send Email from Android with multiple CC addresses

    EXTRA_CC takes a String[] array as input. You are creating a 1-element array holding a comma-delimited string. Try separating out the individual addresses instead, one address per array element. You could use Java's String.split() method for that, eg: Intent.putExtra(TJIntent.JavaClass.EXTRA_CC, StringToJString(Trim(ccTechs)).split(StringToJString('\s*,\s*')) ); Also, whether or not the email will populate the CC field is up to the email app that processes the Intent, it is not up to your code. It is possible that the email app you are testing with simply ignores the EXTRA_CC data. For example, Gmail 4.2 suffered from this problem, but that was fixed in Gmail 4.3.
  20. Remy Lebeau

    Delphi 10.4 GetIt connection issue

    You need to set the ServiceUrl to https://getit.embarcadero.com instead. https://getitnow.embarcadero.com is the web front end that is meant for humans to access, not the IDE to access.
  21. Remy Lebeau

    Converting C struct to Delphi

    The language member is an 'unsigned char' array on the C side, so make sure you use an AnsiChar array, or better a Byte array, on the Delphi side. Don't mistakenly use a (Wide)Char array: language: array[0..3] of AnsiChar; or language: array[0..3] of Byte; You could do it that way, yes (I would suggest (U)Int32 or DWORD instead). Or, you could use {$MINENUMSIZE 4} like David suggested.
  22. Known issue (there are several discussion threads on this forum about it). That server was shutdown 2 months ago. Change GetIt's configuration to use https://getit.embarcadero.com instead of https://getit-104.embarcadero.com, see this discussion for how to do that:
  23. The old Borland socket components do not support Unicode strings. Some methods were updated to at least accept UnicodeString parameters, but they are not transmitted as Unicode, or even converted to 8bit properly. So avoid the SendText()/ReceiveText() methods and just use the SendBuf()/ReceiveBuf() methods, doing any string<->byte conversions manually in your own code. Or Indy, which is already pre-installed in the IDE, handles Unicode strings, and even has an HL7 component that can operate as both client and server modes.
  24. Remy Lebeau

    TetheringManager refusing connection

    But the issue would still be dependent on HOW AppTethering is using Indy internally. Why the Server is using so many ports, and why there are so many incomplete connections between components. What you describe sounds like port exhaustion, but you shouldn't be getting that on a TCP server, only on a TCP client. Without these kind of details, I couldn't say whether the problem is due to an error in AppTethering itself, or in the user's configuration for AppTethering, etc.
  25. Remy Lebeau

    Unfixed bug in Sydney

    Since the bug has workarounds, has Mitov updated his code to apply the workarounds until the bug is fixed?
×