「スクリプト」(2008/02/02 (土) 09:09:27) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
#contents()
*スクリプトによる機能拡張
**検索・マイリスト・ランキングをTubePlayerっぽく一覧表示しつつ画像の一覧表示もする
ソースファイルをメモ帳などに貼り付け、拡張子(.hta)でNicoPlayerのインストールフォルダに保存し実行してください(同じ場所にprototype.jsも置いてください)。もし他の場所に起きたい場合はpathOfDownloadとpathOfNicoPlayerをそれぞれの環境に合わせて編集してください(セパレータはスラッシュ/もしくはダブルバックスラッシュ\\です)。タイトルや再生数などのパラメタを表形式・及び画像で一覧表示します。フィードバックを強化しました。青字はダウンロード済みでクリックすると再生、赤字はまだでクリックすると該当行を強調してダウンロードを開始します。この強調は再表示で解除されます。TitleやPなどヘッダをクリックすると該当項目でソートします(基本降順以後トグル)。
<hta:application maximizebutton="no" selection="yes"
navigable="no" scroll="no" singleinstance="yes"/>
<html>
<head>
<meta http-equiv="MSThemeCompatible" content="yes">
<style>
#display { border:3px double red; color:red; text-align:center; }
#target { width:100%; height:90%; overflow-y:scroll; }
body { background-color:#f7f7f7; }
div { border:solid 1px #ccc; }
table { font-size:9pt; width:100%; }
th { background-color:black; color:white; cursor:pointer; }
img { width:98%; margin:3px; cursor:pointer; }
.even { background-color:#f7f7f7; cursor:pointer; }
.odd { background-color:#ffffff; cursor:pointer; }
.omo { background-color:#e0ffe0; }
.download { color:red; } .play { color:blue; }
.now { background-color:#ffb7b7; }
.playing { background-color:#b7b7ff; }
.activet { background-color:#ccc; }
</style>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
var pathOfDownload = ""; // ダウンロードパス(任意)
var pathOfNicoPlayer = ""; // NicoPlayerインストールパス(任意)
var width = 800, height = 800;
var lastSortKey = "";
var movies = {};
var $_ = function( target, key ) {
return $A( target.getElementsByTagName( key ) );
}
window.onload = function() {
resizeTo( width, height );
var display = document.getElementById( "display" );
try { Prototype } catch( e ) {
display.innerHTML = "prototype.jsが見つかりません。<a href='http://www.prototypejs.org/'>"
+ "こちら</a>よりダウンロードして同じフォルダにおいてください。";
return;
}
if( !pathOfNicoPlayer ) {
unescape( window.location ).match( /file:\/\/\/(.+)\// );
pathOfNicoPlayer = RegExp.$1;
}
if( !ini.load( pathOfNicoPlayer + "/nicoplayer.ini" ) ) {
display.innerHTML = "NicoPlayerが見つかりません。同じフォルダにおいてください。";
return;
}
if( !pathOfDownload ) {
pathOfDownload = ini.download.SavePath;
}
Element.hide( "display" );
}
// nicoplayer.iniが対象(一般的なiniファイルにも有効)
ini = {
// 読み込み済み項目があれば削除(操作プロパティinit/loadを除く)
init : function() {
for( var key in ini ) {
if( !key.match( /^(init|load)$/ ) ) {
delete ini[key];
}
}
},
// iniファイルのパスを引数に取りini以下にセクションと値の組を展開
load : function( path ) {
this.init();
try {
var file = ( new ActiveXObject( "Scripting.FileSystemObject" )
).OpenTextFile( path );
} catch ( e ) {
return;
}
var buffer, section;
while( !file.AtEndOfLine ) {
var line = file.ReadLine();
// セクション取得
if( line.match( /^\[(.+)\]$/ ) ) {
var newSection = RegExp.$1;
if( section && !section.match( /^(init|load)$/ ) ) {
this[section] = buffer;
}
buffer = {};
section = newSection;
}
// 設定値取得
if( buffer && line.match( /^([^=]+)=(.*)$/ ) ) {
buffer[RegExp.$1] = RegExp.$2;
}
}
file.Close();
return this;
}
}
list = {
list:[],
index:-1,
load:function( newlist ) {
if( 0 <= this.index ) {
this.list = this.list.slice( 0, this.index + 1 );
}
this.list.push( newlist );
this.index++;
},
add:function( addlist ) {
( !this.list[this.index] )
? ( this.load( addlist ) )
: ( this.list[this.index] = this.list[this.index].concat( addlist ) );
},
reverse:function() {
if( !this.list[this.index] ) { return; }
this.list[this.index] = this.list[this.index].reverse();
},
back:function() {
if( 0 < this.index ) { this.index--; }
},
forward:function() {
if( this.index < this.list.length - 1 ) { this.index++; }
},
active:function() {
return this.list[this.index];
},
sort:function( key, order ) {
if( !this.list[this.index] ) { return; }
if( key == lastSortKey ) {
this.reverse();
} else {
this.list[this.index] = this.list[this.index].sortBy( function( name ) {
var value = movies[name][key] + "";
if( key == "title" ) {
return value;
} else {
value = value.gsub( "[^0-9]", "" ) - 0;
}
return ( order == "desc" ) ? value : -value;
} );
lastSortKey = key;
}
}
}
EscapeUTF8=function(str){
return str.replace(/[^*+.-9A-Z_a-z-]/g,function(s){
var c=s.charCodeAt(0);
return (c<16?"%0"+c.toString(16):c<128?"%"+c.toString(16)
:c<2048?"%"+(c>>6|192).toString(16)+"%"+(c&63|128).toString(16)
:"%"+(c>>12|224).toString(16)+"%"+(c>>6&63|128).toString(16)+"%"
+(c&63|128).toString(16)).toUpperCase()
})
};
search = function() {
lastSortKey = "";
this.index = 0;
this.timer = setInterval( "search.exec();", 1000 );
this.request = function() {
if( 3 <= ++this.index ){ clearInterval( this.timer ); search.instance = null; }
var key = EscapeUTF8( $F( "keyword" ) );
var option = $( "sort" ).value + "&page=" + this.index;
var url = "http://www.nicovideo.jp/search/" + key + "?" + option;
new Ajax.Request( url, { method:"get", onSuccess:function( response ) {
var buffer = document.createElement( "div" );
buffer.innerHTML = response.responseText;
var pageGuides = { root:{ tag:"table", index:7 }, blocks:{ tag:"td" } };
var blocksGuides = [ ["time", "strong", 0], ["play", "strong", 1], ["src", "img", 1, "src"]
, ["comment", "strong", 2], ["mylist", "strong", 3]
, ["title", "a", 1], ["name", "a", 1, "href", "((sm|ax)\[0-9]+)"]
];
var blocks = parsePage( buffer, pageGuides );
var items = parseBlocks( blocks, blocksGuides );
list.add( $H( items ).keys() );
refreshTable();
} } );
}
this.request();
}
search.instance;
search.exec = function() {
if( !this.instance ) {
this.instance = new this();
} else {
this.instance.request();
}
}
ranking = function() {
lastSortKey = "";
var option = [$F( "rsort" ), $F( "rspan" ), $F( "rgenre" )];
var url = "http://www.nicovideo.jp/ranking/" + option.join( "/" );
new Ajax.Request( url, { method:"get", onSuccess:function( response ) {
var buffer = document.createElement( "div" );
buffer.innerHTML = response.responseText;
var pageGuides = { root:{ tag:"table", index:7 }, blocks:{ tag:"tr" } };
var blocksGuides = [ ["time", "strong", 0], ["date", "strong", 1], ["play", "strong", 2]
, ["comment", "strong", 3], ["target", "p", 1, "([0-9,]+)" ], ["src", "img", 1, "src"]
, ["title", "a", 1], ["name", "a", 1, "href", "((sm|ax)\[0-9]+)"]
];
var blocks = parsePage( buffer, pageGuides );
blocks = blocks.findAll( function( block, index ) { return ( index % 2 ) == 0; } );
var items = parseBlocks( blocks, blocksGuides );
list.load( $H( items ).keys() );
refreshTable();
} } );
}
mylist = function() {
lastSortKey = "";
var url = "http://www.nicovideo.jp/mylist/" + $F( "mylistkeyword" );
new Ajax.Request( url, { method:"get", onSuccess:function( response ) {
var buffer = document.createElement( "div" );
buffer.innerHTML = response.responseText;
var pageGuides = { root:{ tag:"table", index:6 }, blocks:{ tag:"tr" } };
var blocksGuides = [ ["date", "strong", 0], ["time", "strong", 1]
, ["play", "strong", 2], ["comment", "strong", 3], ["src", "img", 1, "src"]
, ["title", "a", 1], ["name", "a", 1, "href", "((sm|ax)\[0-9]+)"]
];
var blocks = parsePage( buffer, pageGuides );
var items = parseBlocks( blocks, blocksGuides );
list.load( $H( items ).keys() );
refreshTable();
} } );
}
parsePage = function( buffer, guides ) {
with( guides ) {
return $_( $_( buffer, root.tag )[root.index], blocks.tag )
}
}
parseBlocks = function( blocks, guides ) {
var items = {};
blocks.each( function( block ) {
var buffer = {};
guides.each( function( g ) {
with( { key:g[0], tag:g[1], index:g[2], param:g[3], regex:g[4] } ) {
var value = $_( block, tag )[index][param ? param : "innerHTML"];
if( regex ) {
new RegExp( regex, "" ).exec( value );
value = RegExp.$1;
}
buffer[key] = value;
}
} );
items[buffer.name] = buffer;
movies[buffer.name] = buffer;
} );
return items;
}
lastMode = "string";
var refreshTable = function( mode ) {
searchFlvFiles();
switch( mode ) {
case "string" :
$( "rstring" ).className = "activet";
$( "rimage" ).className = "";
refreshStringTable();
lastMode = mode;
break;
case "image" :
$( "rstring" ).className = "";
$( "rimage" ).className = "activet";
refreshImageTable();
lastMode = mode;
break;
default :
refreshTable( lastMode );
break;
}
}
var header = [ ["■", "index", "asc"], ["Title", "title", "desc"], ["P", "play", "asc"]
, ["C", "comment", "asc"], ["M", "mylist", "asc"]
, ["Time", "time", "asc"], ["ID", "name", "desc"] ];
refreshStringTable = function() {
var ths = "";
header.each( function( item, index ) {
ths += ( new Template( "<th onclick='list.sort(\"#{key}\", \"#{order}\");refreshTable();'"
+ " onmouseover='this.style.cssText=\"background-color:white; color:black\"'"
+ " onmouseout='this.style.cssText=\"\"'>#{label}</th>" )
).evaluate( { label:item[0], key:item[1], order:item[2] } );
} );
var thead = "<thead><tr>" + ths + "</tr></thead>";
var trs = "";
list.active().each( function( key, index ) {
items = movies[key];
if( !items.index ){ items.index = index + 1; }
var tds = "";
header.each( function( value, index ) {
tds += "<td>" + ( items[value[1]] ? items[value[1]] : "-" ) + "</td>";
} );
var trsvalue = { c1 :( index % 2 ) ? "odd" : "even"
, c2 :movies[items.name].file ? " play" : " download"
, omover:"this.className += \" omo\";"
, omout :"this.className = this.className.replace(/ omo/g, \"\");"
, oc :"action( this );", id:items.name
};
trs += ( new Template( "<tr class='#{c1} #{c2}' onclick='#{oc}'"
+ "onmouseover='#{omover}' onmouseout='#{omout}' id='#{id}'>" )
).evaluate( trsvalue ) + tds + "</tr>";
} );
var tbody = "<tbody>" + trs + "</tbody>";
$( "target" ).innerHTML = "<table>" + thead + tbody + "</table>";
}
refreshImageTable = function() {
var trs = "<tr>";
var tds = "";
list.active().each( function( key, index ) {
items = movies[key];
if( !( index % 5 ) ) {
trs += tds + "</tr>";
tds = "<tr>";
}
items.state = movies[items.name].file ? "playing" : "now";
tds += ( new Template( "<td id='#{name}' align='center' class='#{state}' onclick='action( this )'>"
+ "<img src='#{src}' title='#{title}\n再生:#{play} コメント:#{comment}' /></td>" )
).evaluate( items );
if( index == list.active().length - 1 ) {
trs += tds + "</tr>";
}
} );
var tbody = "<tbody>" + trs + "</tbody>";
$( "target" ).innerHTML = "<table>" + tbody + "</table>";
}
searchFlvFiles = function() {
var fs = new ActiveXObject( "Scripting.FileSystemObject" );
var files = new Enumerator( fs.GetFolder( pathOfDownload ).Files );
while( !files.atEnd() ) {
if( files.item().Name.match( /((sm|ax)\d+).*\.flv$/ ) ) {
if( movies[RegExp.$1] ) {
movies[RegExp.$1].file = files.item();
}
}
files.moveNext();
}
}
execBuildupCommand = function( argument )
{
var shell = new ActiveXObject( "WScript.Shell" );
shell.Run( "\"" + pathOfNicoPlayer + "\\NicoPlayer.exe\" " + argument + " -inactive", 0, true );
shell = null;
}
playingBefore = undefined;
action = function( node ) {
var movieName = node.id;
if( movies[movieName].file ) {
if( playingBefore ) {
playingBefore.className = playingBefore.className.replace( / playing/g, "" );
}
node.className += " playing";
playingBefore = node;
execBuildupCommand( "\"" + movies[movieName].file.Path + "\"" );
} else {
node.className += " now";
execBuildupCommand( "http://www.nicovideo.jp/watch/" + movieName );
}
}
</script>
</head>
<body>
<div id="display">JavaScriptを有効にしてください。</div>
<table id="controller">
<tr><form onsubmit="search.exec();return false;"><td>
<input type="text" id="keyword" value="初音ミク">
<select id="sort">
<option value="">投稿日時が新しい</option>
<option value="order=a">投稿日時が古い</option>
<option value="sort=v" selected>再生が多い</option>
<option value="sort=v&order=a">再生が少ない</option>
<option value="sort=n">コメントが新しい</option>
<option value="sort=n&order=a">コメントが古い</option>
<option value="sort=r">コメントが多い</option>
<option value="sort=r&order=a">コメントが少ない</option>
</select>
<input type="submit" value="検索" />
<!--<button onclick="refreshTable();">再表示</button>-->
</td></form><form onsubmit="mylist();return false;"><td>
<input type="text" id="mylistkeyword" value="2949389/2632878" />
<input type="submit" value="マイリスト" />
</td></form><form onsubmit="ranking();return false;"><td>
<select id="rsort">
<option value="view">再生</option>
<option value="res">コメント</option>
<option value="mylist" selected>マイリスト</option>
</select>
<select id="rspan">
<option value="newarrival">新着</option>
<option value="daily" selected>本日</option>
<option value="weekly">週間</option>
<option value="monthly">月間</option>
<option value="total">合計</option>
</select>
<select id="rgenre">
<option value="all">すべて</option>
<option value="music" selected>音楽</option>
<option value="game">ゲーム</option>
</select>
<input type="submit" value="ランキング" />
</td></form></tr>
</table>
<table id="selector" cellspacing="0" style="border:solid 1px #ccc; border-bottom:0px"><tr>
<td id="rstring" width="45%" align="center" style="cursor:pointer;" onclick="refreshTable('string');" class="activet">一覧</td>
<td id="rimage" width="45%" align="center" style="cursor:pointer;" onclick="refreshTable('image');">画像一覧</td>
<td align="center" style="cursor:pointer;" onclick="list.back();refreshTable();">戻る</td>
<td align="center" style="cursor:pointer;" onclick="list.forward();refreshTable();">進む</td>
</tr></table>
<div id="target"></div>
</body>
</html>
**ローカルファイルを検索し表示
最上部のテキストボックスにキーワードを入力してTabキーを押すと、ローカルファイルを検索しマッチするファイルをリストアップします。お好きなファイルをクリックして再生してください。onchangeではなくonkeyupを使うとインクリメンタル検索になるのですが、このロジックだと重すぎて実用的ではないのでやめました。
<hta:application maximizebutton="no" selection="yes"
navigable="no" scroll="yes" singleinstance="yes"/>
<html>
<head>
<meta http-equiv="MSThemeCompatible" content="yes">
<style>
ul { list-style-type:none; margin:1px; }
li { cursor:pointer; width:100%; border:3px double; margin:3px; font-size:12px }
</style>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
var pathOfDownload = "ダウンロードパス"; // ex) D:\\Download
var pathOfNicoPlayer = "NicoPlayerインストールパス";
var localFlvFiles;
$_ = function( target, key ) {
return $A( target.getElementsByTagName( key ) );
}
$_A = function( target, key ) {
return target.getAttribute( key );
}
onLoad = function( link ) {
resizeTo( 500, 800 );
showList();
}
showList = function() {
searchFlvFiles();
// 検索
var keyword = $F( "keyword" );
if( keyword ) {
localFlvFiles = localFlvFiles.findAll( function( file ) {
return RegExp( keyword, "i" ).test( file.Name );
} );
}
// リストクリア
var ul = $( "target" );
$A( ul.childNodes ).each( function( child ) {
ul.removeChild( child );
} );
// リスト追加
localFlvFiles.each( function( file, index ) {
var li = document.createElement( "li" );
li.setAttribute( "onclick", new Function( "play( \'" + index + "\' );" ) );
file.Name.match( /(.*)\.flv$/ );
var text = document.createTextNode( RegExp.$1 );
li.appendChild( text );
ul.appendChild( li );
} );
}
searchFlvFiles = function() {
if( !localFlvFiles ) {
localFlvFiles = $A();
} else {
localFlvFiles.clear();
}
var fs = new ActiveXObject( "Scripting.FileSystemObject" );
var files = new Enumerator( fs.GetFolder( pathOfDownload ).Files );
while( !files.atEnd() ) {
if( files.item().Name.match( /(sm\d+).*\.flv$/ ) ) {
localFlvFiles.push( files.item() );
}
files.moveNext();
}
}
execBuildupCommand = function( argument )
{
var shell = new ActiveXObject( "WScript.Shell" );
shell.Run( "\"" + pathOfNicoPlayer + "\\NicoPlayer.exe\" " + argument, 0, true );
shell = null;
}
play = function( index ) {
execBuildupCommand( "\"" + localFlvFiles[index].Path + "\"" );
}
</script>
</head>
<body onload="onLoad();">
<input type="text" id="keyword" onchange="showList();" />
<ul id="target" />
</body>
</html>
**マイページに登録されているうち、ダウンロード済みアイテムのプレイリストを作成し開く
ソースファイルをメモ帳などに貼り付け、拡張子(.js)で保存してください。
pathOfNicoPlayerとpathOfDownloadをそれぞれの環境にあったパスに変更してください。
使う時はクリップボードにマイページのアドレス(http://~/0000000/000000:省略不可)を
コピーしてダブルクリックしてください。
またNicoPlayerのプレイリストウィンドウが表示されていれば、自動的に開きます。
// 環境設定
var pathOfNicoPlayer = "NicoPlayerのインストールパス(パスセパレータ \\)";
var pathOfDownload = "動画ファイルのダウンロードパス(同上)";
// クリップボードからマイページのアドレスを取得
var ieObject = new ActiveXObject( "InternetExplorer.Application" );
ieObject.Navigate( "about:blank" );
while ( ieObject.Busy ) {
WScript.Sleep( 100 );
}
var addressOfMypage = ieObject.Document.parentWindow.clipboardData.getData( "text" );
ieObject.Quit();
// マイページアドレスが取得できなかった場合入力ウィンドウを表示(Excelのインストールが必要)
if( !addressOfMypage.match( /.*\/([0-9]+)\/([0-9]+)/ ) ) {
var excelObject = WScript.CreateObject( "Excel.Application" );
if( excelObject != null )
{
addressOfMypage = excelObject.InputBox( "マイページのアドレスを入力してください" );
excelObject.Quit();
}
}
// Msxml2(IE6標準)によりマイページのGETリクエスト送出
var httpObject = WScript.CreateObject( "Msxml2.XMLHTTP" );
httpObject.onreadystatechange = function()
{
if( httpObject.readyState == 4 )
{
getRequestPage( httpObject );
}
}
// open( , , false )は同期指定(さもないと取得前にプログラムが終了する)
httpObject.open( "GET", addressOfMypage, false );
httpObject.send( "" );
function getRequestPage( httpObject )
{
// マイページのテキストを検索しID(sm[0-9]+)をリストアップ
var requestPageText = httpObject.responseText;
var mypageIdList = requestPageText.match( /sm[0-9]+/g );
if( mypageIdList == null ) {
return; // IDが見つからず
}
// ダウンロードフォルダを検索し.flvファイルをIDに基づいてリストアップ
var filesHash = {};
var fsoObject = WScript.CreateObject( "Scripting.FileSystemObject" );
var filesCollection = fsoObject.GetFolder( pathOfDownload ).Files;
for( var file = new Enumerator( filesCollection ); !file.atEnd(); file.moveNext() ) {
var fileName = file.item().Name;
if( fsoObject.GetExtensionName( fileName ) == "flv" ) {
filesHash[fileName.match( /sm[0-9]+/ )] = file.item().Path;
}
}
// マイページのIDとローカルファイルを紐付けプレイリスト形式にする
var newPlaylistText = "", newDownloadListText = "";
for( var i = 0; i < mypageIdList.length; i += 2 ) {
if( filesHash[mypageIdList[i] ] != undefined ) {
newPlaylistText += filesHash[mypageIdList[i] ] + "\n";
}
}
// プレイリストファイル(.m3u)に落とす
addressOfMypage.match( /.*\/([0-9]+)\/([0-9]+)/ );
var newPlylistFileName = RegExp.$1 + "_" + RegExp.$2 + ".m3u";
// OpenTextFile( , 2, true )の2は書出指定(読込1・追記8)、trueは新規作成あり
var pathOfNewPlaylistFile = pathOfNicoPlayer + "\\" + newPlylistFileName;
var newPlaylistFile = fsoObject.OpenTextFile( pathOfNewPlaylistFile, 2, true );
newPlaylistFile.Write( newPlaylistText );
newPlaylistFile.Close();
// NicoPlayerが.m3uファイルのD&Dに対応すると、以下の全ては次の1行になります
// shellObject.Run( "\"" + pathOfNicoPlayer + "\\NicoPlayer.exe\" \"" + pathOfNewPlaylistFile + "\"" );
// プレイリストファイルパスをクリップボードへコピー
var ieObject = new ActiveXObject( "InternetExplorer.Application" );
ieObject.Navigate( "about:blank" );
while ( ieObject.Busy ) {
WScript.Sleep( 100 );
}
ieObject.Document.parentWindow.clipboardData.setData( "text", pathOfNewPlaylistFile );
ieObject.Quit();
// NicoPlayerのプレイリストウィンドウに登録する
var shellObject = WScript.CreateObject( "WScript.Shell" );
shellObject.AppActivate( "NicoPlayer - プレイリスト" );
WScript.Sleep( 100 );
shellObject.SendKeys( "^O" );
WScript.Sleep( 100 );
shellObject.SendKeys( "^V" );
WScript.Sleep( 100 );
shellObject.SendKeys( "%O" );
}
**プレイリストウィンドウにプレイリストファイルをドラッグ&ドロップする(Cランタイム使用)
使い勝手向上のためぜひともD&Dを実装したかったが、スクリプトのみでは実装できなかった。
WindowsAPIをVBAでラップすれば可能だが、あまりに煩雑なので断念した。
[マイページに登録されているうち、ダウンロード済みアイテムのプレイリストを作成し開く]の
\// NicoPlayerが.m3uファイルのD&Dに対応すると、以下の全ては次の1行になります
以下を次のように置き換える。
var shellObject = new ActiveXObject( "WScript.Shell" );
shellObject.Run( "\"ランタイム名.exe\" \"CWndPlayList\" \"NicoPlayer - プレイリスト\" \"" + pathOfNewPlaylistFile + "\"", 0 );
shellObject = null;
ランタイム(正確には違うが)のコードは以下の通り。
開発環境は[[Microsoft公式>http://www.microsoft.com/japan/msdn/vstudio/express/visualc/usingpsdk/]]を参考にしてください。
#define STRICT
#include <windows.h>
#include <cstring>
// DnD操作におけるOS領域のメモリ構造定義
typedef struct drop_files{
DWORD pFiles;
POINT pt;
bool fNC;
bool fWide;
} DropFiles;
int main( int argc, char *argv[] )
{
// パラメータが3個([0]は実行ファイルのパス)未満なら終了
if( argc < 4 ) {
return 0;
}
// 指定窓が見つからなければ終了
// ([1]:クラス名・[2]タイトル、空文字列も検索条件、無効にするにはNULL)
HWND hWndTarget = FindWindowExA( NULL, NULL, argv[1], argv[2] );
if( !hWndTarget ) {
return 0;
}
// D&D操作のための情報を作成
DropFiles df = { sizeof( DropFiles ), { 0, 0 }, false, false };
char *file = argv[3];
// OS領域のメモリリソースを確保し情報を転送
HGLOBAL hGlobalMemory = GlobalAlloc( GHND, sizeof( DropFiles ) + strlen( file ) + 1 );
void *p = GlobalLock( hGlobalMemory );
memcpy( p, ( void * )&df, sizeof( DropFiles ) );
memcpy( ( char * )p + sizeof( DropFiles ), ( void * )file, strlen( file ) + 1 );
GlobalUnlock( hGlobalMemory );
// 指定窓に通知
PostMessageA( hWndTarget, WM_DROPFILES, ( WPARAM )hGlobalMemory, 0 );
// OS領域のメモリリソースを開放
GlobalFree( hGlobalMemory );
return 0;
}
*コメント
#pcomment()
#contents()
*スクリプトによる機能拡張
**検索・マイリスト・ランキングをTubePlayerっぽく一覧表示しつつ画像の一覧表示もする
ソースファイルをメモ帳などに貼り付け、拡張子(.hta)でNicoPlayerのインストールフォルダに保存し実行してください(同じ場所にprototype.jsも置いてください)。もし他の場所に起きたい場合はpathOfDownloadとpathOfNicoPlayerをそれぞれの環境に合わせて編集してください(セパレータはスラッシュ/もしくはダブルバックスラッシュ\\です)。タイトルや再生数などのパラメタを表形式・及び画像で一覧表示します。フィードバックを強化しました。青字はダウンロード済みでクリックすると再生、赤字はまだでクリックすると該当行を強調してダウンロードを開始します。この強調は再表示で解除されます。TitleやPなどヘッダをクリックすると該当項目でソートします(基本降順以後トグル)。
<hta:application maximizebutton="no" selection="yes"
navigable="no" scroll="no" singleinstance="yes"/>
<html>
<head>
<meta http-equiv="MSThemeCompatible" content="yes">
<style>
#display { border:3px double red; color:red; text-align:center; }
#target { width:100%; height:90%; overflow-y:scroll; }
body { background-color:#f7f7f7; }
div { border:solid 1px #ccc; }
table { font-size:9pt; width:100%; }
th { background-color:black; color:white; cursor:pointer; }
img { width:98%; margin:3px; cursor:pointer; }
.even { background-color:#f7f7f7; cursor:pointer; }
.odd { background-color:#ffffff; cursor:pointer; }
.omo { background-color:#e0ffe0; }
.download { color:red; } .play { color:blue; }
.downloaded { color:blue; background-color:#b7ffb7; }
.downloading{ color:red; background-color:#ffb7b7; }
.playing { color:blue; background-color:#b7b7ff; }
.activet { background-color:#ccc; }
</style>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
var pathOfDownload = ""; // ダウンロードパス(任意)
var pathOfNicoPlayer = ""; // NicoPlayerインストールパス(任意)
var width = 800, height = 800;
var lastSortKey = "", download = {};
var fileTemplate = "#{title}(#{name}).flv";
var $_ = function( target, key ) {
return $A( target.getElementsByTagName( key ) );
}
window.onload = function() {
resizeTo( width, height );
var display = document.getElementById( "display" );
try { Prototype } catch( e ) {
display.innerHTML = "prototype.jsが見つかりません。<a href='http://www.prototypejs.org/'>"
+ "こちら</a>よりダウンロードして同じフォルダにおいてください。";
return;
}
if( !pathOfNicoPlayer ) {
unescape( window.location ).match( /file:\/\/\/(.+)\// );
pathOfNicoPlayer = RegExp.$1;
}
if( !ini.load( pathOfNicoPlayer + "/nicoplayer.ini" ) ) {
display.innerHTML = "NicoPlayerが見つかりません。同じフォルダにおいてください。";
return;
}
if( !pathOfDownload ) {
pathOfDownload = ini.download.SavePath;
}
display.innerHTML = "起動中です。しばらくお待ちください。";
movies.load( pathOfDownload );
Element.hide( "display" );
resizeTo( width, height );
setInterval( "interval();", 5000 );
}
// 周期的(5000ms)にダウンロードリストを走査
interval = function() {
for( name in download ) {
if( movies.exist( name ) ) {
movies[name].className = "downloaded";
var target = $( name );
if( target ) {
with( Element ) {
target.className = target.className.replace( /downloading/g, "" );
target.className += " downloaded";
}
}
delete download[name];
}
}
}
movies = {
init : function() {
init( this, "^(init|load|exist)$" );
},
load : function( path ) {
this.init();
var fs = new ActiveXObject( "Scripting.FileSystemObject" );
var files = new Enumerator( fs.GetFolder( path ).Files );
while( !files.atEnd() ) {
if( files.item().Name.match( /((sm|ax)\d+).*\.flv$/ ) ) {
this[RegExp.$1] = { path:files.item().Path, exist:true, className:"play" };
}
files.moveNext();
}
},
exist : function( name ) {
var fs = new ActiveXObject( "Scripting.FileSystemObject" );
if( fs.FileExists( this[name].path ) ) {
this[name].exist = true;
return true;
}
}
}
init = function( node, mask ) {
for( var key in node ) {
if( !RegExp( mask, "" ).test( key ) ) {
delete node[key];
}
}
}
// nicoplayer.iniが対象(一般的なiniファイルにも有効)
ini = {
// 読み込み済み項目があれば削除(操作プロパティinit/loadを除く)
init : function() {
init( this, "^(init|load)$" );
},
// iniファイルのパスを引数に取りini以下にセクションと値の組を展開
load : function( path ) {
this.init();
try {
var file = ( new ActiveXObject( "Scripting.FileSystemObject" )
).OpenTextFile( path );
} catch ( e ) {
return;
}
var buffer, section;
while( !file.AtEndOfLine ) {
var line = file.ReadLine();
// セクション取得
if( line.match( /^\[(.+)\]$/ ) ) {
var newSection = RegExp.$1;
if( section && !section.match( /^(init|load)$/ ) ) {
this[section] = buffer;
}
buffer = {};
section = newSection;
}
// 設定値取得
if( buffer && line.match( /^([^=]+)=(.*)$/ ) ) {
buffer[RegExp.$1] = RegExp.$2;
}
}
file.Close();
return this;
}
}
list = {
list : [],
index : -1,
load : function( newlist ) {
if( 0 <= this.index ) {
this.list = this.list.slice( 0, this.index + 1 );
}
this.list.push( newlist );
this.index++;
},
add : function( addlist ) {
( !this.list[this.index] )
? ( this.load( addlist ) )
: ( this.list[this.index] = this.list[this.index].concat( addlist ) );
},
reverse : function() {
if( !this.list[this.index] ) { return; }
this.list[this.index] = this.list[this.index].reverse();
},
back : function() {
if( 0 < this.index ) { this.index--; }
},
forward : function() {
if( this.index < this.list.length - 1 ) { this.index++; }
},
active : function() {
return this.list[this.index];
},
sort : function( key, order ) {
if( !this.list[this.index] ) { return; }
if( key == lastSortKey ) {
this.reverse();
} else {
this.list[this.index] = this.list[this.index].sortBy( function( items ) {
var value = items[key] + "";
if( key == "title" ) {
return value;
} else {
value = value.gsub( "[^0-9]", "" ) - 0;
}
return ( order == "desc" ) ? value : -value;
} );
lastSortKey = key;
}
}
}
EscapeUTF8=function(str){
return str.replace(/[^*+.-9A-Z_a-z-]/g,function(s){
var c=s.charCodeAt(0);
return (c<16?"%0"+c.toString(16):c<128?"%"+c.toString(16)
:c<2048?"%"+(c>>6|192).toString(16)+"%"+(c&63|128).toString(16)
:"%"+(c>>12|224).toString(16)+"%"+(c>>6&63|128).toString(16)+"%"
+(c&63|128).toString(16)).toUpperCase()
})
};
search = function() {
list.load( [] );
lastSortKey = "";
this.index = 0;
this.timer = setInterval( "search.exec();", 1000 );
this.request = function() {
if( 3 <= ++this.index ){ clearInterval( this.timer ); search.instance = null; }
var key = EscapeUTF8( $F( "keyword" ) );
var option = $( "sort" ).value + "&page=" + this.index;
var url = "http://www.nicovideo.jp/search/" + key + "?" + option;
new Ajax.Request( url, { method:"get", onSuccess:function( response ) {
var buffer = document.createElement( "div" );
buffer.innerHTML = response.responseText;
var pageGuides = { root:{ tag:"table", index:7 }, blocks:{ tag:"td" } };
var blocksGuides = [ ["time", "strong", 0], ["play", "strong", 1], ["src", "img", 1, "src"]
, ["comment", "strong", 2], ["mylist", "strong", 3]
, ["title", "a", 1], ["name", "a", 1, "href", "((sm|ax)\[0-9]+)"]
];
var blocks = parsePage( buffer, pageGuides );
var items = parseBlocks( blocks, blocksGuides );
list.add( items );
refreshTable();
} } );
}
this.request();
}
search.instance;
search.exec = function() {
if( !this.instance ) {
this.instance = new this();
} else {
this.instance.request();
}
}
ranking = function() {
lastSortKey = "";
var option = [$F( "rsort" ), $F( "rspan" ), $F( "rgenre" )];
var url = "http://www.nicovideo.jp/ranking/" + option.join( "/" );
new Ajax.Request( url, { method:"get", onSuccess:function( response ) {
var buffer = document.createElement( "div" );
buffer.innerHTML = response.responseText;
var pageGuides = { root:{ tag:"table", index:7 }, blocks:{ tag:"tr" } };
var blocksGuides = [ ["time", "strong", 0], ["date", "strong", 1], ["play", "strong", 2]
, ["comment", "strong", 3], ["target", "p", 1, "([0-9,]+)" ], ["src", "img", 1, "src"]
, ["title", "a", 1], ["name", "a", 1, "href", "((sm|ax)\[0-9]+)"]
];
var blocks = parsePage( buffer, pageGuides );
blocks = blocks.findAll( function( block, index ) { return ( index % 2 ) == 0; } );
var items = parseBlocks( blocks, blocksGuides );
list.load( items );
refreshTable();
} } );
}
mylist = function() {
lastSortKey = "";
var url = "http://www.nicovideo.jp/mylist/" + $F( "mylistkeyword" );
new Ajax.Request( url, { method:"get", onSuccess:function( response ) {
var buffer = document.createElement( "div" );
buffer.innerHTML = response.responseText;
var pageGuides = { root:{ tag:"table", index:6 }, blocks:{ tag:"tr" } };
var blocksGuides = [ ["date", "strong", 0], ["time", "strong", 1]
, ["play", "strong", 2], ["comment", "strong", 3], ["src", "img", 1, "src"]
, ["title", "a", 1], ["name", "a", 1, "href", "((sm|ax)\[0-9]+)"]
];
var blocks = parsePage( buffer, pageGuides );
var items = parseBlocks( blocks, blocksGuides );
list.load( items );
refreshTable();
} } );
}
parsePage = function( buffer, guides ) {
with( guides ) {
return $_( $_( buffer, root.tag )[root.index], blocks.tag )
}
}
parseBlocks = function( blocks, guides ) {
var items = [];
blocks.each( function( block ) {
var buffer = {};
guides.each( function( g ) {
with( { key:g[0], tag:g[1], index:g[2], param:g[3], regex:g[4] } ) {
var value = $_( block, tag )[index][param ? param : "innerHTML"];
if( regex ) {
new RegExp( regex, "" ).exec( value );
value = RegExp.$1;
}
buffer[key] = value;
}
} );
items.push( buffer );
if( !movies[buffer.name] ) {
var fileName = ( new Template( fileTemplate ) ).evaluate( buffer );
movies[buffer.name] = { path : pathOfDownload + "\\" + fileName, className : "download" };
}
} );
return items;
}
lastMode = "string";
var refreshTable = function( mode ) {
switch( mode ) {
case "string" :
$( "rstring" ).className = "activet";
$( "rimage" ).className = "";
refreshStringTable();
lastMode = mode;
break;
case "image" :
$( "rstring" ).className = "";
$( "rimage" ).className = "activet";
refreshImageTable();
lastMode = mode;
break;
default :
refreshTable( lastMode );
break;
}
}
var header = [ ["■", "index", "asc"], ["Title", "title", "desc"], ["P", "play", "asc"]
, ["C", "comment", "asc"], ["M", "mylist", "asc"]
, ["Time", "time", "asc"], ["ID", "name", "desc"] ];
refreshStringTable = function() {
var ths = "";
header.each( function( item, index ) {
ths += ( new Template( "<th onclick='list.sort(\"#{key}\", \"#{order}\");refreshTable();'"
+ " onmouseover='this.style.cssText=\"background-color:white; color:black\"'"
+ " onmouseout='this.style.cssText=\"\"'>#{label}</th>" )
).evaluate( { label:item[0], key:item[1], order:item[2] } );
} );
var thead = "<thead><tr>" + ths + "</tr></thead>";
var trs = "";
list.active().each( function( items, index ) {
if( !items.index ){ items.index = index + 1; }
var tds = "";
header.each( function( value, index ) {
tds += "<td>" + ( items[value[1]] ? items[value[1]] : "-" ) + "</td>";
} );
var trsvalue = { c1 : ( index % 2 ) ? "odd" : "even"
//, c2 : movies[items.name].exist ? " play" : " download"
, className : movies[items.name].className
, omover : "this.className += \" omo\";"
, omout : "this.className = this.className.replace(/ omo/g, \"\");"
, oc : "action( this );", id:items.name
};
trs += ( new Template( "<tr class='#{c1} #{c2} #{className}' onclick='#{oc}'"
+ "onmouseover='#{omover}' onmouseout='#{omout}' id='#{id}'>" )
).evaluate( trsvalue ) + tds + "</tr>";
} );
var tbody = "<tbody>" + trs + "</tbody>";
$( "target" ).innerHTML = "<table>" + thead + tbody + "</table>";
}
refreshImageTable = function() {
var trs = "<tr>";
var tds = "";
list.active().each( function( items, index ) {
if( !( index % 5 ) ) {
trs += tds + "</tr>";
tds = "<tr>";
}
items.state = movies[items.name].exist ? "playing" : "downloading";
tds += ( new Template( "<td id='#{name}' align='center' class='#{state}' onclick='action( this )'>"
+ "<img src='#{src}' title='#{title}\n再生:#{play} コメント:#{comment}' /></td>" )
).evaluate( items );
if( index == list.active().length - 1 ) {
trs += tds + "</tr>";
}
} );
var tbody = "<tbody>" + trs + "</tbody>";
$( "target" ).innerHTML = "<table>" + tbody + "</table>";
}
execBuildupCommand = function( argument )
{
var shell = new ActiveXObject( "WScript.Shell" );
shell.Run( "\"" + pathOfNicoPlayer + "\\NicoPlayer.exe\" " + argument + " -inactive", 0, true );
shell = null;
}
playingBefore = undefined;
action = function( node ) {
var movieName = node.id;
if( movies[movieName].exist ) {
if( playingBefore ) {
movies[playingBefore].className = "play";
var bnode = $( playingBefore );
if( bnode ) {
bnode.className = bnode.className.replace( / playing/g, "" );
bnode.className += " play";
}
}
movies[movieName].className = "playing";
node.className = node.className.replace( / downloaded/g, "" );
node.className = node.className.replace( / play/g, "" );
node.className += " playing";
playingBefore = movieName;
execBuildupCommand( "\"" + movies[movieName].path + "\"" );
} else {
movies[movieName].className = "downloading";
node.className.replace( / download/g );
node.className += " downloading";
download[movieName] = false;
execBuildupCommand( "http://www.nicovideo.jp/watch/" + movieName );
}
}
</script>
</head>
<body>
<div id="display">JavaScriptを有効にしてください。</div>
<table id="controller">
<tr><form onsubmit="search.exec();return false;"><td>
<input type="text" id="keyword" value="初音ミク">
<select id="sort">
<option value="">投稿日時が新しい</option>
<option value="order=a">投稿日時が古い</option>
<option value="sort=v" selected>再生が多い</option>
<option value="sort=v&order=a">再生が少ない</option>
<option value="sort=n">コメントが新しい</option>
<option value="sort=n&order=a">コメントが古い</option>
<option value="sort=r">コメントが多い</option>
<option value="sort=r&order=a">コメントが少ない</option>
</select>
<input type="submit" value="検索" />
</td></form><form onsubmit="mylist();return false;"><td>
<input type="text" id="mylistkeyword" value="2949389/2632878" />
<input type="submit" value="マイリスト" />
</td></form><form onsubmit="ranking();return false;"><td>
<select id="rsort">
<option value="view">再生</option>
<option value="res">コメント</option>
<option value="mylist" selected>マイリスト</option>
</select>
<select id="rspan">
<option value="newarrival">新着</option>
<option value="daily" selected>本日</option>
<option value="weekly">週間</option>
<option value="monthly">月間</option>
<option value="total">合計</option>
</select>
<select id="rgenre">
<option value="all">すべて</option>
<option value="music" selected>音楽</option>
<option value="game">ゲーム</option>
</select>
<input type="submit" value="ランキング" />
</td></form></tr>
</table>
<table id="selector" cellspacing="0" style="border:solid 1px #ccc; border-bottom:0px"><tr>
<td id="rstring" width="45%" align="center" style="cursor:pointer;" onclick="refreshTable('string');" class="activet">一覧</td>
<td id="rimage" width="45%" align="center" style="cursor:pointer;" onclick="refreshTable('image');">画像一覧</td>
<td align="center" style="cursor:pointer;" onclick="list.back();refreshTable();">戻る</td>
<td align="center" style="cursor:pointer;" onclick="list.forward();refreshTable();">進む</td>
</tr></table>
<div id="target"></div>
</body>
</html>
**ローカルファイルを検索し表示
最上部のテキストボックスにキーワードを入力してTabキーを押すと、ローカルファイルを検索しマッチするファイルをリストアップします。お好きなファイルをクリックして再生してください。onchangeではなくonkeyupを使うとインクリメンタル検索になるのですが、このロジックだと重すぎて実用的ではないのでやめました。
<hta:application maximizebutton="no" selection="yes"
navigable="no" scroll="yes" singleinstance="yes"/>
<html>
<head>
<meta http-equiv="MSThemeCompatible" content="yes">
<style>
ul { list-style-type:none; margin:1px; }
li { cursor:pointer; width:100%; border:3px double; margin:3px; font-size:12px }
</style>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
var pathOfDownload = "ダウンロードパス"; // ex) D:\\Download
var pathOfNicoPlayer = "NicoPlayerインストールパス";
var localFlvFiles;
$_ = function( target, key ) {
return $A( target.getElementsByTagName( key ) );
}
$_A = function( target, key ) {
return target.getAttribute( key );
}
onLoad = function( link ) {
resizeTo( 500, 800 );
showList();
}
showList = function() {
searchFlvFiles();
// 検索
var keyword = $F( "keyword" );
if( keyword ) {
localFlvFiles = localFlvFiles.findAll( function( file ) {
return RegExp( keyword, "i" ).test( file.Name );
} );
}
// リストクリア
var ul = $( "target" );
$A( ul.childNodes ).each( function( child ) {
ul.removeChild( child );
} );
// リスト追加
localFlvFiles.each( function( file, index ) {
var li = document.createElement( "li" );
li.setAttribute( "onclick", new Function( "play( \'" + index + "\' );" ) );
file.Name.match( /(.*)\.flv$/ );
var text = document.createTextNode( RegExp.$1 );
li.appendChild( text );
ul.appendChild( li );
} );
}
searchFlvFiles = function() {
if( !localFlvFiles ) {
localFlvFiles = $A();
} else {
localFlvFiles.clear();
}
var fs = new ActiveXObject( "Scripting.FileSystemObject" );
var files = new Enumerator( fs.GetFolder( pathOfDownload ).Files );
while( !files.atEnd() ) {
if( files.item().Name.match( /(sm\d+).*\.flv$/ ) ) {
localFlvFiles.push( files.item() );
}
files.moveNext();
}
}
execBuildupCommand = function( argument )
{
var shell = new ActiveXObject( "WScript.Shell" );
shell.Run( "\"" + pathOfNicoPlayer + "\\NicoPlayer.exe\" " + argument, 0, true );
shell = null;
}
play = function( index ) {
execBuildupCommand( "\"" + localFlvFiles[index].Path + "\"" );
}
</script>
</head>
<body onload="onLoad();">
<input type="text" id="keyword" onchange="showList();" />
<ul id="target" />
</body>
</html>
**マイページに登録されているうち、ダウンロード済みアイテムのプレイリストを作成し開く
ソースファイルをメモ帳などに貼り付け、拡張子(.js)で保存してください。
pathOfNicoPlayerとpathOfDownloadをそれぞれの環境にあったパスに変更してください。
使う時はクリップボードにマイページのアドレス(http://~/0000000/000000:省略不可)を
コピーしてダブルクリックしてください。
またNicoPlayerのプレイリストウィンドウが表示されていれば、自動的に開きます。
// 環境設定
var pathOfNicoPlayer = "NicoPlayerのインストールパス(パスセパレータ \\)";
var pathOfDownload = "動画ファイルのダウンロードパス(同上)";
// クリップボードからマイページのアドレスを取得
var ieObject = new ActiveXObject( "InternetExplorer.Application" );
ieObject.Navigate( "about:blank" );
while ( ieObject.Busy ) {
WScript.Sleep( 100 );
}
var addressOfMypage = ieObject.Document.parentWindow.clipboardData.getData( "text" );
ieObject.Quit();
// マイページアドレスが取得できなかった場合入力ウィンドウを表示(Excelのインストールが必要)
if( !addressOfMypage.match( /.*\/([0-9]+)\/([0-9]+)/ ) ) {
var excelObject = WScript.CreateObject( "Excel.Application" );
if( excelObject != null )
{
addressOfMypage = excelObject.InputBox( "マイページのアドレスを入力してください" );
excelObject.Quit();
}
}
// Msxml2(IE6標準)によりマイページのGETリクエスト送出
var httpObject = WScript.CreateObject( "Msxml2.XMLHTTP" );
httpObject.onreadystatechange = function()
{
if( httpObject.readyState == 4 )
{
getRequestPage( httpObject );
}
}
// open( , , false )は同期指定(さもないと取得前にプログラムが終了する)
httpObject.open( "GET", addressOfMypage, false );
httpObject.send( "" );
function getRequestPage( httpObject )
{
// マイページのテキストを検索しID(sm[0-9]+)をリストアップ
var requestPageText = httpObject.responseText;
var mypageIdList = requestPageText.match( /sm[0-9]+/g );
if( mypageIdList == null ) {
return; // IDが見つからず
}
// ダウンロードフォルダを検索し.flvファイルをIDに基づいてリストアップ
var filesHash = {};
var fsoObject = WScript.CreateObject( "Scripting.FileSystemObject" );
var filesCollection = fsoObject.GetFolder( pathOfDownload ).Files;
for( var file = new Enumerator( filesCollection ); !file.atEnd(); file.moveNext() ) {
var fileName = file.item().Name;
if( fsoObject.GetExtensionName( fileName ) == "flv" ) {
filesHash[fileName.match( /sm[0-9]+/ )] = file.item().Path;
}
}
// マイページのIDとローカルファイルを紐付けプレイリスト形式にする
var newPlaylistText = "", newDownloadListText = "";
for( var i = 0; i < mypageIdList.length; i += 2 ) {
if( filesHash[mypageIdList[i] ] != undefined ) {
newPlaylistText += filesHash[mypageIdList[i] ] + "\n";
}
}
// プレイリストファイル(.m3u)に落とす
addressOfMypage.match( /.*\/([0-9]+)\/([0-9]+)/ );
var newPlylistFileName = RegExp.$1 + "_" + RegExp.$2 + ".m3u";
// OpenTextFile( , 2, true )の2は書出指定(読込1・追記8)、trueは新規作成あり
var pathOfNewPlaylistFile = pathOfNicoPlayer + "\\" + newPlylistFileName;
var newPlaylistFile = fsoObject.OpenTextFile( pathOfNewPlaylistFile, 2, true );
newPlaylistFile.Write( newPlaylistText );
newPlaylistFile.Close();
// NicoPlayerが.m3uファイルのD&Dに対応すると、以下の全ては次の1行になります
// shellObject.Run( "\"" + pathOfNicoPlayer + "\\NicoPlayer.exe\" \"" + pathOfNewPlaylistFile + "\"" );
// プレイリストファイルパスをクリップボードへコピー
var ieObject = new ActiveXObject( "InternetExplorer.Application" );
ieObject.Navigate( "about:blank" );
while ( ieObject.Busy ) {
WScript.Sleep( 100 );
}
ieObject.Document.parentWindow.clipboardData.setData( "text", pathOfNewPlaylistFile );
ieObject.Quit();
// NicoPlayerのプレイリストウィンドウに登録する
var shellObject = WScript.CreateObject( "WScript.Shell" );
shellObject.AppActivate( "NicoPlayer - プレイリスト" );
WScript.Sleep( 100 );
shellObject.SendKeys( "^O" );
WScript.Sleep( 100 );
shellObject.SendKeys( "^V" );
WScript.Sleep( 100 );
shellObject.SendKeys( "%O" );
}
**プレイリストウィンドウにプレイリストファイルをドラッグ&ドロップする(Cランタイム使用)
使い勝手向上のためぜひともD&Dを実装したかったが、スクリプトのみでは実装できなかった。
WindowsAPIをVBAでラップすれば可能だが、あまりに煩雑なので断念した。
[マイページに登録されているうち、ダウンロード済みアイテムのプレイリストを作成し開く]の
\// NicoPlayerが.m3uファイルのD&Dに対応すると、以下の全ては次の1行になります
以下を次のように置き換える。
var shellObject = new ActiveXObject( "WScript.Shell" );
shellObject.Run( "\"ランタイム名.exe\" \"CWndPlayList\" \"NicoPlayer - プレイリスト\" \"" + pathOfNewPlaylistFile + "\"", 0 );
shellObject = null;
ランタイム(正確には違うが)のコードは以下の通り。
開発環境は[[Microsoft公式>http://www.microsoft.com/japan/msdn/vstudio/express/visualc/usingpsdk/]]を参考にしてください。
#define STRICT
#include <windows.h>
#include <cstring>
// DnD操作におけるOS領域のメモリ構造定義
typedef struct drop_files{
DWORD pFiles;
POINT pt;
bool fNC;
bool fWide;
} DropFiles;
int main( int argc, char *argv[] )
{
// パラメータが3個([0]は実行ファイルのパス)未満なら終了
if( argc < 4 ) {
return 0;
}
// 指定窓が見つからなければ終了
// ([1]:クラス名・[2]タイトル、空文字列も検索条件、無効にするにはNULL)
HWND hWndTarget = FindWindowExA( NULL, NULL, argv[1], argv[2] );
if( !hWndTarget ) {
return 0;
}
// D&D操作のための情報を作成
DropFiles df = { sizeof( DropFiles ), { 0, 0 }, false, false };
char *file = argv[3];
// OS領域のメモリリソースを確保し情報を転送
HGLOBAL hGlobalMemory = GlobalAlloc( GHND, sizeof( DropFiles ) + strlen( file ) + 1 );
void *p = GlobalLock( hGlobalMemory );
memcpy( p, ( void * )&df, sizeof( DropFiles ) );
memcpy( ( char * )p + sizeof( DropFiles ), ( void * )file, strlen( file ) + 1 );
GlobalUnlock( hGlobalMemory );
// 指定窓に通知
PostMessageA( hWndTarget, WM_DROPFILES, ( WPARAM )hGlobalMemory, 0 );
// OS領域のメモリリソースを開放
GlobalFree( hGlobalMemory );
return 0;
}
*コメント
#pcomment()
表示オプション
横に並べて表示:
変化行の前後のみ表示: