Zenモードで時計を表示する方法

  1. AutoHotkey v2を使って実現できたので紹介します。

    元々はWindows11のタスクバーの仕様変更により時計をカスタマイズするフリーソフトTTClockが使用できなくなり、代用としてタスクバー上に時計をオーバーライドするElevenClockやDigital Desktop Clockを使用しました。
    しかし、重かったのとAutoHotkey v2でも出来そうと試行錯誤したところ実現でき、たまたまMeryのZenモードでも表示されたままになることを発見しました。

    ;; TaskBarClock
    ;;
    TaskBarClock := Gui()
    TaskBarClock.Title := "TaskBarClock"
    TaskBarClock.MarginX := 8
    TaskBarClock.MarginY := 1
    TaskBarClock.BackColor := "000000"
    TaskBarClock.SetFont("s12", "Meiryo UI")
    TaskBarClock.Opt("+AlwaysOnTop -Border -Caption +Disabled +ToolWindow")
    ShowClock := TaskBarClock.Add("Text", "cFFFFFF", "2025/01/01 (Mon) 00:00 AM")
    SetTimer(UpdateClock, 15000)
    UpdateClock()
    TaskBarClock.Show("x" A_ScreenWidth-240 " y" A_ScreenHeight-28 " AutoSize NoActivate")
    ;;
    UpdateClock() {
    	ShowClock.Value := FormatTime(, "yyyy/MM/dd (ddd) HH:mm tt")
    }
    ;;
    MouseOver(title) {
        MouseGetPos ,, &id
        return WinExist(title " ahk_id " id)
    }
    ;;
    ClickClock(key_code) {
    	WinHide "TaskBarClock"
    	if (key_code) {
    		Send(key_code)
    	} else {
    		CoordMode("Mouse", "Screen")
    		MouseClick("left", A_ScreenWidth-160, A_ScreenHeight-16, 1)
    	}
    	WinShow "TaskBarClock"
    }
    ;;
    #HotIf MouseOver("TaskBarClock")
    	LButton::	ClickClock("{LButton}")					;; Show TaskBar Calender
    	RButton::	Run("control timedate.cpl")				;; Time & Date Properties
    #HotIf
     |  enaka  |  返信
  2. 情報ありがとうございます。

    > たまたまMeryのZenモードでも表示されたままになることを発見しました。

    なるほど、こうやればタスクバーや他のソフトに依存せずに表示できるんですね。…って、そんなの発見しないでください~😅

    でも、プログラムが苦手な方もいると思うので、そういう時はサクッと使える公式の Zen モード時計 プラグインもありますよ (白目)

    • インストールするだけで表示
    • フォントや位置も簡単に設定可能
    • アナログ時計なども選べます

    共有いただいた方法も面白いので、興味がある方は両方試してみてくださいね♪

    それにしても、AutoHotkey って本当に何でもできちゃいますね。

    Mery へのちょっとしたご要望も、AHK を使えば意外と簡単に解決できるものが結構ありそうですね。

     |  Kuro  |  返信
  3. > でも、プログラムが苦手な方もいると思うので、そういう時はサクッと使える公式の [Zen モード時計 プラグイン](https://mery.booth.pm/items/4420344)もありますよ (白目)

    存じ上げませんでした。シンプルなアナログ時計いいですね。Zenモード以外でも使いたい。

    > それにしても、AutoHotkey って本当に何でもできちゃいますね。

    時計の副産物で常に最前面のコントロールもAutoHotkey v2で出来てしまいました。さよなら、最前面でポーズ。

    ;; Always On Top
    ;;
    AlwaysOnTop() {
    	MouseGetPos(,, &id)
    	WinActivate(id)
    	WinSetAlwaysOnTop(-1, id)
    	ExStyle := WinGetExStyle(id)
    	if (ExStyle & 0x8)
    		ToolTip "常に最前面 【ON】"
    	else
    		ToolTip "常に最前面 【OFF】"
    	SetTimer(ToolTip, -3000)
    }
    ;;
    Pause::	AlwaysOnTop()
    ;;

    > Mery へのちょっとしたご要望も、AHK を使えば意外と簡単に解決できるものが結構ありそうですね。

    F3が遠いのでAutoHotkey v2により、Emacs検索風に検索/置換ダイアログ呼出と次候補/前候補を、C-S/C-Rに同居するというのを実現しています。
    簡単なので興味がある人への宿題ということで。

     |  enaka  |  返信
  4. 最前面でポーズは PowerToys に乗り換えました。境界線 4px の設定で、最前面であることがはっきりわかります。
    enaka さんなら境界線も AHK で実装してしまうかもですが。

     |  TN24  |  返信
  5. >> enaka さん

    > 存じ上げませんでした。シンプルなアナログ時計いいですね。Zenモード以外でも使いたい。

    以前にも今回と似た話題があって、そのときにちょっと遊びで試作してみたんですよね。

    【参考】Zenモードに時計を追加できないか
    https://www.haijin-boys.com/discussions/6246

    ↑ ダウンロードリンクもありますが、当時のものはけっこう簡易版で、設定も INI ファイルを直接編集するしかありませんでした。

    BOOTH 版では、画面上から設定できるようになっていて、ドラッグ アンド ドロップで移動できたり、タイマー機能も追加されています。

    たしか「Zen らしく音で通知せず、視覚的にこっそり知らせてほしい」というご要望に応えて、Windows 95 のラインアート風通知やバイナリ時計など、ちょっとマニアックな機能も詰め込みましたw

    > 時計の副産物で常に最前面のコントロールもAutoHotkey v2で出来てしまいました。さよなら、最前面でポーズ。

    最前面でポーズ、ついに小粒アプリから卒業ですね…。

    それにしても、AHK のコード、すごくシンプル!これならアプリを使うより軽くて安心ですね。

    >> TN24 さん

    > 最前面でポーズは PowerToys に乗り換えました。境界線 4px の設定で、最前面であることがはっきりわかります。

    Mery でも、[タイトル バーとウィンドウの境界線を強調表示する] をオンにすると、最前面時に PowerToys みたいに境界線を色付きで表示できるのですが、この機能は残念ながら Windows 11 限定なんですよね…。

    私も以前は PowerToys を使っていたのですが、うちの低スペック PC ではちょっと重くて。

    そこで、「なんちゃって PowerToys」的な境界線表示機能を Mery に実装してみました。Windows 11 に移行されたときは、ぜひ試してみてください〜。

     |  Kuro  |  返信
  6. >enaka さんなら境界線も AHK で実装してしまうかもですが。

    試行錯誤したところ実装出来ました。AHK関数だけでは無理だったため、DllCallを用いています。
    自分仕様ということで、ダイアログを含めたアクティブなウィンドウに太枠をつけ、常に最前面だった場合には色を変更、としています。
    複数ウィンドウ対応等、好きにカスタマイズしてください。

    > Mery でも、[タイトル バーとウィンドウの境界線を強調表示する] をオンにすると、最前面時に PowerToys みたいに境界線を色付きで表示できるのですが、この機能は残念ながら Windows 11 限定なんですよね…。

    Windows10にも対応しました。Windows11ならばDllCallでCreateRectRgnの代わりにCreateRoundRectRgnを使うと角が丸く出来ます。

    ;; GroupAdd must be written before any Hotkey bindings.
    ;;
    GroupAdd("Invalid", "ActiveBorder")		;; AutoHotkey Script
    GroupAdd("Invalid", "TaskBarClock")		;; :
    GroupAdd("Invalid", "ahk_exe RetroBar.exe")	;; WindowsXP like Task Bar
    GroupAdd("Invalid", "ahk_exe StartMenuX.exe")	;; WindowsXP like Start Menu
    ;;
    CheckValid(id) {
    	if (WinExist(id) == 0)
    		return 0
    	for invalid_id in WinGetList("ahk_group Invalid")
    		if (id == invalid_id)
    			return 0
    	return 1
    }
    ;;
    ;; ActiveBorder
    ;;
    global aot_color := "FF0000"
    global act_color := "FFFFFF"
    global act_name := "ActiveBorder"
    global act_width := 4
    global act_preid := 0
    global act_X, act_Y, act_W, act_H
    ActiveBorder := Gui()
    ActiveBorder.Title := act_name
    ActiveBorder.BackColor := act_color
    ActiveBorder.Opt("+AlwaysOnTop -Caption +ToolWindow +E0x20")
    ActiveBorder.Show("NoActivate")
    global act_id := WinExist(act_name)
    SetTimer(UpdateBorder, 500)
    UpdateBorder()
    ;;
    UpdateBorder() {
    	global act_preid, act_X, act_Y, act_W, act_H
    	global act_color, top_color, act_id
    	id := WinExist("A")
    	if (CheckValid(id) == 0) {
    		ActiveBorder.Hide
    		return
    	}
    	Style := WinGetStyle(id)
    	if (Style & 0x20000000) {
    		ActiveBorder.Hide
    		return
    	}
    	ExStyle := WinGetExStyle(id)
    	if (ExStyle & 0x8)
    		ActiveBorder.BackColor := aot_color
    	else
    		ActiveBorder.BackColor := act_color
    	WinGetPos(&X, &Y, &W, &H, id)
    	if (act_preid == id && act_X == X && act_Y == Y && act_W == W && act_H == H)
    		return
    	act_preid := id
    	act_X := X
    	act_Y := Y
    	act_W := W
    	act_H := H
    	outRect := DllCall("CreateRectRgn", "Int", 0, "Int", 0, "Int", W, "Int", H)
    	inRect := DllCall("CreateRectRgn", "Int", act_width, "Int", act_width, "Int", W - act_width, "Int", H - act_width)
    	actRect := DllCall("CreateRectRgn", "Int", 0, "Int", 0, "Int", 0, "Int", 0, "Ptr")
    	DllCall("CombineRgn", "Ptr", actRect, "Ptr", outRect, "Ptr", inRect, "Int", 4)
    	DllCall("SetWindowRgn", "Ptr", ActiveBorder.Hwnd, "Ptr", actRect, "Int", 1)
    	DllCall("DeleteObject", "Ptr", outRect)
    	DllCall("DeleteObject", "Ptr", inRect)
    	ActiveBorder.Show("x" X " y" Y " w" W " h" H " NoActivate")
    }
     |  enaka  |  返信
  7. 本当に実装されるとは。いやー恐れ入りました。
    確かに PowerToys は全体的に軽いとはいえないので、Always On Top のみの使用なら AHK に乗り換えたいところです。私は FancyZones も使っているので、当面は手放せません。

     |  TN24  |  返信
  8. >私は FancyZones も使っているので、当面は手放せません。

    すでにAHK v1で実装した方がおられるようです。v2には要修正かなあ。
    https://github.com/jgpaiva/GridMove

    軽量な代替アプリもあるようです。
    http://windowgrid.net

    自分は、WindowsSnapすら無効化してWin+Up/Downだけ実装し、また、逆順のタスクスイッチが3つ同時キー押しが辛いので変更しています。

    ;; Window Switch and Resize
    ;;
    WinSize(cur) {
    	global previous_id
    	if WinExist(previous_id) {
    		if (WinGetMinMax(previous_id) == -1 && cur == "up") {
    			WinActivate(previous_id)
    			for id in WinGetList() {
    				if CheckValid(id) {
    					if (WinGetMinMax(id) == -1) {
    						previous_id := id
    					}
    				}
    			}
    			return 0
    		}
    	}
    	id := WinExist("A")
    	if CheckValid(id) {
    		if (WinGetMinMax(id) == 0 && cur == "up") {
    			WinMaximize(id)
    			return 0
    		}
    		if (WinGetMinMax(id) == -1 && cur == "up") {
    			WinActivate(id)
    			return 0
    		}
    		if (WinGetMinMax(id) == 0 && cur == "down") {
    			WinMinimize(id)
    			previous_id := id
    			return 0
    		}
    		if (WinGetMinMax(id) == 1 && cur == "down") {
    			WinRestore(id)
    			return 0
    		}
    	}
    }
    ;;
    RWin & Enter::	Send("#{Tab}{Rwin up}")	;; Windows Task View
    LWin & Enter::	Send("#{Tab}{Rwin up}")
    ;;
    Alt & Esc::	ShiftAltTab
    RWin & Left::	ShiftAltTab
    LWin & Left::	ShiftAltTab
    ;;
    Alt & Tab::	AltTab
    RWin & Right::	AltTab
    LWin & Right::	AltTab
    ;;
    RWin & Esc::	Send("!{Esc}{Rwin up}")
    LWin & Esc::	Send("!{Esc}{Lwin up}")
    ;;
    RWin & Tab::	Send("!+{Esc}{Rwin up}")
    LWin & Tab::	Send("!+{Esc}{Lwin up}")
    ;;
    RWin & Up::	WinSize("up")
    LWin & Up::	WinSize("up")
    RWin & Down::	WinSize("down")
    LWin & Down::	WinSize("down")
    ;;
    Ctrl & Esc::	Send("^+{Tab}")
    Ctrl & Tab::	Send("^{Tab}") 
    ;;
    #t::	Run("taskmgr")		;; Task Manager
    #+t::	Run("taskschd.msc")	;; Task Schedule
    #w::	Send("#{Tab}{Rwin up}")	;; Windows Task View
     |  enaka  |  返信
スポンサーリンク