Grafik in Dialog einfügen
-
hallo,
ich habe nun ein bitmap zu den ressourcen hinzugefügt. nun weiß ich aber nicht, wie ich das auch in den dialog einfügen kann. geht das mit "picture control"? da kann ich dann aber nicht den typ der grafik angeben.
wäre toll, wenn mir das nochmal jemand erklären könnte.
gruß
-
also.. dein bitmab im resorsen heisst z.B bitmabxx
ein picture control auf dem dialog einlegen und mit dem maus markieren.
im eigenschaftfenster whält type :bitmab und bild wählt bitmabxx..und ..fertig.
-
Vielen Dank,
wie einfach. Danke!
-
Ich wollte hier gern noch was zum Anzeigen von zwei Bildern sagen: Man sollte nicht beide Bilder auf den CClienDC blitten. Das mag zwar bei einer simplen Ausgabe funktionieren, wenn man sich jetzt aber denkt, daß das eine Bild ein Hintergrund und das andere ein Sprite ist und man das Sprite über den Bildschirm bewegt, kommt es zu Flackereffekten, weil immer erst der Hintergrund, dann das Sprite, dann wieder der Hintergrund und dann das Sprite gezeichnet wird.
Stattdessen sollte man Double Buffering verwenden, wobei beide Bilder erst in ein drittes Bild kopiert werden und man dieses dann einmal ausgibt. Dieses Verfahren ist übrigens das, nach dem ich vor Monaten mal hier gefragt habe, und wo irgendwelche Klugscheißer mir ständig mit den Hinweisen Google und die Forumssuche gekommen sind. Oder sie gaben mir irgendwelche WinAPI-Tutorials, die mein Problem überhaupt nicht lösten, da dort selbst nur jeweils ein Bild augegeben wurde. Naja, wie auch immer. Ich werde das ganze jetzt ein für allemal klären. Und besagte Klugscheißer sollen mir doch mal nachweisen, wo diese Beschreibung hier im Forum schonmal aufgetaucht ist, so daß ich sie mit der Suche hätte finden können.
In OnPaint kommt folgendes:
CClientDC dc (this); CDC dcHintergrund, dcSprite, dcSpeicher; CBitmap bmpHintergrund, bmpSprite, bmpSpeicher; BITMAP bmH, bmS; bmpHintergrund.LoadBitmap (IDB_HINTERGRUND); bmpHintergrund.GetBitmap (&bmH); dcHintergrund.CreateCompatibleDC (&dc); dcHintergrund.SelectObject (&bmpHintergrund); bmpSprite.LoadBitmap (IDB_SPRITE); bmpSprite.GetBitmap (&bmS); dcSprite.CreateCompatibleDC (&dc); dcSprite.SelectObject (&bmpSprite); bmpSpeicher.CreateComaptibleBitmap (&dc, bmH.bmWidth, bmH.bmHeight); //Der Speicher hat hier die gleiche Größe wie der Hintergrund. dcSpeicher.CreateCompatibleDC (&dc); dcSpeicher.SelectObject (&bmpSpeicher); dcSpeicher.BitBlt (0, 0, bmH.bmWidth, bmH.bmHeight, &dcHintergrund, 0, 0, SRCCOPY); dcSpeicher.BitBlt (m_nX, m_nY, bmS.bmWidth, bmS.bmHeight, &dcSprite, 0, 0, SRCCOPY); //m_nX und m_nY müssen vorher als Membervarialen deklariert werden. Sie speichern hier die Position des Sprites. dc.BitBlt (0, 0, bmH.bmWidth, bmH.bmHeight, &dcSpeicher, 0, 0, SRCCOPY); //Auf das Fenster wird pro Funktionsaufruf nur einmal gezeichnet, was eben das Flackern verhindert.
Alles klar? Erst werden alle Bilder in den Speicher kopiert und dann wird der Speicher auf dem Fenster ausgegeben. So macht man das. Ach ja, und Invalidate braucht man nicht. Man ruft einfach bei jeder Veränderung/Bewegung wieder OnPaint auf. Ich glaube, Invalidate flackert auch, ich bin mir aber nicht sicher.
Und nun sollen mir diese Quacksalber, die mir damals bloß schlaumeierhafte Sprüche lieferten, doch mal sagen, wo es hier im Forum einen weiteren Beitrag zu eben diesem Thema (Double Buffering mit zwei oder mehr Bildern) gibt! Ihr wart ja der Meinung, daß ich nur genug suchen muß. Na los! Wo hätte ich das finden können?
P.S.: Ich selbst habe es dann durch Ausprobieren hinbekommen. Google oder Eure Forumssuche haben mir null geholfen.
-
da bin ich wieder, und wieder mit einem Problem...
ich möchte gerne das bild verschieben, wenn ich dann im Programm die variablen für die Koordinaten ändere, dann wird das bild erst geändert wenn ich das Fenster minimiere und wieder maximiere, oder halt ein Fenster drüber schiebe und wieder runter. Ich weiß halt den befehl nicht, wie ich das Fenster neu zeichnen lasse. ich habe die Bilder in „onPaint“, eingebunden. kann mir jemand erklären wie ich nach dem verschieben der Bilder die Bilder neu zeichnen lasse? thx!Edit:
kann m mir außerdem noch schnell jemand neben bei sagen was
"number = number >> 1;" macht? also wofür sind die beiden ">>"?
-
JumpLink schrieb:
kann m mir außerdem noch schnell jemand neben bei sagen was
"number = number >> 1;" macht? also wofür sind die beiden ">>"?Er Dividier "number" durch 2
-
Das stimmt nicht ganz genau, dann damit wird der Inhalt von number um ein bit nach rechts geschoben.
Entsprechend:
number << 1
ein Bit nach links geschoben.
Was auch mit 2(mal oder durch 4) geht usw.
Um aber den Sinn zu erklären(ja man kann das auch zum Rechnen benutzen):
Willst du das 3. und 4. Bit haben, dann geht das so:
number = (number >> 2) & 0xFF;
anderes Problem:
Du mußt das neu Zeichnen Veranlassen. Das macht man so:
[code]
CXXX::OnPaint()
{
//hier Zeichnen
}
CXXX:Verschieben()
{
//hier neue Position setzen
Invalidate(); //Veranlast das neu Zeichnen aufruf von OnPaint
}
[quote]
Gruß Matthias
-
@<<: aber wenn man etwas um ein bit verschiebt, kann es dann nicht zu problemen im speicher führen? Ich habe dieses beispiel in einem programm gesehen, in dem zahlen in binare zahlen umgewandelt werden. kann mir jemand ein beispiel machen? was würde z.B passieren wenn in "number" 255 steht?
@Zeichnen: okay danke, funktioniert. kann ich auch einstellen das nur ein einzelnes Bild oder ein bestimmter Bereich neu gezeichent wird? denn wenn ich das bild nun verschiebe, flimmert ab und zu das ganze Fenster.
-
*hochzieh*
-
okay danke, funktioniert. kann ich auch einstellen das nur ein einzelnes Bild oder ein bestimmter Bereich neu gezeichent wird? denn wenn ich das bild nun verschiebe, flimmert ab und zu das ganze Fenster.
Hast Du nur ein Bild auf dem gesamten Fenster oder hast Du ein Hintergrund- und darauf ein Vordergrundbild und willst nur das Vordergrundbild verschieben?
Wenn zweiteres richtig ist und Dein zu bewegendes Bild auf einem Hintergrundbild liegt, solltest Du Invalidate meiner Meinung nach gar nicht benutzen. Klar flackert das. (Das hab ich aber schonmal gesagt.) Ruf einfach an der entsprechenden Stelle, wo Du das Fenster aktualisieren willst, nochmal OnPaint auf! (Oder vielleicht besser: Schreibe eine Funktion void Ausgabe () und packe die sowohl in OnPaint als auch an jeder Stelle, wo sich die Position verändert. Dann spart er sich nämlich den Aufruf von CDialog::OnPaint, wenn Du bloß die Bilder veränderst.) Und Du solltest natürlich generell die Möglichkeit nutzen, die ich weiter oben geschildert habe, wo Du erst alles in einen DC speicherst, der den Back-Buffer darstellt, und dann diesen auf das Fenster blittest. Glaub mir: Dann gibt es keinerlei Flackern mehr.
Wenn Du nur ein Bild hast, geht obige Version natürlich nicht, da er ja dann die Reste des alten Bildes nicht löschen würde. Für diesen Fall gibt es InvalidateRect. Du mußt zuerst eine Instanz von CRect oder von der Struktur RECT erstellen, die die vier Eckpunkte speichert. Und die übergibst Du dann der Funktion InvalidateRect und er zeichnet nur das entsprechende Rechteck neu.
-
Hilfe!
Hab lange gesucht, aber einfach keine brauchbare Lösung für mein Problem gefunden. Ich krieg es jetzt auch hin, dass in meinem Dialog ein Bitmap angezeigt wird, aber ich schaffe es nicht, eine transparente Farbe nicht anzeigen zu lassen.
Hier mein Code ( OnPaint() ) für ein Bild dass nur aus schwarzen Pixeln besteht.
{ CPaintDC dc(this); CBitmap bitmap; bitmap.LoadBitmap(IDB_BLACK); CDC dcb; CRect rect; GetClientRect(rect); BITMAP bm; bitmap.GetBitmap(&bm); dcb.CreateCompatibleDC(dc); dcb.SelectObject(bitmap); dcb.SetBkColor(0); dcb.SetBkMode(TRANSPARENT); dc.StretchBlt(0, 0, rect.Width(), rect.Height(), &dcb, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); }
Mein Dialogfenster wird zwar immerhin schwarz, aber es sollte eigentlich nicht schwarz werden, weil schwarz ja transparent ist.
Was mach ich bloß falsch???
-
Hab nach langem Suchen doch was gefunden.
Hätte gedacht es würde vielleicht einfacher gehenFür alle die es interessiert:
http://support.microsoft.com/default.aspx?scid=kb;en-us;79212