window icon
tinyBigGAMES

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.

DanielH

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

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

DanielH

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
#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

Dizzy Egg

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!!

tinyBigGAMES

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?

torhu

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

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

Edgar Reynaldo
Dizzy Egg

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…

Peter Hull

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

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?

torhu

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

Peter Hull

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

tinyBigGAMES

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.👍

torhu

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

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

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

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.

torhu

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

Thread #618660. Printed from Allegro.cc