Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: GDI drawing (Windows Internals)  (Read 4965 times)

0 Members and 1 Guest are viewing this topic.

Big

    Topic Starter


    Beginner

    Thanked: 4
    • Experience: Experienced
    • OS: Windows XP
    GDI drawing (Windows Internals)
    « on: July 15, 2010, 06:38:01 AM »

    Hello

    I'm sure most of you are familiar with the following Windows symptoms/bugs:

    - when your CPU is stressed and you try to drag a window around (let's say notepad),
      the GDI drawing system draws that window in each position, but,
      it doesn't erase the previous window & position.

    - when you close a particular program, which was previously in a non-responding state,
       a rectangle with the dimensions of this program is left out, but with the background
       of your current background

    - when you printscreen a non-video overlay video and you try to paste it in paint,
      then drag the image around, the video will appear to stay stationary like some sort of
      image you are sliding under a poster frame


    I would like to have all these symptoms explained; why Windows behaves like this,
    what happens and why it's happening (no no, it's not homework, just nerdy curiosity).

    Thanks
    Computerhope is corrupt.

    Big

      Topic Starter


      Beginner

      Thanked: 4
      • Experience: Experienced
      • OS: Windows XP
      Re: GDI drawing (Windows Internals)
      « Reply #1 on: July 15, 2010, 04:31:16 PM »
      Is everyone ignoring me or something?
      Computerhope is corrupt.

      patio

      • Moderator


      • Genius
      • Maud' Dib
      • Thanked: 1769
        • Yes
      • Experience: Beginner
      • OS: Windows 7
      Re: GDI drawing (Windows Internals)
      « Reply #2 on: July 15, 2010, 04:51:42 PM »
      It's Summer...sorry no none has responded yet...

      However in the meantime it would be helpful to posta as many specs on the machine you can dig up ...when this started and info on whatever protection apps you are currently running...

      BTW Welcome Aboard !
      " Anyone who goes to a psychiatrist should have his head examined. "

      BC_Programmer


        Mastermind
      • Typing is no substitute for thinking.
      • Thanked: 1140
        • Yes
        • Yes
        • BC-Programming.com
      • Certifications: List
      • Computer: Specs
      • Experience: Beginner
      • OS: Windows 11
      Re: GDI drawing (Windows Internals)
      « Reply #3 on: July 15, 2010, 08:13:23 PM »
      just to let you know- I'm writing a response to this.  ;)
      I was trying to dereference Null Pointers before it was cool.

      BC_Programmer


        Mastermind
      • Typing is no substitute for thinking.
      • Thanked: 1140
        • Yes
        • Yes
        • BC-Programming.com
      • Certifications: List
      • Computer: Specs
      • Experience: Beginner
      • OS: Windows 11
      Re: GDI drawing (Windows Internals)
      « Reply #4 on: July 15, 2010, 09:07:19 PM »
      It's the very nature of the messagepump system.


      Every windows application that has windows has a messagepump. it looks something like this:
      Code: [Select]
          MSG msg;
          while(GetMessage(&msg, hwnd, 0, 0))
          {
              TranslateMessage(&msg);
              DispatchMessage(&msg);

           

              // do stuff

          }
      Basically, GetMessage() retrieves the next message that appears on the queue- if there are no messages (things like WM_MOUSEMOVE,WM_LBUTTONDOWN, WM_KEYDOWN, WM_MOVE, WM_SIZE, and many many others) then the messagepump thread goes to sleep until their is.

      When everything is running smoothly- the pump is easily able to keep up with the messages that are being dispatched. but when an application is getting less CPU time then optimal, messages build up in the queue.

      Namely, with regard to your window dragging behaviour, the WM_PAINT message. Since the CPU is stressed, and your sending dozens of WM_MOVE messages (by moving the window), which in the default processing (DefaultWindowProc, which most window handlers will call to perform default handling aside from their special handling) is handled by invalidating the window rectangle and posting a WM_PAINT message., which is added to the queue.

      under normal circumstances, the WM_PAINT is usually acquired by the messagepump before too many messages build up, and it is serviced and the painting is performed. When the message thread is not getting enough timeslices, though, the queue builds up, and those WM_PAINT messages go unnoticed.

      But the InvalidateRect() call performed earlier does not- it invalidates the window and essentially causes the entire thing to clear to the background color of the window.

      Note that this doesn't apply just to windows, but also to commandbuttons and textboxes and so forth, all of which are technically windows with their own window procedures. All the window procedures in an application are usually managed by a single messagepump, which accepts all the messages windows sends the application and dispatches them to the appropriate window procedures. Additionally, when you drag a window around, windows not only has to send the WM_PAINT message to the window you moved (and invalidate it's entire rectangle to force redrawing of the entire thing) but it also has to invalidate the area of the windows behind it that you are "revealing"- including the desktop. depending on how many windows are behind the window you are moving, it can be a lot. And when your system is already stressed by, say a background process, even these actions can be sluggish. The results aren't always the same- all of the "symptoms" you specified are all the result of the messagepump getting an inadequate amount of CPU time, or simply not enough CPU time to handle the messages.

      The second one, re the program being closed, is really a application specific thing. Most programs are closed when they send all their windows the WM_CLOSE message. between the WM_CLOSE message and the WM_DESTROY message (which is sent after the window is completely destroyed) the child windows of the window are also closed and destroyed. And, of course, the windows behind it all recieve a WM_PAINT message to paint any areas that the now gone window were covering.
      It is the latter point that is important.  If that application is having trouble keeping up or is otherwise occupied (thereby meaning that it's messagepump isn't pumping) then the WM_PAINT will be added to the queue, but not serviced (handled). therefore, it won't paint- therefore, the image left by the now destroyed window will not be painted. Sometimes other windows that were also covered will be running fine and perfectly able to handle the message, so you only get one window that doesn't see mto be painting.

      You may be wondering, how if one application can't handle it's messages, how other programs can handle them perfectly fine and with no problems. This is both a result of the design of the "problem" application as well as the design of the pre-emtive multi-tasking environment that windows is. You see, back in the day, Windows wasn't pre-emptive- it was cooperative. What this means is that all the programs worked as a big happy family, yield()ing control to one another, they all trusted each other intrinsically, like the fool does the knave. Unfortunately, because some programmers are morons, this didn't always work out so well. See, when some people were writing a program, they would sometimes only think of themselves. This was selfish obviously. They wouldn't yield control very often, if at all. So no other programs could run. (this was windows 3.1... only way to stop a runaway process was with Control+Alt+Del, and that usually left things pretty unstable). There was "task management" in the form of "how much CPU time do DOS programs get compared to windows programs" but you didn't have anything like process priority like we do now.

      Anyway, now, cooperative multitasking is no longer "optional" all programs are forced to do so, resistance is futile measured in ohms. The big Word processor is treated no differently then the little dinky address program you have- Unless <you> want it to. no longer can the capitalist word processor grow fat on the extra CPU cycles of the other programs! There was a revolution! Now, with the pre-emptive multitasking, Windows only gives each thread a certain amount of time to run before it preemptively (thus the name) says "OK! THAT'S IT! SHARE!" and switches to another thread/program. basically when you encounter this CPU-based issue with a single program, it's usually monopolizing the entire CPU, right? But at the same time, it isn't! because of the way the task scheduler works, while the troubled program is having trouble keeping up with it's messages (probably because it's doing something else, like repaginating a document, compiling or whatever), the other programs aren't having those problems- so when the task scheduler switches to them, and they have waiting messages, they can check them. If they don't (which is usually the case) they just say "don't bother me, I'm sleeping zzz" and the task scheduler says "FINE! NO DINNER FOR YOU!" (the task scheduler has an anger problem) and then gives that timeslice to another needy program, usually the one who is trying to repaginate the document.

      Most of your other symptoms are merely "artifacts" from one or several programs being able to process certain amounts of their messages, and the various interactions between the programs based on the order that they end up being handled. The "box effect" when you close a program (as I finally come back to address the question) is usually the result of the client area of the window being invalidated- and then the desktop, or whatever programs are behind it, paints that rectangle, making it "look" like a clear frame. Eventually, when the window is truly destroyed windows will "finish" the destruction by invalidating the entire window rectangle, thus causing the rest of the "frame" to be written over.

      I'm not sure what you mean with the last question/note, (regarding printscreen, overlay videos, etc) but  I imagine it's related to what I've already noted here.


      As a final note, the entire graphics architecture was completely overhauled with Aero in Vista and 7; programs still write to what they think are paint over invalidated rectangles and to device contexts, but what they are actually doing is paint onto a surface. That surface is them composited on the screen with the various other surfaces that make up the other windows using Direct3d. This eliminates <all> of the issues you mentioned- if a program is not responding, for example, it's client area isn't simply not painted, since really the program has simply stopped painting to the surface- it doesn't have direct access to screen elements like a non-aero program would. In this case the program is simply lightened and you get the "not responding" prompt. Without aero enabled, though, it's the same as before- since technically when you are using Aero Basic (Vista/7 Basic) you are really using a modified version of the Luna theme engine that XP used.

      Lastly: that was all from memory so it might be inaccurate or even *gasp* wrong; I'm rather certain of most of it, though.
      I was trying to dereference Null Pointers before it was cool.

      Big

        Topic Starter


        Beginner

        Thanked: 4
        • Experience: Experienced
        • OS: Windows XP
        Re: GDI drawing (Windows Internals)
        « Reply #5 on: July 16, 2010, 03:33:44 AM »
        Thank you for your truly excellent reply, BC.
        That was very well explained.
        Some of it was hilarious, lol.

        As for the last question that you didn't fully understand, try reproducing it to see what I mean:

        - Open up a (DVD) video
        - Printscreen it
        - Keep the movie near-fullscreen (with the borders maybe)
        - Paste in ms paint
        - Now drag the 'image' around

        You will see that it seems you didn't printscreen at all but that you are moving
        a rectangle around in the 'movie poster'.
        This is a concept especially familiar in game design,
        when you 'slide things under a frame so they appear to be moving'.

        Thanks.
        Computerhope is corrupt.

        BC_Programmer


          Mastermind
        • Typing is no substitute for thinking.
        • Thanked: 1140
          • Yes
          • Yes
          • BC-Programming.com
        • Certifications: List
        • Computer: Specs
        • Experience: Beginner
        • OS: Windows 11
        Re: GDI drawing (Windows Internals)
        « Reply #6 on: July 16, 2010, 04:16:17 AM »
        Thanks, I managed to get that to do so in a VM.

        At first, I couldn't figure out what was going on. but once I closed everything down (except paint) it made sense.

        If you do so yourself, you'll notice that the area that was "transparent" was a specific colour- (a very close to but not quite black, in my case). the copy-paste operation didn't actually copy the image of the DVD, but rather a "background colour" that was being used by directshow to know how to mask it's output.

        First- whenever you play a DVD or most video, it's <always> on top of <everything> the only reason it ever clips properly is because the media program takes care of it- that is, it's not "automatic" like it is with things like textboxes and buttons and so forth.

        Most media programs use a method whereby they tell Directshow (or whichever video API) "ok, you can use this window to display your video" and it also specifies a "mask" colour- which is to say, "you can display your video on this window, and in this particular rectangle of it, but only where I use this particular colour" The colour used isn't really that important, what's important is that now any window that overlaps it that contains that colour will essentially become transparent where it uses that colour. however, solid areas of a very very near black colour are nearly unlikely, often times either that or a very near magenta or other "very close to a defined colour but a few teensy bits off" is chosen for the mask colour.

        When you copy and paste, you are copying and pasting, not an image of the DVD, but rather the colour area that the window has to tell the Video API where to draw it's video- so, when that window and colour is over top of your media player, directshow  (or whatever), since it only looks at the entire screen and not at particular windows or areas, sees that colour in the rectangle the media program specified and draws in it. This is why the rest of the program seems unaffected- it's not the mask colour, so directshow leaves it be.


        I was trying to dereference Null Pointers before it was cool.