Escrcpy开始投屏时窗口设定与电脑输入法自动屏蔽脚本

我的更多帖子

原因

因为Escrcpy点击投屏时,默认是电脑的屏幕居中,然后窗口的高度也不是屏幕的高度。我认为这样对于屏幕的利用是不高的。所以,我需要它一投屏就在屏幕的最左边且窗口的高度是和屏幕的高度是一致的。

方法

  1. 利用Power Toys布局,按住Shift键就把投屏窗口变成我想要的样式。
  2. Escrcpy设置中本身就有这个设定的:偏好设置>窗口控制
    显然,方法2可以比方法1可以少一步的操作。

Escrcpy窗口控制的设定

  1. 先要知道自己的显示分辨率:桌面右键>显示设置>显示分辨率
  2. 知道软件窗口的尺寸的方法:我用PixPin截图工具,当你框选后右上角会显示是象素尺寸
  3. 设定窗口的宽度与高度
    a. 填写的高度=屏幕的高度-边框条的高度(如果你是无边框就不用减,边框条的高度就是先投屏再用Pixpin来量出高度)
    b. 填写的宽度=先投屏并调整尺寸,然后用Pixpin来量出宽度
  4. 设定窗口坐标
    先说明,设定里说相对于桌面中心是不正确的。实际上就是屏幕左上角为原点(0,0)
    a. 纵坐标=边框条的高度(按道理不填写的话,窗口的边框条应该是紧贴屏幕的边缘,实际上边框条有一半被屏幕遮挡了)
    b. 横坐标=0(因为我要窗口在最左边,填0就可以了)

AHK电脑输入法自动屏蔽脚本

投屏的时候,我有使用物理键盘在手机输入的需求。于时,我做了两件事

  1. 自定义了一个"中文输入法"的皮肤,这样的好处是虚拟键盘不会占据屏幕太多的空间。然后又可以方便输入emoji与特殊符号
  2. 使用ChatGPT写了一个AHK脚本,只要是包含Escrcpy字符的窗口,都会自动按下快捷键Ctrl+\,一离开包含Escrcpy字符的窗口,就再自动按一次Ctrl+\。(我使用的输入法是Bime,虎码输入方案)

image.png

以下为该AHK代码

#Persistent
SetTitleMatchMode, 2 ; 启用部分匹配
prevWasScrcpy := false

SetTimer, CheckWindow, 300
return

CheckWindow:
WinGetTitle, currentWinTitle, A

if (InStr(currentWinTitle, "scrcpy")) {
    if (!prevWasScrcpy) {
        Send, !\
        prevWasScrcpy := true
    }
} else {
    if (prevWasScrcpy) {
        Send, !\
        prevWasScrcpy := false
    }
}
return
2 个赞

很有意思的想法,但我是直接用命令行启动 Scrcpy 的,并且不需要手动处理输入法虚拟键盘,所以我稍微修改了一下功能:

  1. VBS 脚本一键启动 Scrcpy 并运行 AHK 脚本
  2. 兼容多显示器场景,窗口会在它创建时所在的显示器内移动
  3. 允许自定义移动到左边缘还是右边缘
  4. 通过 Scrcpy 模拟物理键盘,在支持的输入法中会自动隐藏虚拟键盘

代码如下,有需自取:

VBS 脚本

' scrcpy 程序路径
scrcpyProgramPath = "scrcpy.exe"
' scrcpy 启动参数
scrcpyArguments = "-m 1920 -b 30M --max-fps=60 --no-audio --stay-awake --turn-screen-off --power-off-on-close --keyboard=uhid --mouse-bind=bnsh:++++ --shortcut-mod=ralt"
scrcpy = """" & scrcpyProgramPath & """ " & scrcpyArguments

' ahk 程序路径
ahkProgramPath = "C:\Program Files\AutoHotkey\v2\AutoHotkey.exe"
' ahk 脚本路径
ahkFilePath = "C:\Users\user\scrcpy.ahk"
ahk = """" & ahkProgramPath & """ """ & ahkFilePath & """"

CreateObject("Shell.Application").ShellExecute "cmd.exe", "/c " & scrcpy, "", "", 0
CreateObject("WScript.Shell").Run ahk, 0, False

