2

I have been trying to create a test program that just displays a bitmap image on the screen for a while now. Ideally, the image would be translucent (have an alpha channel) and "click throughable." However, I have not found any way to do this.

The application that I have for this is a keyboard indicators app that runs in the background and displays a popup image onscreen for a couple seconds whenever a modifier like num lock or caps lock is pressed.

What I have found is an MSDN example for how to render an image on the screen, but I haven't been able to make this work properly in a Windows Forms app. In the Form1.cs of a blank WFA app, I have:

using System.Drawing;
using System.Windows.Forms;

namespace KeyboardIndicators
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            PictureBox pictureBox1 = new PictureBox();
            pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
        }

        private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs pe)
        {
            Bitmap myBitmap = new Bitmap("Profile Image.jpg");
            Graphics g = pe.Graphics;
            g.DrawImage(myBitmap, 100, 100);
        }
    }
}

I am probably missing a lot here, but I am not having much luck debugging it in Visual Studio.

I have yet to find a site online that fully describes how to do something like what I would like to do. I have seen this kind of thing done before in other apps, so I know it can be done somehow.

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
ifconfig
  • 6,242
  • 7
  • 41
  • 65

2 Answers2

2

I found the answer to my question thanks to the initial answer by @Habeeb on this question, which inspired me to research that method. By looking at this Q/A, I realized I didn't need to create a helper function to do this. To @Idle_Mind's point also, I set the WS_EX_TRANSPARENT flag to transparent.

This is the code I ended up with in my Form1.cs file: (I ended up changing the test image to cube.png, a .png image with an alpha channel)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace KeyboardIndicators {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();

      PictureBox pictureBox = new PictureBox();

      Image myBitmap = Image.FromFile("cube.png");
      Size bitmapSize = new Size(myBitmap.Width, myBitmap.Height);

      this.Size = bitmapSize;
      pictureBox.ClientSize = bitmapSize;

      pictureBox.Image = myBitmap;
      pictureBox.Dock = DockStyle.Fill;
      this.Controls.Add(pictureBox);
      this.FormBorderStyle = FormBorderStyle.None;
    }

    protected override CreateParams CreateParams {
      get {
        CreateParams createParams = base.CreateParams;
        createParams.ExStyle |= 0x00000020; // WS_EX_TRANSPARENT

        return createParams;
      }
    }
  }
}

When run, the following is shown onscreen:

Screenshot of running program

This works for me, as it is overlayed on all apps I need, is semi-transparent and is click-throughable.

ifconfig
  • 6,242
  • 7
  • 41
  • 65
0

From your code, I do not see the Bitmap image is set to the PictureBox. Please try the below code:

pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage ;
MyImage = new Bitmap(fileToDisplay);
pictureBox1.ClientSize = new Size(xSize, ySize);
pictureBox1.Image = (Image) MyImage ;

If you want to add PictureBox via code, see below:

private void Form1_Load(object sender, EventArgs e)
{
    var picture = new PictureBox
    {
        Name = "pictureBox1",
        Size = new Size(xSize, ySize),
        Location = new Point(100, 100),
        Image = Image.FromFile("hello.jpg"),

    };
    this.Controls.Add(picture);
}

The first piece of code shows how to update image, but a different approach.

Habeeb
  • 7,601
  • 1
  • 30
  • 33
  • If I just use the code you suggested, (replacing the path and size with the proper values) nothing is displayed. The file path is just the file name (as a string) if the image is imported into the project? My Solution Explorer looks [like this](https://imgur.com/s9l7lDt). The test image is `Profile Image.jpg`. – ifconfig Feb 25 '18 at 06:43
  • Did you add the pictureBox1 control to the form? – Habeeb Feb 25 '18 at 06:47
  • What control should I add? – ifconfig Feb 25 '18 at 06:48
  • PictureBox. I should be added to the form. For instance, you had created a new PictureBox control in code, but not added to Form. – Habeeb Feb 25 '18 at 06:52
  • Sure, but how can I do that? – ifconfig Feb 25 '18 at 06:52
  • See the updated answer to show how PictureBox is added to Form. – Habeeb Feb 25 '18 at 06:58
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/165770/discussion-between-ifconfig-and-habeeb). – ifconfig Feb 25 '18 at 06:59