How to use Python Strings when calling Windows API - python

I'm trying to create a new Windows window by calling the win32gui.CreateWindow Function. The Window is created as expected, however the title is made up of Chinese (or other similar) characters, instead of reading "Hello, World!".
By counting the number of characters and reading documentation, I guessed that windows is using double width characters and python is not. Here are some of the things I tried to make it display properly, none of these attempts worked however:
def to_16(s):
s = s.encode('utf-16')
return "".join([format(i, "X").rjust(2,"0") for i in s])
def to_16(s):
return ''.join([f'{c}{chr(32)}' for c in s])
def to_16(s):
return ''.join([chr(i) for i in s.encode('utf-16')])
This is the code I use to create the window:
import ctypes
import cython
import win32, win32gui, win32ui, win32con, win32api
LRESULT = ctypes.c_longlong
WNDPROC = ctypes.CFUNCTYPE(LRESULT,
ctypes.wintypes.HWND,
ctypes.c_uint,
ctypes.wintypes.WPARAM,
ctypes.wintypes.LPARAM)
#WNDPROC
def WindowProc(hWnd:ctypes.wintypes.HWND,
uMsg:ctypes.c_uint,
wParam:ctypes.wintypes.WPARAM,
lParam:ctypes.wintypes.LPARAM)->LRESULT:
if uMsg == win32con.WM_PAINT:
hDC, paintStruct = win32gui.BeginPaint(hWnd)
rect = win32gui.GetClientRect(hWnd)
win32gui.DrawText(hDC,
'Hello send by Python via Win32!',
-1,
rect,
win32con.DT_SINGLELINE | win32con.DT_CENTER | win32con.DT_VCENTER)
win32gui.EndPaint(hWnd, paintStruct)
return 0
elif uMsg == win32con.WM_DESTROY:
print('Window: destroyed')
win32gui.PostQuitMessage(0)
return 0
else:
return win32gui.DefWindowProc(hWnd, uMsg, wParam, lParam)
HCURSOR = ctypes.wintypes.HICON
class WNDCLASSEX(ctypes.Structure): # tagWNDCLASSEXA
_fields_ = [("cbSize" , ctypes.c_uint),
("style" , ctypes.c_uint),
("lpfnWndProc" , WNDPROC),
("cbClsExtra" , ctypes.c_int),
("cbWndExtra" , ctypes.c_int),
("hInstance" , ctypes.wintypes.HINSTANCE),
("hIcon" , ctypes.wintypes.HICON),
("hCursor" , HCURSOR),
("hbrBackground", ctypes.wintypes.HBRUSH),
("lpszMenuName" , ctypes.wintypes.LPCWSTR),
("lpszClassName", ctypes.wintypes.LPCWSTR),
("hIconSm" , ctypes.wintypes.HICON),]
def WinMain():
print('Start...')
hInstance = win32api.GetModuleHandle()
hPrevInstance = None
lpCmdLine = ''
nCmdShow = win32con.SW_SHOWNORMAL
szWindowClass = 'DesktopApp' # The main window class name.
szTitle = 'Hello, World!' # The string that appears in the application's title bar.
wcex = WNDCLASSEX()
wcex.cbSize = ctypes.sizeof(WNDCLASSEX)
wcex.style = win32con.CS_HREDRAW | win32con.CS_VREDRAW
wcex.lpfnWndProc = WindowProc
wcex.cbClsExtra = 0
wcex.cbWndExtra = 0
wcex.hInstance = hInstance
wcex.hIcon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
wcex.hCursor = win32api.LoadCursor(None, win32con.IDC_ARROW)
wcex.hbrBackground = ctypes.wintypes.HBRUSH(win32con.COLOR_WINDOW+1)
wcex.lpszMenuName = None
wcex.lpszClassName = szWindowClass
wcex.hIconSm = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
print('Setup: done')
wndClassAtom = 0
try:
wndClassAtom = ctypes.windll.user32.RegisterClassExA(wcex)
print(f'wndClassAtom: {wndClassAtom}')
except Exception as e:
print(e)
finally:
if wndClassAtom == 0:
print('Call to RegisterClassEx failed!')
return 1
print('Class: registered')
hInst = hInstance
hWnd = 0
try:
hWnd = win32gui.CreateWindow(wndClassAtom,
to_16(szTitle),
win32con.WS_OVERLAPPEDWINDOW,
win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT,
500, 100,
0,
0,
hInstance,
None)
print(f'hWnd: {hWnd}')
except Exception as e:
print(e)
finally:
if not hWnd:
win32gui.UnregisterClass(wndClassAtom, hInstance)
print('Call to CreateWindow failed!')
return 1
print('Window: created')
win32gui.ShowWindow(hWnd,
nCmdShow)
win32gui.UpdateWindow(hWnd)
# Dispatch messages
win32gui.PumpMessages()
win32gui.UnregisterClass(wndClassAtom, hInstance)
return 0
errCode = WinMain()
if errCode == 1: print('----------WINDOWS ERROR----------')
I'd love for a robust way to pass python strings to the Windows API.

