| |
|
|
Georg Teles | SetMenuItemBitmap-Unit
Transparentes Bitmap auf MenuItem setzen, Stil beibehalten
Bitmap mit einem Alpha-Kanal aus einer Instance transparent auf ein beliebiges MenuItem eines bereits existierenden Menüs setzt, ohne den Stil des Menüs zu ändern
funktioniert auch auf TrackMenu, allerdings muss es bereits geladen worden sein (s. externes Menu als TrackMenu [...] )
Herunterladen
enthaltene main.bmp ist mit einem Alpha-Kanal versehen, muss natürlich in PROFAN.EXE zum Testen eingebunden werden
Win XP Win Vista Win 7 Win 8 Win 10 |
|
|
| |
|
|
|
Georg Teles | Win 7, 8, 10 geht, bei XP nicht, menno
|
|
|
| |
|
|
|
ByteAttack | Georg Teles (16.02.2016)
Win 7, 8, 10 geht, bei XP nicht, menno
Altes Problem mit XP - Alphakanäle in PNG werden auch erst ab Vista unterstützt... |
|
|
| |
|
|
|
Georg Teles | ByteAttack (16.02.2016)
Altes Problem mit XP - Alphakanäle in PNG werden auch erst ab Vista unterstützt...
hm, aber es ist eine Bitmap - wie regelt denn XP die Transparenz, war da nicht sowas wie eine belegte Farbe (s. pink also RGB(255,0,255) die als Alpha Kanal interpretiert wird in XP ? |
|
|
| |
|
|
|
| Das was Du meinst scheint sich mir eher auf BitBlit-Operationen [...] zu beziehen - da kann man im Prinzip 1 Farbe als transparent (bzw. nicht zu überzeichnen) definieren. Ist meist Farbe 0.
So zeichnet Roland dann auch z.B. bei Loadbmp ...; -1
Das hat mit Transluzenz bzw. Alpha-Kanal dann aber nichts zu tun.
Wie war das denn nur... zeichnet Windows bei diesen Menü-Bildchen nicht sowieso irgend eine bestimmte Farbe transparent?! mir war so...
Ich schätze, dass Roland das besser weiß. |
|
|
| |
|
|
|
RGH | Ich habe das Ganze mal zum Anlass genommen, im kommenden XProfan X3 auch bei normalen Menüs Icons zu erlauben. Die Syntax ist die gleiche wie bei den Customdraw-Menüs, nur dass das Icon-Handle als negativer Wert angegeben wird.
Da Windows nicht direkt Icons, sondern eine Bitmap bei normalen Menüs erwartet, habe ich dazu eine Routine geschrieben, die ein Icon in eine Bitmap umwandelt.
Zur Transparenz: Bei den Customdraw-Menüs mache ich ja eh' alles selbst, das heißt, ich zeichne das Icon auf das Menü. Icons haben ja von sich aus Transparenz und da muss ich mich nicht darum kümmern.
Hierbei gilt nicht eine Frabe als transparent, sondern Icons haben noch eine sogenannte Maske: eine zweifarbige schwarz/weiße Bitmap, bei der die Pixel schwarz sind, die nicht transparent sind. Um nun also eine Bitmap aus einem Icon zu erzeugen, erzeuge ich eine leere Bitmap in der Größe des Icons und kopiere nun Pixel für Pixel die Bitmap des Icons in die neue Bitmap, wobei ich nur bei den schwarzen Pixeln der Maske die Original-Farbe nehme und bei den übrigen Pixeln, die zuvor ermittelte Systemfarbe des Menü-Hintergrunds:
function IconToBitmap(DC: hDC; Icon: THandle; bc: integer): THandle; var bmpResult: tHandle; bmpColorOld, bmpMaskOld, bmpResultOld: tHandle; IInfo: ICONINFO; hdcColor, hdcMask, hdcResult: tHandle; c, m, x, y, dx, dy: integer; begin bmpResult := 0; If GetIconInfo(Icon, IInfo) then begin dx := IInfo.xHotspot * 2; dy := IInfo.yHotspot * 2; bmpResult := CreateCompatibleBitmap(DC, dx, dy); // DCs erzeugen hdcColor := createCompatibleDC(DC); hdcMask := createCompatibleDC(DC); hdcResult := createCompatibleDC(DC); // Bitmaps zuweisen bmpColorOld := SelectObject(hdcColor, IInfo.hbmColor); bmpMaskOld := SelectObject(hdcMask, IInfo.hbmMask); bmpResultOld := SelectObject(hdcResult, bmpResult); for x := 0 to dx - 1 do begin for y := 0 to dy - 1 do begin c := getPixel(hdcColor,x,y); m := getPixel(hdcMask,x,y); if m = 0 then setPixel(hdcResult,x,y,c) else setPixel(hdcResult,x,y,bc); end; end; // Ergebnis zuweisen bmpResult := SelectObject(hdcResult, bmpResultOld); // Aufräumen DeleteObject(SelectObject(hdcMask, bmpMaskOld)); DeleteObject(SelectObject(hdcColor, bmpColorOld)); DeleteObject(IInfo.hbmColor); DeleteObject(IInfo.hbmMask); DeleteDC(hdcColor); DeleteDC(hdcMask); DeleteDC(hdcResult); end; Result := bmpResult; end;
Kann man den komischen Code-Formatierer auch abschalten, damit der Code so dargestellt wird, wie ich ihn geschrieben habe? Ich hasse Programme, die glauben für mich mitdenken zu müssen. Gruß Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 17.02.2016 ▲ |
|
|
|
|
Georg Teles | iF (17.02.2016)
Das hat mit Transluzenz bzw. Alpha-Kanal dann aber nichts zu tun. Wie war das denn nur... zeichnet Windows bei diesen Menü-Bildchen nicht sowieso irgend eine bestimmte Farbe transparent?! mir war so...
genau, damit hat das nichts zutun, in XP wird vermutlich eine bestimmte Farbe transparent gemacht bzw. wird "ersetzt" , kenne noch die "Pinke" Farbe hehe --- bin bereits über genau diese Funktion gestolpert, mal schauen ob das klappt |
|
|
| |
|
|
|
Georg Teles | RGH (17.02.2016)
Da Windows nicht direkt Icons, sondern eine Bitmap bei normalen Menüs erwartet, habe ich dazu eine Routine geschrieben, die ein Icon in eine Bitmap umwandelt.
Aaah habe die Routine noch nicht ganz verstanden: genauer was Du mit RGH (17.02.2016)
und bei den übrigen Pixeln, die zuvor ermittelte Systemfarbe des Menü-Hintergrunds meinst, denn sobald man den Fokus auf das Menü hat, wird der Hintergrund des Menüs ja anders als ohne Fokus ? Ähnliches Tutorial mit BitBlit habe ich vor 2 Tagen schon gesehen [...] mal die Routine ausprobieren ob sie das gleiche täten tut wie das Tutorial
RGH (17.02.2016)
Kann man den komischen Code-Formatierer auch abschalten, damit der Code so dargestellt wird, wie ich ihn geschrieben habe? Ich hasse Programme, die glauben für mich mitdenken zu müssen.
HA das kann ich auch nicht ausstehen, besonders Programme die ohne vorwarnung etwas tun was man nicht möchte |
|
|
| |
|
|
|
RGH | Vor Aufruf der oben gezeigten Routine ermittele ich mit der API getSysColor(color_menu) die Hintergrundfarbe des Menüs. Diese wird in bc übergeben. (Der erste Parameter ist der aktive DeviceContext, der zweite das Icon-Handle und der dritte die Hintergrundfarbe.)
Das Ändern der Farbe beim Darüberfahren mit der Maus erledigt Windows. Das Menü ist zu dem Zeitpunkt ja schon gezeichnet.
Die Größe des Icons ermittle ich über die Position des Hotspots, da dieser bei Icons immer exakt in der Mitte liegt. (Bei einem Cursor wäre die Ermittlung ein der Größe etwas aufwändiger, da sie nicht in der Info-Struktur drin steht.) Außerdem ermittle habe ich in der Info-Struktur das Handle zur farbigen Bitmap und zur Masken-Bitmap. Um die Bitmaps nun zu bearbeiten, muss man den Bitmaps nun einem DeviceContext zuweisen, ebenso der Ergebnis-Bitmap. Der übliche Verwaltungsaufwand halt, wenn man direkt mit der API programmiert. In der Schleife lese ich dann Pixel für Pixel die Farbe der farbigen Bitmap und gleichzeitig die des entsprechenden Pixels der Maske. Ist dieses 1, setze ich das entsprechende Pixel der Ergebnis-Bitmap auf die Farbe, ist es 0, dann auf die Hintergrundfarbe. Und dann ist noch das übliche Aufräumen angesagt.
Gruß Roland |
|
|
| Intel Duo E8400 3,0 GHz / 4 GB RAM / 1000 GB HDD - ATI Radeon HD 4770 512 MB - Windows 7 Home Premium 32Bit - XProfan X4 | 17.02.2016 ▲ |
|
|
|
|
Georg Teles | Aaah vielen Dank für die detaillierte Erklärung, nun ist einleuchtend wieso da die Höhe / Breite * 2 steht, weil Hotspot des Icons in der Mitte ist
RGH (17.02.2016)
Das Ändern der Farbe beim Darüberfahren mit der Maus erledigt Windows. Das Menü ist zu dem Zeitpunkt ja schon gezeichnet.
Damit klärt sich die Frage danke |
|
|
| |
|
|
|
Georg Teles | Servus!
RGH (17.02.2016)
Das Ändern der Farbe beim Darüberfahren mit der Maus erledigt Windows. Das Menü ist zu dem Zeitpunkt ja schon gezeichnet.
verstehe ich das richtig, heisst das, jedes mal beim Fokusieren auf das Menü wird IconToBitmap ausgeführt ?
Grüße |
|
|
| |
|
|
|
| [OFFTOPIC] RGH (17.02.2016)Kann man den komischen Code-Formatierer auch abschalten, damit der Code so dargestellt wird, wie ich ihn geschrieben habe?
Ja, jetzt, einfach den Quelltext mit einem Ausrufezeichen beginnen - hab Deinen obigen Beitrag entsprechend angepasst. [/OFFTOPIC] |
|
|
| |
|
|