Skip to content

Instantly share code, notes, and snippets.

@ch-yx
Created July 11, 2024 17:41
Show Gist options
  • Save ch-yx/ee85b2c7a9375ff832df469e5b532134 to your computer and use it in GitHub Desktop.
Save ch-yx/ee85b2c7a9375ff832df469e5b532134 to your computer and use it in GitHub Desktop.
import pygame
import clr
import sys
import ctypes
from ctypes import POINTER, WINFUNCTYPE, windll
from ctypes.wintypes import BOOL, HWND, RECT, UINT, LPARAM, WPARAM
from threading import Thread
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
from System.Windows.Forms import Form, Application, TextBox, DockStyle, FormBorderStyle
from System.Drawing import Color, Font, FontStyle
from System.Windows.Forms import ControlStyles,BorderStyle
# Define some constants
WS_EX_LAYERED = 0x00080000
LWA_COLORKEY = 0x00000001
LWA_ALPHA = 0x00000002
import pygame
import clr
import sys
import ctypes
from ctypes import POINTER, WINFUNCTYPE, windll
from ctypes.wintypes import BOOL, HWND, RECT, UINT, LPARAM, WPARAM, HDC, DWORD, BYTE, LONG
from threading import Thread
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
from System.Windows.Forms import Form, Application, TextBox, DockStyle, FormBorderStyle, Keys, BorderStyle, ControlStyles
from System.Drawing import Color, Font, FontStyle, Bitmap, Graphics, Point, Size, Image
# Define some constants
WS_EX_LAYERED = 0x00080000
ULW_COLORKEY = 0x00000001
ULW_ALPHA = 0x00000002
ULW_OPAQUE = 0x00000004
AC_SRC_OVER = 0x00
AC_SRC_ALPHA = 0x01
class BLENDFUNCTION(ctypes.Structure):
_fields_ = [("BlendOp", BYTE),
("BlendFlags", BYTE),
("SourceConstantAlpha", BYTE),
("AlphaFormat", BYTE)]
class CustomTextBox(TextBox):
def __init__(self):
super().__init__()
self.AllowTransparency = True
self.SetStyle(ControlStyles(131072), True) # Enable double buffering
self.SetStyle(ControlStyles(8192), True)
self.SetStyle(ControlStyles.SupportsTransparentBackColor, True) # Enable transparency
#self.SetStyle(ControlStyles(4), False)
self.BackColor = Color.FromArgb(0, 12, 250, 56) # Brown with 50% opacity
self.ForeColor = Color.Purple
self.Font = Font("Arial", 20, FontStyle.Bold)
self.BorderStyle = BorderStyle(0)
self.Multiline = True
class LayeredForm(Form):
def __init__(self):
super().__init__()
self.Width = 200
self.Height = 100
self.FormBorderStyle = FormBorderStyle(0)
self.MaximizeBox = False
self.MinimizeBox = False
self.TopLevel = False
self.AllowTransparency = True
self.textbox = CustomTextBox()
self.textbox.Dock = DockStyle.Fill
self.Controls.Add(self.textbox)
self.Load += self.on_load
#self.Shown += self.on_shown
def on_load(self, sender, event):
self.AllowTransparency = True
self.SetStyle(ControlStyles(131072), True) # Enable double buffering
self.SetStyle(ControlStyles(8192), True)
self.SetStyle(ControlStyles.SupportsTransparentBackColor, True) # Enable transparency
#self.SetStyle(ControlStyles(4), False)
# Set layered window attributes
happ = self.Handle.ToInt64()
exstyle = ctypes.windll.user32.GetWindowLongPtrA(happ, -20)
exstyle |= WS_EX_LAYERED
ctypes.windll.user32.SetWindowLongPtrA(happ, -20, exstyle)
ctypes.windll.user32.SetLayeredWindowAttributes(happ, 0, 1, LWA_ALPHA)####alpha here
self.BackColor = Color.FromArgb(0, 0, 0, 0) # Fully transparent
self.TransparencyKey = Color.FromArgb(0, 0, 0, 0) # Fully transparent
def on_shown(self, sender, event):
self.BackColor = Color.FromArgb(0, 0, 0, 0) # Fully transparent
self.TransparencyKey = Color.FromArgb(0, 0, 0, 0) # Fully transparent
self.Opacity=0.001
def run(self):
Thread(target=lambda: Application.Run(self)).start()
def Close(self):
data = self.textbox.Text
super().Close()
return data
def update_layered_window(self,screen):
happ = self.Handle.ToInt64()
hdc = ctypes.windll.user32.GetDC(self.pygame_window_handle)
memdc = ctypes.windll.gdi32.CreateCompatibleDC(hdc)
bitmap = Bitmap(self.Width, self.Height)
#graphics = Graphics.FromImage(bitmap)
#graphics.Clear(self.BackColor)
if False:
########
happ = self.Handle.ToInt64()
exstyle = ctypes.windll.user32.GetWindowLongPtrA(happ, -20)
exstyle |= WS_EX_LAYERED
ctypes.windll.user32.SetWindowLongPtrA(happ, -20, exstyle)
ctypes.windll.user32.SetLayeredWindowAttributes(happ, 0, 1, LWA_ALPHA)
#####
self.textbox.DrawToBitmap(bitmap, self.textbox.Bounds)
x,y=self.posinpygame
for i in range(self.Height):
for j in range(self.Width):
color=bitmap.GetPixel(j,i)
if 12==color.R and 250 == color.G and 56 == color.B:
pass
else:
screen.set_at((j+x,i+y),color.ToArgb())
######
"""
#####
hbmp = bitmap.GetHbitmap(self.BackColor).ToInt64()
oldbmp = ctypes.windll.gdi32.SelectObject(memdc, hbmp)
if 1:
blend = BLENDFUNCTION()
blend.BlendOp = AC_SRC_OVER
blend.BlendFlags = 0
blend.SourceConstantAlpha = 150
blend.AlphaFormat = AC_SRC_ALPHA
class chyxpoint(ctypes.Structure):
_fields_ = [("x", LONG),
("y", LONG)]
ctypes.windll.user32.UpdateLayeredWindow(happ, hdc, ctypes.byref(chyxpoint(20,20)), ctypes.byref(ctypes.wintypes.SIZE(self.Width, self.Height)),
memdc, ctypes.byref(ctypes.wintypes.POINT(0, 0)), 0, ctypes.byref(blend), ULW_ALPHA)
"""
""" ctypes.windll.gdi32.SelectObject(memdc, oldbmp)
ctypes.windll.gdi32.DeleteObject(hbmp)
ctypes.windll.gdi32.DeleteDC(memdc)
ctypes.windll.user32.ReleaseDC(0, hdc) """
def create_layered_form(pygame_window_handle, pos):
pygame_window_handle = pygame_window_handle.get_wm_info()['window']
app = LayeredForm()
happ = app.Handle.ToInt64()
app.pygame_window_handle=pygame_window_handle
app.posinpygame=pos
# Set the parent to None to avoid issues with transparency
ctypes.windll.user32.SetParent(happ, pygame_window_handle)
# Set the position and size of the layered window
ctypes.windll.user32.SetWindowPos(
happ,
0, # HWND_TOP
pos[0], pos[1],
200, # Width
100, # Height
0x0040 # SWP_SHOWWINDOW
)
app.run()
return app
if __name__ == "__main__":
pygame.init()
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption('Pygame with WinForms Example')
textbox = create_layered_form(pygame.display, (40, 80))
clock = pygame.time.Clock()
running = True
while running:
screen.fill("green")
pygame.draw.rect(screen, "red", pygame.Rect(30, 30, 60, 60))
textbox.update_layered_window(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
print(textbox.Close())
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment