Jump to content

Remy Lebeau

Members
  • Content Count

    2349
  • Joined

  • Last visited

  • Days Won

    95

Everything posted by Remy Lebeau

  1. Odd. Are you ABSOLUTELY SURE that those event handlers are actually assigned to the TWebBrowser?
  2. Are you sure about that? I don't use the REST stuff, but seems to me like that should be in its own separate package, not cluttering the RTL. Just because the exception's stack trace mentions rtl250.bpl does not mean the REST stuff resides in the RTL itself. The runtime class registration functionality is in the RTL, which other packages can then call into to share their classes with each other (among other things). I suggest you hunt down the real package that the REST stuff actually resides in, and make sure your 2 DLLs are using that package dynamically rather than statically.
  3. Remy Lebeau

    TIdSNTP.SyncTime ??

    If you don't want to run the whole app elevated, and don't want to use a separate elevated process for the sync code, you could separate the sync code into a COM object, and then the main app can run unelavated and load the COM object elevated when needed by using the COM Elevation Moniker. This way, everything is kept in a single process.
  4. Remy Lebeau

    Missing DPR

    There is a free Community Edition available. What is the EXACT error message? Does it say WHICH dpr file is missing? Maybe your project has a dependency that is missing? Can you provide your project's file hierarchy, setup, etc?
  5. Remy Lebeau

    TIdSNTP.SyncTime ??

    TIdSNTP.SyncTime() uses the Win32 SetLocalTime() function, which requires the calling process to have the SE_SYSTEMTIME_NAME privilege present in its user token (even if it is not enabled, it just needs to be present - SetLocalTime() will enable it for the duration of the call). By default, only an elevated admin has that privilege present in its token. So, you will have to either run your whole app as an elevated user, or at least split out your sync code into a separate process or service that runs as an elevated admin or the SYSTEM account.
  6. Remy Lebeau

    Can 32bit dll with Form/Frame be used in 64 bit project?

    Right idea, but wrong solution. A DLL Surrogate can be registered to act as a proxy, allowing a 32bit DLL server to be accessible to a 64bit process. Not sure if this will work for your ActiveX control since it uses a UI, but it might be worth investigating. For that to work correctly, you would need to make a BPL package, not a plain DLL. But the same 32bit/64bit restriction applies to packages, too. No, a 32bit DLL/BPL cannot be used directly in a 64bit process. If the above doesn't work for your control, you may have to separate out your UI into its own 32bit program, and have your main 64bit program communicate with it using an IPC mechanism.
  7. Remy Lebeau

    Open android gallery with intent

    Well, I don't have 10.4.1 installed (or the sources for it), so there you go, just shows how little I know
  8. Remy Lebeau

    Open android gallery with intent

    I doubt that Delphi has natively imported the MediaStore.Images.Media class, but you should be able to import it manually using Java2OP, then you can access the EXTERNAL_CONTENT_URI field like this, eg: var pickIntent: JIntent; // replace TJMediaStore_Images_Media with whatever name Java2OP imports for it... pickIntent := TJIntent.JavaClass.init(TJIntent.JavaClass.ACTION_PICK, TJMediaStore_Images_Media.JavaClass.EXTERNAL_CONTENT_URI);
  9. Remy Lebeau

    How to detect if TIDMessage is unable to read an email

    TIdMessage is designed to parse RFC822-style emails only (EML files, etc). Attempting to load anything else is basically undefined behavior, there is no guarantee if/how errors will be reported back into user code. There is no single point of query where you can discover the result of a failed parse. So, your best option is to just filter out non-RFC822 files before you try to load them into TIdMessage. Basically, analyze a handful of bytes at the beginning of a given file, and if they don't appear to resemble RFC822-style headers then simply don't load the file at all (all of the non-EML file formats you have mentioned are well-documented and easily identifiable). This is something I may consider adding to TIdMessage itself in a future release, but that is not going to happen anytime soon, so I suggest you add it to your own code.
  10. Remy Lebeau

    Behaviour of TListView (Delphi XE)

    In non-virtual mode, each list item has its own physical TListItem object in memory, and their respective data is stored directly in the ListView control itself (well, in its HWND, anyway). In virtual mode, all data is held in the user's code instead. There is only 1 physical TListItem created, used internally by the TListView, where its content is reset each time an operation is performed that requires a physical TListItem object. For instance, when reading the TListView.Items[index] property, or calling method that takes a TListItem as input or returns a TListItem as output. IN MOST CASES, this design allows non-virtual code to continue working the same way as in non-virtual mode, just with the addition of the OnData... event handlers. But there are some corner cases to be aware of where this design does not work as expected, for instance doing tasks that require access to more than 1 TListItem at the same time. Your example demonstrates this when by causing an operation that resets the TListItem that is being observed.
  11. Remy Lebeau

    TIDMessage Date

    The TIdMessage.Date property is expressed in LOCAL TIME, not in UTC. The only way the TIdMessage.Date property would be in UTC is if either the calling machine is actually in the UTC timezone (which you say is the case here), or if Indy can't determine the local machine's timezone correctly. If you want to read an email's original timestamp (which may or may not be in UTC to begin with), you can read the raw 'Date' header via the TIdMessage.Headers.Values['Date] property. But then you will have to parse the string yourself.
  12. Remy Lebeau

    Opening a document in FMX without custom code

    There is no cross-platform way to open a path/url. Every platform has different requirements, so you need platform-specific coding.
  13. Remy Lebeau

    SMTP Server -> Client

    If you can't update the app to use SSL/TLS, then yes. That is an option, yes. Though, using a full SMTP server (ie TIdSMTPServer) might be a bit excessive, a simpler connection proxy (such as TIdMappedPortTCP) might suffice, since you just need to activate SSL/TLS on the outgoing connection. It really depends on whether you intend to utilize the SMTP STARTTLS command or not, since that will dictate WHEN the SSL/TLS handshake needs to be performed.
  14. Remy Lebeau

    Batch Reading Emails from Windows Explorer

    Only if you are planning on compiling the IdCoderTNEF unit into the IndyProtocols package each time. Which you don't NEED to do, you could simply drop IdCoderTNEF.pas into your project folder, or Indy source folder, and have your project(s) refer to that unit as-is. No.
  15. All of that applies to T(Object)Dictionary, as well. If the TComponent or associated object is freed, you have to manually remove them from the dictionary to avoid dangling pointers. TDictionary doesn't support object management at all. TObjectDictionary, on the other hand, simply lets you specify whether the dictionary owns the objects stored as Keys/Values, in that if an entry is removed/altered in the dictionary, the associate Key/Value objects are freed automatically as needed. But, if those same objects are freed external to the dictionary, the dictionary entry that refers to them is not removed automatically. You still have to handle that manually. The likelihood is reduced, but not eliminated. It is still possible to have invalid references, if you are not careful. In your code, perhaps, but not the overhead needed to manage the dictionary elements, hash tables, etc. You are actually adding runtime overhead to the program just to gain writing simpler code. But whatever. It is up to each user to decide whatever they are comfortable using.
  16. There is nothing wrong with using the Tag property for pointers. It is specifically intended to hold user-defined data, and intentionally pointer-sized because storing pointers in it is very common practice. It is even documented that way So, there is no misuse here. That is your choice, and it will certainly work. I prefer to use the Tag instead, it offers a 1:1 relationship without any overhead of a lookup table.
  17. Remy Lebeau

    Batch Reading Emails from Windows Explorer

    It is not enough to just add the file to the folder, you would have to actually edit the IndyProtocols package to reference the file. Because it is still being used by the IDE. You would have to remove Indy from the IDE first. Have you read the installation instructions yet?
  18. That is not possible. Delphi is a compiled language, you can't alter object layouts at runtime. The best you could do is store your data in another class/record object that you create at runtime, and then use the component's Tag property to point at that object.
  19. Remy Lebeau

    Batch Reading Emails from Windows Explorer

    Then you don't have your project setup to include that folder in its search paths. Simply adding the unit to the Protocols folder won't magically add it to Indy, since it is already compile. That would require adding the unit to Indy's Protocols package, and then recompiling and reinstalling Indy.
  20. Remy Lebeau

    converting this TidBytes code To Tbytes

    Binary compatible, in that they have the same memory layout, yes. But you can't pass a TBytes to a 'var TIdBytes' function parameter, and vice versa, unless you use a type-cast, eg: type PIdBytes = ^TIdBytes; var Bytes: TBytes; SetLength(Bytes, 6 + Buffersize); CopyTIdString('Audio1', PIdBytes(@Bytes)^, 0); CopyTIdBytes(RawToBytes(Buffer^, Buffersize), 0, PIdBytes(@Bytes)^, 6, Buffersize); Or maybe just: var Bytes: TBytes; SetLength(Bytes, 6 + Buffersize); CopyTIdString('Audio1', TIdBytes(Bytes), 0); CopyTIdBytes(RawToBytes(Buffer^, Buffersize), 0, TIdBytes(Bytes), 6, Buffersize);
  21. Remy Lebeau

    converting this TidBytes code To Tbytes

    CopyTIdBytes() is just a Move() from one TIdBytes to another, using starting source/target indexes and a byte length: procedure CopyTIdBytes(const ASource: TIdBytes; const ASourceIndex: Integer; var VDest: TIdBytes; const ADestIndex: Integer; const ALength: Integer); {$IFDEF USE_INLINE}inline;{$ENDIF} begin {$IFDEF DOTNET} System.array.Copy(ASource, ASourceIndex, VDest, ADestIndex, ALength); {$ELSE} //if these asserts fail, then it indicates an attempted buffer overrun. Assert(ASourceIndex >= 0); Assert((ASourceIndex+ALength) <= Length(ASource)); Move(ASource[ASourceIndex], VDest[ADestIndex], ALength); {$ENDIF} end; CopyTIdString(), on the other hand, is a little more involved, as it first has to convert the input String to bytes in a specified encoding, and then it moves those bytes into the target TIdBytes where specified: procedure CopyTIdString(const ASource: String; var VDest: TIdBytes; const ADestIndex: Integer; const ALength: Integer = -1; ADestEncoding: IIdTextEncoding = nil {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF} ); overload; {$IFDEF USE_INLINE}inline;{$ENDIF} begin CopyTIdString(ASource, 1, VDest, ADestIndex, ALength, ADestEncoding {$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF} ); end; procedure CopyTIdString(const ASource: String; const ASourceIndex: Integer; var VDest: TIdBytes; const ADestIndex: Integer; const ALength: Integer = -1; ADestEncoding: IIdTextEncoding = nil {$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF} ); overload; {$IFDEF USE_INLINE}inline;{$ENDIF} var LLength: Integer; {$IFDEF STRING_IS_ANSI} LTmp: TIdWideChars; {$ENDIF} begin {$IFDEF STRING_IS_ANSI} LTmp := nil; // keep the compiler happy {$ENDIF} LLength := IndyLength(ASource, ALength, ASourceIndex); if LLength > 0 then begin EnsureEncoding(ADestEncoding); {$IFDEF STRING_IS_UNICODE} ADestEncoding.GetBytes(ASource, ASourceIndex, LLength, VDest, ADestIndex); {$ELSE} EnsureEncoding(ASrcEncoding, encOSDefault); LTmp := ASrcEncoding.GetChars(RawToBytes(ASource[ASourceIndex], LLength)); // convert to Unicode ADestEncoding.GetBytes(LTmp, 0, Length(LTmp), VDest, ADestIndex); {$ENDIF} end; end; So, given your example, the simplest translation to TBytes would look like this: var Bytes: TBytes; SetLength(Bytes, 6 + Buffersize); TEncoding.Default.GetBytes('Audio1', 1, 6, Bytes, 0); Move(Buffer^, Bytes[6], Buffersize);
  22. Remy Lebeau

    Batch Reading Emails from Windows Explorer

    Like I said, the IdCoderTNEF unit has been in the Protocols folder for years. But if you are using the version of Indy that shipped pre-installed with each IDE, and they don't have the unit present, then Embarcadero must have chosen not to distribute it. The unit is not actually referenced by the IndyProtocols package, as it is not part of the main Indy packages, just a standalone utility unit, so Embarcadero may have just skipped it as a non-dependency. In which case, you will have to download it from Indy's GitHub repo instead (https://github.com/IndySockets/Indy/blob/master/Lib/Protocols/IdCoderTNEF.pas).
  23. Remy Lebeau

    Batch Reading Emails from Windows Explorer

    Which version of Indy are you looking at? TIdCoderTNEF was introduced in Indy 10, are you looking at Indy 9, perhaps? TIdCoderTNEF is not documented in the help files. No, TIdCoderTNEF still exists in Indy 10. TIdCoderTNEF has been in Indy 10 for over a decade. It is in the IndyProtocols package. There is no documentation available for TIdCoderTNEF, other than comments in the unit itself. I think it was created after the last time the documentation was updated, which was sadly a very long time ago. In a nutshell, you would simply extract a TNEF attachment from a normal email, and pass that attachment to TIdCoderTNEF.Parse(), which will then populate a TIdMessage with the relevant message data (headers, body, attachments, etc) from the TNEF.
  24. Remy Lebeau

    Batch Reading Emails from Windows Explorer

    Since the MSG format is publicly documented, it would be feasible to add support for it in Indy, in a manner that does not depend on Outlook APIs. Similar to how Indy already does for TNEF (winmail.dat) attachments via the TIdCoderTNEF class. But having the TIME to make such an implementation is an issue, for me at least.
  25. Remy Lebeau

    remove part of string and compare

    Messages are used, yes (LB_ADDSTRING, etc). But not the message queue, no. The messages in question would be SENT directly to the ListBox's window procedure for immediate processing, not POSTED to the message queue of the thread that owns the ListBox awaiting dispatching to the ListBox's window procedure.
×