AHK 脚本

#requires AutoHotkey v2.0

#SingleInstance Force
SendMode("Input")
SetWorkingDir(A_ScriptDir)
SetTitleMatchMode(2)
FileEncoding("UTF-8")

global DWMWA_EXTENDED_FRAME_BOUNDS := 9

class Monitor {
    static getCount() {
        return MonitorGetCount()
    }

    static getIndexByWindow(title := "A") {
        local rect := getWindowRect(title)
        local borders := []
        loop Monitor.getCount() {
            borders.Push(Monitor.getRectByIndex(A_Index))
        }

        ; 先按窗口中心点的坐标确定在哪个显示器上
        local centerX := rect.x + rect.w / 2
        local centerY := rect.y + rect.h / 2
        for (i, v in borders) {
            if (centerX >= v.l && centerX <= v.r && centerY >= v.t && centerY <= v.b) {
                return i
            }
        }
        ; 再按窗口左上角点的坐标确定在哪个显示器上
        for (i, v in borders) {
            if (rect.x >= v.l && rect.x <= v.r && rect.y >= v.t && rect.y <= v.b) {
                return i
            }
        }
    }

    static getRectByIndex(index) {
        local l := 0
        local t := 0
        local r := 0
        local b := 0
        MonitorGet(index, &l, &t, &r, &b)

        local w := Abs(r - l)
        local h := Abs(b - t)

        return { l: l, t: t, r: r, b: b,
            x: l, y: t, w: w, h: h }
    }

    static getWorkAreaRectByIndex(index) {
        local l := 0
        local t := 0
        local r := 0
        local b := 0
        MonitorGetWorkArea(index, &l, &t, &r, &b)

        local w := Abs(r - l)
        local h := Abs(b - t)

        return { l: l, t: t, r: r, b: b,
            x: l, y: t, w: w, h: h }
    }
}

getWindowRect(title := "A") {
    local x := 0
    local y := 0
    local w := 0
    local h := 0

    try {
        WinGetPos(&x, &y, &w, &h, title)
    }

    return { x: x, y: y, w: w, h: h }
}

getWindowRealRect(title := "A") {
    local x := 0
    local y := 0
    local w := 0
    local h := 0

    local rect := Buffer(16, 0)
    try {
        DllCall("dwmapi\DwmGetWindowAttribute",
            "Ptr", WinExist(title),
            "UInt", DWMWA_EXTENDED_FRAME_BOUNDS,
            "Ptr", rect,
            "UInt", rect.size,
            "UInt")
        x := NumGet(rect, 0, "Int") - x
        y := NumGet(rect, 4, "Int") - y
        w := NumGet(rect, 8, "Int") - x
        h := NumGet(rect, 12, "Int") - y
    } catch {
        return { x: x, y: y, w: w, h: h }
    }

    return { x: x, y: y, w: w, h: h }
}

moveAndResize(title := "A", edge := "left") {
    local status := 1
    try {
        status := WinGetMinMax(title)
    }
    if (status != 0) {
        return
    }

    local rect := getWindowRect(title)
    local real := getWindowRealRect(title)
    local area := Monitor.getWorkAreaRectByIndex(Monitor.getIndexByWindow(title))

    local ratio := real.w / real.h
    local xShadowW := real.x - rect.x
    local yShadowH := (rect.h - real.h) / 2

    local w := area.h * ratio + (xShadowW + 1) * 2
    local h := area.h + (yShadowH + 1) * 2
    local x := edge == "left" ? area.l - (xShadowW + 1) : area.r - w
    local y := area.t - 1

    WinMove(x, y, w, h, title)
}

; 使用示例
; 该示例查找 scrcpy.exe 程序所创建的首个窗口,如果使用的不是 scrcpy.exe,则需要修改查找条件
global hwnd := WinWait("ahk_exe scrcpy.exe", , 5)
if (hwnd) {
    moveAndResize("ahk_id" . hwnd, "left")
} else {
    MsgBox("Scrcpy 未启动或未找到窗口")
}
2 个赞

这个中文输入法皮肤是fcitx5 android可以自定义的吗?求教程分享

据我所知,小企鹅输入法是不能自已写皮肤与布局的。