I'm trying to paint over an external application's window, in my case more specifically the desktop and behind all visible icons.
I figured out after trial and error that you can use:
WinDef.HWND desktop = User32.INSTANCE.FindWindow(null, "Desktop");
WinDef.HDC desktopWindow = User32.INSTANCE.GetDC(desktop);
for (int i=0; i<1920; i++) {
for (int j=0; j<1080; j++) {
GDI32.INSTANCE.SetPixel(desktopWindow, i, j, 155);
}
}
However, this draws above everything in front of the screen and is extremely slow. It takes around 22 seconds to fill my screen.
Is there a correct way of drawing shapes or images directly on the desktop? (Behind the icons)
EDIT: I've found a way of painting behind the icons, thanks to this article: https://www.codeproject.com/articles/856020/draw-behind-desktop-icons-in-windows
But there is still the problem that SetPixel is too slow
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.GDI32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
public class Main {
private static WinDef.HWND workerw = null;
public static void main(String[] args) {
init();
if (workerw != null) {
WinDef.HDC desktopWindow = User32.INSTANCE.GetDC(workerw);
for (int i=0; i<1920; i++) {
for (int j=0; j<1080; j++) {
GDI32.INSTANCE.SetPixel(desktopWindow, i, j, 100);
}
}
User32.INSTANCE.ReleaseDC(workerw, desktopWindow);
}
}
private static void init() {
WinDef.HWND progman = User32.INSTANCE.FindWindow("Progman", null);
User32.INSTANCE.PostMessage(progman, 0x052C, new WinDef.WPARAM(0), new WinDef.LPARAM(0));
User32.INSTANCE.SendMessageTimeout(progman, 0x052C, new WinDef.WPARAM(0), new WinDef.LPARAM(0), User32.SMTO_NORMAL, 1000, new WinDef.DWORDByReference());
User32.INSTANCE.EnumWindows((hwnd, pntr) -> {
WinDef.HWND p = User32.INSTANCE.FindWindowEx(hwnd, new WinDef.HWND(Pointer.createConstant(0)), "SHELLDLL_DefView", null);
if (p != null) {
workerw = User32.INSTANCE.FindWindowEx(new WinDef.HWND(Pointer.createConstant(0)), hwnd, "WorkerW", null);
}
return true;
}, Pointer.createConstant(0));
}
}
If there's an alternative to GDI32.INSTANCE.SetPixel
it would be great.
Edit2: I read about the BitBlt function (which is included in JNA), I am unsure how to use it to copy an bitmap to the HDC. https://msdn.microsoft.com/en-us/library/windows/desktop/dd183370(v=vs.85).aspx