News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Drawing Desktop

Started by Bieb, June 21, 2005, 11:18:08 PM

Previous topic - Next topic

Bieb

Okay, so calling GetHandle with 0 as one of the parameters (I can't remember which at the moment) is supposed to give you a drawing handle for the desktop.  If you actually try drawing to this handle, what happens?  Does your stuff show up on the desktop?  Over the icons?  Under the icons?  Will it crash my machine?  This whole thing seems very interesting...

Ramon Sala

Hi Robert,

Have a look at the Easy Code Code attached project.

Ramon


[attachment deleted by admin]
Greetings from Catalonia

Tedd

I seem to remember a similar question about using SetPixel..
Drawing on the desktop is fine, it doesn't appear to crash. At a guess it will go ontop of the desktop background (picture), under any windows, and under icons (which are really just windows.)
No snowflake in an avalanche feels responsible.

MichaelW

It draws on top of everything.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
        hDC       dd 0
        screen_w  dd 0
        screen_h  dd 0
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke GetDC, 0
    mov   hDC, eax
    invoke GetSystemMetrics, SM_CXSCREEN
    mov   screen_w, eax
    invoke GetSystemMetrics, SM_CYSCREEN
    mov   screen_h, eax

    .WHILE (TRUE)
        invoke nrandom, screen_w
        mov   ebx, eax
        invoke nrandom, screen_h
        mov   esi, eax
        invoke nrandom, 32
        mov   edi, eax
        invoke GetPixel, hDC, ebx, esi
        add   esi, edi
        invoke SetPixel, hDC, ebx, esi, eax

        invoke crt__kbhit
        test    eax,eax
        jz    @F
        .BREAK
      @@:
    .ENDW

    invoke ReleaseDC, 0, hDC
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start

eschew obfuscation

Bieb

Hmm.  Is there a way to draw below windows and icons?

Dark Schneider

I guessed:

- Get desktop's DC
- Select a bitmap into that DC to get its old bitmap
- Draw into that old bitmap and select it back into desktop's DC

Will this work?
I don't know.

hutch--

Robert, here is a toy to test out, it places a button on the desktop and responds to it in a subclass procedure. The idea is to create a window with no background brush so its clear and write what you like to it using the desktop as a parent and respond as you like with a subclass or similar message handling procedure.

[attachment deleted by admin]
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MichaelW

I have not tried any bitmap-related functions yet, but SetPixel always fails for the desktop DC (GetDesktopWindow -> GetDC), and even though the GradientFill function returns success, the desktop is unaffected.
eschew obfuscation

Phil

#8
Michael and Hutch: Thanks for you concise examples. What Michael's program does is very similar to an Amiga hack named melt that I'd mentioned in another post. It blended the colors of surrounding pixels and worked it's way from the top of the screen downward to give it a melting appearance. Any keyboard or mouse activity caused the program to restore the original screen and exit. Maybe I'll try to find the old melt.c source and port it to MASM32!

I added InvalidateRect and UpdateWindow to Michael's original code to refresh the Desktop when the program exits. I'm not sure that this will work under all versions of Windows because the window handle I'm using is NULL (0) like it is for GetDC. I think it will probably be okay though.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
        hDC       dd 0
        screen_w  dd 0
        screen_h  dd 0
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke GetDC, 0
    mov   hDC, eax
    invoke GetSystemMetrics, SM_CXSCREEN
    mov   screen_w, eax
    invoke GetSystemMetrics, SM_CYSCREEN
    mov   screen_h, eax

    .WHILE (TRUE)
        invoke nrandom, screen_w
        mov   ebx, eax
        invoke nrandom, screen_h
        mov   esi, eax
        invoke nrandom, 32
        mov   edi, eax
        invoke GetPixel, hDC, ebx, esi
        add   esi, edi
        invoke SetPixel, hDC, ebx, esi, eax

        invoke crt__kbhit
        test    eax,eax
        jz    @F
        .BREAK
      @@:
    .ENDW
    invoke InvalidateRect, 0, 0, FALSE
    invoke UpdateWindow, 0
    invoke ReleaseDC, 0, hDC
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


Update on melt.c:
Here's the heart of the matter that I'm working on porting from the original source:
FOREVER {
  message = (struct IntuiMessage *)GetMsg(win->UserPort);
  if(message != (struct IntuiMessage *)NULL) {
    class = message->Class;
    ReplyMsg(message);
    if(class == CLOSEWINDOW) {
      return;
    }
  }
  for(mask=1; mask<+(1<<DEPTH)-1; mask*=2) {
    u = RangeRand(scr->Width - 3) + 1;
    v = RangeRand(scr->Height - 3) + 1;
    x = RangeRand(scr->Width - 1 - u) + 1;
    y = RangeRand(scr->Height - 2 - v) + 1;
    dx = RangeRand(3) - 1;
    dy = RangeRand(3);  /* also try dy = RangeRand(3) - 1;  */

    BltBitMap(bitmap, x, y,
              bitmap, x+dx, y+dy,
              u, v, 0x0c0, mask, TempA);
  } /* end of for mask */

}     /* end of FOREVER */
}     /* end of melt */


And here's the *correct* info for both Leo Schwab and the author from the source. I had erroneously 'remembered' that Leo had written this one but I was mistaken yet again! Ahhhh, how I too loved my Amiga for better, for worse, for richer, for poorer, and for nice features like hardware assisted BitBlt! Ancient technology by todays graphics processor standards but truly amazing for a late 80's 68K system!

