Ich kann bestätigen, dass es möglich ist, die Drag&Drop-Funktionalität für Dateien und Ordner im HTA-Fenster mit " Web-Browser "(keine Notwendigkeit, ActiveX-Objekte von Drittanbietern, HTML5 oder Manipulationen an der Registrierung zu verwenden).
Sein eingeschalteter "RegisterAsDropTarget"-Parameter ermöglicht solche Operationen, während der "Web Browser" selbst in jedem Windows seit XP oder 2000 standardmäßig eingebaut ist. Auf diese Weise funktioniert er für Eingabedateien, die in einem beliebigen Gebietsschema benannt sind (Unterstützung von Unicode-Namen), während z. B. WScript und CScript dies standardmäßig nicht unterstützen.
Nachfolgend finden Sie ein Beispiel, das als eigenständige Komponente mit vielen benutzerdefinierten Funktionen einschließlich Stilen und Hintergründen implementiert wurde. Sie funktioniert sowohl für 64- als auch für 32-Bit-Ordnerpfade und kann in den DOM-Baum für bestimmte Fenster eingefügt werden.
Speichern Sie den nachstehenden Quellcode als Textdatei und ändern Sie seine Erweiterung in "hta". Starten Sie dann die erhaltene Anwendung durch einen Doppelklick darauf.
<script>
/*
Extended Drop Target v1.1.4 (https://tastyscriptsforfree.wix.com/page/scripts)
Copyright 2017-2020 Vladimir Samarets. All rights reserved.
tastyscriptsforfree@protonmail.com
Release date: November 9, 2020.
Use this script sample entirely at your own risk.
This script sample is copyrighted freeware and I am not responsible for any damage or data loss it could unintentionally cause.
You may modify it but please leave a comment with direct link to https://tastyscriptsforfree.wix.com/page/scripts in that case.
*/
offscreenBuffering = true; //postpone the application window appearance till its UI is ready
var O = function(o){return new ActiveXObject(o);},
WSS = O('WScript.Shell'),
env = WSS.Environment('Process'),
head = document.documentElement.firstChild, //head
PID; //PID of 64 bit HTA instance
if(!env('is64bit')) //indicates whether the application is launched as 64 bit or not
{
!function hide(e){try{moveTo(10000, 10000);}catch(e){try{hide();}catch(e){hide();}}}(); //hiding the application window
head.insertBefore(document.createElement('<hta:application showInTaskBar=0>'), head.firstChild); //hiding the application in the Taskbar
var WMI= //a small library written by me for obtaining WMI instance, its common methods and properties
{ //below is a sample of creating a process with certain window shifts and environment variables
//and obtaining its <ProcessId> by using WMI
SWL:new ActiveXObject('WbemScripting.SWbemLocator'),
PRMS:function(p)
{
var s = WMI.PS.SpawnInstance_();
for(var i in p)
s[i] = p[i];
return s;
},
Create:function(c, s, d)
{
var CreateIn = WMI.CreateIn.SpawnInstance_();
CreateIn.CommandLine = c;
CreateIn.ProcessStartupInformation = s;
CreateIn.CurrentDirectory = d;
return WMI.PRC.ExecMethod_('Create', CreateIn).ProcessId;
}
};
WMI.PRC = (WMI.WM = WMI.SWL.ConnectServer('.', 'root/cimv2')).Get('Win32_Process');
WMI.PS = WMI.WM.Get('Win32_ProcessStartup');
WMI.CreateIn = WMI.PRC.Methods_('Create').InParameters;
var ID = O('Scriptlet.TypeLib').GUID.substr(0, 38), //the unique ID obtaining
EV = 'is64bit='+ID; //passing the unique ID to 64 bit HTA instance as an Environment variable
for(var items = new Enumerator(env); !items.atEnd(); items.moveNext())
EV += '?' + items.item(); //obtaining all Environment variables for current process
PID = WMI.Create //obtaining PID of 64 bit HTA instance
(
'mshta "' + decodeURIComponent(location.pathname) + '"', //current path
WMI.PRMS
(
{
X:10000, Y:10000, //hiding the application window before it is shown in order to resize it smoothly
EnvironmentVariables:
EV.split('?') //obtaining an array of all Environment variables by using this approach is universal for different
//versions of Windows
/*
[ //another way to pass certain Environment variables
'is64bit='+ID, //indicates that the application is launched as 64 bit
'SystemRoot='+env('SystemRoot'), //for start
'SystemDrive='+env('SystemDrive'), //for hyperlinks
'TEMP='+env('TEMP'), //for "mailto" links
'CommonProgramW6432='+env('CommonProgramW6432') //for ADODB.Stream
]
*/
}
)
);
head.firstChild.insertAdjacentHTML('afterEnd', '<object id=' + ID + ' PID=' + PID +
' classid=clsid:8856F961-340A-11D0-A96B-00C04FD705A2><param name=RegisterAsBrowser value=1>'); //registering current HTA window in collection of windows
showModalDialog('javascript:for(var ws=new ActiveXObject("Shell.Application").Windows(),i=ws.Count;i-->0;)if((w=ws.Item(i))&&w.id=="'+ID+'"){w.s=document.Script;break;}', 0,
'dialogWidth:0;unadorned:1;'); //silent stop of the script and obtaining window focus for "AppActivate"
close();onerror=function(){close();};throw 0; //declining any further attempts of executing the rest statements of the code
}
var w,dt=new Date();
head.insertBefore(document.createElement('<hta:application contextMenu=no selection=no scroll=no>'), head.firstChild); //adding custom HTA header dynamically
document.title='Extended Drop Target';
resizeTo(800, 400);
for(var ws = O('Shell.Application').Windows(), i = ws.Count; i -- > 0;)
if((w = ws.Item(i)) && w.id == env('is64bit'))
{
PID = w.PID;
w.document.Script.WSS.AppActivate(PID); //using "WScript.Shell" in focus to activate
//the application window of 64 bit HTA instance;
//remember that "WScript.Shell" should be
//in focus in order "AppActivate" to work properly
break;
}
document.write('<body>'); //obtaining body
if(w && w.id == env('is64bit'))
w.s.close(); //closing previous 32 bit HTA instance while being in safe focus
document.body.appendChild(document.createTextNode('Debug screen (for test purposes only):'));
document.body.appendChild(document.createElement('br'));
document.body.appendChild(document.createElement('<textarea id=result cols=85 rows=5>'));
document.body.appendChild(document.createElement('p'));
document.body.appendChild(document.createTextNode('Extended Drop Target:'));
document.body.appendChild(document.createElement('br'));
document.body.appendChild
(
(
function createDropTarget(doc, filesAllowed, foldersAllowed, dTStyle, hdFont, wMColor, dMColor, pMColor, eMColor, process, resolve, msg, dBgImage, bBgImage,
description, redirect)
{
var dropTarget = doc.createElement('<span style="' + dTStyle + '">'),
ms = dropTarget.appendChild
(
doc.createElement('<span style="width:100%;height:100%;padding:10px;overflow:hidden;">')
), //message screen that hides Web Browser during dropped items processing
WB = '<object classid=clsid:8856F961-340A-11D0-A96B-00C04FD705A2 style="width:100%;height:100%;"><param name=Location value="about:<body onload=\'b=0;\'' +
' ondragover=(function(){clearTimeout(b);b=setTimeout(\'location.reload();\',100);}()) bgColor=' + dMColor +
' style=\'width:100%;height:100%;position:absolute;margin:0;border:0;overflow:hidden;\'>'+ (description || '') +'">',
processing = 1, //indicates whether a dropped item processing is started or not
processed = 1, //indicates whether a dropped item is processed or not
DBcatched = 1, //indicates whether DownloadBegin Web Browser event has been catched or not
allowed, //indicates whether drop target is allowed or not
allowedText = (filesAllowed ? foldersAllowed ? msg[32] : msg[33] : foldersAllowed ? msg[34] : ''), //"Drop a file or folder here."
WBTReset, //timeout for Web Browser reset
startProcessing = function(p) //processing the item path received after item drop (item path)
{
clearTimeout(WBTReset);
dropTarget.children[processed = 1].removeNode();
createDropTarget();
setTimeout(function()
{
var delay = 0;
if(p) //the item can be accessed
{
sM(msg[38] + p + '</div>', pMColor); //show "Processing"
var dt = new Date(), //date before processing
e; //error ID
try{e = process(p);}catch(e){e = 43;} //unknown error occured
dt = new Date() - dt; //date after processing
delay += dt>1000 ? 0 : 1000 - dt;
if(!e) //no errors occured
setTimeout(function(){sM(msg[39] + createDropTarget.timeToHMSR(dt) + ' =-</div>', pMColor);}, delay); //show "Processed in"
else //an error occured
{
var err;
try{resolve(e);}catch(err){;}
setTimeout(function(){sM(msg[39] + createDropTarget.timeToHMSR(dt) + ' =-</div><br>' + msg[e], eMColor);}, delay); //show "Processed in" with error
if(!redirect)
delay += 1000;
}
}
else //the item can't be accessed
{
sM(msg[40] + msg[41] + allowedText + msg[42], eMColor); //show "The item is not a file or folder, can't be accessed or its size is too big."
delay += 1000;
}
sDM(delay + 1000);
}, 1000);
},
setWBTReset = function(r) //setting a timeout for Web Browser reset (reset)
{
if(!processing)
{
processing = 1;
ms.style.display = '';
if(r)
WBTReset = setTimeout(startProcessing, 1000);
}
},
DB = function() //catching "DownloadBegin" Web Browser event
{
DBcatched = 1;
setWBTReset(1);
},
STC = function(p) //catching "StatusTextChange" Web Browser event (item path)
{
setWBTReset(p);
if(!processed && /file:|</.test(p))
{
if(/file:/.test(p))
startProcessing(filesAllowed ? decodeURIComponent(p).replace(/.+:((?:\/{3})|(?=\/{2}))(.+)...$/,'$2').replace(/\//g,'\\') : 0);
else if(/</.test(p))
{
if(!DBcatched) //indicates that drop target is leaved without drop
{
processed = 1;
clearTimeout(WBTReset);
sM(msg[31] + allowedText + msg[35] + '</div>', dMColor, dBgImage); //show "Drop a file or folder here."
allowed = 1;
ms.style.display = '';
}
else //shortcuts with complex structure
startProcessing();
}
}
},
NC2 = function(o, p) //catching "NavigateComplete2" Web Browser event (Web Browser object, item path)
{
if(!processed)
startProcessing(foldersAllowed && typeof p == 'string' && p.match(/^[^:]/) ? p : 0);
},
NE = function() //catching "NavigateError" Web Browser event
{
if(!processed)
startProcessing();
},
sM = function(m, c, bgImage) //show message (message, background or text color, background image)
{
if(dBgImage || bBgImage)
{
if(bgImage)
ms.style.backgroundImage = 'url(' + bgImage + ')';
ms.style.color = c;
}
else
ms.style.backgroundColor = c;
m = '<div style="font:' + hdFont + ';">' + m;
if(!redirect)
ms.innerHTML = m;
else
redirect(m);
},
sDM = function(delay) //show default message (delay)
{
setTimeout(function(){allowed = 1;}, delay);
setTimeout(function(){if(allowed)sM((allowedText ? msg[31] + allowedText + msg[35] : msg[36]) + '</div>', dMColor, dBgImage);}, delay + 100); //show "Drop a file or folder
//here." or "Drop Target is
} //disabled."
sM(msg[30], wMColor, dBgImage); //show welcome message
ms.ondragenter=function()
{
if(allowed && (filesAllowed || foldersAllowed) && !event.dataTransfer.getData('text')) //text dropping is not allowed
{
event.dataTransfer.dropEffect='move';
return false;
}
}
ms.ondragover = function()
{
if(allowed && (filesAllowed || foldersAllowed) && !event.dataTransfer.getData('text')) //text dropping is not allowed
{
event.dataTransfer.dropEffect='move';
if(!Math.abs(event.x - this.x) && !Math.abs(event.y - this.y)) //accepting only slow mouse motion
{
this.style.display = 'none';
DBcatched = allowed = processing = processed = 0;
sM(msg[37], dMColor, bBgImage); //show "Analysing..."
}
this.x = event.x;
this.y = event.y;
return false;
}
}
!(createDropTarget = function()
{
dropTarget.insertAdjacentHTML('beforeEnd', WB);
with(dropTarget.children[1])
{
RegisterAsDropTarget = Silent = Offline = 1;
attachEvent('DownloadBegin', DB);
attachEvent('StatusTextChange', STC);
attachEvent('NavigateComplete2', NC2);
attachEvent('NavigateError', NE);
}
})();
createDropTarget.timeToHMSR = function(d) //convert date to hours, minutes, seconds and remainder (milliseconds) notation (date)
{
var r = d % 3600000,
h = d / 3600000 ^ 0, //hours
m = r / 60000 ^ 0, //minutes
s = r % 60000 / 1000 ^ 0; //seconds
r = d % 1000; //remainder (milliseconds)
return ((h ? h + 'h' : '') + (m ? (h ? ' ' : '') + m + 'm' : '') + (s ? (h || m ? ' ' : '') + s + 's' : '') + (r ? (h || m || s ? ' ' : '') + r + 'ms' : '')) || '0ms';
},
sDM(3000); //postponing Web Browser access while it generates its events at start
return dropTarget;
}
(
//BEGIN of Extended Drop Target custom settings
document, //"document" object of certain window
1, //indicates whether processing of files is allowed or not
1, //indicates whether processing of folders is allowed or not
'width:350px;height:150px;border:2px blue solid;font:bold 10pt Arial;text-align:center;cursor:default;overflow:hidden;word-break:break-all;', //drop target style
'bold 12pt Tahoma', //message header font
'yellow', //welcome message background color if background image is not set or text color otherwise
'mediumaquamarine', //default message background color if background image is not set or text color otherwise
'limegreen', //processing message background color if background image is not set or text color otherwise
'salmon', //error message background color if background image is not set or text color otherwise
function(p) //data processing sample (file or folder path)
{
alert('Here goes data processing sample.\n\nProcessing:\n' + p);
//throw 1; //unknown error occured
//return 1; //certain error 1 occured
return 0; //no errors
},
function(e) //error resolving sample (error ID)
{
switch(e)
{
case 1:
result.value = '\nCertain error 1 is catched.'; //additional action sample for certain error 1
updateData1();
break;
default:
result.value = '\nAn unknown error is catched.'; //additional action sample for an unknown error
sendEmail();
break;
}
file.Close(); //built-in silent catching of errors if certain error resolving method is still inaccessible
},
{ //list of all messages for Extended Drop Target
30: 'Welcome!</div><br>Hello World!', //welcome message
31: 'Drop a ', //31, 32, 33, 34, 35 - "Drop a file or folder here."
32: 'file or folder',
33: 'file',
34: 'folder',
35: ' here.',
36: 'Drop Target is disabled.',
37: '-= Analysing... =-</div>',
38: '-= Processing =-</div><br><div style="text-align:left;">',
39: '-= Processed in ',
40: "-= Can't be processed =-</div><br>",
41: 'The item is not a ', //41, 32, 33, 34, 42 - "The item is not a file or folder,<br>can't be accessed or its size is too big."
42: ",<br>can't be accessed or its size is too big.",
43: 'An unknown error occured.', //unknown error message
1: 'Certain error 1 occured.' //certain error 1 message
//certain error # message
//...
}
//,'C:\\Windows\\Web\\Screen\\img103.png' //default background image or "undefined" (optional)
//,'C:\\Windows\\Web\\Screen\\img102.jpg' //busy mode background image or "undefined" (optional)
//,'<div style=\'font:10pt Tahoma;padding:20px;\'>List of files supported by default.</div>'
//description length depends on the message language or its actual bytes count or "undefined" (optional)
//,function(m){result.value = m;} //sample for receiving messages or "undefined" (optional)
//END of Extended Drop Target custom settings
)
)
);
result.value = '\nLoading time for 64 bit instance (if possible): ' + createDropTarget.timeToHMSR(new Date() - dt) + '.';
moveTo(screen.availWidth / 2 - 400, screen.availHeight / 2 - 200);
</script>