2012-01-07 61 views
1

enter image description here我有一個應用程序有2個窗體,每個窗體和應用程序都有單獨的圖標。在Form1BitBtn1.Click Form2上顯示Nonmodaly和Form1BitBtn2.Click Form1已關閉。在Form2BitBtn1.Click Form2已關閉和Form2BitBtn2.Click Form1已關閉。它工作正常。但問題是,在Windows 7任務欄中,Form1圖標是模糊的,另一個問題是使用Form1BitBtn1.Click顯示Form2時,應用程序只顯示Form1圖標而不顯示Form2圖標。 請幫幫我。Windows 7中的模糊Delphi窗體圖標任務欄

這裏是下載鏈接爲我的項目文件是「http://hotfile.com/dl/140219264/04ce49c/Delphi_XE2_Form_Handler.7z.html

我的代碼如下:

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. 
+4

請編輯您的問題包括** **小屏幕捕獲或東西給你在問什麼。 「Windows 7任務欄中的模糊Delphi窗體圖標」很難從模糊描述和一些完全不相關的代碼中理解,你希望人們編譯和運行以便甚至(可能)知道你在問什麼。這裏的人想要幫助,但你需要真正解釋你想要幫助什麼,才能使之成爲可能。 :)(你發佈的代碼只能在幾個事件中重複幾件事;它們都是'DoubleBuffered:= True' /'Font.Color:= '沒有理由完成。) – 2012-01-07 03:49:40

+3

澄清,'DoubleBuffered: = True'可以在Object Inspector中執行一次*(或者甚至在FormCreate中執行一次),並且在您每次執行操作時都會浪費精力。在你問的任何問題的範圍內改變Font.Color是沒有意義的(不管它是什麼,它與字體顏色的改變無關)。這些代碼都不適用於與應用程序或窗口圖標相關的任何問題。 – 2012-01-07 03:54:12

+0