* Melt -- Yet another screen hack. This is the direct result of playing with Tilt too late at night.
Thank you Leo. Stephen B. Coy *


Vortex


Phil

#10
I've just delighted myself with an example of using BitBlt to draw to the desktop. I've been attempting to port an ancient program named 'melt' from the Amiga source years ago and I came up with an unusual, but interesting display hack.

Caution: This program makes it appear that your display and machine is loosing its senses. It waits for any key to be pressed before it exits and restores the machine. I do not think it could be considered to be harmful in any way but it could be aggravating if you loose focus on the Dos window where the application is expecting to hear a key-press. I'd like to add code to also exit on mouse activity but I would rather not open a window and set up a message loop to do it. Can anyone suggest a simple way to check?

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
        hDC       dd 0
        hdcCompat dd 0
        hdcScreen dd 0
        hbmScreen dd 0
        screen_w  dd 0
        screen_h  dd 0
        szDisplay  db "DISPLAY",0
        msg       db 100 dup(0)
    .code

Quake proc

        LOCAL w :DWORD, h :DWORD, x :DWORD, y :DWORD, x1 :DWORD, y1 :DWORD

        mov ebx, 60                 ; repeat 60 times for each call
top:
        mov eax, screen_w           ; width less than one-forth of screen
        shr eax, 2
        invoke nrandom, eax
        add eax, 1
        mov w, eax

        mov eax, screen_h           ; height less than one-eigth of screen
        shr eax, 3
        invoke nrandom, eax
        add eax, 1
        mov h, eax

        mov eax, screen_w           ; top-left-x
        sub eax, 1
        sub eax, w
        invoke nrandom, eax
        add eax, 1
        mov x, eax

        mov eax, screen_h           ; top-left-y
        sub eax, 2
        sub eax, h
        invoke nrandom, eax
        add eax, 2
        mov y, eax

        mov eax, 3                  ; destination top-left-x
        invoke nrandom, eax
        sub eax, 1
        add eax, x
        mov x1, eax

        mov eax, 3                  ; destination top-left-y
        invoke nrandom, eax
        sub eax, 1
        add eax, y
        mov y1, eax

        invoke BitBlt,hdcScreen,x,y,w,h,hdcScreen,x1,y1,SRCCOPY     

        sub ebx, 1
        jnz top

        ret

Quake endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    invoke GetDC, 0
    mov   hDC, eax
    invoke GetSystemMetrics, SM_CXSCREEN
    mov   screen_w, eax
    invoke GetSystemMetrics, SM_CYSCREEN
    mov   screen_h, eax
    invoke CreateDC,ADDR szDisplay, NULL, NULL, NULL
    mov hdcScreen, eax
    invoke CreateCompatibleDC, hdcScreen
    mov hdcCompat, eax
    invoke CreateCompatibleBitmap,hdcScreen,screen_w,screen_h
    mov hbmScreen, eax
    invoke SelectObject, hdcCompat, hbmScreen

    print chr$("Press any key to restore your screen. Don't mouse around!")
    print chr$(13,10,"If you loose focus on the Dos window then the quake")
    print chr$(" may",13,10,"last longer than you'd like!",13,10)

    invoke Sleep, 3000              ; display *caveat* for 3 seconds

    .WHILE (TRUE)
        invoke Sleep, 10            ; slow things down a bit
        invoke Quake
        invoke crt__kbhit
        test    eax,eax
        jz    @F
        .BREAK
      @@:
    .ENDW

    invoke DeleteObject, hdcCompat
    invoke DeleteObject, hbmScreen
    invoke DeleteDC, hdcScreen
    invoke InvalidateRect, 0, 0, FALSE
    invoke UpdateWindow, 0
    invoke ReleaseDC, 0, hDC

    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


Also, I think that I've allocated and properly deleted and released the graphics objects correctly but I'm still very new to Win32 so if anyone see's any problems please let me know so I can fix them and update the source.

Edit: Code modifed to Sleep for a bit and slow things down in main loop. Also, I reduced the maximum size of the choosen screen bitmap and this changed the effect slightly but reduced the time for the program to respond to a key-press, cleanup, and exit. Still searching for an easy way to detect any mouse or user activity so I can cleanup and exit when the user touches anything. Looks like I'm going to have to create a window and set up a message loop!


zooba

 :clap: That is very cool  :8)

Phil

I've finished an inital pass to wrap the Quake desktop writer above into a transparent window that exits as soon as the mouse or keyboard is touched. I also put the algorithm into a thread and set it to THREAD_PRIORITY_IDLE.

I was looking for a much simpler way to detect either keyboard or mouse activity but I haven't found it yet. Maybe this is the only reasonable way to do it. I'd appreciate any comments and especially hearing about any problems anyone may have running this on their machine.

It's not a useful program in any way but I was facinated by some of the 'ink blots' that appear as it thoroughly distorts the desktop! I'm still working on getting an adequate 'melt' algorithm to work and look like it should. I called this 'quake' because it reminded me of what the patterns on the screen might look like if they were caught in an earthquake.


[attachment deleted by admin]

Tedd

Small suggestion:

In your CreateWindowEx call, change the WS_OVERLAPPED style to WS_POPUP -- it removes the titlebar :wink (and border)
No snowflake in an avalanche feels responsible.

zooba

Another small suggestion:

Don't use a transparent window, just grab a shot of the desktop and draw that on the window. That way anything that updates (ie. Winamp) won't show up on top of the quake.

:U I really love this, looks great on a 1920x1250 display  :bg