Display multiple instances of a shaped window/image on desktop?

81 Views Asked by At

I'm trying to display an image multiple times on the desktop in different positions but I'm not sure how to go about it. Right now I'm trying out Wxruby but I'm wondering if there is another way to do it that I'm missing.

So far I'm able to display one image at one position with wxruby pretty much from one of the samples:

require 'wx'
include Wx

class Warning < Wx::App
  include Wx
  def on_init(x = 300, y = 300)
    @frame = Frame.new( nil, -1, "Application", Point.new(x,y), Size.new(50,50), FRAME_SHAPED|SIMPLE_BORDER|FRAME_NO_TASKBAR|STAY_ON_TOP)
    @frame.show
    @has_shape = false
    @delta = [0,0]

    evt_paint {on_paint}

    shape = File.join( 'pathToImage' )
    @bmp = Bitmap.new( Image.new(shape) )
    @frame.set_client_size(@bmp.width, @bmp.height)

    if PLATFORM == 'WXGTK'
      # wxGTK requires that the window be created before you can
      # set its shape, so delay the call to SetWindowShape until
      # this event.
      evt_window_create { set_window_shape }
    else
      # On wxMSW and wxMac the window has already been created, so go for it.
      set_window_shape
    end

    #@frame.paint { | dc | dc.draw_bitmap(@bmp, 0, 0, true) }
  end

  def set_window_shape
    r = Region.new(@bmp)
    @has_shape = @frame.set_shape(r)
  end

  def on_paint
    @frame.paint { | dc | dc.draw_bitmap(@bmp, 0, 0, true) }
  end
end

app = Warning.new
app.main_loop
1

There are 1 best solutions below

0
On BEST ANSWER

I finally figured it out! This ruby script uses the wx gem to display the shaped windows and uses some windows stuff to get the current screen resolution(I assume of the primary monitor).

It gets the resolution then the width/height of the image you want to display across the desktop. One note on the image, it appears that when wx displays an image(I don't know if its just for shaped windows or not) any part of the image that is solid black is not display but instead you see what is behind the window.

Hope this save someone some trouble later on, or if not oh well.

require 'wx'
require 'dl/import'
require 'dl/struct'
include Wx

class Warning < Wx::Frame
  include Wx
    @@x = 0
    @@y = 0
  def setXY(x = 0, y = 0)
    @@x = x
    @@y = y
  end
  def initialize(parent, bmp)
    super(nil, -1, '', pos = [@@x,@@y], size = DEFAULT_SIZE, style = FRAME_SHAPED|SIMPLE_BORDER|FRAME_NO_TASKBAR|STAY_ON_TOP)
    @has_shape = false
    @delta = [0,0]
    @bmp = bmp

    evt_paint {on_paint}
    self.set_client_size(@bmp.width, @bmp.height)

    if PLATFORM == 'WXGTK'
      # wxGTK requires that the window be created before you can
      # set its shape, so delay the call to SetWindowShape until
      # this event.
      evt_window_create { set_window_shape }
    else
      # On wxMSW and wxMac the window has already been created, so go for it.
      set_window_shape
    end
    self.paint { | dc | dc.draw_bitmap(@bmp, 0, 0, true) }
  end

  def set_window_shape
    r = Region.new(@bmp)
    @has_shape = self.set_shape(r)
  end

  def on_paint
    self.paint { | dc | dc.draw_bitmap(@bmp, 0, 0, true) }
  end
end # of Warning

class WarnTest < Wx::App
  def on_init
    @frame = Frame.new()
    warnings = []
    resolution = getScreenResolution()
    shape = File.join( 'image you want' )
    @bmp = Bitmap.new( Image.new(shape) )
    imageWidth = @bmp.get_width
    imageHeight = @bmp.get_height

    imagesAcross = resolution[0] / imageWidth
    imagesDown = resolution[1] / imageHeight

    j = 0
    (1..imagesDown).each do |y|
      i = 0
      (1..imagesAcross).each do |x|
        warnings << [(imageWidth * i), (imageHeight * j)]
        i = i + 1
      end
      j = j + 1
    end

    warnings << [resolution[0], resolution[1]]

    # Create a new window for each xy in warnings array
    warnings.each do |x|
      win = Warning.new(self, @bmp)
      win.setXY(x[0], x[1])
      win.show(true)
      win.update
      sleep 0.01
    end
  end # of on_init

  def getScreenResolution
    sM_CXSCREEN =   0
    sM_CYSCREEN =   1
    user32 = DL.dlopen("user32")

    get_system_metrics = user32['GetSystemMetrics', 'ILI']
    x, tmp = get_system_metrics.call(sM_CXSCREEN,0)
    y, tmp = get_system_metrics.call(sM_CYSCREEN,0)
    res = [x, y]
    return res
  end # of getScreenResolution
end # of WarnTest

app = WarnTest.new
app.main_loop