I am trying to understand python's capability to use Windows Messages with pywin32 library. For this I have created 2 scripts that are supposed to run parralel to each other. One is a client that is supposed to send messages the other is a server that is supposed to print all incoming messages. To use window messeages I have given them gui windows with tkinter library.
But when I run them paralel server doesn't recieve any messages even though it seems that there are no errors and the windows handles check out. I made sure that I was reaching the correct handle using Microsoft Spy++ in Visual Studio.
I find their handles using this function:
def get_window_handle_by_tittle(tittle):
window_handle = [0]
def window_callback(hwnd, lParam):
window_tittle, window_handle = lParam
current_tittle = win32gui.GetWindowText(hwnd)
if current_tittle == window_tittle:
# check if this is the target window
window_handle[0] = hwnd
return False
else:
return True
try:
# Start the enumeration of top-level windows
lParam = (tittle, window_handle)
win32gui.EnumWindows(window_callback, lParam)
return window_handle[0]
except pywintypes.error as e:
if window_handle[0] and window_handle[0] != 0:
# Check window title if provided
return window_handle[0]
else:
return None
except Exception as e:
print(f"Error getting window handle: {e}")
And here are the code for client and the codes for client and the server that I run as different python scripts' main functions.
import time
import win32api
import win32gui
import tkinter as tk
import pywintypes
WM_USER = 0x0400
WM_STATEREQUEST = WM_USER + 1005
WM_STATEANSWER = WM_USER + 1006
def client:
root = tk.Tk()
root.title("WM_client")
root.geometry("400x300")
root.update()
root.deiconify()
python_hwnd = get_window_handle_by_tittle("WM_client")
print(f"Server handle is {hex(python_hwnd)}, starting listening")
target = get_window_handle_by_tittle("WM_server")
while True:
print(f"message to be sent {hex(int(target))}, {WM_STATEREQUEST} , {hex(python_hwnd)}, 0")
response = win32api.SendMessage(target, WM_STATEREQUEST, python_hwnd, 0)
print("server sent message response code", response)
print("last error given", win32api.GetLastError())
time.sleep(1)
def server:
root = tk.Tk()
root.title("WM_server")
root.geometry("400x300")
root.update()
root.deiconify()
python_hwnd = get_window_handle_by_tittle("WM_server")
print(f"Server handle is {hex(python_hwnd)}, starting listening")
while True:
msg = win32gui.PeekMessage(python_hwnd, 0, 100, win32con.PM_NOREMOVE)
if msg[0] != 0:
# Extract values from the tuple
window_handle, message_type, w_param, l_param, time_posted, (cursor_x, cursor_y) = msg[1]
if message_type != 96:
# exclude windows paint messages
# Print each value
print("\nWindow Handle:", window_handle)
print("Message Type:", hex(message_type), message_type)
print("wParam:", w_param)
print("lParam:", l_param, "\n")
Again this is not a problem with Server's PeekMessage function but instead with client. Because if that were e the case I would have been able too see them using Spy++. So right now I don't believe I need to make a hook function instead of pywin32's peek message function. Problem here is messages are not being sent or atleast not being sent to the correct window somehow.
I have expecerd the server to print out the messages that are send by SendMessage() function. Especially after confirming the window handles of the script windows.