Тема: HTA & JScript: Extended Drop Target - Юникод-приемник файлов и папок
Вот мы и подошли вплотную к интерфейсной составляющей HTML приложения "Resource Extractor".
Речь пойдет о встроенной поддержке drag and drop (перетаскивания и бросания) файлов и папок в окно HTA.
Вступление. Что сейчас известно о drag and drop в HTA.
Стоит отметить, что в HTA с поддержкой функциональности drag and drop для файлов и папок в окно, на первый взгляд, все выглядит достаточно безнадежно - по крайней мере таких примеров мне встретить не удалось.
Уточню еще раз, что ни о каком HTML5 говорить здесь не приходится, а о сторонних ActiveX объектах Windows ничего не знает: их нужно устанавливать и регистрировать, что выходит за рамки данной темы.
Чаще всего предлагается, как после манипуляций с реестром можно добиться, чтобы HTML приложение принимало на вход файлы и папки, брошенные на его значок.
Аналогичным образом работают скрипты с хостами WScript и CScript.
Неприятности такого подхода - стороннее вмешательство, либо изменение системных настроек напрямую, отсутствие UI для данной операции, тогда как задумка HTA уходит в интерактивность посредством пользовательского интерфейса, и в довершение WScript и CScript, как мне удалось убедиться, не поддерживают пути после drag and drop на Юникоде.
Удавалось также встречать экперименты drag and drop на textarea, но там все ограничивается текстовыми файлами.
Дальше в лес - больше дров. Проблемы Web Browser, JScript и VBScript.
Единственный известный мне встроенный в любую версию Windows, начиная с XP (возможно и 2000), ActiveX объект с поддержкой drag and drop файлов и папок это Web Browser.
Есть у Web Browser такое интересное свойство как "RegisterAsDropTarget" - оно-то и позволяет превратить его в приемник файлов и папок.
А дальше сталкиваемся с тем, что, во-первых, Web Browser дает обратную связь с собой только через свои события, а во-вторых, обработка этих событий находится под большим вопросом.
Казалось бы, отменить событие "BeforeNavigate2" и взять с него путь брошенного на приемник файла или папки - вот и вся задача. Но не тут-то было.
VBScript умеет ловить события и отменять их для runtime-объекта, но беспомощен для объекта, представленного в виде HTML-ноды, так как не предоставляет в этом случае корректных методов для обработки событий.
JScript умеет ловить события для объекта, представленного в виде HTML-ноды, но не может отменять их в силу ограничения на передачу объектов по ссылке.
Ко всему прочему, даже поймать событие "BeforeNavigate2" в Windows XP можно только для runtime-объекта и причем на VBScript, тогда как JScript его не увидит.
Анализ приводит к описаниям схожих проблем с "BeforeNavigate2" в Windows XP от Microsoft:
h t t p://support.microsoft.com/kb/311298/EN-US/ или h t t p://c-bit.net/kb/311298/EN-US/
и
h t t p://support.microsoft.com/kb/325079/EN-US/ или h t t p://c-bit.net/kb/325079/EN-US/
В описаниях перечислены другие платформы, но и желающих отправить отчет по HTA на эту тему, как представляется, было в то время немного. Таким образом, проблема c событием "BeforeNavigate2" в Windows XP осталась и в Service Pack 3.
Стоит отметить, что событие "BeforeNavigate2" уже ловится на VBScript и JScript как для runtime-объекта, так и для объекта, представленного в виде HTML-ноды, в Windows 7 и 10, что значительно позволяет сократить код по сравнению с обходом данной проблемы.
Глубокое исследование показало, что все эти проблемы можно обойти.
Создание компонента drag and drop.
Проблемы удалось обойти за счет жесткой переинициализации Web Browser с предшествующим ей разрушением объекта.
При этом стоит отметить, что от разрушенного Web Browser, по всей видимости, остаются потоки в памяти, которые временно блокируют изменение обработанных им файлов сторонними программами до завершения скрипта.
Но это ложка дегтя в бочке меда, так как drag and drop файлов и папок в окно HTA да и еще с поддержкой путей на Юникоде оказывается возможным встроенными средствами.
Дальше мне пришлось столкнуться с анализом череды большого количества событий Web Browser, которые отличаются и количеством, и структурой, и временем появления, и порядком их возникновения на разных версиях Windows.
Тем не менее, я поставил себе цель обеспечить поддержку drag and drop файлов и папок в окно HTA для Windows XP.
Глубокое исследование позволило совместить всю эту цепь событий в единое целое.
В результате получился компонент "Extended Drop Target", поддерживающий drag and drop файлов и папок в окно HTA как для Windows XP, так и для Windows 7 и 10 (поддержка других версий ожидается, но не тестировалась).
Данная работа представляет собой расширенную, доработанную и настраиваемую под пользователя версию, представленную в виде уединенного компонента, возвращаемого функцией "createDropTarget", который можно поместить в любое место дерева DOM определенного окна с передачей на вход всех настроек в виде стилей, сообщений, функций обработки данных и ошибок.
Поддерживается и графика - при желании можно установить изображения в качестве фона.
Со всеми возможностями можно ознакомиться подробнее ниже.
Скриптовый пример имеет следующие специальные возможности:
не требует установки какого-либо стороннего программного обеспечения и поддерживает любую версию Windows, начиная с XP (возможно и 2000) с определенными ActiveX объектами, не запрещенными по умолчанию;
полностью написан на JScript в файле скриптового формата HTA и использует следующие ActiveX объекты: WScript.Shell, Scriptlet.TypeLib, WbemScripting.SWbemLocator, Shell.Application и Shell.Explorer.2, также известный как Microsoft Web Browser;
тестировался и адаптирован для Windows XP, Windows 7 и Windows 10;
не пишет каких-либо записей в реестр и не сохраняет каких-либо персональных данных на вашем жестком диске;
не выходит в сеть каким-либо способом;
поддерживает функциональность drag and drop для папок и файлов;
работает с именами входящих файлов на любой локали (поддержка символов Юникода в именах);
работает как с 32-битными, так и с 64-битными путями папок;
реализован как автономный компонент, который может быть вставлен в дерево DOM для определенного окна;
имеет множество возможностей, которые можно настроить, включая стили, принятием соответствующих входных параметров;
поддерживает показ дополнительного пользовательского описания продукта;
отправляет результаты в соответствующую функцию на входе;
разрешает неизвестные и пользовательские ошибки, передавая их в соответствующую функцию на входе;
имеет встроенную скрытую обработку ошибок в случае, если какой-либо метод устранения ошибок все еще недоступен;
может быть легко переведен на другие языки принятием входного блока сообщений;
поддерживает перенаправление drag and drop сообщений;
разделяет с основным скриптом функцию timeToHMSR для преобразования даты в представление в виде часов, минут, секунд и остатка (миллисекунд);
не требует какой-либо вложенной структуры для 64-битной части скрипта (новый код может быть просто добавлен в конец);
получает все необходимые паузы и фокусы для того, чтобы приложение оставалось поверх других окон при старте;
получает собственный PID, который может быть использован вновь позже;
не требует никаких системных путей или деклараций, которые могут отсутствовать в некоторых версиях Windows (например, "SysNative" неизвестен для Windows XP 32 bit).
Скриптовый пример демонстрирует:
как скрыть HTA во время его динамического создания;
как запустить HTA в виде 64-битного процесса без использования системных путей или деклараций;
как получить скрытую остановку скрипта в HTA;
как поддерживать функциональность drag and drop для файлов и папок в HTA;
как бороться с подтвержденной проблемой "BeforeNavigate2" для Web Browser в Windows XP;
как решить подтвержденные проблемы с немедленным вызовом <moveTo> или <resizeTo> при старте в Windows XP
и как передать и использовать переменные среды для процесса, созданного с помощью WMI.
Работа с исходным кодом.
Для запуска скриптового примера скопируйте его исходный код и сохраните его в текстовом файле, сменив его расширение на "hta".
Запуск скриптового примера осуществляется двойным нажатием, как и в случае с обычной программой.
Рекомендую использовать AkelPad для просмотра сохраненного исходного кода примера с правильными отступами.
Вы можете использовать скриптовый пример на свое усмотрение, но, пожалуйста, оставьте комментарий с прямой ссылкой на tastyscriptsforfree.wix.com/page/scripts в этом случае.
<script>
/*
Extended Drop Target v1.1.2 (h t t p s://tastyscriptsforfree.wix.com/page/scripts)
Copyright 2017-2020 Vladimir Samarets. All rights reserved.
tastyscriptsforfree@protonmail.com
Release date: October 30, 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.
*******
The purpose of this script sample:
the script sample is intendent to maintain drag and drop functionality for files and folders in HTA with support of 64 and 32 bit folder paths and Unicode file names.
*******
The script sample has the following special features:
it requires no third party software installation and supports any Windows version since XP with certain ActiveX objects not restricted by default;
it is entirely written in JScript in HTA scripting file format and uses the following ActiveX objects: WScript.Shell, Scriptlet.TypeLib, WbemScripting.SWbemLocator, Shell.Application
and Shell.Explorer.2 also known as Microsoft Web Browser;
it was tested and adapted for Windows XP, Windows 7 and Windows 10;
it writes no registry values and stores no personal settings on your hard disk;
it doesn't access network in any way;
it supports drag and drop functionality for files and folders;
it works for input files named in any locale (Unicode names support);
it works both for 64 and 32 bit folder paths;
it is implemented as self-contained component that could be inserted into DOM tree for certain window;
it has many features that could be customized including styles by accepting corresponding input parameters;
it supports showing an additional custom product description;
it passes its results to corresponding input function;
it resolves unknown and custom errors by passing them into corresponding input function;
it has built-in silent catching of errors if certain error resolving method is still inaccessible;
it could be easily translated to other languages by accepting input block of messages;
it supports redirecting of drag and drop messages;
it shares with the main script "timeToHMSR" function for converting date to hours, minutes, seconds and remainder (milliseconds) notation;
it requires no nested structure for 64 bit instance scripting (new code can be simply added to the end);
it obtains all necessary pauses and focuses in order for the application to stay on top of other windows during its start;
it obtains the application PID which can be reused later;
it requires no system paths or declarations which could be absent in some versions of Windows (for example, "SysNative" is unknown for Windows XP 32 bit).
*******
The script sample demonstrates:
how to hide HTA while having it dynamically created;
how to launch HTA as 64 bit without using system paths or declarations;
how to obtain hidden stop for script in HTA;
how to maintain drag and drop functionality for files and folders in HTA;
how to deal with confirmed "BeforeNavigate2" issue of Web Browser in Windows XP;
how to deal with confirmed immediate "moveTo" or "resizeTo" issues at application start in Windows XP
and how to pass and use environment variables for process created by WMI.
*******
The script sample has the following current limitations:
maximum file size for processing based on Windows 7 and Windows 10 limitations is 3.99 GB (4,293,918,718 bytes);
all successfully processed files are treated as in use under any circumstances until the script is closed;
it is possible to set some image as a background for Web Browser but it is not currently supported because it ruins Extended Drop Target functionality;
a third party error is shown in Windows 7 and Windows 10 for dropped HTML files if they have errors in their scripts with "async" property;
an excessive Web Browser error is shown in case the folder path is valid no more.
*******
Basic documentation and articles I used:
'VBScript Scripting Techniques: Environment Variables' by Rob van der Woude
(h t t p s://w w w.robvanderwoude.com/vbstech_data_environment.php);
'Using Win32_ProcessStartup to change environment' post by Rico Rosenlund
(h t t p s://microsoft.public.scripting.wsh.narkive.com/hW1GURnH/using-win32-processstartup-to-change-environment);
'WSH: exchanging data and objects between scripts - 2' by Xameleon (March, 2011) in Russian
(h t t p://forum.script-coding.com/viewtopic.php?id=5573);
'VBScript Scripting Techniques: HTAs' by Rob van der Woude
(h t t p s://w w w.robvanderwoude.com/vbstech_hta.php);
'InternetExplorer and WebBrowser objects' by Ludogovskiy Aleksander in Russian
(h t t p s://script-coding.com/WSH/WebBrowser.html);
'Windows Script 5.6 Documentation' (script56.chm) by Microsoft Corporation
(h t t p s://w w w.microsoft.com/en-us/download/confirmation.aspx?id=2764);
'MSDN' related documentation by Microsoft Corporation
(h t t p s://docs.microsoft.com/en-us/);
Windows XP BeforeNavigate2 issue:
'BUG: The BeforeNavigate2 event of the WebBrowser control does not fire if hosted in a Visual Basic .NET 2002 application'
on c-bit.net and support.microsoft.com (September 14, 2005)
(h t t p://c-bit.net/kb/311298/EN-US/, h t t p://support.microsoft.com/kb/311298/EN-US/);
'BUG: The BeforeNavigate2 Event of WebBrowser Control Does Not Fire If Hosted in a Visual C# .NET Application'
on c-bit.net and support.microsoft.com (June 25, 2004)
(h t t p://c-bit.net/kb/325079/EN-US/, h t t p://support.microsoft.com/kb/325079/EN-US/);
Windows XP moveTo and resizeTo issues:
'"Access is denied" by executing .hta file with JScript on Windows XP x64' discussion on stackoverflow.com (January 21, 2009)
(h t t p s://stackoverflow.com/questions/464679/access-is-denied-by-executing-hta-file-with-jscript-on-windows-xp-x64);
'Something strange with HTAs' discussion on social.technet.microsoft.com (September 19, 2011)
(h t t p s://social.technet.microsoft.com/Forums/officeocs/en-US/92bf1e76-ebd5-4462-bd52-533e69305a5c/something-strange-with-htas?forum=ITCG).
*******
Basic software I used:
AkelPad 4.9.8 by Aleksander Shengalts and Alexey Kuznetsov (as development environment)
(h t t p://akelpad.sourceforge.net/en/download.php);
OLE/COM Object Viewer v2.10.059 (oleview.exe) by Charlie Kindel, Michael Nelson, and Michael Antonio (for documentation purposes).
*/
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(0, 0, 'dialogWidth:0;unadorned:1;'); //stopping the script and obtaining window focus for "AppActivate"
}
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.document.Script.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 bgColor=' +
dMColor + ' style=\'width:100%;height:100%;position:absolute;margin:0px;border:0px;overflow:hidden;\'>' + (description || '') + '<script>var b=document.body;' +
'b.ondragenter=b.ondragover=b.onmouseenter=b.onmouseover=b.onmousemove=function(){clearTimeout(b);b=setTimeout(\'location.reload();\',100);}<\/script>">',
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
{
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); //Web Browser reset is needed because its events can't be declined further in JavaScript,
with(dropTarget.children[1]) //BeforeNavigate2 event has also a confirmed issue and can't be catched in Windows XP
{ //by default while VBScript provides no working methods to catch them for ActiveX objects
RegisterAsDropTarget = Silent = Offline = 1; //represented as HTML nodes
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 'error 2'; //certain error 2 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(); //built-in silent catching of errors if certain error resolving method is still inaccessible
break;
case 'error 2':
result.value = '\nCertain error 2 is catched.'; //additional action sample for certain error 2
updateData2(); //built-in silent catching of errors if certain error esolving method is still inaccessible
break;
default:
result.value = '\nAn unknown error is catched.'; //additional action sample for an unknown error
sendEmail(); //built-in silent catching of errors if certain error resolving method is still inaccessible
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
'error 2': 'Certain error 2 occured.' //certain error 2 message
//certain error # message
//certain error # 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:<ul><li>Bitmap Files (*.bmp;*.dib)<li>JPEG (*.jpg;*.jpeg;*.jpe;*.jfif)<li>GIF(*.gif)</ul></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);
/*
some built-in in Windows 10 background samples:
'C:\\Windows\\Web\\Screen\\img103.png'
'C:\\Windows\\Web\\Screen\\img102.jpg'
some built-in in Windows 7 background samples:
'C:\\Windows\\Web\\Wallpaper\\Nature\\img3.jpg'
'C:\\Windows\\Web\\Wallpaper\\Landscapes\\img10.jpg'
some built-in in Windows XP background samples:
'C:\\WINDOWS\\Zapotec.bmp'
'C:\\WINDOWS\\Soap Bubbles.bmp'
*/
</script>
Перевод "Extended Drop Target" на русский язык и примеры настроек.
Все настройки "Extended Drop Target" находятся в разделе между "//BEGIN of Extended Drop Target custom settings" и "//END of Extended Drop Target custom settings".
Для перевода на русский язык замените блок английских сообщений на блок русских сообщений:
{
30: 'Добро пожаловать!</div><br>Здравствуй, Мир!',
31: 'Сюда принимается ',
32: 'файл или папка',
33: 'файл',
34: 'папка',
35: '.',
36: 'Приемник элементов отключен.',
37: '-= Анализ... =-</div>',
38: '-= Обработка =-</div><br><div style="text-align:left;">',
39: '-= Обработано за ',
40: '-= Невозможно обработать =-</div><br>',
41: 'Данный элемент это не ',
42: ',<br>не может быть доступен<br>или его размер слишком велик.',
43: 'Произошла неизвестная ошибка.',
1: 'Произошла определенная ошибка 1.',
'error 2': 'Произошла определенная ошибка 2.'
}
Для дальнейшей обработки результатов замените функцию с комментарием "//data processing sample (file or folder path)" на свою.
Возникающие исключения в функции ловятся скрыто и автоматически.
Возвращенные функцией ID ошибок обрабатываются отдельно как пользовательские ошибки.
Пользовательские ID ошибок задаются в конце общего блока сообщений.
Для встраивания "Extended Drop Target" в другое окно передайте на вход "document" соответствующего окна.
Для включения/отключения поддержки drag and drop для файлов или папок измените соответствующий флаг (1 или true; 0, undefined или false):
1, //indicates whether processing of files is allowed or not
1, //indicates whether processing of folders is allowed or not
Для изменения размеров "Extended Drop Target", параметров границы, параметров шрифта заголовка сообщений, текста, а также выравнивания обратитесь к строкам:
'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
Если в качестве фона выбрано изображение, то изменяется цвет текста.
Для обработки ошибок замените функцию с комментарием "//error resolving sample (error ID)" на свою.
Возникающие исключения в функции ловятся скрыто и автоматически.
Пользовательские ID ошибок задаются в конце общего блока сообщений.
Для показа изображений в качестве фона раскомментируйте соответствующие строки:
,'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)
Важно сохранять порядок следования передаваемых параметров, поэтому вместо предшествующих нераскомментированных строк в настройках всегда прописывайте:
,undefined
При необходимости используйте картинки для вашей версии Windows из блока ниже, либо замените раскомментированные строки на пути к своим изображениям:
/*
some built-in in Windows 10 background samples:
'C:\\Windows\\Web\\Screen\\img103.png'
'C:\\Windows\\Web\\Screen\\img102.jpg'
some built-in in Windows 7 background samples:
'C:\\Windows\\Web\\Wallpaper\\Nature\\img3.jpg'
'C:\\Windows\\Web\\Wallpaper\\Landscapes\\img10.jpg'
some built-in in Windows XP background samples:
'C:\\WINDOWS\\Zapotec.bmp'
'C:\\WINDOWS\\Soap Bubbles.bmp'
*/
Для показа произвольного пользовательского описания продукта раскомментируйте:
,'<div style=\'font:10pt Tahoma;padding:20px;\'>List of files supported by default:<ul><li>Bitmap Files (*.bmp;*.dib)<li>JPEG (*.jpg;*.jpeg;*.jpe;*.jfif)<li>GIF(*.gif)</ul></div>'
Это пример дополнительной информации для пользователя, который не ограничивает текущую функциональность.
Для показа произвольного пользовательского описания продукта на русском языке замените эту запись на:
,'<div style=\'font:10pt Tahoma;padding:20px;\'>Список поддерживаемых файлов по умолчанию:<ul><li>Bitmap Files (*.bmp)<li>JPEG (*.jpg;*.jpeg)<li>GIF(*.gif)</ul></ul></div>'
Длина описания ограничена возможностями Web Browser.
Для перенаправления drag and drop сообщений в другую область или окно раскомментируйте:
,function(m){result.value = m;} //sample for receiving messages or "undefined" (optional)
Данный пример перенаправит сообщения в textarea, расположенную выше "Extended Drop Target". При этом сообщения в "Extended Drop Target" больше показаны не будут, хотя по-прежнему может происходить смена фона как ответная реакция на происходящие события.
Если показ сообщений не нужен, но и их перенаправление не требуется, то можно поставить простую заглушку:
,function(m){;} //sample for receiving messages or "undefined" (optional)
Желаю вам приятной работы с функциональностью drag and drop для файлов и папок в окне HTA.