View previous topic :: View next topic |
Author |
Message |
jcc7
Joined: 22 Feb 2004 Posts: 657 Location: Muskogee, OK, USA
|
Posted: Mon Apr 18, 2005 9:03 pm Post subject: toVariant() might make ActiveX easier to use |
|
|
(I've uploaded my modified source to the Core32 repository at dsource in case someone would like to see my changes in context.)
As I've mentioned in the D newsgroup, a toVariant function may make it easier to use ActiveX. With some invaluable help from Derek, I've managed to come up with some functional code. It's not everything I'd like it to be yet, but it's already fun for me to play around with: Code: | VARIANTARG toVariant(...)
{
VARIANTARG variant;
if (_arguments.length < 1)
return VARIANT.init;
if(_arguments.length == 1)
{
/* Strings */
if (_arguments[0] == typeid(wchar[]))
{
debug writef("wchar[]\t");
variant.n1.n2.vt = VT_BSTR;
variant.n1.n2.n3.bstrVal = cast(wchar*) (va_arg!(char[])(_argptr) ~ "\0");
}
else if (_arguments[0] == typeid(char[]))
{
debug writef("char[]\t");
variant.n1.n2.vt = VT_BSTR;
variant.n1.n2.n3.bstrVal = SysAllocString(std.utf.toUTF16(va_arg!(char[])(_argptr) ~ "\0"));
}
/* Unsigned Integers */
else if (_arguments[0] == typeid(bit))
{
debug writef("bit\t");
variant.n1.n2.vt = VT_BOOL;
if(va_arg!(bit)(_argptr) == true)
variant.n1.n2.n3.boolVal = 1;
else
variant.n1.n2.n3.boolVal = 0;
}
else if (_arguments[0] == typeid(ubyte))
{
debug writef("ubyte\t");
variant.n1.n2.vt = VT_UI1; /* I'm not sure about this. */
variant.n1.n2.n3.bVal = va_arg!(ubyte)(_argptr);
}
else if (_arguments[0] == typeid(ushort))
{
debug writef("ushort\t");
variant.n1.n2.vt = VT_UI2; /* I'm not sure about this. */
variant.n1.n2.n3.uiVal = va_arg!(ushort)(_argptr);
}
else if (_arguments[0] == typeid(uint))
{
debug writef("uint\t");
variant.n1.n2.vt = VT_UI4; /* I'm not sure about this. */
variant.n1.n2.n3.ulVal = va_arg!(uint)(_argptr);
}
else if (_arguments[0] == typeid(ulong)) /* 8 bits */
{
debug writef("ulong\t");
variant.n1.n2.vt = VT_UI4; /* 4 bits -- long won't fit! */
variant.n1.n2.n3.lVal = va_arg!(ulong)(_argptr);
}
/* Signed Integers */
else if (_arguments[0] == typeid(byte))
{
debug writef("byte\t");
variant.n1.n2.vt = VT_I1; /* I'm not sure about this. */
variant.n1.n2.n3. cVal = va_arg!(byte)(_argptr);
}
else if (_arguments[0] == typeid(short))
{
debug writef("short\t");
variant.n1.n2.vt = VT_I2;
variant.n1.n2.n3.iVal = va_arg!(short)(_argptr);
}
else if (_arguments[0] == typeid(int))
{
debug writef("int\t");
variant.n1.n2.vt = VT_I4;
variant.n1.n2.n3.lVal = va_arg!(int)(_argptr);
}
else if (_arguments[0] == typeid(long)) /* 8 bits */
{
debug writef("long\t");
variant.n1.n2.vt = VT_I4; /* 4 bits -- long might not fit! */
variant.n1.n2.n3.lVal = cast(int) va_arg!(long)(_argptr);
}
/* Floating Point */
else if (_arguments[0] == typeid(float))
{
debug writef("float\t");
variant.n1.n2.vt = VT_R4;
variant.n1.n2.n3.fltVal = va_arg!(float)(_argptr);
}
else if (_arguments[0] == typeid(double))
{
debug writef("double\t");
variant.n1.n2.vt = VT_R8;
variant.n1.n2.n3.dblVal = va_arg!(double)(_argptr);
}
else
throw new Exception("toVariant doesn't know what to do with it.");
}
else
throw new Exception("[unimplemented feature] toVariant can't use more than one arguemnt yet");
return variant;
} |
I think that the main code can be made simpler yet, but I like to implement incrementally (and I reached a good place to take a breath): Code: | void main()
{
AXO ie=new AXO("InternetExplorer.Application");
try
{
VARIANTARG myArg;
ie.call("Navigate",VARIANT.init,VARIANT.init,VARIANT.init,VARIANT.init, toVariant("http://www.altavista.com/"));
ie.set("Width", toVariant(850));
ie.set("Height", toVariant(710));
ie.set("Top", toVariant(10));
ie.set("Left", toVariant(10));
ie.set("ToolBar", toVariant(false));
ie.set("MenuBar", toVariant(false));
ie.set("StatusBar",toVariant(false));
ie.set("Visible",toVariant(true));
}
finally
{
int ret = MessageBoxA(null, "Message\0", "Title\0", 0);
ie.call("Quit");
}
} |
It also might be nice to add some library pragmas so that people don't need to guess which .lib's are required: Code: | pragma(lib, "win32.lib");
pragma(lib, "uuid.lib");
pragma(lib, "ole32.lib");
/* for _CLSIDFromProgID@8, _CoCreateInstance@20, _CoInitialize@4, _CoUninitialize@0 */
pragma(lib, "oleaut32.lib");
/* for _SysFreeString@4, _SysAllocString@4 */ |
2005-12-15 Update: Fixed link to Core32 SVN.
Last edited by jcc7 on Thu Dec 15, 2005 9:13 am; edited 1 time in total |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Mon Apr 18, 2005 9:15 pm Post subject: |
|
|
Great! Now all you have to do is fromVariant() for the getters... ! Seriously, if you want to do it.... Just kidding...
Relatively speaking, that's the easy part (D <-> COM). The hard part is with Walnut. See, DMDScript only has "number". So, a toVariant function has to guess: from "number" to what? int? long? short? signed? unsigned? etc... That's once of the reasons I was thinking about type checking: that AXO class could check: "oh, this function takes a 32b-signed-integer, so I'll convert from number to the respective type".
But still, this is great. Thanks. |
|
Back to top |
|
|
jcc7
Joined: 22 Feb 2004 Posts: 657 Location: Muskogee, OK, USA
|
Posted: Mon Apr 18, 2005 9:26 pm Post subject: |
|
|
Carlos wrote: | Great! Now all you have to do is fromVariant() for the getters... ! Seriously, if you want to do it.... Just kidding...
Relatively speaking, that's the easy part (D <-> COM). The hard part is with Walnut. See, DMDScript only has "number". So, a toVariant function has to guess: from "number" to what? int? long? short? signed? unsigned? etc... That's once of the reasons I was thinking about type checking: that AXO class could check: "oh, this function takes a 32b-signed-integer, so I'll convert from number to the respective type".
But still, this is great. Thanks. | I'm unfamiliar with the DMDScript aspects, so I can't help with those.
I was wondering if the conversion from varargs to VARIANTs could be postponed until the last minute (so that the toVariant() calls could be moved from main to the guts of the ActiveX functions). I haven't actually tried doing this yet, so my idea could be impractical. But I plan on giving it a shot. (I'd like to do it tomorrow, but I'm pretty sure I won't have time until Wednesday evening.) In any case, you're welcome to tweak and experiment with my code any way you want. I haven't covered all of the data types in toVariant yet, and my implementations of "long" and "ulong" are likely wrong. |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Tue Apr 19, 2005 7:31 am Post subject: |
|
|
I think that'd be the right. I mean it'd be much better to do "ie.set("Visible", true)" instead of "ie.set("Visible", toVariant(true))".
Thanks again. |
|
Back to top |
|
|
Carlos
Joined: 19 Mar 2004 Posts: 396 Location: Canyon, TX
|
Posted: Mon May 23, 2005 11:12 am Post subject: |
|
|
I think std.boxer might help with this, however Walnut is going to have to wait by now: I'm kinda under pressure with my thesis, so I'd better hurry. God willing, I'll be done with my thesis (the text, not the defense and the paperwork) by the end of June. |
|
Back to top |
|
|
dan.lewis
Joined: 21 Feb 2007 Posts: 69 Location: Canada
|
Posted: Fri Feb 23, 2007 10:39 am Post subject: |
|
|
I set up set(), setByRef() and call() to use toVariant() on all the arguments.
I sorta made a fromVariant() as well, but there are still bugs in it, and some of the Variants will be tough to convert to Values.
I figured I'd be impressed at this stage if I get Boolean, String and Number working. _________________ nop
nop ; problem solved |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|