The MASM Forum

General => The Workshop => Windows Graphics Programming => Topic started by: NoCforMe on April 25, 2025, 11:54:11 AM

Title: Moving things around the screen w/GDI
Post by: NoCforMe on April 25, 2025, 11:54:11 AM
Another project with problems.

I'm trying to learn how to move things around the screen with the mouse, using GDI.
Previously I was moving child controls around, for my DialogGen on-screen dialog editing program, so I pretty much know how to do that (although there are still problems with that scheme).

This time I'm moving other things around. Mainly bitmaps at this point.
I'm able to move them pretty well, but there are problems. Mainly flicker. Actually pretty horrible flicker.

(Use the attached program and move the NPN transistor around and see what happens.)

For the time being I'd like to keep this on a conceptual level and proceed without posting any code. (I'll be happy to do that later.) This isn't so much a problem with coding as it is with design, and with understanding how the OS works with graphics and what its limitations are.

What I'm doing is this:

OK, now that I have a memory DC, I'm doing this:


As you can see this works, but at a very high price. If you move the mouse at any speed above s-l-o-w, it flickers badly.

Any ideas here? I'm pretty sure I'm doing what I'm doing correctly, so far as coding goes. In other words, I don't think this is a matter of bugs. More a case of poor use of resources.

Am I doing too much moving of stuff between DCs? is that what's causing the flicker?
I was hoping that by only copying a small part of AltDC to the display for each mouse move that I'd be avoiding too much processing.

Should I be doing some kind of double buffering? (Not even sure how that works, to be honest.)

Any better way to do what I'm trying to do here?
Title: Re: Moving things around the screen w/GDI
Post by: zedd on April 25, 2025, 12:04:17 PM
For starters, you have a gdi leak...

Also, double buffering would indeed help.

untitled.PNG

ALso that white rectangle with border appears sometimes when moving the transistor around.
Title: Re: Moving things around the screen w/GDI
Post by: NoCforMe on April 25, 2025, 12:08:50 PM
Quote from: zedd on April 25, 2025, 12:04:17 PMFor starters, you have a gdi leak...
No doubt. Let's not worry about that for the moment. That's not the problem.

QuoteAlso, double buffering would indeed help.
I'm going to read up on it next thing.

Well, a quick read showed ... basically the code I have now.

Question: Does using double buffering mean that I draw everything to a separate buffer (my AltDC) and then copy that entire thing over to the display DC? Because I'm not doing that exactly.
Title: Re: Moving things around the screen w/GDI
Post by: zedd on April 25, 2025, 12:13:54 PM
This is how I would do it... and so far works for me.
If you have the client area already from GetClientRect, you can use that here instead of ps.rcPaint...

        .elseif uMsg == WM_ERASEBKGND          ; adding this helps greatly with flicker issues
          mov eax, 1
          ret
        .elseif uMsg == WM_PAINT
          invoke BeginPaint, hWin, addr ps
          mov hDC, eax                          ; window client area DC
          invoke CreateCompatibleDC, hDC
          mov memDC, eax                        ; memory DC

          invoke CreateCompatibleBitmap, hDC, ps.rcPaint.right, ps.rcPaint.bottom
          mov hBmp, eax                        ; compatible bitmap handle
          invoke SelectObject, memDC, hBmp
          mov hBmp_old, eax

          ;; ###########################################################

          ;; in this example do all of your drawing here to memory DC (memDC) not to window DC (hDC)



          ;; ###########################################################
          ;; bitblt memory Dc to window DC
          invoke BitBlt, hDC, 0, 0, ps.rcPaint.right, ps.rcPaint.bottom, memDC, 0, 0, SRCCOPY
          invoke SelectObject, memDC, hBmp_old
          invoke DeleteObject, hBmp
          invoke DeleteDC, memDC

          invoke EndPaint, hWin, addr ps
Title: Re: Moving things around the screen w/GDI
Post by: sinsi on April 25, 2025, 12:27:49 PM
Quote from: NoCforMe on April 25, 2025, 12:08:50 PMQuestion: Does using double buffering mean that I draw everything to a separate buffer (my AltDC) and then copy that entire thing over to the display DC?
Yes, everything.

I get artifacts when the bitmap is dragged past the top or left
Untitled.png
Title: Re: Moving things around the screen w/GDI
Post by: NoCforMe on April 25, 2025, 12:46:40 PM
Quote from: sinsi on April 25, 2025, 12:27:49 PM
Quote from: NoCforMe on April 25, 2025, 12:08:50 PMQuestion: Does using double buffering mean that I draw everything to a separate buffer (my AltDC) and then copy that entire thing over to the display DC?
Yes, everything.

I get artifacts when the bitmap is dragged past the top or left
Yes, shoulda warned you 'bout that. There's no code to check for boundary conditions (yet). Makes a mess.

So maybe I should concentrate on "everything"?
Title: Re: Moving things around the screen w/GDI
Post by: zedd on April 25, 2025, 12:47:50 PM
I will also add that however you are selecting the transistor and moving it around, that part indeed is working nicely. Congrats.  :thumbsup:
I had tried something similar years ago, but with piss poor results.  :tongue:

I think I could do something similar now, if needed, though -with better results.   :smiley:
Title: Re: Moving things around the screen w/GDI
Post by: zedd on April 25, 2025, 12:52:00 PM
Quote from: NoCforMe on April 25, 2025, 12:46:40 PMSo maybe I should concentrate on "everything"?
Work on getting the double buffering working first. Once done, then you can do the boundary checks, and handle the resource issues (source of gdi leaks), imo.