2

I want to create a VARIANT or _variant_t from a FILETIME in c/c++.
Basically, this is what I want:

FILETIME ft;  
//Populate ft  
VARIANT vFt;  
VariantInit(&vFt);  
vFt.vt = VT_FILETIME;  

Now, how do I set ft inside vFt?

Can anyone please help me with this?

Thanks, Saurabh

Paws
  • 189
  • 2
  • 8

3 Answers3

2

The answer is, you can't store a FILETIME in a VARIANT. From the header file:

 *  VT_FILETIME               [P]     FILETIME

note the [P], and the key above it in the header file:

 * * [V] - may appear in a VARIANT
 * * [T] - may appear in a TYPEDESC
 * * [P] - may appear in an OLE property set
 * * [S] - may appear in a Safe Array

FILETIME can only appear in an OLE property set - not a variant.

There is a VT_DATE that you might be able to use instead.

Bonus Reading

VARENUM enumeration (wtypes.h)

The following table shows where these values can be used.

Value VARIANT TYPEDESC Property set Safe array
VT_ARRAY ✔️
VT_BLOB ✔️
VT_BLOB_OBJECT ✔️
VT_BOOL ✔️ ✔️ ✔️ ✔️
VT_BSTR ✔️ ✔️ ✔️ ✔️
VT_BSTR_BLOB
VT_BYREF ✔️
VT_CARRAY ✔️
VT_CF ✔️
VT_CLSID ✔️
VT_CY ✔️ ✔️ ✔️ ✔️
VT_DATE ✔️ ✔️ ✔️ ✔️
VT_DECIMAL ✔️ ✔️ ✔️
VT_DISPATCH ✔️ ✔️ ✔️
VT_EMPTY ✔️ ✔️
VT_ERROR ✔️ ✔️ ✔️ ✔️
VT_FILETIME ✔️
VT_HRESULT ✔️
VT_I1 ✔️ ✔️ ✔️ ✔️
VT_I2 ✔️ ✔️ ✔️ ✔️
VT_I4 ✔️ ✔️ ✔️ ✔️
VT_I8 ✔️ ✔️
VT_INT ✔️ ✔️ ✔️ ✔️
VT_INT_PTR ✔️
VT_LPSTR ✔️ ✔️
VT_LPWSTR ✔️ ✔️
VT_NULL ✔️ ✔️
VT_PTR ✔️
VT_R4 ✔️ ✔️ ✔️ ✔️
VT_R8 ✔️ ✔️ ✔️ ✔️
VT_RECORD ✔️ ✔️ ✔️
VT_SAFEARRAY ✔️
VT_STORAGE ✔️
VT_STORED_OBJECT ✔️
VT_STREAM ✔️
VT_STREAMED_OBJECT ✔️
VT_UI1 ✔️ ✔️ ✔️ ✔️
VT_UI2 ✔️ ✔️ ✔️ ✔️
VT_UI4 ✔️ ✔️ ✔️ ✔️
VT_UI8 ✔️ ✔️
VT_UINT ✔️ ✔️ ✔️
VT_UINT_PTR ✔️
VT_UNKNOWN ✔️ ✔️ ✔️
VT_USERDEFINED ✔️
VT_VARIANT ✔️ ✔️ ✔️ ✔️
VT_VECTOR ✔️
VT_VERSIONED_STREAM ✔️
VT_VOID ✔️
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
JTeagle
  • 2,196
  • 14
  • 15
  • I need to call an OPC HDA Automation function in C++ (syncReadRaw) which accepts a variant. This variant can either contain a relative time (as a string) or an absolute time (as a FILETIME). I need to send absolute times to this function. Is there any other option for achieving this? Thanks. – Paws Mar 29 '12 at 07:05
  • Unfortunately, they have not given a working example in C++. They have given one for VB, but using relative times only. So, now, if sending a FILETIME is not going to be possible, then I will have to think of converting an absolute time (like say 30-mar-2012 10:15:23) to a relative one using some math. – Paws Mar 29 '12 at 07:11
  • Is it possible that you can pass an OPCHDA_TIME (setting the ftTime member)? I got this from a message board and am wondering if that structure is an OPC extension to a variant... – JTeagle Mar 29 '12 at 07:13
  • Update: Was able to solve this by converting the FILETIME to a DATE and constructing a variant from it: DATE d = convertFileTimeToDate(ft); _variant_t vDate(d); //Call opc function passing vDate Thanks JTeagle. Regards, Saurabh – Paws Mar 29 '12 at 08:08
1

Use InitVariantFromFileTime

http://msdn.microsoft.com/en-us/library/windows/desktop/bb762323(v=vs.85).aspx

Hope that helps

Scott Langham
  • 58,735
  • 39
  • 131
  • 204
1

For those still looking you can try Scott's answer. Here's how I did it using the ATLComTime.h library which takes a few more steps.

FileTime fileTime = yourFileTime;
// dateFileTime will automatically cast to DATE when used as a parameter
COleDateTime dateFileTime(fileTime);  

Since DATE is a COM friendly type you can simply give the 'dateFileTime' variable as a method parameter. If you still want to use the VARIANT simply set the 'dateFileTime' variable into a VARIANT.

VARIANT varDate;
VariantInit(&varDate);
varDate.vt = VT_DATE;
varDate.date = dateFileTime;
// Use the varDate varaible
// ... call some method or use locally
// Don't forget to clear the VARIANT from memory after use
VariantClear(&varDate);

In the called method (still in C++), ie getting the FILETIME back from a DATE variable. The COleDateTime wants to give you a SYSTEMTIME instead of a FILETIME so we have to jump through a few hoops.

FILETIME fileTime;
if (variantDateTime.vt == VT_DATE) // only use if DATE was put into a VARIANT
{
  COleDateTime oleDateTime(variantDateTime.date);
  SYSTEMTIME sysTime;
  oleDateTime.GetAsSystemTime(sysTime);
  SystemTimeToFileTime(&sysTime, &fileTime);
}

If you didn't use a VARIANT you can just initialize the COleDateTime type with the DATE variable.

COleDateTime oleDateTime(dateVariable);
... // etc as above

As stated above it's a bit more work than Scotts answer, but is another way to get a FILETIME across the COM interface barrier.

amisam
  • 91
  • 6