Related

I want to enumerate devices via Ctypes,conversion problem

I want to use Ctypes to enumerate the device, the following examples are C++ language I am not very good at converting, the following code is half of what I wrote
My question is how to conversion this
//Enumerate through all devices in Set
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
&DeviceInfoData);i++)
https://social.msdn.microsoft.com/forums/windowsdesktop/en-US/43ab4902-75b9-4c5c-9b54-4567c825539f/how-to-enumerate-hardware-devices-by-using-setupdi?forum=vcgeneral
import ctypes as ct
from ctypes import wintypes as w
SetupAPI = ct.WinDLL('SetupAPI')
SetupAPI.SetupDiGetClassDevsW.argtypes = w.LPVOID,w.PWCHAR,w.HWND,w.DWORD
SetupAPI.SetupDiGetClassDevsW.restype = w.HANDLE
SetupAPI.SetupDiEnumDeviceInfo.argtypes = w.HANDLE,w.DWORD,w.HANDLE
SetupAPI.SetupDiEnumDeviceInfo.restype = w.BOOLEAN
DIGCF_DEFAULT = 0x00000001
DIGCF_PRESENT = 0x00000002
DIGCF_ALLCLASSES = 0x00000004
DIGCF_PROFILE = 0x00000008
DIGCF_DEVICEINTERFACE = 0x00000010
ClassGuid = None
Enumerator = None
hwndParent = None
Flags = DIGCF_PRESENT | DIGCF_ALLCLASSES
DeviceInfoSet = None
MemberIndex = None
DeviceInfoData = None
class SP_DEVINFO_DATA(ct.Structure):
_fields_ = [
('cbSize',w.DWORD),
('ClassGuid',w.LPVOID),
('DevInst',w.DWORD),
('Reserved',w.ULONG),
]
SP_DEVINFO_DATA = SP_DEVINFO_DATA()
hDevInfo = SetupAPI.SetupDiGetClassDevsW(
ClassGuid,
Enumerator,
hwndParent,
Flags
)
SP_DEVINFO_DATA.cbSize = ct.sizeof(SP_DEVINFO_DATA)
DeviceInfoSet = hex(hDevInfo)
MemberIndex = 1
DeviceInfoData = ct.byref(SP_DEVINFO_DATA)
SetupDiEnumDeviceInfo = SetupAPI.SetupDiEnumDeviceInfo(
DeviceInfoSet,
MemberIndex,
DeviceInfoData
)
print(SetupDiEnumDeviceInfo)
Here's a complete, typesafe example to enumerate a particular device type, in this case USB host controllers:
import ctypes as ct
from ctypes import wintypes as w
import uuid
SetupAPI = ct.WinDLL('SetupAPI')
# ULONG_PTR is defined as an unsigned integer of the same size as a pointer on the OS,
# which is ct.ulonglong on 64-bit or ct.ulong on 32-bit. w.WPARAM happens to follow
# that same definition.
ULONG_PTR = w.WPARAM
# For type safety. A ctypes function will only accept HDEVINFO not any old HANDLE.
class HDEVINFO(w.HANDLE):
pass
# A class to initialize and print GUIDs
class GUID(ct.Structure):
_fields_ = (('Data1', ct.c_ulong),
('Data2', ct.c_ushort),
('Data3', ct.c_ushort),
('Data4', ct.c_ubyte * 8))
def __repr__(self):
return f"GUID('{self}')"
def __str__(self):
return (f'{{{self.Data1:08x}-{self.Data2:04x}-{self.Data3:04x}-'
f'{bytes(self.Data4[:2]).hex()}-{bytes(self.Data4[2:]).hex()}}}')
def __init__(self,guid=None):
if guid is not None:
data = uuid.UUID(guid)
self.Data1 = data.time_low
self.Data2 = data.time_mid
self.Data3 = data.time_hi_version
self.Data4[0] = data.clock_seq_hi_variant
self.Data4[1] = data.clock_seq_low
self.Data4[2:] = data.node.to_bytes(6,'big')
PGUID = ct.POINTER(GUID)
# See https://learn.microsoft.com/en-us/windows-hardware/drivers/install/guid-devinterface-usb-host-controller
GUID_DEVINTERFACE_USB_HOST_CONTROLLER = GUID('{3ABF6F2D-71C4-462A-8A92-1E6861E6AF27}')
class SP_DEVINFO_DATA(ct.Structure):
_fields_ = (('cbSize', w.DWORD),
('ClassGuid', GUID),
('DevInst', w.DWORD),
('Reserved', ULONG_PTR))
def __repr__(self):
return f'SP_DEVINFO_DATA(ClassGuid={self.ClassGuid}, DevInst={self.DevInst})'
# Per docs, the cbSize member must be set to the size of this structure.
def __init__(self):
self.cbSize = ct.sizeof(SP_DEVINFO_DATA)
PSP_DEVINFO_DATA = ct.POINTER(SP_DEVINFO_DATA)
SetupAPI.SetupDiGetClassDevsW.argtypes = PGUID, w.PWCHAR, w.HWND, w.DWORD
SetupAPI.SetupDiGetClassDevsW.restype = HDEVINFO
SetupAPI.SetupDiEnumDeviceInfo.argtypes = HDEVINFO, w.DWORD, PSP_DEVINFO_DATA
SetupAPI.SetupDiEnumDeviceInfo.restype = w.BOOL
SetupAPI.SetupDiDestroyDeviceInfoList.argtypes = HDEVINFO,
SetupAPI.SetupDiDestroyDeviceInfoList.restype = w.BOOL
DIGCF_DEFAULT = 0x00000001
DIGCF_PRESENT = 0x00000002
DIGCF_ALLCLASSES = 0x00000004
DIGCF_PROFILE = 0x00000008
DIGCF_DEVICEINTERFACE = 0x00000010
ClassGuid = GUID_DEVINTERFACE_USB_HOST_CONTROLLER
Enumerator = None
hwndParent = None
Flags = DIGCF_DEVICEINTERFACE | DIGCF_PRESENT
devinfo = SP_DEVINFO_DATA()
# Query for the device interface,
# then enumerate them one by one by incrementing a zero-based index
hDevInfo = SetupAPI.SetupDiGetClassDevsW(ClassGuid, Enumerator, hwndParent, Flags)
try:
MemberIndex = 0
while SetupAPI.SetupDiEnumDeviceInfo(hDevInfo, MemberIndex, ct.byref(devinfo)):
print(devinfo)
MemberIndex += 1
finally:
SetupAPI.SetupDiDestroyDeviceInfoList(hDevInfo)
Output:
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=144)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=137)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=17)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=78)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=24)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=98)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=123)
SP_DEVINFO_DATA(ClassGuid={36fc9e60-c465-11cf-8056-444553540000}, DevInst=41)
My system has eight USB host controllers and the class GUID matches:

Why does window title get truncated? [Windows API] [duplicate]

I been trying to create Win32 Application by using python (2.7) and ctypes module. Window is created and shown but title of window gets truncated. I got 'M' instead of 'My test window'. What I am doing wrong?
Thanks in advance
P.S. Here follows the code and screenshot:
# -*- coding: utf-8 -*-
from sys import platform, exit
from ctypes import *
from ctypes.wintypes import DWORD, HWND, HANDLE, LPCWSTR, WPARAM, LPARAM, RECT, POINT, MSG
WNDPROCTYPE = WINFUNCTYPE(c_int, HWND, c_uint, WPARAM, LPARAM)
WS_EX_APPWINDOW = 0x40000
WS_OVERLAPPEDWINDOW = 0xcf0000
WS_CAPTION = 0xc00000
SW_SHOWNORMAL = 1
SW_SHOW = 5
CS_HREDRAW = 2
CS_VREDRAW = 1
CW_USEDEFAULT = 0x80000000
WM_DESTROY = 2
WHITE_BRUSH = 0
class WNDCLASSEX(Structure):
_fields_ = [("cbSize", c_uint),
("style", c_uint),
("lpfnWndProc", WNDPROCTYPE),
("cbClsExtra", c_int),
("cbWndExtra", c_int),
("hInstance", HANDLE),
("hIcon", HANDLE),
("hCursor", HANDLE),
("hBrush", HANDLE),
("lpszMenuName", LPCWSTR),
("lpszClassName", LPCWSTR),
("hIconSm", HANDLE)]
def PyWndProcedure(hWnd, Msg, wParam, lParam):
if Msg == WM_DESTROY:
windll.user32.PostQuitMessage(0)
else:
return windll.user32.DefWindowProcA(hWnd, Msg, wParam, lParam)
return 0
WndProc = WNDPROCTYPE(PyWndProcedure)
hInst = windll.kernel32.GetModuleHandleW(0)
print(hInst)
wclassName = u'My Python Win32 Class'
wndClass = WNDCLASSEX()
wndClass.cbSize = sizeof(WNDCLASSEX)
wndClass.style = CS_HREDRAW | CS_VREDRAW
wndClass.lpfnWndProc = WndProc
wndClass.cbClsExtra = 0
wndClass.cbWndExtra = 0
wndClass.hInstance = hInst
wndClass.hIcon = 0
wndClass.hCursor = 0
wndClass.hBrush = windll.gdi32.GetStockObject(WHITE_BRUSH)
wndClass.lpszMenuName = 0
wndClass.lpszClassName = wclassName
wndClass.hIconSm = 0
print(wndClass)
regRes = windll.user32.RegisterClassExW(byref(wndClass))
print(regRes)
wname = u'My test window'
hWnd = windll.user32.CreateWindowExW(
0,
wclassName,
wname,
WS_OVERLAPPEDWINDOW | WS_CAPTION,
CW_USEDEFAULT,
CW_USEDEFAULT,
300,
300,
0,
0,
hInst,
0)
print('hWnd', hWnd)
if not hWnd:
print('Failed to create window')
exit(0)
print('ShowWindow', windll.user32.ShowWindow(hWnd, SW_SHOW))
print('UpdateWindow', windll.user32.UpdateWindow(hWnd))
msg = MSG()
lpmsg = pointer(msg)
print('Entering message loop')
while windll.user32.GetMessageA(lpmsg, 0, 0, 0) != 0:
windll.user32.TranslateMessage(lpmsg)
windll.user32.DispatchMessageA(lpmsg)
print('done.')
It is because you are creating a Unicode window with CreateWindowExW but then calling the ANSI DefWindowProcA. You are passing Unicode strings which typically have zero for every other byte since your text is in the ASCII range which explains what you observe.
The solution? Call DefWindowProcW instead.
Actually, a better solution would be to use win32gui instead which wraps this up a bit more for you.
If you provide a regular string rather than an unicode string, the text is displayed properly.
wname = 'My test window'
It looks strange to me because you are using the Unicode API (CreateWindowExW). Maybe the root cause is somewhere else.
I hope it helps

Python 3: Detect monitor power state in Windows

I need my python script to get windows monitor power state.
According to this link in StackOverflow, I can use RegisterPowerSettingNotification to get GUID_MONITOR_POWER_ON but I don't know how to implement it. The objective is to trigger events when the screen goes off.
I can access the funcion at ctypes.windll.user32.RegisterPowerSettingNotification but I need help to call it and get the messsages
RegisterPowerSettingNotification
Power Setting GUIDs
I am running Windows 10 and Python 3
Update:
I was able to call and register the window to receive messages but I'm still unable to get the information I need from it... I know that lparam is a pointer to a structure but I need to get information from it like the GUID PowerSetting and Data fields
import win32con
import win32api
import win32gui
import sys
import time
from ctypes import POINTER, windll
from comtypes import GUID
from ctypes.wintypes import HANDLE, DWORD
PBT_POWERSETTINGCHANGE = 0x8013
def log_info(msg):
""" Prints """
print(msg)
f = open("test.log", "a+")
f.write(msg + "\n")
f.close()
def wndproc(hwnd, msg, wparam, lparam):
print('.')
log_info("wndproc: %s\nw: %s\nl: %s" % (msg, wparam, lparam))
if msg == win32con.WM_POWERBROADCAST:
if wparam == win32con.PBT_APMPOWERSTATUSCHANGE:
log_info('Power status has changed')
if wparam == win32con.PBT_APMRESUMEAUTOMATIC:
log_info('System resume')
if wparam == win32con.PBT_APMRESUMESUSPEND:
log_info('System resume by user input')
if wparam == win32con.PBT_APMSUSPEND:
log_info('System suspend')
if wparam == PBT_POWERSETTINGCHANGE:
log_info('Power setting changed...')
#lparam is pointer to structure i need
if __name__ == "__main__":
log_info("*** STARTING ***")
hinst = win32api.GetModuleHandle(None)
wndclass = win32gui.WNDCLASS()
wndclass.hInstance = hinst
wndclass.lpszClassName = "testWindowClass"
messageMap = { win32con.WM_POWERBROADCAST : wndproc }
wndclass.lpfnWndProc = messageMap
try:
myWindowClass = win32gui.RegisterClass(wndclass)
hwnd = win32gui.CreateWindowEx(win32con.WS_EX_LEFT,
myWindowClass,
"testMsgWindow",
0,
0,
0,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
hinst,
None)
except Exception as e:
log_info("Exception: %s" % str(e))
if hwnd is None:
log_info("hwnd is none!")
else:
log_info("hwnd: %s" % hwnd)
register_function = windll.user32.RegisterPowerSettingNotification
guids_info = {
'GUID_MONITOR_POWER_ON' : '{02731015-4510-4526-99e6-e5a17ebd1aea}',
'GUID_SYSTEM_AWAYMODE' : '{98a7f580-01f7-48aa-9c0f-44352c29e5C0}',
'fake' : '{98a7f580-01f7-48aa-9c0f-44352c29e555}' # just to see if I get an error or a different return from function
}
hwnd_pointer = HANDLE(hwnd)
for name, guid_info in guids_info.items():
result = register_function(hwnd_pointer, GUID(guid_info), DWORD(0))
print('registering', name)
print('result:', result) # result is pointer to unregister function if I'm not mistaken
print()
print('\nEntering loop')
while True:
win32gui.PumpWaitingMessages()
time.sleep(1)
To make the code work it is needed the powerbroadcast_setting structure, a function declaration in ctypes with CFUNCTYPE and a cast from lparam to powerbroadcast_setting
Fully working code:
import win32con
import win32api
import win32gui
import time
from ctypes import POINTER, windll, Structure, cast, CFUNCTYPE, c_int, c_uint, c_void_p, c_bool
from comtypes import GUID
from ctypes.wintypes import HANDLE, DWORD
PBT_POWERSETTINGCHANGE = 0x8013
GUID_CONSOLE_DISPLAY_STATE = '{6FE69556-704A-47A0-8F24-C28D936FDA47}'
GUID_ACDC_POWER_SOURCE = '{5D3E9A59-E9D5-4B00-A6BD-FF34FF516548}'
GUID_BATTERY_PERCENTAGE_REMAINING = '{A7AD8041-B45A-4CAE-87A3-EECBB468A9E1}'
GUID_MONITOR_POWER_ON = '{02731015-4510-4526-99E6-E5A17EBD1AEA}'
GUID_SYSTEM_AWAYMODE = '{98A7F580-01F7-48AA-9C0F-44352C29E5C0}'
class POWERBROADCAST_SETTING(Structure):
_fields_ = [("PowerSetting", GUID),
("DataLength", DWORD),
("Data", DWORD)]
def wndproc(hwnd, msg, wparam, lparam):
if msg == win32con.WM_POWERBROADCAST:
if wparam == win32con.PBT_APMPOWERSTATUSCHANGE:
print('Power status has changed')
if wparam == win32con.PBT_APMRESUMEAUTOMATIC:
print('System resume')
if wparam == win32con.PBT_APMRESUMESUSPEND:
print('System resume by user input')
if wparam == win32con.PBT_APMSUSPEND:
print('System suspend')
if wparam == PBT_POWERSETTINGCHANGE:
print('Power setting changed...')
settings = cast(lparam, POINTER(POWERBROADCAST_SETTING)).contents
power_setting = str(settings.PowerSetting)
data_length = settings.DataLength
data = settings.Data
if power_setting == GUID_CONSOLE_DISPLAY_STATE:
if data == 0: print('Display off')
if data == 1: print('Display on')
if data == 2: print('Display dimmed')
elif power_setting == GUID_ACDC_POWER_SOURCE:
if data == 0: print('AC power')
if data == 1: print('Battery power')
if data == 2: print('Short term power')
elif power_setting == GUID_BATTERY_PERCENTAGE_REMAINING:
print('battery remaining: %s' % data)
elif power_setting == GUID_MONITOR_POWER_ON:
if data == 0: print('Monitor off')
if data == 1: print('Monitor on')
elif power_setting == GUID_SYSTEM_AWAYMODE:
if data == 0: print('Exiting away mode')
if data == 1: print('Entering away mode')
else:
print('unknown GUID')
return True
return False
if __name__ == "__main__":
print("*** STARTING ***")
hinst = win32api.GetModuleHandle(None)
wndclass = win32gui.WNDCLASS()
wndclass.hInstance = hinst
wndclass.lpszClassName = "testWindowClass"
CMPFUNC = CFUNCTYPE(c_bool, c_int, c_uint, c_uint, c_void_p)
wndproc_pointer = CMPFUNC(wndproc)
wndclass.lpfnWndProc = {win32con.WM_POWERBROADCAST : wndproc_pointer}
try:
myWindowClass = win32gui.RegisterClass(wndclass)
hwnd = win32gui.CreateWindowEx(win32con.WS_EX_LEFT,
myWindowClass,
"testMsgWindow",
0,
0,
0,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
hinst,
None)
except Exception as e:
print("Exception: %s" % str(e))
if hwnd is None:
print("hwnd is none!")
else:
print("hwnd: %s" % hwnd)
guids_info = {
'GUID_MONITOR_POWER_ON' : GUID_MONITOR_POWER_ON,
'GUID_SYSTEM_AWAYMODE' : GUID_SYSTEM_AWAYMODE,
'GUID_CONSOLE_DISPLAY_STATE' : GUID_CONSOLE_DISPLAY_STATE,
'GUID_ACDC_POWER_SOURCE' : GUID_ACDC_POWER_SOURCE,
'GUID_BATTERY_PERCENTAGE_REMAINING' : GUID_BATTERY_PERCENTAGE_REMAINING
}
for name, guid_info in guids_info.items():
result = windll.user32.RegisterPowerSettingNotification(HANDLE(hwnd), GUID(guid_info), DWORD(0))
print('registering', name)
print('result:', hex(result))
print('lastError:', win32api.GetLastError())
print()
print('\nEntering loop')
while True:
win32gui.PumpWaitingMessages()
time.sleep(1)

