Actualizado 23/10/2018.
Una de las características más interesantes que presenta CPython es que corre bajo gran cantidad de sistemas operativos. Es por esto que la mayoría de nuestros programas podrán ejecutarse con normalidad en diversas plataformas sin modificar el código original. Python nos permite acceder al API de Windows, por lo que, al utilizarse, el código en cuestión sólo podrá ejecutarse en dicho sistema operativo. El simple hecho de hacerlo le quitaría al lenguaje una de sus cualidades, a mi parecer, más útiles. Sin embargo, en muchas ocasiones resulta conveniente tener acceso a la gran cantidad de funciones que nos presenta el sistema de las ventanas. Es por eso que he decidido dar a conocer los siguientes métodos para lograrlo.
Pywin32
El paquete se instala sencillamente vía pip:
pip install pywin32
Actualmente soporta Python 2.7 y 3.x, tanto sistemas de 32 bits como 64 bits. De todas maneras, es importante aclarar que si cuentas con un sistema de 64 bits pero te manejas con un intérprete de 32, deberás instalar la versión de 32 bits del paquete. Para determinar la versión de Python que actualmente corres, basta con abrir la línea de comandos del intérprete y observar la primera línea en la que encontrarás los detalles.
Sin nada más que aclarar, un ejemplo en el que ejecuto un sonido por el altavoz, muevo la posición del cursor y muestro un mensaje en pantalla:
from win32api import Beep, GetCursorPos, SetCursorPos, MessageBox from win32con import MB_OK if __name__ == "__main__": Beep(200, 200) pos = GetCursorPos() SetCursorPos((pos[0] + 100, pos[1] + 100)) MessageBox(0, "Listo.", "Ejemplo Windows API", MB_OK)
El módulo win32api
cuenta con gran cantidad de las funciones generales del API y win32con presenta numerosas constantes. Con la instalación de Pywin32 también obtenemos otros como win32gui para funciones en relación con interfaces gráficas, win32net, entre otras.
ctypes
Con el módulo ctypes
también es posible acceder al API de Windows, y lo mejor, es parte de la librería estándar. Incluso, permite el acceso a gran cantidad de funciones del API las cuales no podremos encontrar, al menos por ahora, en Pywin32. Este módulo nos permite cargar cualquier librería mediante la función LoadLibrary
. Sin embargo, no es necesario hacerlo con user32 y kernel32 (en donde se encuentran las funciones del API), ya que ctypes lo realiza automáticamente al iniciarse.
A continuación, el mismo ejemplo anterior con ctypes. A diferencia de Pywin32, ctypes no cuenta con las constantes como MB_OK
, ni funciones adaptadas a los tipos propios del lenguaje (tuplas, listas), y en el caso de MessageBox
, deberemos especificar si se trata de ANSI o UNICODE (MessageBoxA
y MessageBoxW
, respectivamente).
from ctypes import c_int, pointer, Structure, windll MB_OK = 0x00000000 class POINT(Structure): _fields_ = [("x", c_int), ("y", c_int)] if __name__ == "__main__": pos = POINT() windll.kernel32.Beep(200, 200) windll.user32.GetCursorPos(pointer(pos)) windll.user32.SetCursorPos(pos.x + 100, pos.y + 100) windll.user32.MessageBoxA(0, "Listo.", "Ejemplo Windows API", MB_OK)
La función GetCursorPos
toma como argumento un puntero que se dirige a una variable del tipo POINT
para almacenar las coordenadas. Como en Python no es posible especificar si se trata de una variable por valor o referencia, hacemos uso de la función ctypes.pointer
. Nótese también la creación de la clase POINT
simulando una estructura.
Como habrás visto, el método de ctypes es ligeramente más complicado. Ambas alternativas para acceder al API cuentan con ventajas y desventajas; se trata de elegir la más adecuada para la tarea que deseas realizar.
Ante cualquier inquietud o duda, no olvides dejar tu comentario.
Curso online 👨💻
¡Ya lanzamos el curso oficial de Recursos Python en Udemy!
Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter
en 2024.
Consultoría 💡
Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.
kbzaloka says:
el proyecto se ha movido aquí:
https://pypi.org/project/pywin32/#files
Victor says:
Saludos amigos.. tengo una api EZClient.dll que contiene una función llamada ClientLogon con los siguientes parámetros
[…]
Al ejecutarlo me da error de argumento y no logro resolverlo. Si alguien podría ayudarme les estaré muy agradecido desde ya gracias
Recursos Python says:
Hola Victor, para estos casos te invito a que crees un tema en el foro para que lo podamos ver con mayor detalle.
Saludos
carlos says:
Hola, acabo de asomarme al mundo del api de windows y me gustaria saber si usando phyton, se puede acceder a todos los metodos que hay relativos a las ventanas, ejemplo :
– se puede acceder a la función GetWindowRect -> según el api de windows se define asi:
BOOL WINAPI GetWindowRect (
_In_ HWND hWnd,
_Out_ LPRECT lpRect
);
Gracias,
Muy buen aporte, empezaré a trastear un poco haber como se me da.
Recursos Python says:
Hola Carlos. Sí, es posible acceder a las funciones relacionadas con ventanas, tanto con pywin32 (vía
import win32gui
) como con ctypes. Si tenés algun problema podés crear un tema en el foro para verlo en detalle.Un saludo.
Andres Niño says:
Excelente post, por casualidad conoces de alguna forma para que el MessageBox se cierre automáticamente después de cierto tiempo.
Recursos Python says:
Hola. Se me ocurre que puedes usar
SendMessage
para enviarWM_CLOSE
al mensaje una vez transcurrido un determinado tiempo. Si tienes problemas te invito a que crees un nuevo tema en el foro y lo vemos.Un saludo.