Mauszeiger wird falsch angezeigt
-
Hallo,
ic wollte in meinem Programm einen eigenen Mauszeiger anzeigen lassen (über einem TImage) und hab dazu einen Cursor erstellt, dessen Auflösung 48x48px beträgt. Wenn ich diesen über
Screen->Cursors[myCursor] = LoadCursor(HInstance,"RES_CURSOR"); Cursor = myCursor;
lade, dann wird er allerdings gestrecht, ich nehme an auf 32x32. Laut Google scheint man aber auch größere Cursor verwenden zu können, nur steht nirgendswo so richtig wie man das anstellt. Hat dabei jemand Erfahrung? GetSystemMetrics in Verbindung mit SM_CX/YCURSOR gibt mir auch 32px aus, aber lässt sich das irgendwie umgehen?
greetz KN4CK3R
-
Dafür wirst du die WinAPI benutzen müssen (CreateIconIndirect).
Siehe z.B. http://groups.google.com/group/borland.public.cppbuilder.vcl/browse_thread/thread/a51f111298cdb158/919febb8945b3f58
-
danke für den Link, aber die Funktion die dort vorgestellt wird, benutzt auch wieder GetSystemMetrics um die Größe zu berechnen, was wiederum 32px ergibt. Kann bei CreateIconIndirect die übergebene Bitmap auch größer sein, wie diese 32px Standartgröße?
greetz KN4CK3R
-
Hallo,
Ja, kann über 32x32 Pixel liegen.
Ausschlaggebend für den Cursor die richtige Maskierung dieses Bitmap (s. ICONINFO).mfg
kpeter
-
oki, hab mir das mal ein wenig angeschaut und das ist genau das was ich brauche. Allerdings bin ich mit der Maske noch nicht so ganz um grünen... (schaut euch den Screenshot an, dann wisst ihr was ich meine
)
http://www.abload.de/img/cursorr6tr.jpg
Der "Cursor" besteht aus einem Rahmen, den ich mit rosa Farbe ummantelt habe. Den rosa Bereich lasse ich als durchsichtig interpretieren:
Graphics::TBitmap *bmpCursor = new Graphics::TBitmap(); ... bmpCursor->TransparentColor = RGB(255,0,255); bmpCursor->Transparent = true;
Den Cursor hab ich dann so erstellt:
ICONINFO icon; icon.fIcon = false; icon.xHotspot = 0; icon.yHotspot = 0; icon.hbmMask = fvrand->MaskHandle; icon.hbmColor = fvrand->Handle; ... = CreateIconIndirect(&icon);
Dass MaskHandle das transparente Bitmuster enthält, war wohl zu früh gefreut. Kann ich das trotzdem benutzen oder muss ich dazu noch eine neue Mask-Version erstellen? Wenn ich selbst erstellen muss, ist es dann mein Bild nur in schwarz/weiß? Also transparent = schwarz und sichtbar = weiß?
greetz KN4CK3R
Edit: hab das mal eben schnell ausprobiert mit dem schwarz/weiß Bild als Maske. Wenn ich den rosa Bereich weiß mache und meinen Rahmen schwarz, dann hab ich das gleiche Ergebnis, wie wenn ich MaskHandle zuweise (wie auf dem Screenshot). Wenn ich das ganze rumdrehe (rosa = schwarz, Rahmen = weiß), dann bekomme ich einen Cursor, der meinen rosa Bereich hat und dort wo der Rahmen ist, durchsichtig ist?! Das ist ja eigentlich das, was ich wollte, nur dass es andersrum halt dieses komische grün ergibt.
-
Hallo,
die Erstellung der HBITMAP in der Struktur ICONINFO ist etwas aufwändiger.
Und wie ich finde, ist es einfacher, sich einen (grösseren) farbigen Cursor gleich aus einer TBitmap zu erzeugen.Beispiel:
*.h
private: Graphics::TBitmap* bmp; Graphics::TBitmap* bmpMask; Graphics::TBitmap* bmpColor; void __fastcall CreateCursorFromBmp(HCURSOR &hCur, Graphics::TBitmap *bmp); HCURSOR hBigCursor; public: __fastcall TForm1(TComponent* Owner); __fastcall ~TForm1(void);
*.cpp
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { bmp = new Graphics::TBitmap; bmp->LoadFromFile("cursor2.bmp"); bmpMask = new Graphics::TBitmap; bmpColor = new Graphics::TBitmap; CreateCursorFromBmp(hBigCursor, bmp ); } //--------------------------------------------------------------------------- __fastcall TForm1::~TForm1(void) { delete bmp; delete bmpMask; delete bmpColor; DeleteObject(hBigCursor); } //--------------------------------------------------------------------------- void __fastcall TForm1::CreateCursorFromBmp(HCURSOR &hCur, Graphics::TBitmap *bmp) { int wi = bmp->Width; int hi = bmp->Height; bmpMask->Width = wi; bmpMask->Height = hi; bmpColor->Width = wi; bmpColor->Height = hi; bmpMask->PixelFormat = bmp->PixelFormat; bmpColor->PixelFormat = bmp->PixelFormat; TRect rect = Rect(0, 0, wi, hi); bmpMask->Canvas->CopyMode = cmNotSrcCopy; // alt cmMergePaint; bmpMask->Canvas->CopyRect(rect, bmp->Canvas, rect); bmpColor->Canvas->CopyMode = cmSrcInvert; bmpColor->Canvas->CopyRect(rect, bmp->Canvas, rect); // --- begin edit ---- bmpColor->Canvas->CopyMode = cmDstInvert; bmpColor->Canvas->CopyRect(rect, bmpColor->Canvas, rect); // --- end edit ---- ICONINFO iconinf; iconinf.fIcon = false; iconinf.xHotspot = 0; iconinf.yHotspot = 0; iconinf.hbmMask = bmpMask->Handle; iconinf.hbmColor = bmpColor->Handle; hCur = CreateIconIndirect(&iconinf); } //--------------------------------------------------------------------------- // Beispiel void __fastcall TForm1::Panel1MouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { ::SetCursor( hBigCursor ); }
Weisse Farben im Bitmap sind im Cursor transparent.
Vielleicht gibt dir das ne Anregung oder du machst es gleich somfg
kpeteredit: Code ergänzt/geändert
-
weiß bedeutet transparent und alles was nicht 255,255,255 entspricht, ist sichtbar? Oder ist das noch eine Abstufung dann, also grau = halbtransparent? Auf jeden Fall schonmal danke für den Code, werde ich mir heute nachmittag mal genauer anschauen.
greetz KN4CK3R
-
KN4CK3R schrieb:
weiß bedeutet transparent und alles was nicht 255,255,255 entspricht, ist sichtbar?
Ja, zumindest mit obiger Funktion.
Ansonsten einfach mal experimentieren. Eventuell bekommt jemand eine andere TransparentColor festgelegt
Das Ergebnis bitte hierher posten...mfg
kpeter
-
Microsoft macht das ganze ein wenig anders (sicher der Teil den Canvas übernimmt) und mit Alpha von 0-100
http://support.microsoft.com/kb/318876
Edit: gerade mal deine Funktion an meine Bedürfnisse angepasst und es funktioniert fast so wie es soll, danke. Problem ist jetzt noch, dass der eigentlich gelbe Rahmen nur über weißen Hintergrund gelb ist. Wenn ich mit der Maus über ein Bild gehe, dann wird das gelbe schwachblau?!
greetz KN4CK3R
-
So,
zugegeben hab ich auch nur auf weissem Untergrund getestet...
Nu sollte es aber gehen, habe die Funktion leicht ergänzt:
Zeile 39 anderer CopyMode.
Damit ist TransparentColor jetzt schwarz. Zu beachten beim anlegen der Bitmap.In Zeilen 47/48 invertiert sich das bmpColor nochmal.
mfg
kpeter
-
wunderbar, jetzt passts genau. Gibt es irgendwo zu den einzelnen CopyModes eine Beschreibung? In der Borland-Hilfe steht bei mir dazu nichts.
greetz KN4CK3R
-
Unter Graphics.TCopyMode (BCB2009) solltest du aber fündig werden...
ed/
Hier ist auch der Link zu embarcadero
-
BCB2006 gibts das scheinbar noch nicht, da steht nur das in der Hilfe:
Beschreibung
Mit der Eigenschaft CopyMode können Sie beeinflussen, wie Grafiken auf der Zeichenfläche gezeichnet werden. CopyMode wird verwendet, wenn ein Bild mit der Methode CopyRect von einer anderen Zeichenfläche kopiert wird. Auch TBitmap-Objekte bedienen sich dieser Eigenschaft, wenn sie sich selbst auf einer Zeichenfläche zeichnen.Mit CopyMode lassen sich beim Erzeugen eines Bildes eine Vielzahl von Effekten erzielen. Durch das Kombinieren von mehreren Bildern mit unterschiedlichen CopyModes können Sie Spezialeffekte erzielen, indem Sie beispielsweise Bilder mischen oder Teile eines Bitmaps transparent anzeigen.
Die Onlinehilfe scheint da aktueller zu sein.
greetz KN4CK3R
-
Nee,
diese Auflistung steht schon in der bcb3.hlp, BCB Version 3. Die ist vom 1998...
Mit der Online-Version hast du natürlich recht.edit: Hast du den Code aus deinem MS-Link getestet?
mfg
kpeter
-
ja getestet hab ich den, funktioniert auch, allerdings war ich zu unfähig den an mein Problem richtig anzupassen.
Auch hab ich ein wenig mit dem Transparenzwert herumgespielt, allerdings war mir das 9F nicht ganz schlüssig und ich kam auf keinen Wert der komplette Transparenz dargestellt hätte.Auf die Gefahr hin, dass ich gesteinigt werde. Meine BCB2006 Hilfe hat kein Thema zu TCopyMode. Unter Graphics wird kein TCopyMode aufgeführt und den Text von TBitmap->TCopyMode hab ich schon gepostet. Auch wenn ich nach cmNotSrcCopy suchen lasse, wird das Wort nicht gefunden.
greetz KN4CK3R
-
KN4CK3R schrieb:
ja getestet hab ich den, funktioniert auch...
Ist vielleicht mal was für einen neuen Thread.
mfg
kpeter