Why does glXGetVisualFromFBConfig always fail to find a valid visual from my FBConfig?

Can anyone explain why glXGetVisualFromFBConfig is failing, the FbConfigs I have seem to be valid and match what I request but passing the FBConfig to glXGetVisualFromFBConfig does not return a visual and i have been unable to figure out why.
import sys
import xcb
import xcb.glx
import xcb.composite
import xcb.xproto as xproto
import Xlib
from Xlib.display import Display
from ctypes import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL import GLX
try:
from OpenGL.GLX import struct__XDisplay
except ImportError as err:
from OpenGL.raw._GLX import struct__XDisplay
class alpha_glx_example:
xlib = cdll.LoadLibrary('libX11.so')
xlib.XOpenDisplay.argtypes = [c_char_p]
xlib.XOpenDisplay.restype = POINTER(struct__XDisplay)
xdisplay = xlib.XOpenDisplay(None)
display = Xlib.display.Display()
attrs = []
def __init__(self):
self.xserver = xcb.connect()
self.xclient = self.xserver.core
self.setup = self.xserver.get_setup()
self.canvas = self.setup.roots[0]
self.root_window = self.canvas.root
self.depth = self.setup.roots[0].root_depth
self.visual = self.setup.roots[0].root_visual
composite_ext = self.load_extension('Composite', xcb.composite.key)
render_ext = self.load_extension('RENDER', xcb.render.key)
glx_ext = self.load_extension('GLX', xcb.glx.key)
""" lets setup are opengl settings and create the context for our window """
self.add_attribute(GLX.GLX_RENDER_TYPE, GLX.GLX_RGBA_BIT)
self.add_attribute(GLX.GLX_DRAWABLE_TYPE, GLX.GLX_WINDOW_BIT)
self.add_attribute(GLX.GLX_X_RENDERABLE, True)
self.add_attribute(GLX.GLX_RED_SIZE, 8)
self.add_attribute(GLX.GLX_GREEN_SIZE, 8)
self.add_attribute(GLX.GLX_BLUE_SIZE, 8)
self.add_attribute(GLX.GLX_ALPHA_SIZE, 8)
#~ self.add_attribute(GLX.GLX_DEPTH_SIZE, 24)
#~ self.add_attribute(GLX.GLX_DOUBLEBUFFER, True)
config_count = c_int()
configs = GLX.glXChooseFBConfig(self.xdisplay, self.display.get_default_screen(), self.get_attributes(), byref(config_count))
if config_count.value is 0 or configs.__class__ is "<class 'OpenGL.raw._GLX.LP_struct_anon_103'>":
sys.exit('no matching configs found')
print self.attrs
print '\nfind visual from choose fbconfig %s found' % config_count.value
count = 0
# lets poke the configs to make sure we are getting what we expect from glXChooseFBConfig
for i in range(0, config_count.value):
config = configs[i]
count += 1
print 'count %d' % count
xrender = c_int()
GLX.glXGetFBConfigAttrib(self.xdisplay, config, GLX.GLX_X_RENDERABLE, byref(xrender))
print 'xrender = %d' % xrender.value
red_size = c_int()
print GLX.glXGetFBConfigAttrib(self.xdisplay, config, GLX.GLX_RED_SIZE, byref(red_size))
print 'red size = %s' % red_size.value
test = c_int()
print GLX.glXGetFBConfigAttrib(self.xdisplay, config, GLX.GLX_ALPHA_SIZE, byref(test))
print 'alpha size = %d' %test.value
picture_formats = render_ext.QueryPictFormats().reply()
# for some reason glXGetVisualFromFBConfig fails to find any visuals
for i in range(0, config_count.value):
count += 1
config = configs[i]
visual = GLX.glXGetVisualFromFBConfig(self.xdisplay, config)
print visual
if 'OpenGL.raw._GLX.LP_struct_anon' in str(visual.__class__):
continue
def glx_visual_info(self, visual):
print('GLX Visual Info')
print('rgb depth = %s' % visual.depth)
print('red mask = %s' % visual.red_mask)
print('green mask = %s' % visual.green_mask)
print('blue mask = %s' % visual.blue_mask)
print('colour map = %s' % visual.colormap_size)
print('screen id = %s' % visual.screen)
print('bits per rgb = %s' % visual.bits_per_rgb)
print('visual = %s' % visual.visual)
print('visual id = %s' % visual.visualid)
def add_attribute(self, setting, value=None):
"""just to nicely add opengl parameters"""
self.attrs.append(setting)
if value:
self.attrs.append(value)
def get_attributes(self):
""" return our parameters in the expected structure"""
attrs = self.attrs + [0, 0]
return (c_int * len(attrs))(*attrs)
def load_extension(self, name, xcb_key):
# test extension is present
extension = self.xclient.QueryExtension(len(name), name).reply()
if extension.present != 1:
print("%s not available" % name)
return
print('Using %s extension' % name)
return self.xserver(xcb_key)
if __name__ == "__main__":
alpha_glx_example()
In my case I had decided that these structures OpenGL.raw._GLX.LP_struct_anon_103 where invalid responses when in fact they are not, I think I had assumed anon was anonymous and was initially inspecting a bad response when only some of the results where invalid.
Seems OpenGL.raw._GLX.LP_struct_anon_103 are valid but you need to make sure that the result.contents values are not null pointer.

