I have an application having 2 Forms, each Form and Application have individual Icon. On Form1BitBtn1.Click Form2 is Shown-Nonmodaly and on Form1BitBtn2.Click Form1 is closed. On Form2BitBtn1.Click Form2 is Closed and Form2BitBtn2.Click Form1 is closed. It works fine. But the problem is that in Windows 7 Taskbar the Form1 Icon is Blurred and another problem is that when Form2 is shown using Form1BitBtn1.Click the application shows only Form1 Icon but not Form2 Icon.
Please help me.
Here is the download link for my project file is “http://hotfile.com/dl/140219264/04ce49c/Delphi_XE2_Form_Handler.7z.html“
My code is as below :
unit KoushikHalder01;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls,
Vcl.ComCtrls;
type
TForm01 = class(TForm)
BitBtn01: TBitBtn;
BitBtn02: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure FormHide(Sender: TObject);
procedure BitBtn01MouseEnter(Sender: TObject);
procedure BitBtn02MouseEnter(Sender: TObject);
procedure BitBtn01MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BitBtn02MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BitBtn01MouseLeave(Sender: TObject);
procedure BitBtn02MouseLeave(Sender: TObject);
procedure BitBtn02Click(Sender: TObject);
procedure BitBtn01Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form01: TForm01;
implementation
{$R *.dfm}
uses KoushikHalder02;
procedure TForm01.BitBtn01Click(Sender: TObject);
begin
Doublebuffered := True;
Form02.Show;
if Form01.Visible = true then Form01.BringToFront;
end;
procedure TForm01.BitBtn01MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
BitBtn01.Font.Color :=10379745;
end;
procedure TForm01.BitBtn01MouseEnter(Sender: TObject);
begin
BitBtn01.Font.Color :=16711825;
end;
procedure TForm01.BitBtn01MouseLeave(Sender: TObject);
begin
BitBtn01.Font.Color :=15756035;
end;
procedure TForm01.BitBtn02Click(Sender: TObject);
begin
Form01.Close;
end;
procedure TForm01.BitBtn02MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
BitBtn02.Font.Color :=10379745;
end;
procedure TForm01.BitBtn02MouseEnter(Sender: TObject);
begin
BitBtn02.Font.Color :=16711825;
end;
procedure TForm01.BitBtn02MouseLeave(Sender: TObject);
begin
BitBtn02.Font.Color :=15756035;
end;
procedure TForm01.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Doublebuffered := True;
end;
procedure TForm01.FormCreate(Sender: TObject);
begin
Doublebuffered := True;
end;
procedure TForm01.FormHide(Sender: TObject);
begin
Doublebuffered := True;
end;
procedure TForm01.FormShow(Sender: TObject);
begin
Doublebuffered := True;
end;
end.
What is happening here is, in my view, due to a design flaw in the VCL framework. The underlying windows framework maintains not one, but two icons for each top-level window. These icons are associated with a window either via the window class (see
WNDCLASSEX) or throughWM_SETICONmessages.The VCL framework always calls
WM_SETICONpassingICON_BIGand so only the large icon is assigned. For Windows 7 the large icon is used on the taskbar and the small icon is used on the window’s caption bar. On earlier versions of Windows, which had smaller taskbars, the small icon was used on the taskbar. For 100% font scaling the large icon is 32px and the small icon is 16px. For large fonts, the required icon sizes change.Now, if an application only supplies one of the required icons, the system will scale the icon provided when it needs to draw the icon size which has not been supplied. If you supply a large icon only then, generally, the resulting scaled small icon looks fine. If you supply a small icon only then it’s much harder to scale and what typically happens is that the small icon (shown on the caption bar) looks fine, but the large icon is pixellated.
In fact what is happening to you is neither of these problems. The VCL code means that you are always specifying, to Windows, the large icon. However, you are clearly supplying a small icon, almost certainly 16px. This has the same result as calling
WM_SETICONwithICON_SMALLand the 32px icon is pixellated.The simplest solution for you is to use the 32px icon in for
Form.IconorApplication.Icon, wherever it is that you set the icon. This will work fine for much of the time.However, if your application ever runs with font scaling active then you will encounter pixellation again. With font scaling, both icon sizes can be increased. In order to handle this properly you must provide to the underlying Windows framework an icon of the correct size. If you don’t then there will be pixellation. You can find out the icon sizes by calling
GetSystemMetrics.Now it is often sufficient just to supply a large icon and rely on the built in scaling to produce the small icon. If you really care about visuals you should of course use an icon specifically prepared for such small sizes. A 32px icon down-scaled to 16px will not be as effective visually as a 16px icon produced by a skilled visual designer. To make the VCL use the small icon you provide requires extra work. Specifically you need to send the
WM_SETICONforICON_SMALL. In my code base I do this and in fact avoid usingTForm.Iconat all and callWM_SETICONfor both icon sizes. In order to get the fine-grained control needed to do this right the VCL mechanisms just interfere.