在 QB64 中捕获 Alt-F4

Posted

技术标签:

【中文标题】在 QB64 中捕获 Alt-F4【英文标题】:Trap Alt-F4 in QB64 【发布时间】:2018-03-30 02:22:18 【问题描述】:

我有一个实用程序,它有一个由 Alt-F4 调用的函数,但我不能,因为它会关闭窗口。 QB64中如何捕获Alt-F4?

以下代码示例显示了检查 Alt-F4 的各种方法:

REM Trap Alt-F4 in QB64
DO
    _LIMIT 100
    x$ = INKEY$
    IF x$ = CHR$(27) THEN END
    IF LEN(x$) = 2 THEN
        IF ASC(RIGHT$(x$, 1)) = 107 THEN
            PRINT "Alt-F4"
        END IF
    END IF
LOOP
END

也试过这个没有效果:

KEY 15, CHR$(8) + CHR$(62)
ON KEY(15) GOSUB KeyTrap
KEY(15) ON
DO
    _LIMIT 100
    x$ = INKEY$
    IF x$ = CHR$(27) THEN END
LOOP
END
KeyTrap:
PRINT "Alt-F4"
RETURN

还尝试将 Alt-F4 困在 _EXIT 陷阱中,但没有结果:

' start timer trap.
ON TIMER(1) GOSUB Timer.Trap
TIMER ON
VarQ = _EXIT
DO
    _LIMIT 100
LOOP
END
' timer ctrl-break trap.
Timer.Trap:
VarQ = _EXIT
_DELAY 1
IF VarQ THEN ' Control-Break
    x$ = INKEY$
    IF LEN(x$) = 2 THEN
        IF ASC(RIGHT$(x$, 1)) = 107 THEN
            PRINT "Alt-F4"
            RETURN
        END IF
    END IF
    CLS
    SYSTEM
END IF
RETURN

另一种可能的捕获 Alt-F4 的方法:

只有这样才能检查更多的键击。

CONST KEY_RALT& = 100307
CONST KEY_LALT& = 100308
' start timer trap.
ON TIMER(1) GOSUB Timer.Trap
TIMER ON
VarQ = _EXIT
DO
    _LIMIT 100
LOOP
END
' timer ctrl-break trap.
Timer.Trap:
VarQ = _EXIT
_DELAY 1
IF VarQ THEN ' Control-Break
    x = _KEYHIT
    IF x = CVI(CHR$(0) + CHR$(62)) THEN ' F4
        IF _KEYDOWN(KEY_RALT&) OR _KEYDOWN(KEY_LALT&) THEN
            PRINT "Alt-F4"
            RETURN
        END IF
    END IF
    CLS
    SYSTEM
END IF
RETURN

还有一个使用内存地址检查的示例代码:

同样,它也不会捕获 Alt-F4:

DO
    _LIMIT 30
    b$ = INKEY$
    IF LEN(b$) THEN
        IF b$ = CHR$(27) THEN END
        DEF SEG = 0
        IF PEEK(1047) MOD 16 = 8 THEN
            IF b$ = CHR$(0) + "k" THEN
                PRINT "Alt-F4"
            END IF
        END IF
        DEF SEG
    END IF
LOOP

【问题讨论】:

Alt-F4 的行为由 Windows 控制。我发现的一个建议是remove the Close option from the window's system menu(请参阅第一个DisableCloseButton 函数;在您的情况下,hwnd 将被GetForegroundWindow() 替换)。顺便说一句,PEEK 解决方案不起作用,因为 QB64 的 16 位内存是模拟的,这意味着您正在读取内存,而不是硬件状态。当然,即使它有效,您仍然需要在窗口消息循环处理按键之前阅读它(因为多线程)。 MSDN 说只启用/禁用关闭/最小化/最大化。我不想改变那些,只告诉QB64不要陷进Alt-F4。 在这种情况下,您可能可以捕获一条消息,例如 WM_KEYDOWN;理论上,它会出现在WM_SYSCOMMAND 之前,允许您过滤该按键,因此WM_SYSCOMMAND 消息永远不会通过Alt-F4 与SC_CLOSE 一起传递。捕获按键的类似选项可能是RegisterHotKey。然而,我从来不需要这个特殊的功能,所以我不能确定这需要多少 C 代码,如果有的话,甚至你是否需要为新的消息循环或其他东西启动自己的线程,只是为了捕获按键。 为什么一定要alt-F4?作为软件开发人员,您应该针对潜在用户的需求进行编码,我认为典型用户不会对劫持 Windows 快捷键的应用程序感到满意。最快、最好的(在我 35 多年的开发经验中)的建议是选择另一个快捷键。 Esc 怎么样 :) 我曾经(几十年前)没有找到工作,因为我处理的遗留代码使用 F1 作为转义键(中止),招聘经理说每个人都知道 F1 是为了寻求帮助。是的,我知道,但我的客户十年来一直在使用 F2 寻求帮助。我只是同情而已。 【参考方案1】:

我相信答案很简单:

全屏运行。

Alt+Enter 或更改您的程序设置。我忘记了 Alt+F4 的 chr$ 代码是什么,但我很确定它是 CHR$(0) + CHR$(x) 格式。

希望这会有所帮助!

【讨论】:

Alt-Enter 对 Alt-F4 没有影响,它们都被 Windows 困住了 Alt+Enter 是否全屏显示?自从我使用 Qbasic 以来已经有好几年了,而且我没有方便的 Windows 安装。我几乎 100% 肯定我成功地捕捉到了它,但我也知道我总是全屏运行。此外,它让我很震惊,我想我使用的是 QB32。 Alt-Enter 进入全屏与Alt-F4 关闭窗口有什么关系? 使用我使用的Qbasic版本,当程序全屏时,Windows不会捕获那么多的关键命令。因此,Alt+F4 将无法被 Windows 捕获,我可以在 Qbasic 中捕获它。 Alt+Enter 只是将 Qbasic 置于全屏状态的键命令 (IIRC) 好吧,不知道。尽管如此,我的用户必须全屏显示关闭窗口仍然没有任何意义。

以上是关于在 QB64 中捕获 Alt-F4的主要内容,如果未能解决你的问题,请参考以下文章

32 位程序无法捕获在 32 位进程上进行的击键,但能够捕获在 64 位进程上进行的击键

使用 Spyder 3.3 无法在 input() 中捕获 Ctrl+C

在 64 位机器上捕获的 32 位进程的调试转储

在 PhoneGap 中读取图像捕获文件

保存捕获的图像时出现 JavaCV 错误

kmplayerX64 怎么打开OSD?