2

I've gone through several other posts regarding similar issues and all seem to point to this code. Since, I'm working on creating a desktop overlay, I setup a short program to create a top window and hopefully isolate the issue but, despite my efforts I can't figure out why this seemingly widely accepted solution is failing for me or what I could be missing.

I've verified that the handle being retrieved is referencing the correct window, trimmed away unnecessary functions, and explored other variations of setting window styles through personal trial and error and mimicking some examples found through programcreek.com.

from tkinter import *
from PIL import Image, ImageTk
from win32gui import GetForegroundWindow, ShowWindow, FindWindow,
                     SetWindowLong, GetWindowLong
from win32con import SW_MINIMIZE, WS_EX_LAYERED, WS_EX_TRANSPARENT, GWL_EXSTYLE

def setClickthrough(root, window="Applepie"):
    hwnd = FindWindow(None, window)
    styles = GetWindowLong(hwnd, GWL_EXSTYLE)
    styles |= WS_EX_LAYERED | WS_EX_TRANSPARENT
    print(SetWindowLong(hwnd, GWL_EXSTYLE, styles))

# Dimensions
width = 1920 #self.winfo_screenwidth()
height = 1080 #self.winfo_screenheight()

root = Tk()
root.geometry('%dx%d' % (width, height))
root.title("Applepie")
root.attributes('-transparentcolor', 'white', '-topmost', 1)
root.config(bg='white') 
root.attributes("-alpha", 0.25)
root.wm_attributes("-topmost", 1)
root.bg = Canvas(root, width=width, height=height, bg='white')

setClickthrough(root)

frame = ImageTk.PhotoImage(file="Resources/Test/Test-0000.gif")
root.bg.create_image(1920/2, 1080/2, image=frame)
root.bg.pack()
root.mainloop()

The TkInter window was successfully made transparent and clickable-through using the solution provided by acw1668 using:

root.attributes('-transparentcolor', 'white', '-topmost', 1)
root.config(bg='white')
root.bg = Canvas(root, width=width, height=height, bg='white')

Problem persists with creating an image in the canvas. Need to be able to have additional images be clickable through as well:

frame = ImageTk.PhotoImage(file="Resources/Test/Test-0000.gif")
root.bg.create_image(1920/2, 1080/2, image=frame)
martineau
  • 119,623
  • 25
  • 170
  • 301
Matt
  • 49
  • 5
  • What did you want to do? – jizhihaoSAMA Apr 09 '20 at 05:30
  • You can use `root.attributes('-transparentcolor', 'white', '-topmost', 1)` and `root.config(bg='white')` to make a click-through window. It works in my Windows 10 running Python 3.8.2. – acw1668 Apr 09 '20 at 10:20
  • @acw1668 That does in fact make the window transparent and clickable-through but, as soon as I pack the canvas into it, the canvas is not clickable-through. Is there a way to propagate those attributes to the Canvas as well? – Matt Apr 09 '20 at 17:23
  • Set the background color of the canvas to white as well. – acw1668 Apr 09 '20 at 17:36
  • @acw1668 Ah... so I think my problem lies in the fact that I'm creating images on the canvas as part of the overlay and those are not becoming clickable through... Including something like this: `frame = ImageTk.PhotoImage(file="Resources/Test/Test-0000.gif")` and `root.bg.create_image(1920/2, 1080/2, image=frame)` – Matt Apr 09 '20 at 18:05

1 Answers1

2

Turns out the handle was not being captured properly using FindWindow and using alternatives such as root.frame() or root.winfo_id() did not match the handle of the window for some reason. By passing in the winfo_id() of the Canvas, I was able to get the below code to work:

    self.root.config(bg='#000000') 
    self.root.wm_attributes("-topmost", 1)
    self.root.attributes('-transparentcolor', '#000000', '-topmost', 1)

    print("Configuring bg")
    self.bg = Canvas(self.root, highlightthickness=0)
    self.setClickthrough(self.bg.winfo_id())

Calling:

def setClickthrough(self, hwnd):
    print("setting window properties")
    try:
        styles = GetWindowLong(hwnd, GWL_EXSTYLE)
        styles = WS_EX_LAYERED | WS_EX_TRANSPARENT
        SetWindowLong(hwnd, GWL_EXSTYLE, styles)
        SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA)
    except Exception as e:
        print(e)
Matt
  • 49
  • 5
  • I have exactly the same problem but I don't understand at all how you made it work, and what is "self" supposed to be ? – the shadow Feb 23 '23 at 12:42