I am not an expert and I am trying to show a rectangle on screen which follows mouse movements from a settle starting point, just as when you select something in word or paint. I came with this code:
import win32gui
m=win32gui.GetCursorPos()
while True:
n=win32gui.GetCursorPos()
for i in range(n[0]-m[0]):
win32gui.SetPixel(dc, m[0]+i, m[1], 0)
win32gui.SetPixel(dc, m[0]+i, n[1], 0)
for i in range(n[1]-m[1]):
win32gui.SetPixel(dc, m[0], m[1]+i, 0)
win32gui.SetPixel(dc, n[0], m[1]+i, 0)
As you can see, the code will draw the rectangle, but the previous ones will remain until the screen updates.
The only solution I've came with is to take the pixel values i will paint before set them black, and redraw them every time, but this makes my code pretty slow. Is there an easy way to update the screen faster to prevent this?
...
Edited with solution.
As suggested by @Torxed, using win32gui.InvalidateRect solved the updating problem. However, I found that setting only the color of the points I need to be set is cheaper than asking for a rectangle. The first solution renders quite clean, while the second remains a little glitchy. At the end, the code that worked the best for me is:
import win32gui
m=win32gui.GetCursorPos()
dc = win32gui.GetDC(0)
while True:
n=win32gui.GetCursorPos()
win32gui.InvalidateRect(hwnd, (m[0], m[1], GetSystemMetrics(0), GetSystemMetrics(1)), True)
back=[]
for i in range((n[0]-m[0])//4):
win32gui.SetPixel(dc, m[0]+4*i, m[1], 0)
win32gui.SetPixel(dc, m[0]+4*i, n[1], 0)
for i in range((n[1]-m[1])//4):
win32gui.SetPixel(dc, m[0], m[1]+4*i, 0)
win32gui.SetPixel(dc, n[0], m[1]+4*i, 0)
The division and multiplication by four is necessary to avoid flickering, but is visually the same as using DrawFocusRect.
This will only work if you remain bellow and to the right from your initial position, but it is just what I needed. Not difficult to improve it to accept any secondary position.