Python - ctypes
Jump to navigation
Jump to search
Tutorials
See:
- http://docs.python.org/lib/ctypes-ctypes-tutorial.html
- http://starship.python.net/crew/theller/ctypes/tutorial.html
References
- http://wiki.python.org/moin/ctypes
- http://bytes.com/topic/python/answers/607023-c_string-missing-ctypes
Simple Examples
The API exported from the demo DLL is as follows:
extern "C" {
__declspec(dllexport) char* next(int id);
__declspec(dllexport) void next_s(char* buf, int buflen, int id);
__declspec(dllexport) void xxx_s(char* buf, int buflen, int id);
}
#!/usr/bin/env python
import ctypes
import pprint
libx = ctypes.CDLL('x')
pprint.pprint(x.__dict__)
print type(x)
x.next.restype = ctypes.c_char_p
print "%s\n" % x.next(4)
GUI Examples
TestGUI
import win32api
import win32con
import win32gui
##a = 0
##b = 1
##while b < 10:
## print b
## a, b = b, a+b
##def windowEnumerationHandler(hwnd, resultList):
##
## '''Pass to win32gui.EnumWindows() to generate list of window handle, window text tuples.'''
##
## resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
## print resultList;
def windowEnumerationHandler(hwnd, resultList):
'''Pass to win32gui.EnumWindows() to generate list of window handle, window text, window class tuples.'''
resultList.append((hwnd, win32gui.GetWindowText(hwnd), win32gui.GetClassName(hwnd)))
## resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
# print resultList;
import ctypes
##def getClassName(hwnd):
## resultString = ctypes.c_string("\000" * 32)
## ctypes.windll.user32.GetClassNameA(hwnd, resultString, len(resultString))
## return resultString.value
topWindows = []
win32gui.EnumWindows(windowEnumerationHandler, topWindows)
##def findTopWindow(wantedText=None, wantedClass=None):
## topWindows = []
## win32gui.EnumWindows(windowEnumerationHandler, topWindows)
## for hwnd, windowText, windowClass in topWindows:
## if wantedText and not windowText.startswith(wantedText):
## continue
## if wantedClass and not windowClass == wantedClass:
## continue
## return hwnd
# Please correct me if I'm wrong anywhere
#
# when a program executes it adds a top level window handle to the system
#
# window handles are unique across the system at any given time
# window handles are assigned by the operating system for each execution of a program,
# and therefore a window cannot be referred to by its window handle from a previous
# execution run
#
# in order to find a particular window handle (control), for example a button (so that we
# can send a win32con.WM_LBUTTONDOWN message) we need to start a the programs top level window
# and search the window handle tree until we find the desired control.
#
# uniquely identifying a control requires prior knowledge about the hierarchical
# layout of the interested program's windows, because even Control IDs can be used multiple
# times for different windows
#
# while depth > 0
# check current handle against what we want (window text, window class, control ID?)
# at the specified array[depth]
#
# if check is good
#
# hwnd = win32gui.GetParent()
# if hwnd is NULL return
# else
# depth--
#
# end while
# return true!
# win32event.WaitForInputIdle
def findControl(topHwnd, selectionFunction):
def searchChildWindows(currentHwnd):
childWindows = []
try:
win32gui.EnumChildWindows(currentHwnd, windowEnumerationHandler, childWindows)
except win32gui.error, exception:
# This seems to mean that the control does *cannot* have child windows
return
for childHwnd, windowText, windowClass in childWindows:
print "Found ", childHwnd, windowText, windowClass
print win32gui.HIWORD(childHwnd)
if win32gui.IsWindow(childHwnd):
print "it is a window"
someID = 0x0000E900
try:
dlgitem = win32gui.GetDlgItem(childHwnd, someID)
print "WOOO", childHwnd, dlgitem
except:
print "not here"
## hTmp = ::GetDlgItem( m_hToolBarsParent, lId );
## if( hTmp != NULL )
## m_mapTool.insert( TIdMap::value_type( ::GetDlgCtrlID( hTmp ), hTmp ) );
##
## lId++;
if selectionFunction(childHwnd, windowText, windowClass):
return childHwnd
else:
descendentMatchingHwnd = searchChildWindows(childHwnd)
if descendentMatchingHwnd:
return descendentMatchingHwnd
return
return searchChildWindows(topHwnd)
def keystroke(hwnd, key):
win32gui.SendMessage(hwnd, win32con.WM_KEYDOWN, key, 0)
win32gui.SendMessage(hwnd, win32con.WM_KEYUP, key, 0)
##win32gui.FindWindow("None", "PythonWin")
#eudoraMain = win32gui.FindWindow("EudoraMainWindow", "Eudora - [benjamin.lee (<Dominant>)]")
# py_hwnd = win32gui.FindWindow("Afx:400000:8:10011:0:2a07cf", "PythonWin")
py_hwnd = win32gui.FindWindow("Afx:400000:8:10011:0:6000d5", "PythonWin")
win32gui.PostMessage(0x000100D0, win32con.WM_LBUTTONDOWN, 0x00000001, 0x000A0099)
win32gui.PostMessage(0x000100D0, win32con.WM_LBUTTONUP, 0x00000000, 0x000A0099)
print win32gui.GetActiveWindow()
print win32gui.GetForegroundWindow()
#win32gui.SendMessage(py_hwnd, win32con.WM_SYSKEYDOWN, win32con.VK_MENU, 0)
print win32gui.GetActiveWindow()
print win32gui.GetForegroundWindow()
#win32gui.SendMessage(py_hwnd, win32con.WM_SYSKEYDOWN, ord('F'), 0)
print win32gui.GetActiveWindow()
print win32gui.GetForegroundWindow()
#win32gui.SendMessage(py_hwnd, win32con.WM_SYSCHAR, ord('f'), 0)
print win32gui.GetActiveWindow()
print win32gui.GetForegroundWindow()
# win32gui.SendMessage(py_hwnd, win32con.WM_SYSCOMMAND, win32con.SC_KEYMENU, 0)
print win32gui.GetActiveWindow()
print win32gui.GetForegroundWindow()
# keystroke(py_hwnd, ord('F'))
#win32gui.SendMessage(py_hwnd, win32con.WM_KEYDOWN, ord('o'), 0)
#win32gui.SendMessage(py_hwnd, win32con.WM_CHAR, ord('o'), 0)
#win32gui.SendMessage(py_hwnd, win32con.WM_KEYUP, win32con.VK_MENU, 0)
print win32gui.GetActiveWindow()
print win32gui.GetForegroundWindow()
#win32gui.SendMessage(py_hwnd, win32con.WM_KEYUP, ord('F'), 0)
# win32gui.SendMessage(py_hwnd, win32con.WM_COMMAND, 57601, 0)
print "hello", win32gui.LOWORD(py_hwnd), win32gui.HIWORD(py_hwnd)
# win32gui.
# e900
# win32gui.SendMessage(py_hwnd, win32con.WM_SYSKEYUP, ord('F'), 0)
##optDialog = findTopWindow(wantedText="Options")
## print optDialog
import time
##fgw = win32gui.GetForegroundWindow()
##win32gui.SetForegroundWindow(eudoraMain)
##
##
##def syskeystroke (key):
## win32api.keybd_event( key,
## 0x45,
## win32con.KEYEVENTF_EXTENDEDKEY | 0,
## 0 );
## win32api.keybd_event( key,
## 0x45,
## win32con.KEYEVENTF_EXTENDEDKEY | win32con.KEYEVENTF_KEYUP,
## 0);
##
##syskeystroke (win32con.VK_NUMLOCK)
##syskeystroke (win32con.VK_MENU)
##
##print ord("F")
##
##syskeystroke (ord ("F"))
##syskeystroke (ord ("I"))
##time.sleep(2)
##syskeystroke (win32con.VK_ESCAPE)
##
####syskeystroke (win32con.VK_CONTROL)
####syskeystroke (ord ("N"))
##
### combo Ctrl+N
##win32api.keybd_event( win32con.VK_CONTROL, 0x45, win32con.KEYEVENTF_EXTENDEDKEY | 0, 0 );
##win32api.keybd_event( ord ("N"), 0x45, win32con.KEYEVENTF_EXTENDEDKEY | 0, 0 );
##win32api.keybd_event( ord ("N"), 0x45, win32con.KEYEVENTF_EXTENDEDKEY | win32con.KEYEVENTF_KEYUP, 0);
##win32api.keybd_event( win32con.VK_CONTROL, 0x45, win32con.KEYEVENTF_EXTENDEDKEY | win32con.KEYEVENTF_KEYUP, 0);
##
##
##time.sleep(2)
##
##win32gui.SetForegroundWindow(fgw)
##
##win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYDOWN, win32con.VK_MENU, 0)
###win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYDOWN, (ord("F") | 0x20000000 ), 0)
##
##win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYDOWN, ord("F"), 0)
###keystroke(eudoraMain, "f")
###keystroke(eudoraMain, "i")
###win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYDOWN, "F", 0)
##
##win32gui.SendMessage(eudoraMain, win32con.WM_SYSCHAR, "X", 0)
##win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYUP, ord("F"), 0)
##
##win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYUP, win32con.VK_MENU, 0)
#win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYUP, (ord("F") | 0x20000000 ), 0)
#win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYDOWN, (ord("X") | 0x20000000 ), 0)
#win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYUP, (ord("X") | 0x20000000 ), 0)
#win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYDOWN, 'I', 0)
#win32gui.SendMessage(eudoraMain, win32con.WM_SYSKEYUP, 'I', 0)
## wm_syskeydown for VK_MENU (alt)
## wm_syskeydown for Ord('F')
## wm_syschar for 'F'
## wm_syskeyup for Ord('F'),
## wm_syskeyup for VM_MENU
#keystroke(eudoraMain, "i")
exit
def findAButtonCalledOK(hwnd, windowText, windowClass):
return windowClass == "Button" and windowText == "OK"
def findAButtonCalledDate(hwnd, windowText, windowClass):
return windowClass == "Button" and windowText == "S&ubject"
#return windowClass == "Button" and windowText == "&Date"
# okButton = findControl(eudoraMain, findAButtonCalledOK)
#okButton = findControl(py_hwnd, findAButtonCalledOK)
## dateButton = findControl(eudoraMain, findAButtonCalledDate)
def click(hwnd):
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, 0, 0)
win32gui.SendMessage(hwnd, win32con.WM_LBUTTONUP, 0, 0)
# click(dateButton)
##
##
####optDialog = findTopWindow(wantedText="Options")
####
####okButton = findControl(optDialog, lambda hwnd, windowText, windowClass : windowClass == "Button" and windowText == "OK")
####
####click(okButton)
##
##
##def getEditText(hwnd):
##
## result = []
##
## bufferlength = struct.pack('i', 255)
##
## linecount = win32gui.SendMessage(hwnd, win32con.EM_GETLINECOUNT, 0, 0)
##
## for line in range(linecount):
##
## linetext = bufferlength + "".ljust(253)
##
## linelength = win32gui.SendMessage(hwnd, win32con.EM_GETLINE, line, linetext)
##
## result.append(linetext[:linelength])
##
## return result
##
##
##genTop = findTopWindow(wantedText="Generating the Runtime")
##
##def editFinder(hwnd, windowText, windowClass): return windowClass == "Edit"
##
##genEdit = findControl(genTop, editFinder)
##
##print getEditText(genEdit)
##
##def getMultipleWindowValues(hwnd, getCountMessage, getValueMessage):
##
## bufferlength = struct.pack('i', 255)
##
## count = win32gui.SendMessage(hwnd, getCountMessage, 0, 0)
##
## for itemIndex in range(count):
##
## value = array.array('c', bufferlength + str().ljust(253))
##
## valueLength = win32gui.SendMessage(hwnd, getValueMessage, itemIndex, value)
##
## yield value.tostring()[:valueLength]
##
##
##def getComboboxItems(hwnd): return getMultipleWindowValues(hwnd, getCountMessage=win32con.CB_GETCOUNT, getValueMessage=win32con.CB_GETLBTEXT)
##def getEditText(hwnd): return getMultipleWindowValues(hwnd, getCountMessage=win32con.EM_GETLINECOUNT, getValueMessage=win32con.EM_GETLINE)
##
##
##def selectComboboxItem(hwnd, item):
##
## win32gui.SendMessage(hwnd, win32con.CB_SETCURSEL, item, 0)
##
## click(hwnd)
##
## keystroke(hwnd, win32con.VK_RETURN)
##
##
##
##
##
### Find the ACE window library selection combo
##
##def findAceLibrarySelectionFunction(hwnd, windowText, windowClass): return windowClass == "ComboBox" and ("EVO1" in getComboboxItems(hwnd))
##
##libCombo = findControl(findTopWindow(wantedText="ACE"), findAceLibrarySelectionFunction)
##
##
### Get a list of the combo items
##items = getComboboxItems(libCombo)
##print "Items: " + str(items)
##import random
##
##
### Pick one at random, and select it
##selectItemIndex = random.randrange(len(items))
##print "Selecting: " + items[selectItemIndex]
##selectComboboxItem(libCombo, selectItemIndex)
A scrap of sample code from a past SVT exercise implemented using Python and ctypes:
#!/usr/bin/env python
## import ctypes
from ctypes import *
from ctypes.wintypes import *
import win32con
import sys
import time
#dll = windll.MouseHook
# the dll is called hooksm.dll
dll = cdll.hooksm
#startfn = dll.setMyHook
#stopfn = dll.clearMyHook
# startfn()
dll.search_msg = c_int (win32con.WM_SETTEXT)
#windll.user32.DefWindowProcA(c_int(hwnd), c_int(message), c_int(wParam), c_int(lParam))
txt = "Analysis is complete for:"
startfn = dll.hksmSetHook
#startfn.argtypes = [c_ulong, c_int, c_uint, c_long, c_char_p, c_ulong]
startfn (
# c_ulong(0x00000238),
c_ulong(0x00000000),
c_int (win32con.WM_SETTEXT),
c_uint(win32con.NULL),
c_char_p(txt),
0x00000000
)
startt = time.time()
print startt
#time.sleep(20)
print "sync pre"
syncfn = dll.Synchronize
print "sync start"
syncfn()
print "sync stop"
endt = time.time()
print endt
print endt - startt
dll.hksmUnsetHook ()
#stopfn()
#flog = dll.log