PDA

View Full Version : [DHTML] ActiveX Simplified



magicgavin
07-16-2007, 07:43 PM
1) CODE TITLE: ActiveX Simplified

2) AUTHOR NAME/NOTES:
Created by Gavin Delphia 2007
All Rights Reserved

3) DESCRIPTION:

This script consitst of ActiveX functions that are accessed through javascript such as read and writting to files. Moving, copying, deleting, finding attributes of files. It can also list all files in a folder, get the computer user name, domain name, and computer name. Supports ascii to binary conversion and the reverse. It also has a function to launch any application found on a computer.

This library only works with internet Explorer and it is intended for use with Microsoft Hypertext Application or .hta
Errors and limited functionality may occur if used in a .html or .htm

[Call Format:] $funcname(target,parameters)

Every function either returns True, False, or the Requested Data.
For query functions such as does a $FileExist() and $FolderExist() true and false represent yes and no respectively.
The $OpenFile() function returns the documents contents if true or false if a error occurs.
All other functions return True for action executed or false for action failed.

$OpenFile(file) -
opens file and returns text

$GetFolderFiles(folder) -
Returns array of files in target folder

$GetFileBaseName(file) -
Returns just the name of the file without the path or file extension

$GetFileExtension(file) -
Returns just the file extension without the path or name

$GetFileName(file) -
Returns the file name followed by the extension. No path

$GetParentFolder(file) -
Returns the parent folder of any file or folder

$CreateFile(file,datatowrite) -
Creates a file with specified data

$CreateFolder(folder) -
Creates a folder

$DeleteFile(file) -
Deletes File

$DeleteFolder(folder) -
Delets Folder

$FileExist(file) -
Returns true if file exists and false if it does not

$FolderExist(folder) -
Returns true if folder exists and false if it does not

$CopyFile(file,destionation) -
Copies file to the destionation

$CopyFolder(folder,destination) -
Copies folder to the destination

$MoveFile(file,destination) -
Deletes file from original location and moves to destination

$MoveFolder(folder,destination) -
Deletes folder from original location and moves to destination

$GetComputerName() -
Returns the name of the computer

$GetUserName() -
Returns the name of the user

$GetUserDomain() -
Returns the domain of the user

$LaunchApp(target_app) -
Launches the specified application. Eg $LaunchApp('cmd.exe')

$ToBinary(string) -
Returns string converted to binary

$ToAscii(string) -
Returns string converted to ascii



4) URL TO CODE:

