Jump to content

Mark Williams

Members
  • Content Count

    226
  • Joined

  • Last visited

Community Reputation

12 Good

Technical Information

  • Delphi-Version
    Delphi 10.4 Sydney

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Mark Williams

    IsElevated

    No. I just need to know if user has run my app in elevated mode. My App launches Outlook and if one is running elevated and the other isn't then you get an OLE error. I just want to be able to advise user which is doing which so they can correct.
  2. Mark Williams

    IsElevated

    Is there a simple way to check if my app is running elevated? I can see a few oldish posts on this on Google, but nothing recent. I was just wondering if newer Delphi has introduced a simple function for it, although I couldn't find anything in help or likely units. Or perhaps there is a new Windows API procedure?
  3. Mark Williams

    Retrieving gmail email with TIDPop3

    I'm just going to swerve it and use the IMAP component, which seems much fitter for purpose. Just grateful I hadn't invested too much time in Pop3 before hitting a snag.
  4. Mark Williams

    Retrieving gmail email with TIDPop3

    Sorry to have to say "ignorance"! Didn't know there was an INDY IMAP client. Thanks for pointing in the right direction. Have abandoned Pop3.
  5. Mark Williams

    Retrieving gmail email with TIDPop3

    I am trying to retrieve the contents of my gmail using TIDPop3 as a test. I can connect, login fine. I then use CheckMessages to find out how many emails there are. It tells me there are 274. However, my Gmail Inbox believes there are over 1500 and my All Mail box tells me there are over 7500. I download the headers using following: Count:=CheckMessages; for i := 1 to count do begin IDMessage1.Clear; RetrieveHeader(i, IDMessage1); ListBox1.Items.Add(IDMessage1.From.Address+' '+IDMessage1.Subject+' '+DateTimeToStr(IDmessage1.Date)); end; It is starting (almost) with the oldest emails and then proceeding forwards to the most recent. However, the first email it retrieves is not the oldest. It skips a handful. Then it gets a small batch, skips some more and then produces a larger batch. It all seems a bit random. Are there any obvious reasons why CheckMessages is reporting only a small portion of the actual emails and also why RetrieveHeader may be skipping batches? Out if interest, I tried RetrieveHeader outside the range of CheckMessages, but well within the true email count and (unsurprisingly) it threw up a range error.
  6. Mark Williams

    IPropertyStore MultiValue Strings

    Of course. I was just posting an example to show how to handle array data. I wasn't (at least not intentionally) suggesting that it is a good idea to repeat that code for every tag. My own code attempts to extract dozens of tag values and that is done by passing the tags into a separate function.
  7. Mark Williams

    IDGlobalProtocols GmtOffsetStrToDateTime

    Awesome. Thanks so much.
  8. Mark Williams

    IDGlobalProtocols GmtOffsetStrToDateTime

    That would certainly solve my problem.
  9. Mark Williams

    IPropertyStore MultiValue Strings

    Sorry I didn't see any code. Looking back at your post, do you mean the suggestion to use PropVariant's vt member to ascertain type? If so, I haven't ignored it. The simple example I posted was just to show, for anyone interested, how to extract array type info. The example doesn't pass in the MetaDataTagType parameter nor does it reference the vt member as it didn't need to given that the tagtype PKEY_Music_Artist is known to be an array type.
  10. Mark Williams

    IPropertyStore MultiValue Strings

    A slight but important update to the code sample in my initial entry. Original code: if SHGetPropertyStoreFromParsingName(PWideChar(fileName), nil, GPS_READWRITE, IPropertyStore, Store) <> S_OK Whilst using the GETPROPERTYSTOREFLAG of GPS_READWRITE will work fine for media files that Windows can both read and write, it will fail to open media files which Windows can only read. Obvious really, but caused me a half hour of consternation before I realised why I couldn't read the tags for certain other files for eg AVI. In such cases using the GPS_READWRITE tag will get you an "Access Denied" result. If all you want to do is read the tags then use GPS_DEFAULT.
  11. Mark Williams

    IPropertyStore MultiValue Strings

    It is the PKEY_MUSIC_ARTIST that I was having difficulties with. I can extract PKEY_Music_AlbumArtist) no problem via the bStrVal value. However, did you get comma delimited values from PKEY_Music_AlbumArtist? If so, it's a bit odd that MS should declare PKEY_Music_AlbumArtist as a string value instead of an array value.
  12. Mark Williams

    IPropertyStore MultiValue Strings

    Yes. You guess right! And for anyone interested in how to extract the info from type 4127 the following seems to do the job ok. v, v2 : PropVariant; k : cardinal; begin try OlECheck(store.GetValue(MetaDataTag, v)); if metaDataTag = PKEY_Music_Artist then begin if PropVariantGetElementCount(v) > 0 then //for some reason never exits loop unless you query this first begin for k := 0 to PropVariantGetElementCount(v) -1 do begin if PropVariantGetElem(v, k, v2) = S_OK then Result :=Result + v2.bstrVal + ',' end; end; NB the index for PropVariantGetElem is 0 based. Interestingly (and rather annoyingly) after testing I have realised that some files have properties stored as multivalue strings in an array with only one item, but with comma separated values! Really does seem to defeat the purpose of the array type, but possibly explains why @emailx45 possibly got a comma separated array of values from a single string PropVariant (see below).
  13. Mark Williams

    IDGlobalProtocols GmtOffsetStrToDateTime

    The simple solution to my specific problem would be to change the declaration of either or both StrInternetToDateTime and GMTToLocalDateTime so that it takes a var parameter rather than a constant so that users can then submit the returned value to GmtOffsetStrToDateTime without having to work out/duplicate all the work Indy already does in parsing the header to extract the relevant portion. I appreciate that I am the only person who seems to have asked for this functionality to date, but it is such a simple change would it be possible to incorporate into an upcoming update?
  14. Mark Williams

    IDGlobalProtocols GmtOffsetStrToDateTime

    The TTimeZone unit is probably fine for my purposes. All I need to be able to do is get the UTC time zone from the end of the email header.
  15. Mark Williams

    IPropertyStore MultiValue Strings

    I am trying to extract meta data from media files using the IPropertyStore interface. So far I have no problem extracting most property values, but I am having difficulties with certain variant types. Below is part of the code used. Procedure ExtractMediaTags(fileName : String); type TMetaDataTagType = (mdtString, mdtInteger, mdtLongInt, mdtDateTime); var Store : IPropertyStore; Function GetMetaDataValueAsString(Const MetaDataTag : TPropertyKey; MetaDataTagType : TMetaDataTagType) :String; var v : PropVariant; begin try OlECheck(store.GetValue(MetaDataTag, v)); try case MetaDataTagType of mdtString : if assigned(v.bstrVal) then Result := v.bstrVal; mdtInteger : Result := v.iVal.ToString; mdtLongInt : Result := v.hVal.QuadPart.ToString; mdtDateTime :Result := FileTimeToDateTimeStr(v.filetime); end; finally PropVariantClear(v); end; except end; end; var v : PropVariant; s : string; begin if SHGetPropertyStoreFromParsingName(pWideChar(FileName), Nil, GPS_READWRITE, IPropertyStore, store)<>S_OK then exit; AddMetaData(pd.DocProps, '70', GetMetaDataValueAsString(PKEY_Music_Artist, mdtString)); AddMetaData(pd.DocProps, '74', GetMetaDataValueAsString(PKEY_Music_AlbumArtist, mdtString)); end; For example, I am able to extract the value for PKEY_MUSIC_ALBUMARTIST. But not for PKEY_MUSIC_ARTIST. The MS docs describe both variant values as being of type VT_LPWSTR (here). However, more detailed remarks state that PKEY_MUSIC_AlbumArtist references a string value (here) and PKEY_Music_Artist references a "Multivalue String" (here). I have queried the TVarType of PKEY_Music_Artist and it doesn't register as any of the specified TVarTypes not even varUnknown. Although PKEY_MUSIC_AlbumArtist also doesn't register as any TVarType. Does anyone have any idea what type "Multivalue String" is and how I would read it?
×