UpdateLayeredWindow in pywin32

L

livibetter

Hi!

I am trying to making an On-Screen Display, which is implemented by
wx.Frame.
Basically I created a wx.Frame with style like

super(OSDBase, self).__init__(parent, id, title,
style = wx.STAY_ON_TOP |
wx.FRAME_NO_TASKBAR |
wx.TRANSPARENT_WINDOW |
wx.NO_BORDER)
self.SetTransparent(128)

But if I try to draw an image with alpha channel(like PNG format), I
always get
a background behind this image. But I don't want the background.

Then I read this article, http://www.codeproject.com/csharp/OSDwindow.asp
The demo program is written in C#. I understand that I need to use
UpdateLayeredWindow to update visual content of a layered window.

But I always got an error:

Traceback (most recent call last):
File "osd_post.py", line 60, in <module>
osd.Update()
File "osd_post.py", line 56, in Update
2)
pywintypes.error: (87, 'UpdateLayeredWindow', 'The parameter is
incorrect.')

I am not sure did I use UpdateLayeredWindow correctly.

Any help would be appreciated.


My Python is 2.5, pywin32 is 210, wxPython is 2.8.1

UpdateLayeredWindow Function Help from MSDN:
http://msdn2.microsoft.com/en-us/library/ms633556.aspx

UpdateLayeredWindow Function Help from pywin32:
http://aspn.activestate.com/ASPN/do...win32/win32gui__UpdateLayeredWindow_meth.html

My source code:

"""pyitctrl - OSD"""
# Created Date : 2007/03/14
# Author: livibetter

import wx, winxpgui, win32con

class OSDBase(wx.Frame):
def __init__(self, parent, id, title):
super(OSDBase, self).__init__(parent, id, title,
style = wx.STAY_ON_TOP |
wx.FRAME_NO_TASKBAR |
wx.TRANSPARENT_WINDOW |
wx.NO_BORDER)
self.SetTransparent(128)

print hex(winxpgui.GetWindowLong(self.GetHandle(),
win32con.GWL_EXSTYLE))
print winxpgui.GetLayeredWindowAttributes(self.GetHandle())

self.img = wx.Image("icon.png")
self.bmp = self.img.ConvertToBitmap()
w, h = self.bmp.GetWidth(), self.bmp.GetHeight()
self.SetClientSize( (w, h) )

def Update(self):
print "Update"

screenDC = winxpgui.GetDC(winxpgui.GetDesktopWindow())
print screenDC
cScreenDC = winxpgui.CreateCompatibleDC(0)
print cScreenDC

(w, h) = self.GetSizeTuple()
bmp = wx.EmptyBitmap(w, h)
tmpDC = wx.MemoryDC()
tmpDC.SelectObject(bmp)
tmpDC.SetBackground(wx.Brush("BLACK"))
tmpDC.Clear()
tmpDC.DrawBitmap(self.bmp,0,0, True)
tmpDC.Destroy()
del tmpDC

winxpgui.SelectObject(cScreenDC, bmp.GetHandle())

winxpgui.UpdateLayeredWindow(self.GetHandle(),
screenDC,
self.GetPositionTuple(),
self.GetSizeTuple(),
cScreenDC,
(0,0),
0,
(0,0,128,1),
win32con.ULW_ALPHA)

app = wx.App(False)
osd = OSDBase(None, wx.ID_ANY, 'OSD Frame')
osd.Update()
osd.Show()

app.MainLoop()
 
L

livibetter

I have found the cause

"Please note that after SetLayeredWindowAttributes has been called,
subsequent UpdateLayeredWindow calls will fail until the layering
style bit is cleared and set again."
from http://msdn2.microsoft.com/en-us/library/ms632599.aspx#layered

But I still can't use winxpgui.UpdateLayeredWindow, Now I am using
ctypes to enable calling UpdateLayeredWindow, and this works.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,175
Messages
2,570,944
Members
47,492
Latest member
gabbywilliam

Latest Threads

Top