By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,275 Members | 1,745 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,275 IT Pros & Developers. It's quick & easy.

Get a control over a window

P: n/a
Hi,

I was wondering how do I get control over a window (Win32).
to be more specific, I need to find a handle to a window of a certain
program and minimize the window.

May 15 '07 #1
Share this Question
Share on Google+
5 Replies


P: n/a
On May 15, 8:06 am, Tom Gur <gur....@gmail.comwrote:
Hi,

I was wondering how do I get control over a window (Win32).
to be more specific, I need to find a handle to a window of a certain
program and minimize the window.
It sounds pretty complicated to me, but here's what I found:

http://mail.python.org/pipermail/pyt...er/352639.html
http://forums.devshed.com/python-pro...ws-132273.html

That should get you started. If you figure it out, post your code so
the rest may benefit.

Mike

May 15 '07 #2

P: n/a
On 15 Mai, 15:06, Tom Gur <gur....@gmail.comwrote:
Hi,

I was wondering how do I get control over a window (Win32).
to be more specific, I need to find a handle to a window of a certain
program and minimize the window.

There are many ways to get the handle of a window.
Assuming you have ctypes at hand, you could try:
>user32 = ctypes.windll.user32
hwnd = user32.FindWindowA(classname, title)
if hwnd:
user32.PostMessageA(hwnd, WM_SYSCOMMAND, SC_ICON, 0)
If you need it more acurate you could search MSDN
for how to enumerate all running processes and get the
handles of their windows. Process32First (...) could be
a start for reading.

Jürgen

May 15 '07 #3

P: n/a
Tom Gur <gu*****@gmail.comwrote:
I was wondering how do I get control over a window (Win32).
to be more specific, I need to find a handle to a window of a certain
program and minimize the window.
Here's a function which returns a list of all windows where the class is
'PuTTY' or the title contains a particular string:

from win32gui import EnumWindows, GetClassName, EnumChildWindows
from win32ui import CreateWindowFromHandle, MessageBox

def toplevelWindows():
res = []
def callback(hwnd, arg):
name = GetClassName(hwnd)
w = CreateWindowFromHandle(hwnd)
title = w.GetWindowText()
if "'s password:" in title or name=='PuTTY':
res.append(w)
EnumWindows(callback, 0)
return res

You can minimize a window once you have found it by calling ShowWindow
(or SetWindowPlacement).

If you don't want to depend on Python's win32 extensions being installed
then you can also do the same thing using ctypes.

In either case be very careful that you are only picking up the windows
you wanted to find as enumerating top level windows will return a lot of hidden windows and if you start messing with these you will probably need to reboot your system.

Here's something adapted from some stuff where I was playing with ctypes
(so you could probably cut out a lot of crud). It's a complete program
which will find a Firefox window with a specified string in the title
and minimize it (without the test for the classname it will also minimize
the command window you run it from).
--------- minimize.py -------------
#
# Minimize a specified window.
#
import sys
import ctypes
from ctypes import *

def _stdcall(dllname, restype, funcname, *argtypes):
# a decorator for a generator.
# The decorator loads the specified dll, retrieves the
# function with the specified name, set its restype and argtypes,
# it then invokes the generator which must yield twice: the first
# time it should yield the argument tuple to be passed to the dll
# function (and the yield returns the result of the call).
# It should then yield the result to be returned from the
# function call.
def decorate(func):
api = getattr(WinDLL(dllname), funcname)
api.restype = restype
api.argtypes = argtypes

def decorated(*args, **kw):
iterator = func(*args, **kw)
nargs = iterator.next()
if not isinstance(nargs, tuple):
nargs = (nargs,)
try:
res = api(*nargs)
except Exception, e:
return iterator.throw(e)
return iterator.send(res)
return decorated
return decorate

from ctypes.wintypes import HWND #, RECT, POINT
LPARAM = c_ulong

class metaENUM(type(ctypes.c_int)):
def __init__(cls, name, bases, namespace):
'''Convert enumeration names into attributes'''
names = namespace.get('_names_', {})
if hasattr(names, 'keys'):
for (k,v) in names.items():
setattr(cls, k, cls(v))
names[v]=k
else:
for (i,k) in enumerate(names):
setattr(cls, k, cls(i))
super(metaENUM, cls).__init__(name, bases, namespace)

class ENUM(ctypes.c_int):
'''Enumeration base class. Set _names_ attribute to a list
of enumeration names (counting from 0)
or a dictionary of name:value pairs.'''
__metaclass__ = metaENUM
def __str__(self):
return self.__repr__(fmt="%(value)s")

def __repr__(self, fmt="<%(name)s %(value)s>"):
try:
return self._names_[self.value]
except:
return fmt % dict(name=self.__class__.__name__, value=self.value)
def __int__(self):
return self.value

class BITMASK(ENUM):
'''Some Microsoft 'enums' are actually bitmasks with several bits or'd together'''
def __repr__(self, fmt="<%(name)s %(value)s>"):
v = self.value
values = []
while v:
bit = v&(~v+1)
try:
values.append(self._names_[bit])
except (KeyError, IndexError):
values.append(fmt % dict(name=self.__class__.__name__, value=self.value))
v &= ~bit
if not values:
return '0'
return '|'.join(values)
def __or__(self, other):
return type(self)(int(self.value)|int(other.value))

class SHOWCMD(ENUM):
_names_ = '''SW_HIDE SW_NORMAL SW_SHOW_MINIMIZED SW_SHOW_MAXIMIZED
SW_SHOW_NOACTIVATE SW_SHOW SW_MINIMIZE SW_SHOWMINNOACTIVE
SW_SHOWNA SW_RESTORE SW_SHOWDEFAULT SW_FORCEMINIMIZE'''.split()

