1

I have been searching for code to help solve this problem. here is the best answer I could find below.

import win32api
import win32con
import win32gui
import time
import threading

#Code example modified from:
#Christophe Keller
#Hello World in Python using Win32

# New code: Define global
windowText = 'Hello send by Python via Win32!'

def main():
    #get instance handle
    hInstance = win32api.GetModuleHandle()

    # the class name
    className = 'SimpleWin32'

    # create and initialize window class
    wndClass                = win32gui.WNDCLASS()
    wndClass.style          = win32con.CS_HREDRAW | win32con.CS_VREDRAW
    wndClass.lpfnWndProc    = wndProc
    wndClass.hInstance      = hInstance
    wndClass.hIcon          = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
    wndClass.hCursor        = win32gui.LoadCursor(0, win32con.IDC_ARROW)
    wndClass.hbrBackground  = win32gui.GetStockObject(win32con.WHITE_BRUSH)
    wndClass.lpszClassName  = className

    # register window class
    wndClassAtom = None
    try:
        wndClassAtom = win32gui.RegisterClass(wndClass)
    except Exception as e:
        print (e)
        raise e

    hWindow = win32gui.CreateWindow(
        wndClassAtom,                   #it seems message dispatching only works with the atom, not the class name
        'Python Win32 Window',
        win32con.WS_OVERLAPPEDWINDOW,
        win32con.CW_USEDEFAULT,
        win32con.CW_USEDEFAULT,
        win32con.CW_USEDEFAULT,
        win32con.CW_USEDEFAULT,
        0,
        0,
        hInstance,
        None)

    # Show & update the window
    win32gui.ShowWindow(hWindow, win32con.SW_SHOWNORMAL)
    win32gui.UpdateWindow(hWindow)

    # New code: Create and start the thread
    thr = threading.Thread(target=customDraw, args=(hWindow,))
    thr.setDaemon(False)
    thr.start()

    # Dispatch messages
    win32gui.PumpMessages()


# New code: Attempt to change the text 1 second later
def customDraw(hWindow):
    global windowText
    time.sleep(1.0)
    windowText = 'Something new'
    win32gui.RedrawWindow(hWindow, None, None, win32con.RDW_INVALIDATE | win32con.RDW_ERASE)


def wndProc(hWnd, message, wParam, lParam):

    if message == win32con.WM_PAINT:
        hDC, paintStruct = win32gui.BeginPaint(hWnd)

        rect = win32gui.GetClientRect(hWnd)
        win32gui.DrawText(
            hDC,
            windowText,
            -1,
            rect,
            win32con.DT_SINGLELINE | win32con.DT_CENTER | win32con.DT_VCENTER)

        win32gui.EndPaint(hWnd, paintStruct)
        return 0

    elif message == win32con.WM_DESTROY:
        print('Being destroyed')
        win32gui.PostQuitMessage(0)
        return 0

    else:
        return win32gui.DefWindowProc(hWnd, message, wParam, lParam)

if __name__ == '__main__':
    main()

unfortunately the output is "Hello send by Python via Win32!" and then "something new"

this is a good start but I need "something new" to update to "something new 2" and "something new 3" etc

is there anyway I can display "something new 2" and "something new 3" and so on, from a text file containing "something new" "something new 2" "something new 3" and so on?

the updating "windowText = something new" would be very long if I had to input that over and over so maybe it would be better to display a line of a text file one by one.

so my question is this how can I display text from a text file one line at a time as "something new"

or how can I display "something new 2" "something new 3" etc easily using the current code?

Steed
  • 61
  • 9

1 Answers1

1

Use SetTimer instead of creating additional threads. Example:

import win32api, win32con, win32gui
import timer

windowText = 'Hello send by Python via Win32!'
hWindow = 0

def main():
    hInstance = win32api.GetModuleHandle()
    className = 'SimpleWin32'

    wndClass                = win32gui.WNDCLASS()
    wndClass.style          = win32con.CS_HREDRAW | win32con.CS_VREDRAW
    wndClass.lpfnWndProc    = wndProc
    wndClass.hInstance      = hInstance
    wndClass.hIcon          = win32gui.LoadIcon(0, win32con.IDI_APPLICATION)
    wndClass.hCursor        = win32gui.LoadCursor(0, win32con.IDC_ARROW)
    wndClass.hbrBackground  = win32gui.GetStockObject(win32con.WHITE_BRUSH)
    wndClass.lpszClassName  = className
    wndClassAtom = win32gui.RegisterClass(wndClass)

    hWindow = win32gui.CreateWindow(wndClassAtom,                   
        'Python Win32 Window',
        win32con.WS_OVERLAPPEDWINDOW, 0, 0, 600, 400, 0, 0, hInstance, None)

    win32gui.ShowWindow(hWindow, win32con.SW_SHOWNORMAL)
    win32gui.UpdateWindow(hWindow)
    timer.set_timer(1000, customDraw)
    win32gui.PumpMessages()

counter = 0
def customDraw(timer_id, time):
    global hWindow
    global counter
    global windowText
    if counter > 2:
        counter = 0
    text = ["test 0", "test 1", "test 2"]
    windowText = text[counter]
    counter = counter + 1
    win32gui.InvalidateRect(hWindow, None, True)

def wndProc(hWnd, message, wParam, lParam):
    if message == win32con.WM_PAINT:
        hDC, paintStruct = win32gui.BeginPaint(hWnd)
        rect = win32gui.GetClientRect(hWnd)
        win32gui.DrawText(hDC, windowText, -1, rect,
            win32con.DT_SINGLELINE | win32con.DT_CENTER | win32con.DT_VCENTER)
        win32gui.EndPaint(hWnd, paintStruct)
        return 0

    elif message == win32con.WM_DESTROY:
        print('Being destroyed')
        win32gui.PostQuitMessage(0)
        return 0

    else:
        return win32gui.DefWindowProc(hWnd, message, wParam, lParam)

if __name__ == '__main__':
    main()
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77
  • thank you it took a little bit to work in your solution to my code but it works! thank you kindly! – Steed Feb 22 '19 at 13:23