151 lines
5.0 KiB
Python
151 lines
5.0 KiB
Python
#--------------------------------------------------------------------
|
|
#
|
|
# PyGUI - Win32 - Utilities
|
|
#
|
|
#--------------------------------------------------------------------
|
|
|
|
import win32con as wc, win32ui as ui, win32gui as gui, win32api as api
|
|
from win32api import HIWORD, LOWORD
|
|
from GUI import application
|
|
from GUI.Exceptions import Cancel, InternalError
|
|
|
|
win_dlog_class = "#32770"
|
|
win_color3dhilight = api.GetSysColor(wc.COLOR_3DHILIGHT)
|
|
win_color3dlight = api.GetSysColor(wc.COLOR_3DLIGHT)
|
|
win_color3dface = api.GetSysColor(wc.COLOR_3DFACE)
|
|
win_color3dshadow = api.GetSysColor(wc.COLOR_3DSHADOW)
|
|
win_menubar_height = api.GetSystemMetrics(wc.SM_CYMENU)
|
|
win_bg_color = api.GetSysColor(wc.COLOR_3DFACE)
|
|
win_screen_width = api.GetSystemMetrics(wc.SM_CXFULLSCREEN)
|
|
win_screen_height = api.GetSystemMetrics(wc.SM_CYFULLSCREEN)
|
|
win_screen_rect = (0, 0, win_screen_width, win_screen_height)
|
|
|
|
#win_bg_brush = ui.CreateBrush(wc.BS_SOLID, win_color3dface, 0)
|
|
#win_bg_hbrush = win_bg_brush.GetSafeHandle()
|
|
|
|
# An empty brush for not painting anything with
|
|
win_null_brush = ui.CreateBrush(wc.BS_NULL, 0, 0)
|
|
win_null_hbrush = win_null_brush.GetSafeHandle()
|
|
|
|
# All components hook the following messages
|
|
|
|
win_event_messages = (
|
|
wc.WM_KEYDOWN, wc.WM_KEYUP,
|
|
wc.WM_SYSKEYDOWN, wc.WM_SYSKEYUP,
|
|
wc.WM_MOUSEMOVE,
|
|
wc.WM_LBUTTONDOWN, wc.WM_LBUTTONDBLCLK, wc.WM_LBUTTONUP,
|
|
wc.WM_MBUTTONDOWN, wc.WM_MBUTTONDBLCLK, wc.WM_MBUTTONUP,
|
|
wc.WM_RBUTTONDOWN, wc.WM_RBUTTONDBLCLK, wc.WM_RBUTTONUP,
|
|
#wc.WM_MOUSELEAVE,
|
|
)
|
|
|
|
# Dummy CWnd for use as parent of containerless components.
|
|
# Also used as the main frame of the CWinApp.
|
|
|
|
win_none = ui.CreateFrame()
|
|
win_none.CreateWindow(None, "", 0, (0, 0, 10, 10))
|
|
|
|
win_plain = ui.CreateWnd()
|
|
win_plain.CreateWindow(None, None, 0, (0, 0, 10, 10), win_none, 0)
|
|
win_plain_class = gui.GetClassName(win_plain.GetSafeHwnd())
|
|
|
|
#--------------------------------------------------------------------
|
|
|
|
win_command_map = {
|
|
0: '_win_bn_clicked', # BN_CLICKED
|
|
wc.CBN_SELCHANGE: '_cbn_sel_change',
|
|
}
|
|
|
|
class WinMessageReflector(object):
|
|
|
|
def _win_install_event_hooks(self, win):
|
|
win.HookMessage(self._win_wm_scroll, wc.WM_HSCROLL)
|
|
win.HookMessage(self._win_wm_scroll, wc.WM_VSCROLL)
|
|
|
|
#
|
|
# Disabled for now because overriding control colours
|
|
# doesn't seem to work properly on XP.
|
|
#
|
|
# def OnCtlColor(self, dc, comp, typ):
|
|
# #print "WinMessageReflector.OnCtlColor" ###
|
|
# meth = getattr(comp, '_win_on_ctlcolor', None)
|
|
# if meth:
|
|
# return meth(dc, typ)
|
|
|
|
def _win_wm_scroll(self, message):
|
|
#print "WinMessageReflector._win_wm_scroll:", self, message ###
|
|
wParam = message[2]
|
|
code = wParam & 0xffff
|
|
lParam = message[3]
|
|
self._forward_reflected_message(lParam, '_win_wm_scroll', code)
|
|
|
|
def OnCommand(self, wParam, lParam):
|
|
#print "WinMessageReflector.OnCommand: code = 0x%04x 0x%04x lParam = 0x%08x" % (
|
|
# HIWORD(wParam), LOWORD(wParam), lParam)
|
|
try:
|
|
code = HIWORD(wParam)
|
|
id = LOWORD(wParam)
|
|
if id != 0:
|
|
if self != win_none_wrapper:
|
|
self._win_menu_command(id)
|
|
else:
|
|
name = win_command_map.get(code)
|
|
if name:
|
|
self._forward_reflected_message(lParam, name)
|
|
except Cancel:
|
|
pass
|
|
except:
|
|
application().report_error()
|
|
|
|
def _forward_reflected_message(self, lParam, method_name, *args):
|
|
wnd = ui.CreateWindowFromHandle(lParam)
|
|
meth = getattr(wnd, method_name, None)
|
|
if meth:
|
|
meth(*args)
|
|
|
|
def _win_menu_command(self, id):
|
|
raise InternalError("_win_menu_command called on non-window: %r" % self)
|
|
|
|
win_none_wrapper = WinMessageReflector()
|
|
win_none_wrapper._win = win_none
|
|
win_none_wrapper._win_install_event_hooks(win_none)
|
|
win_none.AttachObject(win_none_wrapper)
|
|
|
|
#--------------------------------------------------------------------
|
|
#
|
|
# Debugging routines
|
|
#
|
|
|
|
win_message_names = {}
|
|
|
|
win_exclude_names = ["WM_MOUSEFIRST"]
|
|
|
|
for name, value in wc.__dict__.iteritems():
|
|
if name.startswith("WM_") and name not in win_exclude_names:
|
|
win_message_names[value] = name
|
|
|
|
def win_message_name(num):
|
|
return win_message_names.get(num) or num
|
|
|
|
def dump_flags(flags):
|
|
for name in wc.__dict__.iterkeys():
|
|
if name.startswith("WS_") and not name.startswith("WS_EX"):
|
|
value = wc.__dict__[name]
|
|
if flags & value:
|
|
print "%20s = 0x%08x" % (name, value & 0xffffffffL)
|
|
|
|
def win_deconstruct_style(flags):
|
|
win_do_deconstruct_style(flags, "WS_", "WS_EX_")
|
|
|
|
def win_deconstruct_style_ex(flags):
|
|
win_do_deconstruct_style(flags, "WS_EX_")
|
|
|
|
def win_do_deconstruct_style(flags, prefix, not_prefix = None):
|
|
d = wc.__dict__
|
|
for name in d.iterkeys():
|
|
if name.startswith(prefix):
|
|
if not not_prefix or not name.startswith(not_prefix):
|
|
value = d[name]
|
|
if value and flags & value == value:
|
|
print "%25s 0x%08x" % (name, value)
|