Recent

Author Topic: Wrong icon for new window when mainform is invisible  (Read 15405 times)

GADZombie

  • New Member
  • *
  • Posts: 46
  • 8bitrlz
    • Zombie Mastah
Wrong icon for new window when mainform is invisible
« on: January 27, 2014, 10:42:57 am »
Hello
I have Lazarus on Windows 8 64 bit.
I have made a procedure which changes form's icon to different picture. It works very good. The icon is created with both sizes: 16x16 and 32x32.
The problem is, when mainform in the project is invisible (hidden, no button on taksbar), then every other window can't change it's icon to different. It always receive default project icon. Even if I create 10 windows, every one has default project icon, not that I create. But when the mainform is visible, every other window can change it's icon to whatever I want.
Why it isn't working? Is this some kind of bug in Lazarus?

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Wrong icon for new window when mainform is invisible
« Reply #1 on: January 27, 2014, 11:31:31 am »
Why it isn't working? Is this some kind of bug in Lazarus?

Usually the quickest way to get suggestions from other people about code you have written that does not have the effect you desire is to share the code. Sometimes there will be a missing element (or logic flaw) in your code which someone 'outside' of your code will notice immediately. Less often we conclude that you have uncovered a bug in Lazarus.

GADZombie

  • New Member
  • *
  • Posts: 46
  • 8bitrlz
    • Zombie Mastah
Re: Wrong icon for new window when mainform is invisible
« Reply #2 on: January 27, 2014, 09:06:48 pm »
I had to prepare a full example. It was not so easy :).
Please, you can download it from here: http://gad.art.pl/bonus/formicontest.zip
There is a source code and compiled to exe example.
There are 2 forms. The first one is main and it creates an icon in tray. When you'll  open a popup from tray icon you may show main form and create new secondary form. There is button to create icon for current window. Now - try to open main form and open secondary form, then assign an icon to it (with button inside). It works fine. New icon appears.
Now hide main form using button and try to assign an icon to secondary form again. New icon disappears and default project icon will show in secondary form.

I noticed this behaviour only when secondary window has no border, as in this example. When there is a border, it works fine!
But I need windows without borders...
Thanks in advance.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Wrong icon for new window when mainform is invisible
« Reply #3 on: January 27, 2014, 10:33:04 pm »
Perhaps I'm being thick... but don't borderless windows lack icons by design - there is no border decoration for the OS to put an icon on, just as the OS cannot place Minimize/Maximize or Close icons either.
Unless you manually draw the icon within the client area of the window, you will never see an icon on a borderless window, surely?  ;)

GADZombie

  • New Member
  • *
  • Posts: 46
  • 8bitrlz
    • Zombie Mastah
Re: Wrong icon for new window when mainform is invisible
« Reply #4 on: January 27, 2014, 10:37:48 pm »
Nope. Secondary form is visible on the taskbar. Every one secondary form has it's own button on the taskbar and that is why I want them have different icons.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Wrong icon for new window when mainform is invisible
« Reply #5 on: January 27, 2014, 10:58:31 pm »
Would changing your btnAssignHereClick handler to the following do what you want?

Code: [Select]
procedure TForm1.btnAssignHereClick(Sender: TObject);
begin
  Application.Icon.Assign(CreateIcon);
  TrayIcon1.Icon.Assign(Icon);
end;

GADZombie

  • New Member
  • *
  • Posts: 46
  • 8bitrlz
    • Zombie Mastah
Re: Wrong icon for new window when mainform is invisible
« Reply #6 on: January 27, 2014, 11:08:49 pm »
No. Did you see my example? It shows what I want.
The tray icon don't need to change. Main form icon should not change also. But 'secondary form' is a window I create dynamically (there may be many of them at once) and I want every one has different icon. Main form may be invisible, but secondary shows on timer sometimes, when main form is hidden. And there is the problem. When main form is hidden, secondary forms has wrong icons. When main form is visible, secondary forms has different icons like I want.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Wrong icon for new window when mainform is invisible
« Reply #7 on: January 28, 2014, 11:52:40 pm »
The attached project has a way of creating and assigning icons to borderless forms that seems to work OK (at least on Windows).
It's somewhat different from your approach, since that leads to a memory leak when assigning a png to an icon (perhaps you hadn't noticed - but if you use heaptrace it's obvious). I found the simplest way to do this without memory leaks is to go via a temporary imagelist.

GADZombie

  • New Member
  • *
  • Posts: 46
  • 8bitrlz
    • Zombie Mastah
Re: Wrong icon for new window when mainform is invisible
« Reply #8 on: January 29, 2014, 08:53:54 am »
Thank you for your example. It's much different than mine. I will test it later, because I don't have Lazarus now. But why do you think there is a memory leak when I assign png picture to an icon? It works fine. I didn't try your example yet, but you use imagelist and bitmap and I don't know if this will keep alpha channel in my pictures. That's why I used png format. I load png files and covert them to icon. If I don't use png format, the alpha channel doesn't work properly. I did try it, but it's different issue, not for this thread, so maybe I will not discuss it  here.
Is there a memory leak when I assign png to icon?
Code: [Select]
var
  tmpPng: TPortableNetworkGraphic;
