Jump to content

Remy Lebeau

Members
  • Content Count

    3000
  • Joined

  • Last visited

  • Days Won

    135

Everything posted by Remy Lebeau

  1. 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.
  2. 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
  3. 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);
  4. 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.
  5. 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.
  6. 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.
  7. 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.
  8. 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.
  9. 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.
  10. 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.
  11. 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.
  12. 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?
  13. 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.
  14. 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.
  15. 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);
  16. 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);
  17. 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).
  18. 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.
  19. 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.
  20. 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.
  21. Remy Lebeau

    Batch Reading Emails from Windows Explorer

    No, it does not, only emails in RFC822 format, like .EML files.
  22. Remy Lebeau

    Why do these 2 statments produce different results ?

    '#$02' (w/ quotes) is a string literal consisting of 4 distinct characters: '#', '$', '0', '2'. The string you are searching, 'bla,bla,#$02,bla', contains that 4-char substring in it, hence the result is > 0. #$02 (w/o quotes) is a single Char whose numeric value is 2. The string you are searching does not contain that character in it, hence the result is 0.
  23. Remy Lebeau

    Any luck using 10.4.1 on Windows 8.1?

    Support for OSX 64-bit was introduced in 10.3.2: https://blog.marcocantu.com/blog/2019-july-building-mocOS64-apps-delphi.html Support for Android 64-bit was introduced in 10.3.3: https://blog.marcocantu.com/blog/2019-delphi-android-64bit-rad-1033.html
  24. Remy Lebeau

    Find UDP Server

    Subnet broadcasting is supported only in IPv4, not in IPv6, you have to use multicasting instead.
  25. That parameter is what I was referring to.
×