FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

toVariant() might make ActiveX easier to use

 
Post new topic   Reply to topic     Forum Index -> Walnut
View previous topic :: View next topic  
Author Message
jcc7



Joined: 22 Feb 2004
Posts: 655
Location: Muskogee, OK, USA

PostPosted: Mon Apr 18, 2005 9:03 pm    Post subject: toVariant() might make ActiveX easier to use Reply with quote

(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
View user's profile Send private message AIM Address
Carlos



Joined: 19 Mar 2004
Posts: 396
Location: Canyon, TX

PostPosted: Mon Apr 18, 2005 9:15 pm    Post subject: Reply with quote

Great! Now all you have to do is fromVariant() for the getters... Laughing! 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
View user's profile Send private message Yahoo Messenger MSN Messenger
jcc7



Joined: 22 Feb 2004
Posts: 655
Location: Muskogee, OK, USA

PostPosted: Mon Apr 18, 2005 9:26 pm    Post subject: Reply with quote

Carlos wrote:
Great! Now all you have to do is fromVariant() for the getters... Laughing! 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. Sad

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
View user's profile Send private message AIM Address
Carlos



Joined: 19 Mar 2004
Posts: 396
Location: Canyon, TX

PostPosted: Tue Apr 19, 2005 7:31 am    Post subject: Reply with quote

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
View user's profile Send private message Yahoo Messenger MSN Messenger
Carlos



Joined: 19 Mar 2004
Posts: 396
Location: Canyon, TX

PostPosted: Mon May 23, 2005 11:12 am    Post subject: Reply with quote

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
View user's profile Send private message Yahoo Messenger MSN Messenger
dan.lewis



Joined: 21 Feb 2007
Posts: 69
Location: Canada

PostPosted: Fri Feb 23, 2007 10:39 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Walnut All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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