2017-11-24 18 views
0

Ich verwende eine Schaltfläche, die nicht DPI-bewusst ist. Ich benutze es überall in meinem Code, also möchte ich idealerweise ein paar Zeilen im SetIcon des Buttons hinzufügen.Ändern der Größe eines HICON

Die SetIcon-Methode verwendet (nicht überraschend) einen HICON als Parameter - und ich möchte das Symbol abhängig von der DPI-Auflösung ändern (so die meiste Zeit seine Größe vergrößern).

bearbeiten Wie unten angegeben, war meine Frage nicht klar. Ich möchte nicht die Größe des Symbols ändern - wie von einer Ressource gelesen - aber ich möchte ein HICON od 16x16 in ein neues HICON von 40x40 verwandeln. Ich habe einen Code, der ein PNG liest (das ein HICON zurückgibt) und LoadImage (noch LoadIconWithScaleDown) wird nicht damit arbeiten.

Irgendwelche Ideen?

+0

Das Ändern der Frage, nachdem die Antwort bereits gegeben wurde, wird nicht empfohlen. Auch deine modifizierte Frage ist noch unklar. Sie haben "etwas Code", der 16x16 Symbol macht, erhalten Sie es nur, um 40x40 Symbol zu machen. Oder vergrößern Sie das Symbol, wenn Sie sich nicht um die Auflösung kümmern. Was hat das mit DPI zu tun? es sei denn, Ihre DPI-Einstellungen liegen bei 250 Prozent! –

+0

@BarmakShemirani Ich habe OP gebeten, seine Frage zur Klarstellung zu bearbeiten. Ich denke, es ist jetzt ganz klar. Ich habe derzeit keine Zeit, meine Antwort zu aktualisieren, die wie folgt aussehen könnte: 1. Erstellen Sie einen 32-Bit-Speichergerätekontext. 2. 'DrawIconEx()' in diesen Speicher DC, um das Symbol zu skalieren. 3. CreateIcon() 'aus den Bits des Speichers DC, um das zurück in ein Symbol zu verwandeln. – zett42

+0

@ zett42 - Danke dafür - würde die Transparenz funktionieren? – BadJerry

Antwort

1

Die DPI-Skalierung mit GetDeviceCaps abrufen und durch 96 dividieren, um den DPI-Faktor zu erhalten.

Multiplizieren Sie die Symbolgröße mit diesem DPI-Faktor. Beispiel:

int default_size = 16; 
CClientDC dc(GetDesktopWindow()); 
int logpixy = dc.GetDeviceCaps(LOGPIXELSY); 
size = MulDiv(default_size, logpixy, 96); 

hicon = (HICON)LoadImage(AfxGetApp()->m_hInstance, 
      MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, size, size, LR_DEFAULTCOLOR); 
button.SetIcon(hicon); 

Sie müssen verschiedene Symbolgrößen speichern. Zum Beispiel 16x16, 20x20, 24x24, 32x32. Wenn die genaue Größe nicht verfügbar ist, wählt LoadImage die nächste Übereinstimmung aus.

+1

Ich empfehle, 'LoadImage' mit [' LoadIconWithScaleDown'] (https://msdn.microsoft.com/en-us/library/windows/desktop/bb775703 (v = vs.85) zu ersetzen.aspx), die seit Windows Vista verfügbar ist. Dies verbessert die Bildqualität erheblich, wenn eine genaue Übereinstimmung der gewünschten Bildgröße in der Icon-Ressource nicht verfügbar ist. In diesem Fall lädt 'LoadImage' das Bild mit der nächsten * unteren * Größe und skaliert es nach oben, während' LoadIconWithScaleDown' das nächste * größere * Bild lädt und verkleinert, wodurch das skalierte Bild detaillierter und schärfer erscheint. – zett42

+0

@ zett42 Das macht die Dinge viel einfacher. Sie sollten den Kommentar in eine separate Antwort ändern. –

+0

Ich war ein bisschen faul. Danke, dass Sie mich ermutigt haben, das zu überwinden. :) – zett42

4

Verwenden Sie LoadIconWithScaleDown() (verfügbar seit Windows Vista), um ein Symbolbild in der gewünschten Größe zu laden, die bereits durch den DPI-Skalierungsfaktor skaliert wurde.

Eine andere Antwort schlägt die Verwendung von LoadImage() vor, aber LoadIconWithScaleDown() wird die Bildqualität erheblich verbessern, wenn eine genaue Übereinstimmung der gewünschten Bildgröße in der Symbolressource nicht verfügbar ist. In diesem Fall lädt LoadImage() das Bild mit der nächsten unteren Größe und skaliert das, während LoadIconWithScaleDown() das nächste größere Bild lädt und skaliert, was das skalierte Bild detaillierter und schärfer erscheinen lässt.

int cx = GetSystemMetrics(SM_CXSMICON); // scaled for system DPI! 
int cy = GetSystemMetrics(SM_CYSMICON); // scaled for system DPI! 

HICON hIcon = NULL; 
HRESULT hr = LoadIconWithScaleDown(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDI_ICON1), 
            cx, cy, &hIcon); 

if(SUCCEEDED(hr)) 
{ 
    button.SetIcon(hIcon); 
} 

Hinweis: ich GetSystemMetrics() bin mit der Standardgröße von einem kleinen Symbol zu bekommen, für das aktuelle System DPI skaliert. Dies ist gut genug, wenn Ihre Anwendung nur System-DPI-aware ist. Wenn Ihre Anwendung pro Monitor-DPI-fähig ist, interessiert Sie möglicherweise GetSystemMetricsForDpi(), die von einem aktuellen Windows 10-Update hinzugefügt wurde.

+0

Danke dafür - ich kannte LoadIconWithScaleDown nicht, aber das war nicht genau mein Frage. Ein großer Teil meines Codes liest PNGs als HICON (ich habe das nicht geschrieben) und ich möchte die HICON, die ich in einem neuen HICON erhalte, in der Größe ändern können. – BadJerry

+0

@BadJerry Sie sollten Ihre Frage bearbeiten, um diese wichtigen Informationen hinzuzufügen. Es hätte von Anfang an da sein müssen, damit wir nicht unsere Zeit damit verschwenden mussten, unangemessene Antworten zu geben. – zett42

+0

Herzliche Entschuldigung @ zett42 - Ich schätze deine Hilfe aber sehr (und ich habe etwas gelernt). Werde das jetzt tun. – BadJerry

Verwandte Themen