最終更新日 2024-09-25

「個別ブラウザ枠」の記述パターン

ここでは「個別ブラウザ」枠を表示して、利用する黄金パターンを提示します。

マクロライブラリのサンプルにあるのは危険

https://hide.maruo.co.jp/lib/macro/v922macsamples.htmlにあるサンプルは様々なことを省略してしまっており、
これらをそのままに利用するのは適切ではありません。

UIクラスに独自の名前を付けて管理しよう

test.mac
hidemaruversion "9.25.99";

jsmode "WebView2\\" + currentmacrofilename; // currentmacrofilenameのところは、特定の名前を付ける場合、マクロファイルや役割に応じて変更する

js {

objUITemplate?._destructor();

class UITemplate { // ここのクラス名はマクロファイル名ごとに書き換える。「ここだけではなく、このファイル内の全てのUITemplate」を変更する必要がある。
    static strTargetLabel = "";
    static idInitInterval;
    static idUpdateInterval;
    static strHtmlFileName = "";
 
    constructor(option) {
        UITemplate.strTargetLabel = option.target;
        UITemplate.strHtmlFileName = option.html;
        UITemplate.openBrowserPane();
        UITemplate.setInitInterval();
        UITemplate.setUpdateInterval();
    }
 
    _destructor() {
        UITemplate.clearInitInterval();
        UITemplate.clearUpdateInterval();
    }
 
    static clearAllInterval() {
        UITemplate.clearInitInterval();
        UITemplate.clearUpdateInterval();
    }
 
    static setInitInterval() {
        UITemplate.idInitInterval = hidemaru.setInterval(UITemplate.checkCompleteBrowserPane, 500);
    }
 
    static clearInitInterval() {
        hidemaru.clearInterval(UITemplate.idInitInterval);
    }
 
    static outputAlert(err) {
        let dll = loaddll("HmOutputPane.dll");
        dll.dllFunc.Output(hidemaru.getCurrentWindowHandle(), err + "\r\n");
    }
 
    static setUpdateInterval() {
        UITemplate.idUpdateInterval = hidemaru.setInterval(UITemplate.updateBrowserPane, 1000);
    }
 
    static clearUpdateInterval() {
        hidemaru.clearInterval(UITemplate.idUpdateInterval);
    }
 
    static makeUrl() {
        let absoluteUrl = new URL(currentmacrodirectory() + "\\" + UITemplate.strHtmlFileName);
        let idSomeParam = 12345; // ここは何かパラメータを最初に伝えることがあるなら利用する
        let params = new URLSearchParams();
        params.set("strIDSomeParam", String(idSomeParam));
        absoluteUrl.search = new URLSearchParams(params).toString();
        return absoluteUrl;
    }
 
    static openBrowserPane() {
        let absoluteUrl = UITemplate.makeUrl();
        const json_arg = {
            target: UITemplate.strTargetLabel,
            uri: absoluteUrl.href,
            show: 1,
            place: "leftside",
            initialize: "async",
        };
 
        browserpanecommand(json_arg);
 
    }
 
    static closeBrowserPane() {
        const json_arg = {
            target: UITemplate.strTargetLabel,
            show: 0,
        };
 
        browserpanecommand(json_arg);
    }
 
    static checkCompleteBrowserPane() {
        try {
            let readyState = browserpanecommand({ target: UITemplate.strTargetLabel, get: "readyState" });
            if (readyState == "complete") {
                UITemplate.clearInitInterval();
                UITemplate.onBrowserPaneCompleted();
            }
        } catch (err) {
            UITemplate.outputAlert(err);
        }
    }
 
    static onBrowserPaneCompleted() {
        try {
            browserpanecommand({
                target: UITemplate.strTargetLabel,
                focus: 1,
            });
        } catch (err) {
            UITemplate.outputAlert(err);
        }
    }

    // 今回は全体の文字列にするが何か変化があった場合に送信する用途
    static prevConditionParam = -1;
    static prevUpdateCount = -1;

    // 全体のテキストの文字数が前回と違ったら、その数を返し、同じならnullを返す。
    static getChangeConditionParam() {

        // updateCountが増えていないなら、テキストが編集されていないのは自明
        let nUpdateCount = hidemaru.getUpdateCount();
        if (UITemplate.prevUpdateCount == nUpdateCount) {
            return null;
        }
        UITemplate.prevUpdateCount = nUpdateCount;

        // 全体のテキストの文字数をカウント
        let totalText = hidemaru.getTotalText();
        let length = totalText.length;
        if (UITemplate.prevConditionParam != length) {
           UITemplate.prevConditionParam = length;
            return length;
        }
        return null;
    }

    static updateBrowserPane() {
        try {
            let isShowNow = browserpanecommand({ target: UITemplate.strTargetLabel, get: "show" });
            if (isShowNow == "0") { // 数値ではなく文字列なので注意...
                UITemplate.clearAllInterval();
            }


            let conditionParam = UITemplate.getChangeConditionParam();
            if (conditionParam) {
                browserpanecommand({ target: UITemplate.strTargetLabel, url: "javascript: conditionParam=" + conditionParam });
            }
        } catch (err) {
            UITemplate.outputAlert(err);
        }
    }
}
 
try {
    // let ではなく寿命が残るvarである必要がある。
    // "BrowserPane"のところはレンダリングペインの種類ごとに必ず変更すること
    var objUITemplate = new UITemplate(
                        {
                           target: "_each", // 個別ブラウザであることを意味する
                           html: "BrowserPane.html"
                        }
                        );
} catch (err) {
    objUITemplate?._destructor();
    UITemplate.outputAlert(err);
}
 
} // js

HTML 側

test.mac
<!DOCTYPE html>
<html lang="ja">
<head>
<title>ボタンクリックサンプル</title>
<style>
@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: dark;
    }
    body {
        background-color:#222244;
    }
}
@media (prefers-color-scheme: light) {
    :root {
        color-scheme: light;
    }
    body {
        background-color:#eeeeff;
    }
}
</style>
</head>

<body>
1番目のパラメータ:<br>
&nbsp;<span id="input_1"></span>
<br>
2番目のパラメータ:<br>
&nbsp;<span id="input_2"></span>

<script>
// ボタンを取得
const btn_1 = document.getElementById("button_1");
// window.alert(btn_1);

let idCallback = 0;
// 現在のURLを取得
let url = new URL(window.location.href);
// パラメータを取得
let params = new URLSearchParams(url.search);
let strIDSomeParam = params.get('strIDSomeParam');
iDSomeParam = Number(strIDSomeParam);

let input_1 = document.getElementById("input_1");
let input_2 = document.getElementById("input_2");

if (iDSomeParam != null) {
    input_1.innerText = String(iDSomeParam);
}

let conditionParam = -1;
function tickFunction() {
    if (conditionParam >=0) {
        input_2.innerText = String(conditionParam);
    }
}
setInterval(tickFunction, 500);

</script>
</body>

</html>
    

注意点など