or, ATTACHED BELOW (see #3 in guidelines below):

Twey
07-16-2007, 08:16 PM
The $ character should be reserved for machine-generated identifiers.

This library would be much more useful if it were coupled with a Java applet rather than using ActiveX. That would extend its use considerably.

magicgavin
07-16-2007, 08:48 PM
The point of this library is to add the advantage of modifying files using javascript. It is intended to be used with the .hta file format which is a format used for developing applications with Javascript. Why use java which requires SDK's, runtimes and compilers and why create something that already exists in Java. The Javascript method to access files other than Ajax is complicated and not readily available in fear of Script Kiddies gaining the power to access the file system. This script is designed for people interested in making client side applications with Javascript not Java.

djr33
07-16-2007, 09:06 PM
Well, that sounds great and all.
But I'm using firefox. And so is basically everyone else here (or at least another browser than IE).
On the web, the stats are more toward IE, perhaps 60% IE - 40% not, but that is still a large user base who would have no access.

Twey
07-16-2007, 09:07 PM
I think you've misunderstood me.
It is intended to be used with the .hta file format which is a format used for developing applications with Javascript.I know what HTA is (and it's a terrible idea, Javascript is really not suited to this kind of application development, as a friend of mine who's spent several months trying to develop a usable set of Windows-style widgets will tell you). I was suggesting that with the addition of an applet this could be made to actually work cross-browser and cross-platform as well.
Why use java which requires SDK's, runtimes and compilers and why create something that already exists in Java.Well, ActiveX requires Windows and IE. What's your point? What would be created would effectively be bindings to the Java applet; it wouldn't be necessary to recreate the functionality within Java.
The Javascript method to access files other than Ajax is complicated and not readily available in fear of Script Kiddies gaining the power to access the file system.There is no Javascript method to access files (so far; Mozilla are working on it (http://www.mozilla.org/js/js-file-object.html)). What you're talking about is ActiveX, which is not Javascript. It's an entirely separate technology to which Microsoft has provided bindings -- much in the way I was suggesting providing bindings to Java, which would be more useful.
This script is designed for people interested in making client side applications with Javascript not Java.Thus, the bindings. The user would not have to touch Java.

djr33, you're missing the point as well. The original script was designed for use with HTAs, which are an IE-only technology (and will run in IE no matter what browser you might use for surfing the Web, at least on Windows). In this capacity, it does work; I just think that that capacity is rather more limited than it need be.

djr33
07-16-2007, 09:17 PM
I'm on a mac. And you're on Linux.
I have XP as well, but I dislike using IE, so why would I want to have a 'good' addition to this program?

Just because someone writes a great macro for word, that doesn't mean it's a good editor for webpages :p
(This is a metaphor, btw.... just in case someone doesn't catch that.)

magicgavin
07-16-2007, 09:23 PM
Thanks guys for the comments. I hope the script will be useful to someone.

Twey
07-16-2007, 09:36 PM
I'm on a mac. And you're on Linux.
I have XP as well, but I dislike using IE, so why would I want to have a 'good' addition to this program?Thus, why I thought the capacity was overly limited. Using a Java applet it would no longer be IE- or Windows-specific.

djr33
07-17-2007, 01:21 AM
I hope it's useful to someone too. Remember, the problem is with ActiveX in the first place, not your coding. Your code seems to be quite well thought out and usable, but it is just limited by the limits of the system.

jscheuer1
07-17-2007, 05:54 AM
pcbuster would love this!

djr33
07-17-2007, 05:57 AM
Haha.

I'll be wondering what's keeping him busy til he arrives :p

Trinithis
07-17-2007, 10:05 PM
Here are better versions of your text converters:


function $ToBinary(text) {
var binText = "", ch = "", bin;
for(var i=0, n=text.length; i<n; ++i) {
ch = text.charAt(i);
bin = ch.charCodeAt(0).toString(2);
while(bin.length<8) bin = "0" + bin;
binText += bin;
}
return binText;
}

function $ToAscii(binText) {
var text = "", bin, dec;
if (binText.length&#37;8!=0) return false;
for(var i=0, n=binText.length/8; i<n; ++i) {
bin = binText.substr(8*i, 8);
dec = 0;
for(var j=0; j<8; ++j) dec += Math.pow(2, j) * bin.charAt(7-j);
text += String.fromCharCode(dec);
}
return text;
}



You could also support full unicode if you wanted:


function $ToBinary(text) {
var binText = "", ch = "", bin;
for(var i=0, n=text.length; i<n; ++i) {
ch = text.charAt(i);
bin = ch.charCodeAt(0).toString(2);
while(bin.length<16) bin = "0" + bin;
binText += bin;
}
return binText;
}

function $ToUnicode(binText) {
var text = "", bin, dec;
if (binText.length%16!=0) return false;
for(var i=0, n=binText.length/16; i<n; ++i) {
bin = binText.substr(16*i, 16);
dec = 0;
for(var j=0; j<16; ++j) dec += Math.pow(2, j) * bin.charAt(15-j);
text += String.fromCharCode(dec);
}
return text;
}


I'm not sure why your version converts "\n" to "00000000" instead of "00001010", so I took it out. But if you really need it to be like that, add the following to $ToBinary's for loop right after you assign (ch):


if(ch=="\n") {
binText += "00000000";
continue;
}

and this to $ToAscii's outer for loop right after you assign (bin):


if(bin=="00000000") {
text += "\n";
continue;
}

Twey
07-18-2007, 12:12 AM
By "full Unicode" I presume you mean UTF-16. Remember, UTF-8 and UTF-32 exist as well.

Trinithis
07-18-2007, 12:31 AM
Yep, that's what I mean, but if I'm not mistaken, JS uses UTF-16 anyway

Twey
07-18-2007, 12:49 AM
js> for(var x in "あ") print("あ".charCodeAt(x).toString(2));
11100011
10000001
10000010I believe it uses whatever encoding it's fed. Here we see it using UTF-8, but my console was in UTF-8.

Trinithis
07-18-2007, 06:11 AM
Could you explain how your code works?

The js> is unfamiliar. (Perhaps a link if need be.)

As is using the for-in like that. Shouldn't there only be 1 charCodeAt(i) because the string is only 1 character long?

djr33
07-18-2007, 06:13 AM
I think that is simply the line of javascript, with 'js>' just showing you that that line is js, and that the output of that line is written below. I don't think that's a command. If so, I'm just as lost as you are :p

Twey
07-18-2007, 12:50 PM
The js> is unfamiliar.It's just the Spidermonkey command-line interpreter. You type code, it gives results. No great mystery.
As is using the for-in like that.Don't do this normally, it's not at all portable. Javascript allows (but JScript doesn't allow) us to treat strings as arrays and loop through or access individual characters as we would elements of an array.
Shouldn't there only be 1 charCodeAt(i) because the string is only 1 character long?It's looping through all three bytes of the character. In UTF-16, that character is only two bytes long; in UTF-8, it's three (thus, UTF-16 is preferred for content with lots of multibyte characters).

magicgavin
07-18-2007, 01:12 PM
I didn't know the binary code for \n so I just use one that was open.

Twey
07-18-2007, 01:20 PM
function $ToBinary(text){
this.tobin="";this.context=text;
for (this.i=0;this.i<this.context.length;this.i++){
this.let=this.context.substr(this.i,1);
if (this.let=="\n"){this.tobin=this.tobin+'00000000'}
if (this.let=="A"){this.tobin=this.tobin+'01000001'}
if (this.let=="B"){this.tobin=this.tobin+'01000010'}
if (this.let=="C"){this.tobin=this.tobin+'01000011'}
if (this.let=="D"){this.tobin=this.tobin+'01000100'}
if (this.let=="E"){this.tobin=this.tobin+'01000101'}
if (this.let=="F"){this.tobin=this.tobin+'01000110'}
if (this.let=="G"){this.tobin=this.tobin+'01000111'}
if (this.let=="H"){this.tobin=this.tobin+'01001000'}
if (this.let=="I"){this.tobin=this.tobin+'01001001'}
if (this.let=="J"){this.tobin=this.tobin+'01001010'}
if (this.let=="K"){this.tobin=this.tobin+'01001011'}
if (this.let=="L"){this.tobin=this.tobin+'01001100'}
if (this.let=="M"){this.tobin=this.tobin+'01001101'}
if (this.let=="N"){this.tobin=this.tobin+'01001110'}
if (this.let=="O"){this.tobin=this.tobin+'01001111'}
if (this.let=="P"){this.tobin=this.tobin+'01010000'}
if (this.let=="Q"){this.tobin=this.tobin+'01010001'}
if (this.let=="R"){this.tobin=this.tobin+'01010010'}
if (this.let=="S"){this.tobin=this.tobin+'01010011'}
if (this.let=="T"){this.tobin=this.tobin+'01010100'}
if (this.let=="U"){this.tobin=this.tobin+'01010101'}
if (this.let=="V"){this.tobin=this.tobin+'01010110'}
if (this.let=="W"){this.tobin=this.tobin+'01010111'}
if (this.let=="X"){this.tobin=this.tobin+'01011000'}
if (this.let=="Y"){this.tobin=this.tobin+'01011001'}
if (this.let=="Z"){this.tobin=this.tobin+'01011010'}
if (this.let=="a"){this.tobin=this.tobin+'01100001'}
if (this.let=="b"){this.tobin=this.tobin+'01100010'}
if (this.let=="c"){this.tobin=this.tobin+'01100011'}
if (this.let=="d"){this.tobin=this.tobin+'01100100'}
if (this.let=="e"){this.tobin=this.tobin+'01100101'}
if (this.let=="f"){this.tobin=this.tobin+'01100110'}
if (this.let=="g"){this.tobin=this.tobin+'01100111'}
if (this.let=="h"){this.tobin=this.tobin+'01101000'}
if (this.let=="i"){this.tobin=this.tobin+'01101001'}
if (this.let=="j"){this.tobin=this.tobin+'01101010'}
if (this.let=="k"){this.tobin=this.tobin+'01101011'}
if (this.let=="l"){this.tobin=this.tobin+'01101100'}
if (this.let=="m"){this.tobin=this.tobin+'01101101'}
if (this.let=="n"){this.tobin=this.tobin+'01101110'}
if (this.let=="o"){this.tobin=this.tobin+'01101111'}
if (this.let=="p"){this.tobin=this.tobin+'01110000'}
if (this.let=="q"){this.tobin=this.tobin+'01110001'}
if (this.let=="r"){this.tobin=this.tobin+'01110010'}
if (this.let=="s"){this.tobin=this.tobin+'01110011'}
if (this.let=="t"){this.tobin=this.tobin+'01110100'}
if (this.let=="u"){this.tobin=this.tobin+'01110101'}
if (this.let=="v"){this.tobin=this.tobin+'01110110'}
if (this.let=="w"){this.tobin=this.tobin+'01110111'}
if (this.let=="x"){this.tobin=this.tobin+'01111000'}
if (this.let=="y"){this.tobin=this.tobin+'01111001'}
if (this.let=="z"){this.tobin=this.tobin+'01111010'}
if (this.let==" "){this.tobin=this.tobin+'00100000'}
if (this.let=="0"){this.tobin=this.tobin+'00110000'}
if (this.let=="1"){this.tobin=this.tobin+'00110001'}
if (this.let=="2"){this.tobin=this.tobin+'00110010'}
if (this.let=="3"){this.tobin=this.tobin+'00110011'}
if (this.let=="4"){this.tobin=this.tobin+'00110100'}
if (this.let=="5"){this.tobin=this.tobin+'00110101'}
if (this.let=="6"){this.tobin=this.tobin+'00110110'}
if (this.let=="7"){this.tobin=this.tobin+'00110111'}
if (this.let=="8"){this.tobin=this.tobin+'00111000'}
if (this.let=="9"){this.tobin=this.tobin+'00111001'}
if (this.let=="!"){this.tobin=this.tobin+'00100001'}
if (this.let=="\""){this.tobin=this.tobin+'00100010'}
if (this.let=="#"){this.tobin=this.tobin+'00100011'}
if (this.let=="$"){this.tobin=this.tobin+'00100100'}
if (this.let=="&#37;"){this.tobin=this.tobin+'00100101'}
if (this.let=="&"){this.tobin=this.tobin+'00100110'}
if (this.let=="'"){this.tobin=this.tobin+'00100111'}
if (this.let=="("){this.tobin=this.tobin+'00101000'}
if (this.let==")"){this.tobin=this.tobin+'00101001'}
if (this.let=="*"){this.tobin=this.tobin+'00101010'}
if (this.let=="+"){this.tobin=this.tobin+'00101011'}
if (this.let==","){this.tobin=this.tobin+'00101100'}
if (this.let=="-"){this.tobin=this.tobin+'00101101'}
if (this.let=="."){this.tobin=this.tobin+'00101110'}
if (this.let=="/"){this.tobin=this.tobin+'00101111'}
if (this.let==":"){this.tobin=this.tobin+'00111010'}
if (this.let==";"){this.tobin=this.tobin+'00111011'}
if (this.let=="<"){this.tobin=this.tobin+'00111100'}
if (this.let=="="){this.tobin=this.tobin+'00111101'}
if (this.let==">"){this.tobin=this.tobin+'00111110'}
if (this.let=="?"){this.tobin=this.tobin+'00111111'}
if (this.let=="@"){this.tobin=this.tobin+'01000000'}
if (this.let=="["){this.tobin=this.tobin+'01011011'}
if (this.let=="\\"){this.tobin=this.tobin+'01011100'}
if (this.let=="]"){this.tobin=this.tobin+'01011101'}
if (this.let=="^"){this.tobin=this.tobin+'01011110'}
if (this.let=="_"){this.tobin=this.tobin+'01011111'}
if (this.let=="`"){this.tobin=this.tobin+'01100000'}
if (this.let=="{"){this.tobin=this.tobin+'01111011'}
if (this.let=="|"){this.tobin=this.tobin+'01111100'}
if (this.let=="}"){this.tobin=this.tobin+'01111101'}
if (this.let=="~"){this.tobin=this.tobin+'01111110'}
if (this.let=="�"){this.tobin=this.tobin+'10000000'}
if (this.let=="�"){this.tobin=this.tobin+'10100001'}
if (this.let=="�"){this.tobin=this.tobin+'10100010'}
if (this.let=="�"){this.tobin=this.tobin+'10100011'}
if (this.let=="�"){this.tobin=this.tobin+'10100100'}
if (this.let=="�"){this.tobin=this.tobin+'10100101'}
if (this.let=="�"){this.tobin=this.tobin+'10100110'}
if (this.let=="�"){this.tobin=this.tobin+'10100111'}
/* There's more... this is actually too long to post! */
}
return this.tobin;
}Dear gods! You do realise that you can convert a single-byte character to binary by doing:
this.let.charAt(0).toString(2);... didn't you? And what's with the this.x, this.y? this in this case is window, since the functions weren't called as properties of anything. Those are unnecessarily globals, and the this. bit is redundant.
function frontPad(s, len, chr) {
for(var r = s.toString(); r.length < len; r = (chr || "0") + r);
return r;
}

function group(arr, len) {
for(var i = 0, r = [], n = arr.length; i < n; ++i) {
if(i % len === 0)
r.push([]);
r[r.length - 1].push(arr[i]);
}
return r;
}

function StrToBin(str, charsiz) { // I refuse to use $.
for(var i = -1, r = "", n = str.length - 1; i < n; r += frontPad(str.charCodeAt(++i).toString(2), charsiz || 8));
return r;
}

function BinToStr(bin, charsiz) {
for(var i = 0, cs = group(bin.split(""), charsiz || 8), n = cs.length; i < n; cs[i] = String.fromCharCode(parseInt(cs[i++].join(""), 2)));
return cs.join("");
}

magicgavin
07-18-2007, 02:06 PM
I intended this.x and this.y ect so that you could do the following

var conversion1=new $ToAscii('00000000'); - returns \n
var conversion2=new $ToAscii('01010000'); - returns P

then later if you needed the result back without reconverting you could do

conversion1.tobin - would equal \n
conversion2.tobin - would equal P

Now that I look at it though it was stupid in this case seeing how the function returns the result to a variable anyways.

I also wanted to prevent variable conflicts.


Also to trinithis
I would like to ask premission to use your conversion functions to replace my own. Yours are much more efficient.

Twey
07-18-2007, 04:04 PM
Mine are more efficient still. Have a look at the code at the bottom of my last post.

My comment on using $ in identifiers stands, by the way. ECMA-262, section 7.6, second paragraph, states:
The dollar sign is intended for use only in mechanically generated code.

magicgavin
07-18-2007, 04:37 PM
I used the dollar sign to prevent duplicate functions. I intended people to link the script and start using it. I wanted to make sure my functions and there functions were unique and short so I added the $. If you know of another valid symbol let me know.

Twey
07-18-2007, 04:43 PM
The best way of doing it is to use a namespacing object:
var ActiveXFunctions = {
frontPad : function(s, len, chr) {
for(var r = s.toString(); r.length < len; r = (chr || "0") + r);
return r;
},

group : function(arr, len) {
for(var i = 0, r = [], n = arr.length; i < n; ++i) {
if(i &#37; len === 0)
r.push([]);
r[r.length - 1].push(arr[i]);
}
return r;
},

strToBin : function(str, charsiz) {
for(var i = 0, r = "", n = str.length; i < n; r += this.frontPad(str.charCodeAt(i++).toString(2), charsiz || 8));
return r;
},

binToStr : function(bin, charsiz) {
for(var i = 0, cs = this.group(bin.split(""), charsiz || 8), n = cs.length; i < n; cs[i] = String.fromCharCode(parseInt(cs[i++].join(""), 2)));
return cs.join("");
}
};Then call them:
var bin = ActiveXFunctions.strToBin("Hello");
var str = ActiveXFunctions.binToStr(bin);

magicgavin
07-18-2007, 05:06 PM
I'm unfamiliar with your code so could you create the namespace using my code as an example without the $ signs :)

Trinithis
07-18-2007, 05:59 PM
Feel free to use it if you want, but Twey's is indeed better.

Twey
07-18-2007, 06:30 PM
I'm unfamiliar with your codeIt's just object literal syntax (http://www.wait-till-i.com/index.php?p=239).

magicgavin
07-18-2007, 06:36 PM
Thanks I'll start using that in my scripts instead of the this.variable.

Twey
07-18-2007, 06:39 PM
They both have their places. this.varname is used when you want to create a constructor function. Object literal notation only creates a single object: perfect for namespaces.

magicgavin
07-18-2007, 07:50 PM
No longer contains $ in function names.
New Binary and Ascii Conversion by Twey. - Credited in file too :)

Added Custom Error handler
Added Window Resizing

Although some of the functions do not relate to the ActiveX Objects they are useful when creating a .hta

Twey
07-18-2007, 08:05 PM
Perhaps you should call them "HTA Utility Functions." Also, the purpose of explaining the benefits of namespacing to you was not to have you namespace only my code :p Namespace identifiers should be something unique, too: the difference is that you only have to have one. "To" does not count as a highly original identifier :p

magicgavin
07-18-2007, 08:33 PM
ok, I'm going on vacation soon but I'll work on converting them all to use namespace rather than this.variable

Twey
07-18-2007, 09:15 PM
You're not using "this.variable" at all. All those variables you think are nice and safe actually aren't, they're global, about as unprotected as they possibly can be.

magicgavin
07-18-2007, 11:07 PM
So I got rid of all the global this.variable and I only used this. to call functions within the namespace.

I also made all the functions in the namespace format with better names that "To".

Thanks again Twey. I recently saw the this.variable in a function and I misunderstood it's use. I have also been wondering how to do namespaces but I could never find a good tutorial.

I've been coding for almost 5 years now and it's a little embarrasing to make a mistake that stupid.

Twey
07-18-2007, 11:55 PM
Not in Javascript, I hope :p Advanced Javascript can be a little daunting to those coming from more rigid languages (heck, it took me by surprise). I'm quite worried that as a five-year coder you never thought to look for an character/code conversion function before deciding to hard-code a list of every possible ASCII character using if statements, though :p

magicgavin
07-19-2007, 12:09 AM
I honestly didn't create the conversion. I found the script on a website and asked premission to use it but no one knew who made it. I recreated it using the codes that already existed (except \n which I added as 00000000) so that it used the this.variable mistake I had been doing. If I had invested time instead of taking the cheap way out it would have looked something like the other persons script that I asked premission to use.