「スクリプト」の編集履歴(バックアップ)一覧はこちら

スクリプト」(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()

表示オプション

横に並べて表示:
変化行の前後のみ表示:
目安箱バナー