2009-04-01 46 views
6

(Tôi đang sử dụng Visual Studio 2008, mặc dù tôi nhớ có vấn đề tương tự với các phiên bản cũ là tốt.)Vấn đề với thiết lập biểu tượng ứng dụng

Tôi đã thử phương pháp khác nhau (nhiều trong số họ đề cập trong this other question), nhưng tôi vẫn đang gặp một số vấn đề lạ:

  1. Khi đó có một biểu tượng như một nguồn lực, nó hiển thị như biểu tượng tập tin thực thi ngay lập tức, nhưng đối với biểu tượng để hiển thị trên thanh tác vụ, tôi phải khởi động lại máy tính. Cho đến lúc đó, nó vẫn tiếp tục hiển thị như bất cứ biểu tượng nào trước đó. Làm sạch dung dịch, khởi động lại VS, không có tác dụng. Không phải là một vấn đề thực sự lớn, vì nó sẽ không ảnh hưởng đến một exe phát hành, nhưng nó sẽ được tốt đẹp để biết nơi nó giữ biểu tượng cũ lưu trữ và làm thế nào để thoát khỏi nó.

  2. Bất kể tôi làm gì, biểu tượng được hiển thị khi alt-tabbing là biểu tượng ứng dụng mặc định (hình vuông và màu trắng và chung). Điều này bao gồm nhúng biểu tượng trong tệp thực thi, cũng như đặt ICON_BIG với WM_SETICON.

Đối với vấn đề thứ hai, mã của tôi trông giống như sau:

hIcon = (HICON)(
     LoadImage(NULL, szFilename, IMAGE_ICON, 32, 32, LR_LOADFROMFILE)); 
    if(hIcon) 
     SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 

Tuy nhiên, sau khi gửi WM_SETICON, GetLastError() lợi nhuận 6, "Việc xử lý không hợp lệ.". hWnd là tay cầm cửa sổ hợp lệ và hIcon dường như là một biểu tượng xử lý hợp lệ. Tôi đã cố gắng tìm kiếm lý do tại sao WM_SETICON có thể gây ra lỗi đó, và ít nhất, để tìm ra WHICH xử lý nó nghĩ là không hợp lệ, nhưng không có may mắn được nêu ra. Tôi đã xóa mã lỗi ngay lập tức trước khi gọi số SendMessage(), vì vậy nó phải được đặt ở đâu đó trong quá trình xử lý thư.

Tôi đã thử một phương pháp thay thế, tải các biểu tượng từ exe chính nó, nơi mà các ID của tài nguyên là 101 (đó là nguồn lực đầu tiên và duy bao gồm):

hIcon = (HICON)(
     LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(101), 
     IMAGE_ICON, 48, 48, 0)); 
    if(hIcon) 
     SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 

... nhưng điều tương tự xảy ra; sau khi gọi số SendMessage(), GetLastError() cho cùng trạng thái lỗi.

Tôi đã thử các thứ nguyên khác nhau (chẳng hạn như 48x48, tất cả đều có trong tệp biểu tượng), nhưng không có hiệu ứng khác. Tôi biết nó chắc chắn tìm và tải hình ảnh, bởi vì nếu tôi chỉ định kích thước không tồn tại hoặc ID tài nguyên không hợp lệ hoặc tên tệp sai (tùy thuộc vào cách tôi tải nó), nó không hoạt động lâu trước SendMessage().

Kỳ lạ thay, nếu tôi chỉ định ICON_SMALL thay vì ICON_BIG, cuộc gọi thành công không có trạng thái lỗi, nhưng từ the docs, tôi cần phải sử dụng ICON_BIG để thiết lập các biểu tượng sử dụng trong khi alt-tabbing. Ngoài ra, nếu tôi sử dụng ICON_BIG nhưng tải biểu tượng 16x16, tôi sẽ không nhận được trạng thái lỗi, nhưng không có gì thay đổi.

Bất kỳ ý tưởng nào về nguyên nhân có thể gây ra WM_SETICON không thành công? Bất cứ điều gì khủng khiếp sai với bất kỳ mã nào tôi đã đăng (ngoài các vấn đề định dạng/phong cách/đúc, vì nó đơn giản hóa chỉ là những điều cơ bản)?

Trả lời

3

Tôi đã xem lại trang này để xem liệu tôi có thể đóng câu hỏi của mình hay không. Tôi đã không thể hiển thị biểu tượng của ứng dụng trong danh sách alt-tab chỉ bằng cách nhúng nó vào tệp thực thi; nó sẽ hiển thị trong thanh tác vụ, dưới dạng biểu tượng của tệp trong Explorer và các nơi khác tốt.

