Clicking "through" a transparent form

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • HaLo2FrEeEk
    Contributor
    • Feb 2007
    • 404

    Clicking "through" a transparent form

    The program I'm writing has 2 forms, a main control form, then another that is completely transparent except for a 1 pixel border, sizing handles at the 4 corners, and a moving handle in the middle. When you click a button in the main form a screenshot is taken of the portion of the screen outlined by the second form. This works great, but I've run into an issue.

    The second form is simply a form without a form border, with an arbitrary background color (maroon), with the transparency key set to that color, so that the form is transparent. Unfortunately, this means that if I set the form over another window, I can't control what's underneath that window, which means that if the main control window ends up underneath the form, I can't click the button and I have to move the form out of the way so I can get at the control window.

    Is there a way that I can make the screenshot box appear on top of all other windows, but still allow me to click through it to control whatever is underneath it? An example of this would be Camtasia Recorder. It has a bounds box that you can move and resize to specify the portion of the screen that you want to record, but you can still control any windows that might be underneath it.
  • Christian Binder
    Recognized Expert New Member
    • Jan 2008
    • 218

    #2
    I've tried to reproduce this, but if I make a Form transparent, I can click "through" it and the underlying Control gets the mouse-event.

    I simply created a Form, set it's BackColor and it's TransparencyKey to Color.Red and it's FormBorderStyle to None and it works.

    Maybe you can tell me what else you've changed, so that I can reproduce this behavior, so it would be easier to help for me.

    Comment

    • HaLo2FrEeEk
      Contributor
      • Feb 2007
      • 404

      #3
      Well here is a build of the current version:

      Screenshot 1.1

      And here's the source:

      Screenshot 1.1 Source

      When I move the control window underneath the screenshot bounds, I cannot control the main window. I currently have it set up so that the main form's background color changes to red if it intersects or is contained within the screenshot bounds form. As far as I remember I did exactly what you did. My BackColor is Maroon, FormBorderStyle is None, and TransparencyKey is Maroon. The only other differences are that I have ShowIcon and ShowInTaskbar set to false, and Size and Location are set using a settings file.

      There is a panel that is set to dock mode Fill (backcolor transparent), so that I can have a single-pixel border on the bounds, but I tried deleting it and even without it I couldn't interact with objects under the bounds window, so that can't be it.

      Hopefully my source code helps.

      Comment

      • Christian Binder
        Recognized Expert New Member
        • Jan 2008
        • 218

        #4
        I started your exe and it worked well. If I drag the transparent form over the main-form, the main-form gets red but I can still click trough the form on the "covered" button.
        I'm using Windows XP, maybe it just doesn't work on the os you are using?

        Comment

        • HaLo2FrEeEk
          Contributor
          • Feb 2007
          • 404

          #5
          Windows 7 Ultimate x64. I can't see that XP would have a feature like that and then have it taken out in later versions, that seems ridiculous.

          Does anyone else have any ideas as to how I might accomplish this for all operating systems?

          Comment

          • Christian Binder
            Recognized Expert New Member
            • Jan 2008
            • 218

            #6
            I've tried it on Windows 7 Ultimate 32 Bit (in a Virtual PC) and it worked like it did on XP (correctly), so it doesn't seem to depend on the OS. Did you even tried it on another PC or Virtual PC?
            I hope that someone else can figure out what's wrong here ...

            Comment

            • HaLo2FrEeEk
              Contributor
              • Feb 2007
              • 404

              #7
              I just tried it in Windows XP Mode, the virtual Windows XP installation that comes with Windows 7. It worked as expected. It just doesn't make sense that it would work in Windows XP, and Windows 7 32 bit, but Windows 7 64 bit. That seriously makes no sense at all.

              Anyone else with Windows 7 x64, PLEASE try this out for me, I really want to get this resolved.

              Edit: Oh my god! On a whim I went ahead and disabled Desktop Composition (which would be disabled in a virtual machine, and which didn't exist in XP) and it worked, I was able to click through the form. With desktop composition turned on, I am not able to do so.

              There has to be a way around this though, obviously since Camtasia does it.

              Edit 2: I've been reading up and I've read about a lot of ways that this is supposed to work, but none have. I've read about using a DllImport and importing the SetWindowLong() and GetWindowLong() API methods, then using them...that didn't work. I read about using WndProc and performing a HitTest, that didn't work. Now I'm reading about Regions, and I think this is just the thing I need.

              There is an issue though, I need to know how I can define a region that excludes not only the 8 sizing handles on the edges of the form, but also the moving handle in the middle of the form, and exclude everything else. Since my screenshot bounds form can be any size, when I load it, or resize it, I have to reposition the handles, which means that the region will have to reposition itself as well. I just can't think of how I could create the shape that I need, with the hole in the middle, and dynamically. Can someone please help!

              Also, if there is a better way that anyone knows of other than Regions, PLEASE let me know.

              Comment

              • GaryTexmo
                Recognized Expert Top Contributor
                • Jul 2009
                • 1501

                #8
                Oddball idea, but do you need to have that other window over top? I'm just brainstorming here, but could you just draw the extra stuff manually?

                Perhaps there's even a way you could draw to the screen outside your window bounds? I dunno, just trying to think of something that you haven't tried yet.

                (Oh hey also, did you ever get that thing working about positioning the window outside when it overlapped? I don't know if I heard back from you in that other thread and I'm curious as to how it turned out :D)

                Comment

                • HaLo2FrEeEk
                  Contributor
                  • Feb 2007
                  • 404

                  #9
                  Which window on top? Currently I have the screenshot bounds form set to TopMost so that it always appears above everything else. And what extra stuff would I draw manually?

                  And I don't really need to draw anything outside the window bounds, I just want the bounds window itself to be clickthrough. I managed to get it to work using regions, I just set up a GraphicsPath and added the rectangles from each of the handles. When one of the handles is clicked the region is set to null so I have the normal window being redrawn, when I release the mouse the region is recalculated and reapplied to the form. This makes only the portions of the form defined in the region actually respond to mouse interaction, the rest goes below to any underlying windows or controls. The reason I have it null the region when I mousedown is because before I was having it update the region during the mouseMove event, but that was causing it to be SUPER slow, so I moved the region calculations to it's own method that I call on the mouseUp event. It works better that way.

                  And finally, I had decided to forgo that attempt. I replied to the thread, but I didn't see that you replied back with an example code. I'll look it through though. I just opened up Camtasia and noticed that when the control form overlaps the bounds form in any way, it automatically moves the top-right corner of the control form to the bottom-left (underneath) of the bounds form. I tried that, but I think I had an issue with spacing. I was trying to get the control form to place itself exactly at the right edge, and that worked fine, but I wanted it to be a few pixels below the bounds form so the shadow didn't interfere with the screenshot, and I had issues with that. I'll have a look at it again though and see what I can come up with.

                  I'll also upload my new source code with the regions later on, I'm about to go swimming, I am absolutely beat right now. I was out in town all day and it's about 100° out today, and I was wearing all black for a job interview.

                  Comment

                  • GaryTexmo
                    Recognized Expert Top Contributor
                    • Jul 2009
                    • 1501

                    #10
                    I was a bit confused on what you wanted I think. What I was suggesting though was maybe try drawing not on the form so that clicks went through. Kind of like an overlay. It was just an idea... a shot in the dark if you will :)

                    And cool, glad you found something that worked for you with the window relocation stuff!

                    Comment

                    • HaLo2FrEeEk
                      Contributor
                      • Feb 2007
                      • 404

                      #11
                      Here's my updated source and application:

                      Screenshot 1.2
                      Screenshot 1.2 Source

                      What I did for the clickthrough capabilities was define a region covering the entire form, essentially saying that the entire surface should respond to clicks, then I excluded portions of the region, like this:

                      reg.exclude(new Rectangle(1, topLeft.Bottom, this.ClientSize .Width - 2, handleRight.Top - TopRight.Bottom ));

                      I only had to make 4 exclusion rectangles and it works a dream. When one of the handles is clicked, the region is turned off so the main form can be updated with the new size and location in real time, when the mouse is released, the region redraws itself based on the new positions of the handles.

                      This was a fun adventure, with a lot of frustrations, but I learned a lot. Thanks for helping me find the right direction, guys.

                      Comment

                      Working...