Allegro.cc - Online Community

Allegro.cc Forums » Allegro Development » window icon

This thread is locked; no one can reply to it. rss feed Print
window icon
tinyBigGAMES
Member #17,458
February 2020
avatar

Is there no way to specify an icon BEFORE the window is displayed for the first time? I see the default window icon, then I change it to a desired icon, then just before the window closes, I see the default icon again. It's a little thing but it's visual annoyance.

Jarrod Davis
Owner/Lead Developer
tinyBigGAMES LLC

DanielH
Member #934
January 2001
avatar

I load the icon immediately after display creation. I can't even tell the difference. And the window closes so quickly as well. What are you doing different that you even notice it?

easy answer, no.

harder answer, probably. Normally windows programs include a compiled resource.rc file. How to get Allegro to load your icon from that file is unknown. You could probably add a resource.rc file to the library itself then load the icon from it.

torhu
Member #2,727
September 2002
avatar

How do you change to the desired icon, can you show us the code?

DanielH
Member #934
January 2001
avatar

the Allegro way or the Windows way? I was assuming Windows. Maybe you meant Linux.

The Allegro way
void al_set_display_icon(ALLEGRO_DISPLAY *display, ALLEGRO_BITMAP *icon);

As for Windows, that's a bit more complicated.

tinyBigGAMES
Member #17,458
February 2020
avatar

#SelectExpand
1function TGVWindow.Open(aWidth: Integer; aHeight: Integer; aTitle: string): Boolean; 2var 3 LMarshaller: TMarshaller; 4begin 5 Result := False; 6 if FHandle <> nil then Exit; 7 al_set_new_display_flags(ALLEGRO_OPENGL_3_0 or ALLEGRO_RESIZABLE or ALLEGRO_PROGRAMMABLE_PIPELINE); 8 al_set_new_display_option(ALLEGRO_COMPATIBLE_DISPLAY, 1, ALLEGRO_REQUIRE); 9 al_set_new_display_option(ALLEGRO_VSYNC, 2, ALLEGRO_SUGGEST); 10 al_set_new_display_option(ALLEGRO_CAN_DRAW_INTO_BITMAP, 1, ALLEGRO_REQUIRE); 11 al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); 12 al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST); 13 al_set_new_window_title(LMarshaller.AsUtf8(aTitle).ToPointer); 14 FHandle := al_create_display(aWidth, aHeight); 15 if FHandle = nil then Exit; 16 FHWnd := al_get_win_window_handle(FHandle); 17 SetWindowLong(FHwnd, GWL_STYLE, GetWindowLong(FHWnd, GWL_STYLE) and (not WS_MAXIMIZEBOX)); 18 GV.Util.LoadDefaultIcon(al_get_win_window_handle(FHandle)); 19 FWidth := aWidth; 20 FHeight := aHeight; 21 FScale := 1; 22 FRenderTarget := nil; 23 al_register_event_source(GV.Queue, al_get_display_event_source(FHandle)); 24 ScaleToDPI; 25end;

after al_create_display, there is a small delay, enough to see the icon, after al_create_display, everything else runs quickly. LoadDefaultIcon will use the main icon that in the EXE. On shutdown, my custom icon goes away, I see the default icon for a moment. You would not notice it for the most part, but once you do notice it, you can't unnotice the fact that it shows the default icon, then my custom one. Visual annoyance.

Here is a video showing what I mean:
https://www.youtube.com/watch?v=DzkC3DXn37o

And what is going on with the forums today. It takes forever for the page to show. Here is the message I get: Page generated in 170.773603 seconds. This is an eternity :o

Jarrod Davis
Owner/Lead Developer
tinyBigGAMES LLC

Dizzy Egg
Member #10,824
March 2009
avatar

I think the only way to acheive that is to actually build the resource into the executable. I get the same behaviour if I change the icon after creating the display. The only way to make the icon persistent is to actually compile it as a resource, but I only know how to do this in CodeBlocks....

(Ps the site has been misbehaving for a long time now!)

[EDIT] actually I just tested that, and the icon only appears for the console window, not the allegro_display. Back to the drawing board!!

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

tinyBigGAMES
Member #17,458
February 2020
avatar

that exe has an embedded icon. I get the icon from the exe resource. The problem is the allegro does not look for it by default or there is no way to set an icon for a new window. If it would just look for a default group icon inside the exe would solve the problem. SDL now does this. You only need to have a "main" icon resource in the executable, and it will pick it up. If I knew enough about the working of the project and where to make the changes, I would attempt to make the modification. Since I do not code in c/c++ (only dabble enough to get the repo compiled), I don't know where to go in and do it else I surely would. I may have to try at some point. Now when my app starts up, I'm drawn to that default icon, arrrrrrg. ;D. Maybe someone in the know can add this support?

Jarrod Davis
Owner/Lead Developer
tinyBigGAMES LLC

torhu
Member #2,727
September 2002
avatar