begin
  result := TIcon.Create;

  //32x32
  tmpPng := TPortableNetworkGraphic.Create;
  tmpPng.PixelFormat := pf32bit;
  tmpPng.SetSize(32, 32);
  tmpPng.Canvas.Pen.Color := clRed;
  tmpPng.Canvas.MoveTo(0, 0);
  tmpPng.Canvas.LineTo(32, 32);

  result.Assign(tmpPng); //<-- this is the memory leak?
  tmpPng.Free;
I do use tmpPng.Free after that, so where is the leak?

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Wrong icon for new window when mainform is invisible
« Reply #9 on: January 29, 2014, 09:51:51 am »
But why do you think there is a memory leak when I assign png picture to an icon? It works fine.
I agree it works, but not fine if there is a leak. I think there is a leak only because heaptrace reports one.

Quote
I do use tmpPng.Free after that, so where is the leak?
I suppose it must be somewhere in the Assign() call. I looked briefly at the source, and internally AssignImage() is called, which is quite a complex method, and I suspect was not designed to cope with png to icon conversion. However, that is just a guess, I do not know enough about graphics programming to be sure. It does include some lines which are marked as
Code: [Select]
// temporary hack since TRasterImage assign cannot handle multiply rawimages
which does not inspire confidence. ;D
Maybe Felipe or someone who understands graphics better than me can offer advice.
You are right though that png may preserve the alpha channel where a bitmap may not. I had not considered that aspect in the example I offered.

GADZombie

  • New Member
  • *
  • Posts: 46
  • 8bitrlz
    • Zombie Mastah
Re: Wrong icon for new window when mainform is invisible
« Reply #10 on: January 29, 2014, 10:14:05 am »
Thanks anyway for your help, I appreciate it :)
Maybe I will learn something more - what is heaptrace and how to use it in Lazarus? If this will help me finding leaks, it would be great!

If something is wrong inside Assign method, then I think it's a bug in this component. If this works fine with png files, and alpha channel is preserved, so it is implemented in some way. It's doesn't look good because of this leak. Maybe there is a better solution to do the same thing without leaks.

Returning to my first question. Do you think the leaks and using png files rather than imagelist with bitmap is the problem and icons in forms disappears?

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Wrong icon for new window when mainform is invisible
« Reply #11 on: January 29, 2014, 10:44:35 am »
You should definitely be using the heaptrc unit, otherwise you may be unaware of memory leaks.
You can either specify it in your uses clause, or incorporate it via a commandline compiler switch (-gh) or through the the Project Options dialog (Ctrl Shift F11). The Linking page of that dialog has a "Use Heaptrc unit" option, which lets you easily enable/disable this per project.
Output reporting from the unit is by default to the Terminal/console, or if you are developing a GUI app under Windows you get a windowed output. For bad leaks this is seriously annoying, since you have to click away countless windows detailing all the unfreed memory blocks heaptrace has found. So better to use the SetHeapTraceOutput() routine in this case. You can also set an environment variable to control heaptrace output.
Recent versions of the Lazarus IDE include the LeakView tool (Tools->Leakview) which gives you an integrated way to read heaptrace output files. Make sure the compiler switch -gl is also enabled, so you get line number information (memory addresses alone are not very helpful unless you are an assembler programmer and are used to thinking in these terms). Smartlinking leads to loss of this information.
« Last Edit: January 29, 2014, 10:49:38 am by howardpc »

GADZombie

  • New Member
  • *
  • Posts: 46
  • 8bitrlz
    • Zombie Mastah
Re: Wrong icon for new window when mainform is invisible
« Reply #12 on: January 29, 2014, 05:56:43 pm »
The attached project has a way of creating and assigning icons to borderless forms that seems to work OK (at least on Windows).

Well, your project don't have the most important thing - creating new windows when main form is invisible. So I added new menuitem to popup menu that creates new window the same way as creating it by button from main form. Now when main form is hidden and you will create new window from popup menu it works the same as mine project! There is the same bug.
Try the attached project.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: Wrong icon for new window when mainform is invisible
« Reply #13 on: January 29, 2014, 07:19:36 pm »
Taskbar icons are drawn by the OS, which uses the default icon for the executable app. I suppose to customise a taskbar icon you have to override the default behaviour of the OS shell (which probably does not inspect the icon of each minimised window to check if it differs from its application icon). On Windows that would be some Shell_Notify function. I'll try to find out more. If there is an easy solution it will probably not be cross-platform.

GADZombie

  • New Member
  • *
  • Posts: 46
  • 8bitrlz
    • Zombie Mastah
Re: Wrong icon for new window when mainform is invisible
« Reply #14 on: January 29, 2014, 07:35:45 pm »
Thank you very much. I'm afraid of my whole application is not cross-platform ;). So this is not a problem.
But I'm not sure if this all is about shell. If yes, then why I can change those icons when main form is visible?
I will try this thing on Delphi. I have one at work, so I will do it later. I wander if the same is in Delphi application.

 

TinyPortal © 2005-2018