amiga-virus nachprogrammieren ;-)
-
das versteh ich jetz gar nicht...
mit der ScanRegion leg ich ja die 3 verschiedenen regions fest in die hRgn1-3
ich dachte mit GetRegion kann ich die region sozusagen backuppen, sodass ich die
zu jeder zeit mit setregion verwenden kann...warum merkst du dir immer die vorherige region ? die is doch gar nich mehr relevant, ... ich brauch doch immer die region, wo auch meine neue bitmap vollständig hineinpasst...
ich dachte das getregion wäre nur zum abspeichern der einzelnen regionen ??
-
Erstmal heißt es Get/SetWindowRgn(). OK, nun zum Punkt: Wenn du SetWindowRgn() aufrufst, dann "gehört" dir die angegebene Region nicht mehr, sondern dem System. Sie ist dir u.U. verlorengegangen. Du brauchst sie also wieder. Dafür gibt es 2 Möglichkeiten: (a)Du benutzt andauernd Scanregion(), um die aktuelle Region neu zu erstellen; (b)Du benutzt GetWindowRgn(), um die verlorengegangene Region wiederzubekommen.
Verstanden?
-
also bei mir will er nich !
k.a. spiel schon seit 3 stunden mit GetWindowRgn() rum...einzigste was geht is in der WM_INITDIALOGE die dinger mit GetWindowRgn() festzuhalten, nur da hat man das prob, dass die dann wie du schon sagtest, nach einen durchgang verloren sind
die andere variante mit scanregion hab ich schon am anfang getestet.. die hat funktioniert, nur das prob da is, dass es nach jedem timer kurz ruckelt..
ich denke mal dass das ScanRegion() zu viel performance schluckt...aber das verschickt mich, wenns in der WM_INITDIALOGE geht, musses doch auch in der WM_TIMER gehen...
-
also ich kriegs mit GetWindowRgn() nich hin...
past mal deinen kompletten TIMER durchlauf... (bitte
)
ich will wissen ob ich n grundlegenden fehler mach oder obs
nur an ner kleinigkeit liegt...
ich lass das prob jetz mal auf mich liegen...
hab halt vorher die ganzen befehle noch nie verwendet
kein plan auf was man achten muss..
-
Scheinbar hast du GetWindowRgn() noch nicht ganz verstanden. Jedenfalls muss das aus WM_INITDIALOG raus! Sorry, hatte ich übersehen. Aus der MSDN über den 2. Parameter von GetWindowRgn():
Handle to a region. This region receives a copy of the window region.
Was passiert also wohl in den Zeilen
hRgn = ScanRegion(hBitmap, 255, 255, 255); GetWindowRgn(hDlg, hRgn);
Zunächst holen wir uns die "richtige" Region per ScanRegion() und dann weisen wir dem eben neu erstellten Handle schon wieder eine neue Region zu - nämlich die Window-Region, die zu dem Zeitpunkt von WM_INITDIALOG noch das ganze Rechteck beinhaltet. Das KANN nicht richtig sein!
-
OK, also
1. Die GetWindowRgn()s aus der WM_INITDIALOG raus;
2. Die SetWindowRgn()s aus der WM_PAINT raus;
3. Die SetWindowRgn()s in die WM_TIMER rein:if (wParam == TIMER_BMP) { bmp_counter++; if(bmp_counter == 5) bmp_counter = 1; if (bmp_counter == 1) { GetWindowRgn(hDlg, hRgn2); SetWindowRgn(hDlg, hRgn, true); } if (bmp_counter == 2) { GetWindowRgn(hDlg, hRgn); SetWindowRgn(hDlg, hRgn2, true); } if (bmp_counter == 3) { GetWindowRgn(hDlg, hRgn2); SetWindowRgn(hDlg, hRgn3, true); } if (bmp_counter == 4) { GetWindowRgn(hDlg, hRgn3); SetWindowRgn(hDlg, hRgn2, true); } InvalidateRect(hDlg, NULL, TRUE); }
-
hmm...
k.a. also ich denke ich habs so gemacht wie dus gesagt hast...
es will einfach nicht:BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
static HBITMAP hBitmap, hBitmap2, hBitmap3, hBitmapAttack;
HDC hdc, hdcMem;
PAINTSTRUCT ps;
static int bmp_counter = 1;switch (message)
{
case WM_INITDIALOG:hBitmap = LoadBitmap(hPubInst, MAKEINTRESOURCE(BMP_ROBO));
hBitmap2 = LoadBitmap(hPubInst, MAKEINTRESOURCE(BMP_ROBO2));
hBitmap3 = LoadBitmap(hPubInst, MAKEINTRESOURCE(BMP_ROBO3));
if(hBitmap==NULL || hBitmap2==NULL || hBitmap3==NULL)
{
MessageBox(0, "Bitmaps konnten nicht geladen werden !", "ERROR", MB_OK);
PostQuitMessage(0);
}GetObject(hBitmap, sizeof (BITMAP), &bitmap);
GetObject(hBitmap2, sizeof (BITMAP), &bitmap2);
GetObject(hBitmap3, sizeof (BITMAP), &bitmap3);hRgn = ScanRegion(hBitmap, 255, 255, 255);
hRgn2 = ScanRegion(hBitmap2, 255, 255, 255);;
hRgn3 = ScanRegion(hBitmap3, 255, 255, 255);SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE);
SetTimer(hDlg, TIMER_MOVE, 20, NULL);
SetTimer(hDlg, TIMER_BMP, 1000, NULL);
SetTimer(hDlg, TIMER_ATTACK, 2000, NULL);
SetTimer(hDlg, TIMER_RUSH, 20, NULL);return TRUE;
case WM_PAINT:
hdc = BeginPaint (hDlg, &ps);
hdcMem = CreateCompatibleDC (hdc);
if (bmp_counter == 1)
{
SelectObject (hdcMem, hBitmap);
BitBlt (hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
}
if (bmp_counter == 2)
{
SelectObject (hdcMem, hBitmap2);
BitBlt (hdc, 0, 0, bitmap2.bmWidth, bitmap2.bmHeight, hdcMem, 0, 0, SRCCOPY);
}
if (bmp_counter == 3)
{
SelectObject (hdcMem, hBitmap3);
BitBlt (hdc, 0, 0, bitmap3.bmWidth, bitmap3.bmHeight, hdcMem, 0, 0, SRCCOPY);}
if (bmp_counter == 4)
{
SelectObject (hdcMem, hBitmap2);
BitBlt (hdc, 0, 0, bitmap2.bmWidth, bitmap2.bmHeight, hdcMem, 0, 0, SRCCOPY);
}
DeleteDC (hdcMem);EndPaint (hDlg, &ps);
return TRUE;case WM_TIMER:
if (wParam == TIMER_MOVE && RemoveCursor() == false)
{MoveRobo(hDlg);}if (wParam == TIMER_BMP)
{
bmp_counter++;if(bmp_counter == 5)
bmp_counter = 1;if(bmp_counter == 1)
{
GetWindowRgn(hDlg, hRgn2);
SetWindowRgn(hDlg, hRgn, true);
}
if(bmp_counter == 2)
{
GetWindowRgn(hDlg, hRgn);
SetWindowRgn(hDlg, hRgn2, true);
}
if(bmp_counter == 3)
{
GetWindowRgn(hDlg, hRgn2);
SetWindowRgn(hDlg, hRgn3, true);
bmp_counter = 0;
}
if(bmp_counter == 4)
{
GetWindowRgn(hDlg, hRgn3);
SetWindowRgn(hDlg, hRgn2, true);
//bmp_counter = 1;
}
//bmp_counter++;InvalidateRect(hDlg, NULL, true);
}
jetz isses noch komischer als am anfang, als ich das ganze zeug noch in der WM_PAINT hatte... da hat er wenigstens noch den ersten durchgang korrekt angezeigt... sobald ich was in der TIMER mach, spinnts schon am anfang rum
[ Dieser Beitrag wurde am 26.02.2003 um 22:51 Uhr von Hammer editiert. ]
-
was ich mir überlegt hab, dass es am bmp_counter liegen könnte ..!
und zwar weiss ich nicht inwieweit WM_TIMER und WM_PAINT miteinander richtig
kooperieren ...
an was ich gedacht hab , dass der timer gleich am anfang schon bmp_counter um eins erhöht ! und das PAINT dann bei counter 2 anfängt und der timer erst noch bei 1 ist...
weil ich habe festgestellt, dass es fast keinen unterschied macht ob ich GetWindowRgn() im TIMER lasse oder komplett raushau...was mir auch noch aufgefallen ist, gerade jetz wo ich das SetWindowRgn im TIMER drin hab, dass er am anfang gar keine Rgn setzt, erst beim nächsten bild...
d.h. er zeigt am anfang erst das komplette Dlg-Rechteck an, erst beim nächsten counter verschwindet der Dlg und nur die Region wird angezeigt...das sagt mir eigentlich nur eines, dass der fehler im counter liegt, also in dem falle schon gleich am anfang... das würde dann auch erklären warum GetWindowRgn gar keinen Effekt hat...
naja habs aber noch nich hinbekommen, ... wenn dir was einfällt , kannst ja nochmal posten
mfg haMMer
[ Dieser Beitrag wurde am 27.02.2003 um 14:36 Uhr von Hammer editiert. ]
-
Hab deine Mail erhalten.
Und ich hab, glaube ich, das best mögliche draus gemacht. Aber es flackert immernoch ein wenig. Ich bin mir nicht sicher, ob man das überhaupt wegmachen kann. Ich schreib dir den Code hier herein, denn sooo viel ist es auch wieder nicht.
[EDIT] Dein Robo ist dermaßen hässlich... Ich würde nochmal nen anderen machen. Aber vielleicht hattest du das auch vor. [/EDIT]
#include <windows.h> #include "Resource.h" #include "skin.h" //--------------------------------------------------------------------------- #define TIMER_MOVE 1 #define TIMER_BMP 2 #define TIMER_RUSH 3 #define TIMER_ATTACK 4 HBITMAP hBitmap[3]; BITMAP bitmap[3]; // Variablen der Bitmaps RGNDATA* RgnData[3]; HDC hdcMem[3]; HRGN hRgn; HINSTANCE hPubInst;// Handle der main-Instanz POINT pCursor; // Koordinaten des MouseCursors POINT pRobo; // Koordinaten der Bitmap POINT pIcon; int iSize; BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM) { HDC hdc; PAINTSTRUCT ps; static int i, bmp_counter = 0; switch (message) { case WM_INITDIALOG: hBitmap[0] = LoadBitmap(hPubInst, MAKEINTRESOURCE(BMP_ROBO1)); hBitmap[1] = LoadBitmap(hPubInst, MAKEINTRESOURCE(BMP_ROBO2)); hBitmap[2] = LoadBitmap(hPubInst, MAKEINTRESOURCE(BMP_ROBO3)); if(!hBitmap[0] || !hBitmap[1] || !hBitmap[2]) { MessageBox(0, "Bitmaps konnten nicht geladen werden !", "ERROR", MB_OK); PostQuitMessage(0); } hdc = GetDC(hDlg); for(i=0; i < 3; i++) { hdcMem[i] = CreateCompatibleDC(hdc); SelectObject(hdcMem[i], hBitmap[i]); GetObject(hBitmap[i], sizeof(BITMAP), &bitmap[i]); hRgn = ScanRegion(hBitmap[i], 255, 255, 255); iSize = GetRegionData(hRgn, 0,0); RgnData[i] = new RGNDATA[iSize]; GetRegionData(hRgn, iSize, RgnData[i]); DeleteObject(hRgn); } ReleaseDC(hDlg, hdc); hRgn = ExtCreateRegion(NULL, iSize, RgnData[0]); SetWindowRgn(hDlg, hRgn, TRUE); SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE); SetTimer(hDlg, TIMER_MOVE, 20, NULL); SetTimer(hDlg, TIMER_BMP, 1000, NULL); //SetTimer(hDlg, TIMER_ATTACK, 2000, NULL); //SetTimer(hDlg, TIMER_RUSH, 20, NULL); return TRUE; case WM_PAINT: hdc = BeginPaint (hDlg, &ps); i = (bmp_counter == 3) ? 1 : bmp_counter; BitBlt(hdc, 0, 0, bitmap[i].bmWidth, bitmap[i].bmHeight, hdcMem[i], 0, 0, SRCCOPY); EndPaint (hDlg, &ps); return TRUE; case WM_TIMER: if(wParam == TIMER_MOVE && RemoveCursor() == false) MoveRobo(hDlg); if (wParam == TIMER_BMP) { bmp_counter++; if(bmp_counter == 4) bmp_counter = 0; i = (bmp_counter == 3) ? 1 : bmp_counter; DeleteObject(hRgn); hRgn = ExtCreateRegion(NULL, (RgnData[i]->rdh.nCount)*sizeof(RECT) + sizeof(RGNDATAHEADER), RgnData[i]); SetWindowRgn(hDlg, hRgn, TRUE); InvalidateRect(hDlg, NULL, TRUE); } if(wParam == TIMER_RUSH && RemoveCursor() == true) Rush(hDlg); if (wParam == TIMER_ATTACK && RemoveCursor() == true && Rush(hDlg) == true) {} return TRUE; case WM_DESTROY: for(i = 0; i < 3; i++) { SelectObject(hdcMem[i], (HBITMAP)NULL); DeleteObject(hBitmap[i]); DeleteDC(hdcMem[i]); delete[] RgnData[i]; } PostQuitMessage (0) ; return TRUE; } return FALSE; } int WINAPI WinMain(HINSTANCE hI, HINSTANCE, LPSTR, int) { hPubInst = hI; DialogBox(hI, MAKEINTRESOURCE(DLG_ROBO), 0, (DLGPROC)DlgProc); return 0; }
[ Dieser Beitrag wurde am 28.02.2003 um 21:41 Uhr von WebFritzi editiert. ]
-
re:
also erstmal vielen dank für die mühe und deinen einsatz !
aber ich muss leider gestehen, dass es bei mir immernoch probs gibt...
ich habs identisch umgeändert in deiner variante, aber er zeigt nur die erste sekunde die erste bitmap korrekt an, danach erscheint die Dialoge und innerhalb der Dlg werden alle 3 bitmaps überlappend angezeigt, also sprich es passiert gar nix mehr, ausser dass es sich bewegt...
also er fängt richtig an, aber sobald der nächste timertakt kommt, zeigt er alles von einmal an,
sieht so aus als würde er die regions dann gar nich mehr setzen...
oder besser gesagt er klatscht die 2 anderen bitmaps über die erste bitmap drüber, ohne aber vorher die Regions für die 2te und dritte bitmap auszuwählen
und zu setzen!also erstmal muss ich sagen, dass ich selber jetzt gar nix mehr testen kann, da
gewisse sachen komplett neu sind, wie zb. RGNDATA
oder die Schreibweise i = (bmp_counter == 3) ? 1 : bmp_counter; oder das
hRgn = ExtCreateRegion(NULL, RgnData[i]->rdh.nCount, RgnData[i]);dazu müsst ich mich erst reinarbeiten und massiv neue tuts lesen,
klar werde ich auch machen... aber es wäre für mich psychologisch befriedigender, wenn das prob mal vorübergehend beseitigt wäre...hmm, ich dachte bei dir gehts, also muss es bei mir auch gehen...
vielleicht gibt es unterschiede zwischen winXP und win2k ?? weiss ja nich was du fürn OS verwendest
weil ich hab mal das prog bei einem getestet, der hat winXP, und da kam ne windows-fehlermeldung beim starten, obwohls bei mir daheim astrein lief
(das wäre aber ein grund für mich nie wieder unter windows zu coden)
naja was meinst du dazu ?
mfg haMMer
[ Dieser Beitrag wurde am 28.02.2003 um 21:48 Uhr von Hammer editiert. ]
-
Ich hab Win98, glaube aber nicht, dass es an der Windoof-Version liegt. Zunächst mal habe ich noch nen Fehler gefunden bei mir. Aber leider wird das dein Problem nicht beheben. Egal, ich korrigiere ihn erstmal: In WM_TIMER bei wParam == TIMER_BMP müssen die drei letzten Zeilen lauten
hRgn = ExtCreateRegion(NULL, (RgnData[i]->rdh.nCount)*sizeof(RECT) + sizeof(RGNDATAHEADER), RgnData[i]); SetWindowRgn(hDlg, hRgn, TRUE); InvalidateRect(hDlg, NULL, TRUE);
So funzt es bei mir jedenfalls ganz gut. Ich hab das oben nochmal berichtigt. Damit dein Projekt genauso aussieht wie meines, solltest du vielleicht dein Resourcen-Skript nochmal ändern. Da habe ich ne Menge rausgenommen, so dass mein Resourcen-Compiler das überhaupt angenommen hat. Bei mir sieht das so aus:
[code]
// Die Header-Datei heißt Resource.rh
#ifndef RESOURCE_RH
#define RESOURCE_RH#define DLG_ROBO 103
#define BMP_ROBO1 104
#define BMP_ROBO2 105
#define BMP_ROBO3 106#endif
// Das Skript
#include "Resource.rh"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//DLG_ROBO DIALOGEX 0, 0, 122, 74
STYLE WS_POPUP
EXSTYLE WS_EX_TOOLWINDOW
CAPTION ""
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
FONT 8, "MS Sans Serif"
{
}/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
BMP_ROBO1 BITMAP DISCARDABLE "roboter.bmp"
BMP_ROBO2 BITMAP DISCARDABLE "roboter2.bmp"
BMP_ROBO3 BITMAP DISCARDABLE "roboter3.bmp"
/////////////////////////////////////////////////////////////////////////////[/code]
Vielleicht bringt das was, wenn du deines änderst. Ach ja, und außerdem habe ich die Bitmaps so klein wie möglich gemacht. Alle haben jetzt die Größe 52x55. Das verringert den Zeitaufwand bei ScanRegion.Zu deinen Problemen mit den Funktionen:
1.) RGNDATA ist eine Struktur, die (wie der Name schon sagt) Daten für eine Region speichert. Wie das intern genau aussieht braucht dich nicht zu interessieren. Wichtig ist, dass die Regions in meiner Version binär im Speicher vorliegen - in Form von 3 RGNDATA-Strukturen. Das Problem war, dass die Regions nach einmaligem Benutzen wieder "weg waren", wie du ja selber mitbekommen hast. Also muss man sie vor der Benutzung wieder laden. Das kann man per ScanRegion machen, was aber viel zu lange dauert. Also habe ich das mit RGNDATA's gelöst. Am Anfang werden die Regionen gescannt und in danach in den RGNDATA-Strukturen gespeichert. Wenn man eine Region braucht (siehe in WM_TIMER), dann kann man sie einfach per ExtCreateRegion() aus der entsprechenden RGNDATA-Struktur erstellen.
-
diese Denkweise gefällt mir, mit dem abspeichern der regions in die RGNDATA's !
klar, weil mit ScanRegion() hab ichs auch schon hinbekommen, nur dann wirds ziemlich lahm das ganze...(ruckelt immer nach jedem Scan)hmm, ich probiers jetz nochmal mit meinem alten code, mit den if's und so...
hab jetz auch arrays verwendet, is besser... und jo, jetzt probier ichs selbst
nochmal mit RGNDATA.
Weil prinzipiell hat ja alles funktioniert bei mir, nur dass halt die Regions immer verloren gingen nach jedem SetWindowRgn()
Naja und wenn alle stricke reissen, dann nimm ich deinen code wieder !hätte nicht gedacht, dass dieses prog so viel wissen zur winapi benötigt !
krass...aber ich kann nur thx sagen, dass du mir da so viel hilfst
mfg haMMer
-
Klar helfe ich dir. Aber lass dir eins sagen: sooo schwer ist das nicht. Nur ein bisschen fummelig.
-
LOOL!!! jetz gehts! habs selber hingekriegt mit ExtCreateRegion
läuft astrein bei mir, ruckelt nix, gar nix...!DANKE DANKE DANKE !
----------------------------------Wenn wir jetz schon so tief in der thematik drin sind, kannst mir ev. noch
zeigen, wie man diese bitmap nach links rechts spiegeln kann...?
weil ich will noch in abhängigkeit, ob die maus links oder rechts vom robo steht, dass sich der robo dann immer den mauszeiger anguckt-> wieso findest du den Robo hässlich ? also die Form wollte ich auf jeden Fall
so lassen... er soll ja auch den cursor verschlucken können, deshalb der mund..
und naja n zweibeiner solls auch sein...
hey, das ding hab ich mit dem PaintProg unter zubehör gemalt :pmfg haMMer
-
BOOL StretchBlt( HDC hdcDest, // handle to destination DC int nXOriginDest, // x-coord of destination upper-left corner int nYOriginDest, // y-coord of destination upper-left corner int nWidthDest, // width of destination rectangle int nHeightDest, // height of destination rectangle HDC hdcSrc, // handle to source DC int nXOriginSrc, // x-coord of source upper-left corner int nYOriginSrc, // y-coord of source upper-left corner int nWidthSrc, // width of source rectangle int nHeightSrc, // height of source rectangle DWORD dwRop // raster operation code );
StretchBlt creates a mirror image of a bitmap if the signs of the nWidthSrc and nWidthDest parameters or if the nHeightSrc and nHeightDest parameters differ. If nWidthSrc and nWidthDest have different signs, the function creates a mirror image of the bitmap along the x-axis. If nHeightSrc and nHeightDest have different signs, the function creates a mirror image of the bitmap along the y-axis.
Vieleicht funzt das auch mit BitBlt, steht allerdings nicht in der MSDN.
Das Flackern kriegst du übrigens weg, wenn du beim InvalidateRect(hDlg, NULL, TRUE);-Aufruf als letzten Parameter false übergibst oder wenn du noch ein WM_ERASEBKGND-Zweig in deine WndProc machst und einfach nur 0 zurückgibst.
Könntest du mir das Prog bitte mal mailen, ich will mir das auch mal angucken.
-
kann ich machen... aber erstmal probier ich noch das mit dem spiegeln ...
das StretchBlt(), das ruft man dann in der WM_PAINT auf oder ?ich hab mal jemanden gefragt wegen dem spiegeln, nur der hat sich seine funktion selber erstellt zum spiegeln... so ähnlich wie der RegionScanner