amiga-virus nachprogrammieren ;-)



  • 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 :p

    mfg 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


Anmelden zum Antworten