class WindowPlacementFlags(BITMASK):
_names_ = dict(WPF_SETMINPOSITION = 1,
WPF_RESTORETOMAXIMIZED = 2,
WPF_ASYNCWINDOWPLACEMENT = 4)

class Structure(ctypes.Structure):
"""As ctypes Structure but with added repr and comparison testing"""
def __repr__(self):
return "%s(%s)" % (self.__class__.__name__,
", ".join("%s=%r" % (f, getattr(self, f)) for (f,t) in self._fields_))
def __eq__(self, other):
if self._fields_ != other._fields_:
return False
for (f,t) in self._fields_:
if getattr(self,f) != getattr(other,f):
return False
return True

class RECT(Structure):
_fields_ = [("left", c_long),
("top", c_long),
("right", c_long),
("bottom", c_long)]

class POINT(Structure):
_fields_ = [("x", c_long),
("y", c_long)]

class StructureWithLength(Structure):
_fields_ = [('length', ctypes.c_ulong)]
def __init__(self):
ctypes.Structure.__init__(self)
self.length = ctypes.sizeof(self)

class WINDOWPLACEMENT(StructureWithLength):
_fields_ = [
('flags', WindowPlacementFlags),
('showCmd', SHOWCMD),
('ptMinPosition', POINT),
('ptMaxPosition', POINT),
('rcNormalPosition', RECT),
]

def nonzero(result):
# If the result is zero, and GetLastError() returns a non-zero
# error code, raise a WindowsError
if result == 0 and GetLastError():
raise WinError()
return result

WNDENUMPROC = ctypes.WINFUNCTYPE(ctypes.c_int, HWND, LPARAM)
@ _stdcall("user32", c_int, "EnumWindows", WNDENUMPROC, LPARAM)
def EnumWindows(callback, lparam=0):
yield nonzero((yield WNDENUMPROC(callback), lparam))

@ _stdcall("user32", c_int, "GetWindowTextLengthW", HWND)
def GetWindowTextLength(hwnd):
yield nonzero((yield hwnd,))

@ _stdcall("user32", c_int, "GetWindowTextW", HWND, c_wchar_p, c_int)
def GetWindowText(hwnd):
len = GetWindowTextLength(hwnd)+1
buf = create_unicode_buffer(len)
nonzero((yield hwnd, buf, len))
yield buf.value

@ _stdcall("user32", c_int, "GetClassNameW", HWND, c_wchar_p, c_int)
def GetClassName(hwnd):
len = 256
buf = create_unicode_buffer(len)
nonzero((yield hwnd, buf, len))
yield buf.value

@ _stdcall("user32", c_int, "GetWindowRect", HWND, POINTER(RECT))
def GetWindowRect(hwnd):
buf = RECT()
nonzero((yield hwnd, buf))
yield buf

@ _stdcall("user32", c_int, "GetClientRect", HWND, POINTER(RECT))
def GetClientRect(hwnd):
buf = RECT()
nonzero((yield hwnd, buf))
yield buf

@ _stdcall("user32", c_int, "GetWindowPlacement", HWND, POINTER(WINDOWPLACEMENT))
def GetWindowPlacement(hwnd):
buf = WINDOWPLACEMENT()
nonzero((yield hwnd, buf))
yield buf

@ _stdcall("user32", c_int, "SetWindowPlacement", HWND, POINTER(WINDOWPLACEMENT))
def SetWindowPlacement(hwnd, placement):
yield nonzero((yield hwnd, placement))

@ _stdcall("user32", c_int, "IsWindow", HWND)
def IsWindow(hwnd):
yield bool((yield hwnd,))

@ _stdcall("user32", c_int, "ShowWindow", HWND, SHOWCMD)
def ShowWindow(hwnd, showcmd):
yield bool((yield hwnd,showcmd))

def toplevelWindows():
res = []
def callback(hwnd, arg):
res.append(hwnd)
return True
EnumWindows(callback, 0)
return res

def iterWindows(klass, match):
for hwnd in toplevelWindows():
if IsWindow(hwnd):
try:
title = GetWindowText(hwnd)
except WindowsError, e:
continue
if klass==GetClassName(hwnd) and match in title:
yield hwnd

if __name__=='__main__':
for hwnd in iterWindows("MozillaUIWindowClass", sys.argv[1]):
wp = GetWindowPlacement(hwnd)
ShowWindow(hwnd, SHOWCMD.SW_MINIMIZE)
else:
print "Sorry, I couldn't find the window"
-----------------------------------
May 16 '07 #4

P: n/a
Thanks guys, especially Duncan !

That's what I'm using now:

import sys
from win32gui import GetWindowText, EnumWindows, ShowWindow
from win32con import SW_MINIMIZE

def listWindowsHandles():
res = []
def callback(hwnd, arg):
res.append(hwnd)
EnumWindows(callback, 0)
return res

def listWindowsNames():
return (map(GetWindowText, listWindowsHandles()))

def minimizeWindow():
a_hwnd = listWindowsHandles()[listWindowsNames().index(sys.argv[1])]
ShowWindow(a_hwnd, SW_MINIMIZE)

minimizeWindow()

May 17 '07 #5

P: n/a
Thanks guys, especially Duncan !

That's what I'm using now:

import sys
from win32gui import GetWindowText, EnumWindows, ShowWindow
from win32con import SW_MINIMIZE
def listWindowsHandles():
res = []
def callback(hwnd, arg):
res.append(hwnd)
EnumWindows(callback, 0)
return res

def listWindowsNames():
return (map(GetWindowText, listWindowsHandles()))

def minimizeWindow():
a_hwnd = listWindowsHandles()[listWindowsNames().index(sys.argv[1])]
ShowWindow(a_hwnd, SW_MINIMIZE)

minimizeWindow()
May 17 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.