@Koushik - 這個問題是[this one](http://stackoverflow.com/q/2621814/243614)的重複,儘管您發佈了所有代碼? – 2012-01-08 15:21:59

回答

6

在我看來,這裏發生的事情是由於VCL框架中的設計缺陷。基礎的Windows框架不爲每個頂級窗口維護一個,而是兩個圖標。這些圖標通過窗口類(參見WNDCLASSEX)或通過WM_SETICON消息與窗口關聯。

VCL框架始終調用WM_SETICON傳遞ICON_BIG,因此只分配大圖標。對於Windows 7,在任務欄上使用大圖標,並在窗口的標題欄上使用小圖標。在具有較小任務欄的早期版本的Windows上,任務欄上使用了小圖標。對於100%字體縮放,大圖標爲32像素,小圖標爲16像素。對於大字體,所需的圖標大小會發生變化。

現在,如果應用程序只提供其中一個所需的圖標,系統將縮放當需要繪製未提供的圖標大小時提供的圖標。如果您只提供一個大圖標,通常,縮放後的小圖標看起來很好。如果只提供一個小圖標,那麼縮放將變得更加困難,通常情況下,小圖標(顯示在標題欄上)看起來不錯,但大圖標是像素化的。

實際上發生在你身上的事情並不是這些問題。 VCL代碼意味着您總是向Windows指定大圖標。但是,你顯然提供了一個小圖標,幾乎可以肯定是16px。這與調用WM_SETICONICON_SMALL的效果相同,並且32像素圖標是像素化的。

對於你來說最簡單的解決方案是使用32px圖標作爲Form.IconApplication.Icon,無論你在哪裏設置圖標。這在很多時候都能正常工作。

但是,如果您的應用程序運行時字體縮放活躍,那麼您將再次遇到像素化。隨着字體縮放,圖標大小可以增加。爲了正確處理此問題,您必須向底層Windows框架提供正確大小的圖標。如果你不那麼會有像素化。您可以致電GetSystemMetrics找出圖標大小。

SmallIconSize := GetSystemMetrics(SM_CXSMICON); 
LargeIconSize := GetSystemMetrics(SM_CXICON); 

現在通常只要提供一個大圖標並依靠內置的縮放來產生小圖標就足夠了。如果你真的關心視覺效果,你當然應該使用專門爲這種小尺寸準備的圖標。縮小到16px的32像素圖標在視覺上不如有經驗的視覺設計師製作的16像素圖像有效。爲了使VCL使用您提供的小圖標,需要額外的工作。具體而言,您需要發送WM_SETICONICON_SMALL。在我的代碼庫中,我這樣做,實際上完全避免使用TForm.Icon,並且爲圖標大小調用WM_SETICON。爲了獲得所需的細粒度控制,VCL機制正好乾涉。

+0

+1同意。如有必要,最好提供一個大圖標(32x32或48x48),讓Windows縮小而不是提供這兩個圖標,並讓VCL錯誤地選擇小圖標。 – 2012-01-09 15:59:51

+0

我不知道是否有一個額外的「LargeIcon」屬性的自定義TForm後裔將是一個很好的事情,在一個人的工具箱。然後,TForm.Icon的內置行爲無需再擔憂。 – 2012-01-09 16:07:30

+0

@WarrenP事實上,你需要一個SmallIcon屬性! – 2012-01-09 16:14:47

1

我最好的猜測是,你的窗體圖標尺寸爲16×16,並且正在從拉伸16x16到48x48,導致你稱之爲「模糊的外觀」,但當輸入(表單或應用程序中的圖標)分辨率很低時,這是標準的Windows行爲。

圖標可以在同一個.ico文件中有多個分辨率。因此,請將您當前的圖標替換爲同時具有16x16,32x32和48x48尺寸的圖標。窗口將能夠顯示適當的全分辨率圖像。 Windows使用的現代圖標還可能包含一些較大的Vista/Win7圖標,最高可達256x256。 更新 OP報告該圖標已經具有所有正確的大小,並且從其他答案中可以看出,您遇到了VCL內部處理方面的問題,正如David在他的回答中提到的那樣。

總之,窗戶這樣做是因爲你無法避免它。這是一個模糊或像素化的選擇。窗口內的「拉伸」代碼會導致模糊,這正是爲了避免您在不模糊它時會看到的塊狀外觀。

+0

我已添加屏幕截圖。請幫幫我。 – 2012-01-08 06:21:09

+0

我的項目已經有16x16,32x32和48x48大小的圖標。 – 2012-01-08 06:34:46

+2

據我所知,德爾福只設置小圖標,並沒有提供內置的方式來設置大圖標 – 2012-01-08 08:26:52

7

我知道如何解決這個問題,這很簡單。 不要爲Form1.Icon提供圖標。

項目>選項>應用程序>應用程序圖標設置>加載 圖標提供您的圖標信息。

一定要爲您的圖標選擇最佳分辨率。

運行應用程序和shazan!

+0

thanx,爲我工作...'+ 1' – 2014-05-12 09:06:58

+1

此答案不解決被問到的問題。特別是在被問到的問題中,提問者明確指出:「我有一份申請有2份表格,每份表格和申請都有單獨的圖標。」換句話說,所提出的解決方案根本不適用。使用'TForm.Icon'和'TApplication.Icon'看到不同行爲的原因是,當您使用IDE設置圖標時,最終會在'TForm.Icon'中出現一個小圖標,在TApplication中出現一個大圖標。 Icon'。 – 2014-05-12 09:16:31

0

TL; DR版本:不要將Icon屬性設置爲通過從包含多個圖標大小的Win32資源加載而獲得的值以外的任何值。例如,只能使用TIcon.LoadFromResourceName。如果在表單設計器中設置Icon屬性,則只會使用一個圖標大小,從而導致縮放工件。

多年來,VCL一直不支持多圖標大小的圖標圖形的概念:TIcon總是被認爲是一個單一的圖形 - 而不是一組尺寸和分辨率不同的圖形。這仍然是事實,並且VCL中的設計問題可能不容易糾正。

VCL將通過WM_SETICON消息設置窗體圖標。 VCL始終將wParam設置爲ICON_BIG:對VCL源進行的檢查表明,在設置圖標時它從不使用ICON_SMALL。此外,創建窗口類時,hIconhIconSm成員變量WNDCLASSEX結構始終爲NULL。因此,很明顯VCL從來沒有嘗試設置一個小圖標。通常,如果應用程序從不設置小圖標,則Windows會將大圖標的大小調整爲小尺寸,這非常難看。但是,該規則有一個重要的例外。

注意,在Windows資源文件的ICON資源將實際存儲所謂的圖標組,這是從原來的.ico文件一組單獨圖標圖像。 LoadIcon API指出只有大型的32x32圖標會被加載。但是,這實際上並不是真的。看起來,Windows自己維護着一個HICON和原始資源之間的鏈接,所以如果需要其他大小的圖標,Windows可以根據需要加載它們。

這其實是不充分證明,但在MSDN一個地方,指出這樣一個事實:WNDCLASSEX structurehIconSm變量:

的句柄與窗口類關聯的小圖標。如果此成員爲NULL,則系統會搜索由hIcon成員指定的圖標資源,以找到適當大小的圖標作爲小圖標。

因此,儘管VCL沒有正確公衆TForm.Icon類的方式支持小圖標(例如,通過從在設計時的屬性編輯器分配給它),它仍然有可能把事情的工作權使用一個這兩種方法:

  • TForm.Icon屬性未設置(無圖標)。在這種情況下,表單將從TApplication.Icon獲取圖標。這個默認值來自應用程序的MAINICON資源。從TApplication.Create

    FIcon := TIcon.Create; 
    FIcon.Handle := LoadIcon(MainInstance, 'MAINICON'); 
    
  • 如果你不想使用的應用程序默認的圖標,你可以加載在運行時不同的圖標資源;在C++:

    myForm->Icon->LoadFromResourceName(FindHInstance(...), L"OtherResource"); 
    

因此,VCL爲小圖標的基本支持,因爲它支持從資源加載圖標,以及Windows支持從資源載入的大圖標加載小圖標。

如果使用VCL樣式,看到我的答案在這裏一個相關的錯誤:https://stackoverflow.com/a/35067909/562766

相關問題