tôi figured tôi muốn thử một cái gì đó đơn giản để thiết lập các biểu tượng bằng tay, và đi với LoadIcon() thay vào đó, như mã dưới đây cho thấy:

HICON hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1)); 
if(hIcon) 
{ 
    SendMessage(GetHandle(), WM_SETICON, ICON_BIG, (LPARAM)hIcon); 
    DestroyIcon(hIcon); 
} 
// ... Same for ICON_SMALL 

Điều này dường như đã làm các trick. Tôi thực sự không biết tại sao, nhưng cho đến nay nó là sự thay đổi duy nhất có hiệu lực. Nó thực sự không phải là một vấn đề tôi nên dành nhiều thời gian hơn, vì vậy tôi sẽ chỉ đi với điều này.

+0

Tôi cũng gặp phải vấn đề tương tự hôm nay. Thật không may điều này không làm việc cho tôi. Tôi phải tìm kiếm các giải pháp khác trên internet. – Lothar

+0

Phương thức 'LoadImage' hoạt động tốt cho tôi để hiển thị biểu tượng trong menu' alt' + 'Tab' Tôi gặp sự cố khi tôi không đặt' LoadImage' '' '' thành 32x32, một khi tôi đã làm điều đó làm việc như người ở. Xem: http://stackoverflow.com/a/24029664/1828637 – Noitidart

2

Tôi đã sử dụng một tệp .ico với nhiều độ phân giải 16x16, 32x32, 48x48, 96x96 mà không có sự cố, làm biểu tượng ứng dụng. Sau đó, cửa sổ sẽ chọn đúng kích cỡ.

Vỏ cửa sổ có icon cache, có trick để khởi động lại mà không cần khởi động lại hoặc đăng xuất khỏi phiên hiện tại hoặc giết explorer.exe từ trình quản lý tác vụ.

0

Nếu tìm được giải pháp cho tôi. Tôi đã tạo một cửa sổ ứng dụng CFrameWnd vô hình và sau đó một vài cửa sổ chính khác (đó là các cửa sổ hộp thoại). Quy tắc ma thuật không có giấy tờ là: Bạn phải thay đổi biểu tượng lớn trong CFrameWnd được tạo đầu tiên. Trong khi mỗi cửa sổ giữ riêng cá thể ICON_BIG của nó, nó không sử dụng chúng. Vì vậy, có vẻ như không thể hiển thị các biểu tượng thanh tác vụ khác nhau cho các cửa sổ khác nhau bên trong một ứng dụng.

2

OK, điều này đã làm việc một điều trị cho tôi:

HICON hIconSmall =(HICON)LoadImage(handleToYourApplicationInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON,16, 16, 0); 

HICON hIconLarge =(HICON)LoadImage(handleToYourApplicationInstance, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON,256, 256, 0); // Big for task bar, small loaded otherwise. 

SendMessage(yourWindowHandle, WM_SETICON, ICON_SMALL, (LPARAM)hIconSmall) ; 

SendMessage(yourWindowHandle, WM_SETICON, ICON_BIG, (LPARAM)hIconLarge) ; 
0

Đối với bất cứ ai đến với khó khăn này tương tự nếu bạn đang đi để thay đổi ICON_BIG trước tiên bạn phải gửi WM_SETICON với ICON_SMALL và sau đó tiến hành để ICON_BIG.

Ví dụ:

SetLastError(0); 
SendMessage(windowHandle, WM_SETICON, ICON_SMALL, (LPARAM)iconsmallHandle); 
[do error handling] 
SetLastError(0); 
SendMessage(windowHandle, WM_SETICON, ICON_BIG, (LPARAM)iconbigHandle); 
[do error handling] 

Bạn sẽ cần phải sử dụng SetLastError sau khi SendMessage đầu tiên để xóa bất kỳ lỗi trả lại.

Nếu bạn chỉ đang thiết lập ICON_SMALL, bạn có thể bỏ qua ICON_BIG. Đối với bất kỳ lý do gì trong tất cả các bài kiểm tra của tôi, bạn phải đặt ICON_SMALL bất kể biểu tượng đó có cần thay đổi hay không, trước khi cố thay đổi ICON_BIG, nếu không bạn sẽ luôn nhận được mã lỗi 0x6 (xử lý không hợp lệ).

Các vấn đề liên quan