Windows Explorer will load the first icon resource from the executable and display it as the file's icon. You can use the same icon for the window icon, but you have to load the resource yourself, and set it as the window icon using the Windows API functions for this.

RC file:

IDI_ICON1               ICON    DISCARDABLE     "something.ico"

Relevant code:

  HWND winhandle;
  HICON icon;

  icon = LoadIcon(GetModuleHandle(NULL), "IDI_ICON1");
  if (icon) {
    winhandle = al_get_win_window_handle(display);
    SetClassLongPtr(winhandle, GCLP_HICON, (LONG_PTR)icon);
    SetClassLongPtr(winhandle, GCLP_HICONSM, (LONG_PTR)icon);
  }

EDIT: Saw your reply now, don't know if this info is of much use, then...

Dizzy Egg
Member #10,824
March 2009
avatar

I don’t think there’s much can be done, aside from editing the allegro source, but I’m open to being wrong…

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Dizzy Egg
Member #10,824
March 2009
avatar

Meh, I think that’s ok for the console/exe window, but I think the allegro display that zooms in/out on windows still flashes the default icon…that being said. I’ve had a few beers and am contemplating a donor kebab, so…

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Peter Hull
Member #1,136
March 2001

It might need a tweak to Allegro, but could be as simple as setting hIcon to something in this code.

#SelectExpand
1int _al_win_init_window() 2{ 3 // Create A Window Class Structure 4 window_class.cbClsExtra = 0; 5 window_class.cbWndExtra = 0; 6 window_class.hbrBackground = NULL; 7 window_class.hCursor = NULL; 8 window_class.hIcon = NULL; 9 window_class.hInstance = GetModuleHandle(NULL); 10 window_class.lpfnWndProc = window_callback; 11 window_class.lpszClassName = TEXT("ALEX"); 12 window_class.lpszMenuName = NULL; 13 window_class.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC; 14 15 16 RegisterClass(&window_class); 17 18 19 if (_al_win_msg_call_proc == 0 && _al_win_msg_suicide == 0) { 20 _al_win_msg_call_proc = RegisterWindowMessage(TEXT("Allegro call proc")); 21 _al_win_msg_suicide = RegisterWindowMessage(TEXT("Allegro window suicide")); 22 } 23 24 25 return true; 26}

tinyBigGAMES
Member #17,458
February 2020
avatar

I tried these:

window_class.hIcon = (HICON)LoadImage(GetModuleHandle(NULL), "MAINICON", IMAGE_ICON, 32, 32, LR_SHARED);
window_class.hIcon = LoadIcon(GetModuleHandle(NULL), "MAINICON");
window_class.hIcon = LoadIcon(GetModuleHandle(NULL), IDI_HAND);

In Delphi, if you add an ICON to an EXE the default icon resource name will be MAINICON, but it's still showing the default windows icon. I even tried IDE_HAND which is at should be something different, but still shows the default one.

GetModuleHandle(NULL), should get the handle of the EXE therefore it should be picking up the resource from the EXE, correct?

Jarrod Davis
Owner/Lead Developer
tinyBigGAMES LLC

torhu
Member #2,727
September 2002
avatar

The first argument should be NULL when loading a standard icon.

Peter Hull
Member #1,136
March 2001

I can't test myself but maybe try TEXT("MAINICON") instead of just "MAINICON"

tinyBigGAMES
Member #17,458
February 2020
avatar

window_class.hIcon = LoadIcon(GetModuleHandle(NULL), TEXT("MAINICON"));

YES! That was it, now it will pick up a resource name MAINICON from the calling process.

Many thanks to all that helped.👍

Jarrod Davis
Owner/Lead Developer
tinyBigGAMES LLC

torhu
Member #2,727
September 2002
avatar

Right, TEXT will turn "string" into L"string" for you. I think the compiler was supposed to warn you about the type mismatch there. :-X

Peter Hull
Member #1,136
March 2001

Torhu, do you know, is there a way to specify 'the first icon' in an exe file without knowing its name - if so this could be something we could add to Allegro itself.

torhu
Member #2,727
September 2002
avatar

Torhu, do you know, is there a way to specify 'the first icon' in an exe file without knowing its name - if so this could be something we could add to Allegro itself.

It seems you have to enumerate the resource types until you find the icons, then grab the first resource of that type:
https://docs.microsoft.com/en-us/windows/win32/menurc/using-resources#creating-a-resource-list

The docs don't say whether the order of the resources of each type is the same as their order in the .rc files, though. Would probably have to test that.

tinyBigGAMES
Member #17,458
February 2020
avatar

I think it should look for the 1st icon, which will be the numbered icon "1". MAINICON just points to this as why SDL2 will pick up MAINCON in Delphi. It's the 1st numbered icon that it's picking up.

edit: yeah what torhu said.

Jarrod Davis
Owner/Lead Developer
tinyBigGAMES LLC

torhu
Member #2,727
September 2002
avatar

I think looking for an icon with a specific name is reasonable, makes it more explicit. Allegro 4 used "allegro_icon" as the name.

Go to: