クリップボード履歴

クリップボード履歴

最近のWindows10(October 2018 Update以降)では標準機能としてクリップボード履歴「Win+V」なのですが、例のごとく現場PCは「Windows10」じゃない。だったり、Windows10だけど、まだ利用できないバージョンだなど。

勝手にツールなども入れられないので、Windows10標準で稼働するスクリプトを作成して代用することにしました。

使い方

以下のソースコードテキストエディタに張り付けて「クリップボード履歴.hta」として保存。 htaファイルをダブルクリックして起動すれば、クリップボードの履歴が蓄積されていきます。

このPCでは利用できませんエラーになる場合
方法①

クリップボード履歴起動」ショートカットを作成する。

  1. mshta.exe ショートカットを作成し、名前を「クリップボード履歴起動」にする。
    ※mshta.exe フルパス例。"C:\Windows\System32\mshta.exe"
  2. 「 mshta.exe」ショートカットのリンク先に「クリップボード履歴.hta」パスを引数でいれる。
    例)C:\Windows\System32\mshta.exe "C:XXXXX\XXXXX\クリップボード履歴.hta"

ソースコード

<html>
<head><title>クリップボード履歴  【利用法:選択してEnter or ダブルクリック】  </title></head>
<!--
Ver 1.0:2020/12/28:新規作成
Ver 1.1:2020/12/28:起動時にSelectにフォーカスを当てる
Ver 1.2:2020/12/29:Selectは複数選択できないように変更 multiple → size="300"
Ver 1.3:2020/12/29:初回起動で履歴がない場合にSelect[0]がエラーとなるためTryCatch化
-->

<script>
    w = screen.width/3;
    h = screen.height/2;
    window.resizeTo(w, h);
    //画面中央に表示
    window.moveTo((screen.width - w) / 2 , (screen.height - h) / 2 );
</script>


<head>
    <meta http-equiv="Content-Type" content="text/html; charset=shift_jis">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <title>ClipHistory</title>
    <hta:application
        scroll="no"
        border="thin"
        innerboder="no"
        scrollflat="yes"
        CONTEXTMENU="no"
    >
</head>


<style type="text/css">
    select {
        width: 100%;
        height: 70%;
        display:inline;
    }
    textarea {
        width: 100%;
        height: 30%;
        display:inline;
    }
</style>


<body>
<!--
  <form name="myform">
    <input name="myfile" type="file" />
  </form>
-->

    <form name="fm" onkeydown="keydown_enter()">
        <!--<label><font size="2"> 履歴</font></label>-->
        <select type="submit" name="sct" size="300" 
             onChange="DisplayTextArea(this)" onDblClick="copy(this)" >
        </select>
        <textarea id="ta" cols=100 rows=10></textarea>
        <input type="hidden" id="mybutton" value="取り出し" onclick=copy()></input>
    </form>

</body>


<script type="text/javascript">
<!--
    var sfo = new ActiveXObject("scripting.filesystemobject");
    var cd = sfo.buildpath(sfo.getparentfoldername(location.pathname), "クリップボード履歴ファイル");
        if (sfo.folderexists(cd) == 0) {sfo.createfolder(cd);}
    sfo = null;
    //rec_text:前回クリップボード内容を保持
    var rec_txt = "";
    var set_rec = setInterval(rec, 500);
    var hisFileNullFlg = false;
    beforeOpen();


//クリップボードから情報取得
function rec() {
    try {
        //window.clipboardData.getData("text")でクリップボードから取得可能(IE ※HTA含むのみ)
        var cb_txt = window.clipboardData.getData("text");
        if (hisFileNullFlg == false) {
            //直前コピー内容 != 今回コピー内容 AND 今回コピー内容  != null & 今回コピー内容 != SELECT[0]
            if (rec_txt != cb_txt && cb_txt != null && cb_txt != fm.sct[0].value) {
                //Selectへの登録
                setSelect(cb_txt);
            }
        } else {
            if (rec_txt != cb_txt && cb_txt != null  ) {
                //Selectへの登録
                setSelect(cb_txt);
            }
        }
    } catch(e) {
        //alert("クリップボード保存時にエラーが起きました。バグった場合は一度終了して再起動してください");
    }
}

//Selectへの登録
function setSelect(cpWord){
    //履歴表示(Select)用に改行コードは置換
    var tmp = cpWord.replace(/\r\n|\r|\n/g, " ");
    //Selectへ追加
    var ele = document.createElement("option");
        ele.text = tmp.replace(/^\s+|\s+$/g, "").substr(0, 100);
        ele.value = cpWord;
    //option add 位置をしてい「0」が一番最初
    if (navigator.userAgent.match(/Gecko/)) {
        fm.sct.insertBefore(ele, fm.sct.options[insert]);
    }
    else {
        fm.sct.add(ele, 0);
        //Select 一番上だけ選択
        fm.sct.selectedIndex = -1;
        fm.sct[0].selected = true;
    }
    rec_txt = cpWord;
    
    //テキストボックスへ表示
    fm.ta.value = cpWord;
    //セレクトにフォーカス
    document.fm.sct.focus();
}


//クリップボードへ貼り付け
function copy() {
    clearInterval(set_rec);
    var cs = fm.sct.options;
    var str = "";
    //Select複数の場合に連結する
    for (var cc = 0; cc < cs.length; cc ++) {
        if (cs[cc].selected) {
            //str += rec_txt = cs[cc].value + "\r\n";
            str += rec_txt = cs[cc].value;
        }
    }
    window.clipboardData.setData("text", str);
    //Selectへ登録(Selectの一番上と異なる場合のみ)
    if( str != fm.sct[0].value) { setSelect(str); }
    rec_txt = str;
    set_rec = setInterval(rec, 500);
    //alert( sct.value );
    minWindow();
}

//テキストボックスにクリップボード内容を表示
function DisplayTextArea(){
    //alert( "TEST" );
    fm.ta.value = fm.sct.value;
}

function keydown_enter() {
  //Enterキー押下
  if(window.event.keyCode == 13) {
    document.getElementById("mybutton").click();
    minWindow();
  }
  //ESCキー押下
  if(window.event.keyCode == 27) {
    minWindow();
   }
}

function minWindow(){
    //画面を最小化する
    WsShell = new ActiveXObject("WScript.Shell")
    WsShell.SendKeys("% n")
}

function startNotepad(){
    var shell = new ActiveXObject("WScript.Shell");
    shell.Run("C:\\Windows\\System32\\notepad.exe", 1, true);
}

function beforeClose(){
    var sfo = new ActiveXObject("scripting.filesystemobject");
        filename = sfo.buildpath(cd, "クリップボード履歴" + ".txt");
    var ocf = sfo.createtextfile(filename, 2);
    
    var cs = fm.sct.options;
    var str = "";
    //selectの内容を連結
    for (var cc = 0; cc < cs.length; cc ++) {
        str += rec_txt = cs[cc].value + "★クリップボード履歴★\r\n";
    }
    ocf.write(str);
    ocf.close();
    sfo = null;
}

//クローズ時の処理
function window.onbeforeunload(){
    beforeClose();
    //if( event.clientY < 0 || event.altKey ) { event.returnValue = "終了してよろしいですか?" ; }
}

function beforeOpen(){
    //alert("beforeOpen");

    var sfo = new ActiveXObject("scripting.filesystemobject");
    filename = sfo.buildpath(cd, "クリップボード履歴" + ".txt");
    
    if (sfo.FileExists(filename)) {
        if (sfo.getFile(filename).size != 0 ) {
            var stream = sfo.OpenTextFile(filename, 1);
            var text = stream.ReadAll().split("★クリップボード履歴★\r\n");
            stream.Close();
            //alert(text.length);
            var i= 0;
            //初期読み込み時は300個まで。その後の履歴保存時に結果として300個になる。
            while(i<text.length && i<300){
                //Selectへ追加
                var ele = document.createElement("option");
                var line = text[i];
                ele.text = line.replace(/★クリップボード履歴★|^\s+|\s+$|\r\n|\r|\n/g,"").substr(0, 100);
                ele.value =  line.replace("★クリップボード履歴★","");
                //空文字以外を初期登録
                if(ele.value != "") {
                    fm.sct.add(ele);
                }
                i++;
            }
            //alert(hisFileNullFlg);
        } else {
            hisFileNullFlg = true;
            //alert(hisFileNullFlg);
        }
    } else {
        hisFileNullFlg = true;
    }
    sfo = null;
    //一番上のSelect選択(Ver 1.1)
    try{
            fm.sct.focus();
            fm.sct[0].selected = true;
    }catch(e){
        }
}
-->
</script>
</html>