Click here to Skip to main content
15,881,281 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
How to draw and then hide what I drew on a Windows screen on top of programs with no form used, I'm making a subliminal images program, it displays a pic each time for 100 ms every 3 seconds and then hides it, I made it with a form but the form takes focus of Windows on it, and it eats mouse clicks on it and probably keyboard presses when it's on.

Alternatively, how to make the form not get focus and not eat mouse clicks on it?

Also, my program detects the screen boundaries wrongly (maybe because of display zoom and working area issues), would you please tell me how to make the pics be shown on a point from all of the area of the main screen each time and not only close to its top left? or even show the pics each time on a point from the boundaries of the whole screens?

My screen is 4K (3840x2160) and it is detected here as: 3072x1728
Screen.PrimaryScreen.Bounds


And I had the Display Zoom of the primary screen at 125% but now for some reason I can't see it in Dsiplay Settings as the combobox is not enabled and is empty EDIT: Now I can see it..

What I have tried:

public partial class FormPic : Form
    {

        Image image;


        BackgroundWorker bgwLoadImage = new BackgroundWorker();


        public FormPic(string pathToPic)
        {
            InitializeComponent();

            

            timerCloseForm.Interval = Program.durationOfDisplay;

            image = Image.FromFile(pathToPic);


            //if I do this the form gets out of the primary screen and covers a part of the right screen
            //Rectangle s = getSizeAndLoc(new Size(3840,2160), new Size(3840,2160));




            //my screen is 4K(3840x2160) and it is detected here as: 3072x1728
            //this.Bounds= getSizeAndLoc(image.Size, new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height));




            //also here my screen is 4K(3840x2160) and it is detected as: 3072x1728 in System.Windows.SystemParameters.PrimaryScreenWidth and System.Windows.SystemParameters.PrimaryScreenHeight
            this.Bounds= getSizeAndLoc(image.Size, new Size((int)System.Windows.SystemParameters.PrimaryScreenWidth, (int)System.Windows.SystemParameters.PrimaryScreenHeight));






            // to not freeze the program on loading the image and make it load async
            pictureBoxPic.WaitOnLoad = false;

            


            
            // Load the image asynchronously.
            bgwLoadImage.DoWork += BgwLoadImage_DoWork;
            bgwLoadImage.RunWorkerAsync();
        }



        private void BgwLoadImage_DoWork(object sender, DoWorkEventArgs e)
        {
            pictureBoxPic.Image = image;
        }


        

        

        Rectangle getSizeAndLoc(Size s, Size b)
        {
            double ratio;

            if ((double)s.Width / b.Width < (double)s.Height / b.Height)
            {
                ratio = (double)b.Height / s.Height;
            }
            else
            {
                ratio = (double)b.Width / s.Width;
            }

            int w = (int)(s.Width * ratio);
            int h = (int)(s.Height * ratio);

            return new Rectangle(
                  (b.Width - w) / 2
                , (b.Height - h) / 2,
                w, h
                );
        }

        private void timerCloseForm_Tick(object sender, EventArgs e)
        {
            this.Dispose();
            this.Close();
        }

        private void pictureBoxPic_LoadCompleted(object sender, AsyncCompletedEventArgs e)
        {
            this.Show();
        }

        

        private void FormPic_Shown(object sender, EventArgs e)
        {
            timerCloseForm.Start();
        }
    }
Posted
Updated 19-Nov-22 17:11pm
v20
Comments
Kornfeld Eliyahu Peter 17-Nov-22 3:08am    
Under Windows everything is a window... You have no direct access to the screen, but only thru the DC of a window (OpenGL and such can be used to overcome it)...
You may create a transparent window and fiddle with AllowTransparency, TransparencyKey and TopMost properties... It should create a click-throughable form on top of the other windows...
John Smith 27 17-Nov-22 18:31pm    
How can I make it click-throughable while it's not transparent and is showing an image on top of other windows plz?
[no name] 17-Nov-22 23:00pm    
https://stackoverflow.com/questions/69990392/create-a-watermark-application-to-cover-all-screen-on-desktop
John Smith 27 18-Nov-22 0:36am    
https://prnt.sc/bko6iQlP_B-j this doesn't make my form pass mouse clicks to what's behind it, I made the image stay for 1 second (the form) and when I click on it the click doesn't pass through... maybe I need to do the same for the picturebox? EDIT: I tested without the picturebox covering and the click still doesn't pass through.

1 solution

        [DllImport("user32.dll", SetLastError = true)]
        private static extern UInt32 GetWindowLong(IntPtr hWnd, int nIndex);





        [DllImport("user32.dll")]

        static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr dwNewLong);




        [DllImport("user32.dll")]
        static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey, byte bAlpha, uint dwFlags);




        public const int GWL_EXSTYLE = -20;

        public const int WS_EX_LAYERED = 0x80000;

        public const int WS_EX_TRANSPARENT = 0x20;

        public const int LWA_ALPHA = 0x2;

        public const int LWA_COLORKEY = 0x1;








public FormPic()
        {
            InitializeComponent();

            //make the windows click through-able
            SetWindowLong(this.Handle, GWL_EXSTYLE,
(IntPtr)(GetWindowLong(this.Handle, GWL_EXSTYLE) | WS_EX_LAYERED | WS_EX_TRANSPARENT));
          }






private void pictureBoxPic_LoadCompleted(object sender, AsyncCompletedEventArgs e)
        {
           

            //set transparency to from 0 to 255
            SetLayeredWindowAttributes(this.Handle, 0, Properties.Settings.Default.picTransparency, LWA_ALPHA);
            timerCloseForm.Start();


            this.Bounds = getSizeAndLoc(image.Size, new Size(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height));
        }
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900