Prevent windows shutdown from python

I want to prevent windows (xp and 7) from shutting down.
For that it seems I have to intercept the WM_QUERYENDSESSION message and return False.
Ok I have to correct my statement, this program works fine under Windows 7 but on Windows 7 embedded Standard Service Pack 1 it does not prevent the shutdown!?
import ctypes
from ctypes import c_long, c_int, c_wchar_p
import time
import win32api
import win32con
import win32gui
import win32process
oldWndProc = None
def wndproc(hWnd, msg, wParam, lParam):
print("wndproc received message: %s" % msg)
if (msg == win32con.WM_QUERYENDSESSION):
print("wndproc received WM_QUERYENDSESSION")
return 0
# Pass all messages to the original WndProc
return win32gui.CallWindowProc(oldWndProc, hWnd, msg, wParam, lParam)
if __name__ == "__main__":
try:
# Create a window just to be able to receive WM_QUERYENDSESSION messages
win32api.SetLastError(0)
hinst = win32api.GetModuleHandle(None)
messageMap = {}
wndclass = win32gui.WNDCLASS()
wndclass.hInstance = hinst
wndclass.lpszClassName = "PreventShutdownWindowClass"
wndclass.lpfnWndProc = messageMap
myWindowClass = win32gui.RegisterClass(wndclass)
hwnd = win32gui.CreateWindowEx(win32con.WS_EX_LEFT,
myWindowClass,
"PreventShutdownWindow",
0,
0,
0,
win32con.CW_USEDEFAULT,
win32con.CW_USEDEFAULT,
0,
0,
hinst,
None)
print 'CreateWindowEx: ' + str(hwnd)
print 'CreateWindowEx last error: ' + str(win32api.GetLastError())
print ''
# Set WndProc
win32api.SetLastError(0)
WndProcType = ctypes.WINFUNCTYPE(c_int, c_long, c_int, c_int, c_int)
newWndProc = WndProcType(wndproc)
oldWndProc = ctypes.windll.user32.SetWindowLongW( hwnd, win32con.GWL_WNDPROC, newWndProc )
print 'SetWindowLong: ' + str(oldWndProc)
print 'SetWindowLong last error: ' + str(win32api.GetLastError())
print ''
# We provide a reason for the shutdown prevention
win32api.SetLastError(0)
ret = ctypes.windll.user32.ShutdownBlockReasonCreate(hwnd, c_wchar_p("PreventShutdown running which prevents shutdown"))
print 'ShutdownBlockReasonCreate: ' + str(ret)
print 'ShutdownBlockReasonCreatelast error: ' + str(win32api.GetLastError())
print ''
# We elevate the program to be asked as soon as possible to inhibit shutdown
win32api.SetLastError(0)
win32process.SetProcessShutdownParameters(0x4FF, win32con.SHUTDOWN_NORETRY)
print 'SetProcessShutdownParameters last error: ' + str(win32api.GetLastError())
print ''
except Exception, e:
print("Exception: %s" % str(e))
while True:
win32gui.PumpWaitingMessages()
time.sleep(1)

Categories

Resources