http://www.perlmonks.org?node_id=995284


in reply to Re^8: Can't change icon with win32 module
in thread Can't change icon with win32 module

Here is my entire code (it is just an experiment at this stage)
use strict; use warnings; use Win32; use Win32::GUI(); use Win32::API; Win32::API->Import('kernel32','BOOL SetConsoleIcon(HWND icon)'); eval{SetConsoleIcon( Win32::GUI::Icon->new('box1.ico')->{-handle});}; +#eval 2 counter the die from undef return from "new" with "->" print 0+$^E; print " ---\n".'$^E = '; #separated \n just in case print $^E; print " ---\n".'$! = '; print $!; print " ---\n".'$@ = '; print $@; print " ---\n".'FormatMessage = '; print Win32::FormatMessage(Win32::GetLastError()); sleep 50; exit;
At this version it says
0 --- $^E = --- $! = Bad file descriptor --- $@ = --- FormatMessage = The operation completed successfully.
for box2.ico as well as for zzz.pl (instead of box1.ico) it says
0 --- $^E = --- $! = Bad file descriptor --- $@ = Can't use an undefined value as a HASH reference at E:\perl exper +iments\change icon exp 2.pl line 8. --- FormatMessage = The operation completed successfully.
The practical difference between the 3 is that only box1.ico is showed, the other 2 don't change the icon.
When I target a non-existing file, it says
2 The system cannot find the file specified.
It seems to me that Win32::GUI::Icon->new('box1.ico') is just undef when used on box2.ico as well as for zzz.pl.

Replies are listed 'Best First'.
Re^10: Can't change icon with win32 module
by Anonymous Monk on Sep 24, 2012 at 04:48 UTC

    Here is mine

    #!/usr/bin/perl -- use strict; use warnings; use Win32::GUI(); use Win32::API; Win32::API->Import('kernel32','BOOL SetConsoleIcon(HWND icon)'); @ARGV or @ARGV = map { glob $_ } "C:/Progra~1/*.ico", "C:/Progra~1/*/*.ico", "C:/Progra~1/*/*/*.ico", "C:/Progra~1/*/*/*/*.ico", #~ "C:/Progra~1/*/*/*/*/*.ico", "C:/WINDOWS/*/*.ico", "C:/WINDOWS/*/*/*.ico", "C:/WINDOWS/*/*/*/*.ico", #~ "C:/WINDOWS/*/*/*/*/*.ico", #~ "C:/WINDOWS/*/*/*/*/*/*.ico", #~ "C:/WINDOWS/*/*/*/*/*/*/*.ico", ;;;; for my $file ( @ARGV ){ print "$file\n"; eval { my $icon = Win32::GUI::Icon->new( $file ) or die sprintf qq/ErrIcon \$!(%d)(%s)\n\$^E(%d)(%s)\nGLS(% +d)(%s)/, $!,$!,$^E,$^E, Win32::GetLastError(), Win32::FormatMessage(Win32::GetLastError()) ;;;;; SetConsoleIcon( $icon->{-handle} ) or die sprintf qq/ErrSet \$!(%d)(%s)\n\$^E(%d)(%s)\nGLS(%d +)(%s)/, $!,$!,$^E,$^E, Win32::GetLastError(), Win32::FormatMessage(Win32::GetLastError()) ;;;;; 1; } or warn "$@\n\n"; sleep 1; } SetConsoleIcon( undef );## restore __END__ $ perl sicon.pl sicon.pl perlmonks.favicon.ico sicon.pl sicon.pl ErrIcon $!(2)(No such file or directory) $^E(0)() GLS(0)(The operation completed successfully. ) at sicon.pl line 25. perlmonks.favicon.ico sicon.pl ErrIcon $!(2)(No such file or directory) $^E(0)() GLS(0)(The operation completed successfully. ) at sicon.pl line 25.

    Obviously sicon.pl isn't an .ico file

    Looking at these results and Win32::GUI::Icon docs, it is now obvious that it doesn't preserve $^E from the 2-3 ways it tries to load the file, so $^E ends up being uninformative

    FormatMessage() OTOH assumes 0 means success where as $^E doesn't

    Since this program works for me for about a dozen icon files I find in program files

    I must assume there is something wrong with your box2.ico

    good luck figuring it out :) You might hack on some GUI.xs to insert informative diagnostics, or hit up MSDN for specs regarding icon files so you can compare them to box2.ico ...

Re^10: Can't change icon with win32 module
by bulk88 (Priest) on Sep 24, 2012 at 20:38 UTC
    use strict; use warnings; use Win32; use Win32::GUI(); use Win32::API; Win32::API->Import('kernel32','BOOL SetConsoleIcon(HWND icon)'); eval{SetConsoleIcon( Win32::GUI::Icon->new('box1.ico')->{-handle});}; +#eval 2 counter the die from undef return from "new" with "->" print 0+$^E; print " ---\n".'$^E = '; #separated \n just in case print $^E; print " ---\n".'$! = '; print $!; print " ---\n".'$@ = '; print $@; print " ---\n".'FormatMessage = '; print Win32::FormatMessage(Win32::GetLastError()); sleep 50; exit;
    "eval{SetConsoleIcon( Win32::GUI::Icon->new('box1.ico')->{-handle});}; #eval 2 counter the die from undef return from "new" with "->"" duh! If Win32::GUI::Icon returns undef, dont deref or meth call on it. I'm not sure if the print() corrupts GLR or not. SetConsoleIcon is irrelevant to call if you didn't create an Icon handle in the first place. AM is correct, you probably dont have a valid ico file. If you really want to know the GLR error, use a C debugger and step through GUI.xs, or use Win32::API to call User32.dll LoadImage directly. You can also post box2.ico (do a binmode and use Data::Dumper to turn the ico file into a escaped string literal) and I see if it loads on my system and why GUI::LoadImage fails.