前一陣子左眼發生視網膜裂孔,才覺得工作的用眼環境或許不是很好。
本來工作用兩台筆電。
一個14吋NB主要收信看信,有外接LCD 24吋,斜放在桌面右前方。
一個15吋NB放正前方工作。
15吋FHD看字有點吃力,骨董LCD 24吋是斜放著,偏光膜已雪花片片,想想對眼睛應該都不好。
另外有了小孩都得準時下班接小孩,中午時間也利用來工作,即使辦公室強制關燈休息一小時。
於是農曆過年期間就去家樂福搬了BenQ GC2870+Wit ScreenBar,打算對眼睛好一點。
現在兩台筆電都用HDMI接上28吋LCD,Keyboard/Mouse一直以來是透過J5create的資料傳輸線共用,按一下"Alt+S"就可以在兩台電腦間切換使用。
剩下的問題就是切換HDMI1和HDMI2啦。
BenQ的快捷鍵一點也不快捷,要換4~5下按鈕才能完成(我來設計的話最多按兩下完成,這才堪用吧?)。
Step1: 按下2號鍵,顯示各鍵功能。
Step2: 按下2號鍵,進入訊源選單。
Step3: 按下2號鍵,選擇HDMI2。
Step4: 按下3號鍵,確認切換HDMI2。
完成
實在是費時、費神、螢幕還會晃。
所幸顯示器有支援DDC/CI,可以透過軟體去實現切換。
這邊找到的是AutoHotkey這個軟體,我也是第一次用,摸索了一下。
可能有這個需求的人也不多,但希望可以幫到人。
主要內容參考Google來的文章:
https://www.reddit.com/r/AutoHotkey...her_ahk_forums/
下載AutoHotkey並安裝(快速安裝即可)
在"文件"資料夾建立AutoHotkey.ahk文字檔(沒有這個script檔,執行時只會出現help說明檔)
文字檔輸入以下文字,這個Script是透過"Alt+R"鍵,來回傳monitor handle的值(目前輸入源)。
代碼:
; Finds monitor handle
getMonitorHandle()
{
; Initialize Monitor handle
hMon := DllCall("MonitorFromPoint"
, "int64", 0 ; point on monitor
, "uint", 1) ; flag to return primary monitor on failure
; Get Physical Monitor from handle
VarSetCapacity(Physical_Monitor, 8 + 256, 0)
DllCall("dxva2\GetPhysicalMonitorsFromHMONITOR"
, "int", hMon ; monitor handle
, "uint", 1 ; monitor array size
, "int", &Physical_Monitor) ; point to array with monitor
return hPhysMon := NumGet(Physical_Monitor)
}
destroyMonitorHandle(handle)
{
DllCall("dxva2\DestroyPhysicalMonitor", "int", handle)
}
getMonitorInputSource()
{
handle := getMonitorHandle()
DllCall("dxva2\GetVCPFeatureAndVCPFeatureReply"
, "int", handle
, "char", 0x60 ;VCP code for Input Source Select
, "Ptr", 0
, "uint*", currentValue
, "uint*", maximumValue)
destroyMonitorHandle(handle)
return currentValue
}
;~ : Used to set the monitor source, I do not know what happens if you send it a value higher than the maximum.
;~ setMonitorInputSource(source)
{
handle := getMonitorHandle()
DllCall("dxva2\SetVCPFeature"
, "int", handle
, "char", 0x60 ;VCP code for Input Source Select
, "uint", source)
destroyMonitorHandle(handle)
}
; Msgbox with current monitor input source
!r::
msgbox % getMonitorInputSource()
return
前置作業: 開啟DDC/CI
前置作業: HDMI auto (非必要?)
前置作業: 將電腦輸出到 HDMI only (若是設"同步顯示"回傳值都是為0)
開啟AutoHotkey
在HDMI1時,按下Alt+R讀取目前monitor handle (Alt+R是我亂試的,我還沒研究script語法@@)
手動切換到HDMI2,按下Alt+R。
再手動切回HDMI1,記錄回傳值。
GC2870 回傳 HDMI1=17, HDMI2=18 (十進位)
修改 Script
刪除原來的所有內容,輸入以下(文章說要用十六進位輸入,請自行注意)
代碼:
; Finds monitor handle
getMonitorHandle()
{
; Initialize Monitor handle
hMon := DllCall("MonitorFromPoint"
, "int64", 0 ; point on monitor
, "uint", 1) ; flag to return primary monitor on failure
; Get Physical Monitor from handle
VarSetCapacity(Physical_Monitor, 8 + 256, 0)
DllCall("dxva2\GetPhysicalMonitorsFromHMONITOR"
, "int", hMon ; monitor handle
, "uint", 1 ; monitor array size
, "int", &Physical_Monitor) ; point to array with monitor
return hPhysMon := NumGet(Physical_Monitor)
}
destroyMonitorHandle(handle)
{
DllCall("dxva2\DestroyPhysicalMonitor", "int", handle)
}
; Used to change the monitor source
; [BenQ] GC2870
; D-Sub = ?
; HDMI1 = 17 (0x11)
; HDMI2 = 18 (0x12)
setMonitorInputSource(source)
{
handle := getMonitorHandle()
DllCall("dxva2\SetVCPFeature"
, "int", handle
, "char", 0x60 ;VCP code for Input Source Select
, "int", source)
destroyMonitorHandle(handle)
}
; Gets Monitor source
getMonitorInputSource()
{
handle := getMonitorHandle()
DllCall("dxva2\GetVCPFeatureAndVCPFeatureReply"
, "int", handle
, "char", 0x60 ;VCP code for Input Source Select
, "Ptr", 0
, "uint*", currentValue
, "uint*", maximumValue)
destroyMonitorHandle(handle)
return currentValue
}
;~ #IfWinActive
Pause::
if(getMonitorInputSource() != 0x11) ;if not HDMI1
setMonitorInputSource(0x11) ;switch to HDMI1
else
setMonitorInputSource(0x12) ;else switch to HDMI2
return
重新載入(或關閉程式,再重執行)
之後就按 Pause 鍵就可以快速切換 HDMI1/HDMI2 啦啦啦啦啦啦啦
# 完畢 #