Ffi - Popping image on top of the screen

Ey guys, how are you? I`m developing an application in Ruby, using
FXRuby as framework. The fact is that the app take 18 seconds to show
the GUI when it start to run, so it’s too much time to wait for the user
without see any sign who can tell him: “yes…the application is
loading, wait for a while 'till the GUI appear”, so I decided to use a
feature of FXRuby who is supposed to show any kind of image in the
screen while the GUI is loading. Now here is the real trouble: This
Image take 15 seconds to show up and 3 seconds more from that point the
GUI is showed up, so I still have 15 seconds without nothing in the
screen…nothing that can tell the user that the application is
loading. There’s no way to accelerate this process, trust me, I did many
test: the simplest application will take 15 seconds to initialize, a
simple window or image or wathever will take 15 seconds at least.
I was wondering if using ‘ffi’ gem can call some windows .dll(Yes, I’m
developing in Windows XP for Windows XP) function, meaby some function
of the gdi32.dll or user32.dll which can allow me to pop up a .png image
on top of the screen until the GUI application is ready to be show. If
anybody know of a function who can do that or any other way to do that
let me know please, I’ll realy appreciate your help, thanks.

15 seconds to load juts sounds broken to me. Maybe you could/should
profile your startup time and see what’s going on?

If you “just” want a dialog of some sort, then FFI could help

“Unicode Popup Dialog (MRI 1.9)”

Also NB that with jruby apps you can pass java -Dsplash:yo.png, but that
probably doesn’t help you much.
-roger-

I’ve found a way to do this with ‘ffi’ gem using windows gdi32.dll
lybrary, to be specyfic using the C++ functions ‘GetDC’, ‘BitBlt’ and
another function that i don’t realize yet… (I don’t know nothing about
C++ programming, I’ve started to program with Ruby, first language). I
had an error trying this way, the backtrace say something like “GetDC
function doesn’t found in [gdi] library”. Walking away trhough my
PC I realized that gdi32 library was found by ffi, but not by the
search feature of my OS, I just found ‘libgdi32.a’ file. Now I’m stuck
and lost in this way…any help will be aprecciated to solve the
problem with windows functions.
By other side I was taking a look at ‘rubysdl’ gem. I need to know if
in any way can solve the problem with the SDL library…if someone can
give me an advice about if I CAN DISPLAY MY IMAGE(can be .png, .bmp,
doesn’t matter) LOGO APP IN TOP OF THE SCREEN(Windows XP SP3) until my
app GUI is loaded(I can take the wheel from there) then I can know which
way must be taked. I don’t want to spend days learning SDL library if
after all I can’t solve the real problem. I’ll appreciate your help,
thanks for your time.

14 of the 15 seconds is to require the gem ‘fox16’, is heavy…
I was taking a look in Windows Examples · ffi/ffi Wiki · GitHub
it doesn’t seem to cover my spectatives, it works for show strings, but
I want to show my own .png logo.
I’m wondering meaby if I could do this with Rmagick or another gem…
anyone have a clue? thanks for your time.

If it’s OK to use a Microsoft Windows MsgBox which a user will have to
close manually then the following may help. (It might be possible to
use something like SendKeys to close the MsgBox from Ruby.)

It seems to work both with MRI Ruby ruby.exe in a console window and
with MRI Ruby rubyw.exe (no console window, but as my trying that may
be the first time I’ve ever used rubyw.exe, no guarantees!).

a longer example is here:

http://www.pastie.org/4074156

For a Microsoft Windows MsgBox the basic idea is like this for MRI

Ruby 1.9:

require ‘dl’
User32 = DL.dlopen(‘user32’)
User32_MsgBox =
DL::CFunc.new( User32[ ‘MessageBoxA’ ], DL::TYPE_LONG,
‘MessageBox’)

def MsgBox(text, title = “”, buttons_icon_etc=0, timeout=0,
handle=nil)
if (timeout == 0 || ! timeout) && ! handle then
# User32_MsgBox.call returns an array:
# [return_value, [0, text, title, buttons + icon + modality]]
# we only want the return value, hence “result, =”
# #dup used: if text or title are frozen, #pack(‘p’) raises an
exception
result, = User32_MsgBox.call( [ 0, text.dup, title.dup,
buttons_icon_etc
].pack(‘L!ppL!’).unpack(‘L!*’) )
return result
end
raise “MsgBox: to use timeout or handle may need something like
AutoIt”
end

MsgBox(“basic text then title Microsoft Windows MsgBox example” <<
“\ntried in 1.9 but not 1.8”,
"title is ruby " + RUBY_VERSION.to_s)

Posted by Colin B. (Guest)
on 2012-06-12 17:37
(Received via mailing list)

If it’s OK to use a Microsoft Windows MsgBox which a user will have to
close manually then the following may help. (It might be possible to
use something like SendKeys to close the MsgBox from Ruby.)

Thanks for answer but that’s not what I want, I just want a “loading…”
image, like most of the known applications, just the image(I have
prepared one .png or .bmp), not any kind of window, it should be closed
automatically when the FXRuby GUI is ready to be show.
Anybody know how to do the job in this way:

Posted by Damián M. González (igorjorobus)
on 2012-06-12 14:32

I’ve found a way to do this with ‘ffi’ gem using windows gdi32.dll
lybrary, to be specyfic using the C++ functions ‘GetDC’, ‘BitBlt’ and
another function that i don’t realize yet… (I don’t know nothing about
C++ programming, I’ve started to program with Ruby, first language). I
had an error trying this way, the backtrace say something like “GetDC
function doesn’t found in [gdi] library”. Walking away trhough my
PC I realized that gdi32 library was found by ffi, but not by the
search feature of my OS, I just found ‘libgdi32.a’ file. Now I’m stuck
and lost in this way…any help will be aprecciated to solve the
problem with windows functions.

Or perhaps with ‘rubysdl’(SDL) Library…
Thanks for your time friends.

Re: ffi - Popping image on top of the screen
Posted by Roger P. (rogerdpack) on 2012-06-11 17:59

15 seconds to load juts sounds broken to me. Maybe you could/should
profile your startup time and see what’s going on?

I’m back with this trouble, I’m stuck. I’ve installed ‘wxruby’ gem just
to see if is normal to have 15 seconds to load frameworks for build GUI
applications with ‘require’. IT TAKES ONLY 1 SECONDS. So I’m taking the
advice of Roger P. seriously.
FXRuby is just a ‘link’ of FOX C++ framework. There’s no “widget class”
defined in Ruby, all is compiled in C++. I don’t know why it takes 15
seconds to be required…
I just ask you a favour: Can you install the gem?

gem install fxruby

and tell me how many time it takes to be required in irb, just an
approximation:

require ‘fox16’

If my instalation is “broken” as Roger said, I don’t have any idea in
which way… I have the last version of the gem, last version of Ruby,
last version of DevKit and I’m running in Windows XP SP3 updated. Your
help will be appreciated, I’m stuck.

Merely requiring the newest version of fxruby takes almost 20 seconds
for me on Ruby 1.9.3. But I think that older versions were a little
quicker; maybe it’s a regression?

– Matma R.

with this: “tcs-ruby 1.9.3p28 (2012-01-28, TCS patched 2012-01-30)
[i386-mingw32]”

require ‘benchmark’

Benchmark.realtime { require ‘fox16’ }
=> 7.697077

and with 1.8.7:

Benchmark.realtime { require ‘fox16’}
=> 2.79511690139771

Seems messed up to me…8s to load? But maybe it’s expected I don’t
know.

That’s strange. I have posted a topic in the FXRuby bug report just for
the maintainers consideration here:

3 seconds to require in 1.8.7, 15 in 1.9.3, why? · Issue #5 · lylejohnson/fxruby · GitHub

But well…you see the answer.
Meaby when I have a while I’ll write in the mailing list, not too much
interested.

I want to let you know that I’ve found a solution: using wxruby side by
side(for a while) with FXRuby, and I’ve had to implement the solution in
a strange way… but I’ve been around for days trying to make this
work, don’t want to spend more days asking “why this have to work in
this way, there is some better way, etc…”. Look:

require ‘wx’

#This is from wxruby just for popup the logo I want
Wx::App.run do
splash_bitmap = Wx::Bitmap.new(‘XXX.bmp’, Wx::BITMAP_TYPE_BMP)
#I had to stablish the timeout on and in 1 ms, doesn’t work other way
splash = Wx::SplashScreen.new(splash_bitmap,
Wx::SPLASH_CENTRE_ON_SCREEN|Wx::SPLASH_TIMEOUT, 1, nil, -1)

#Require the FXRuby gem(while showing the logo)
require ‘Fox16’

#Load all the files, classes, etc.

#Shut down the wxruby main loop closing the opened first block
#Here is when the logo disappear
end

#Finally start the FXRuby main loop and you have all up and running
#people happy cheering in the streets and dancing polska
if FILE == $0
FXApp.new(‘XXX’, ‘XXX’) do |app|
#This is personal, I disable the FXRuby threads support because I don’t
#use it and if you don’t use it is better this way because main loop
#sleep every 100ms to see if there’s any thread waiting to be executed
app.disableThreads
FXMainWindow.new(app)
app.create
app.run
end
end

Hope this can help someone else than me, thanks to all who helped.

So now there’s an answer on GitHub and a prerelease version that fixes
it (I checked). :slight_smile:

– Matma R.

Yes

3 seconds to require in 1.8.7, 15 in 1.9.3, why? · Issue #5 · lylejohnson/fxruby · GitHub

It’s fixed, was the compiler…
Now I don’t need the logo LOL!!! Takes 1 second to charge the partial
application(developing it).
By the way there’s few things that I want to tell.
I’ve tried both: FXSplashWindow(FXRuby) and Wx::SplashScreen(wxruby).

FXSplashWindow(FXRuby): 1) It open in a different window which live in
your Windows tool bar at the moment it’s created(poped), so for a
esthetic global view you should close the FXSplashWindow object before
the GUI is showed in the screen.
2) No way to put it in the top of the screen, easily can be covered by
any other window.

Wx::SplashScreen(wxruby): All inverse of the other GUI framework. 1) It
is opened ‘behind the scene’.
2) It is in the top of the screen. By the way I recommend using .bmp
images, not .png…the shape with .png files takes other bitmaps from
other existent opened windows…

Well…this is very fun, now I don’t need ‘loading…’ image ^-^
Have fun guys.