问题描述
我正在玩视频游戏,我希望能够在游戏屏幕上放置一个文本计时器,就像它是游戏本身的一部分一样。
现在,我可以用任何一种语言编写程序,在屏幕上显示带有计时器的TextBox,但是如果运行它,则游戏进程(称为game.exe)“失去”了焦点,我得到了文本框由操作系统集中和交互。
是否可以选择显示来自整个不同过程的game.exe的文本“在最上面”?好像屏幕上有“层”。另外,此文字不应太难理解,不可点击或使game.exe进程失去重点。
这是我画的一个非常简单的例子:
非常感谢!
解决方法
使用带有python和tkinter的窗口技巧和一些Windows api解决了该问题。 诀窍是创建一个透明的不可单击的窗口,并将其始终置于顶部。 我基本上将this答案与一堆简单的东西结合在一起,例如删除窗口的边框并设置为自动全屏显示。
from tkinter import *
import time
import win32gui
import win32api
from win32api import GetSystemMetrics
# WIDTH = 500
# HEIGHT = 500
WIDTH = GetSystemMetrics(0)
HEIGHT = GetSystemMetrics(1)
LINEWIDTH = 1
TRANSCOLOUR = 'gray'
title = 'Virtual whiteboard'
global old
old = ()
global HWND_t
HWND_t = 0
tk = Tk()
# tk.title(title)
tk.lift()
tk.wm_attributes("-topmost",True)
tk.wm_attributes("-transparentcolor",TRANSCOLOUR)
tk.attributes('-fullscreen',True)
state_left = win32api.GetKeyState(0x01) # Left button down = 0 or 1. Button up = -127 or -128
canvas = Canvas(tk,width=WIDTH,height=HEIGHT,highlightthickness=0)
canvas.pack()
canvas.config(cursor='tcross')
canvas.create_rectangle(0,WIDTH,HEIGHT,fill=TRANSCOLOUR,outline=TRANSCOLOUR)
canvas.create_text(WIDTH/2,HEIGHT/2,fill="white",font="Arial 20",text="TEXT GOES HERE")
def putOnTop(event):
event.widget.unbind('<Visibility>')
event.widget.update()
event.widget.lift()
event.widget.bind('<Visibility>',putOnTop)
def drawline(data):
global old
if old !=():
canvas.create_line(old[0],old[1],data[0],data[1],width=LINEWIDTH)
old = (data[0],data[1])
def enumHandler(hwnd,lParam):
global HWND_t
if win32gui.IsWindowVisible(hwnd):
if title in win32gui.GetWindowText(hwnd):
HWND_t = hwnd
win32gui.EnumWindows(enumHandler,None)
tk.bind('<Visibility>',putOnTop)
tk.focus()
running = 1
while running == 1:
try:
tk.update()
time.sleep(0.01)
if HWND_t != 0:
windowborder = win32gui.GetWindowRect(HWND_t)
cur_pos = win32api.GetCursorPos()
state_left_new = win32api.GetKeyState(0x01)
if state_left_new != state_left:
if windowborder[0] < cur_pos[0] and windowborder[2] > cur_pos[0] and windowborder[1] < cur_pos[1] and windowborder[3] > cur_pos[1]:
drawline((cur_pos[0] - windowborder[0] - 5,cur_pos[1] - windowborder[1] - 30))
else:
old = ()
except Exception as e:
running = 0
print("error %r" % (e))