amiga-virus nachprogrammieren ;-)



  • ich verschieb das mal in das Webzeugs Forum



  • Original erstellt von kingruedi:
    ich verschieb das mal in das Webzeugs Forum

    ?



  • Zum Thema Mauskoordinaten ermitteln: Wie wär's mit GetCursorPos??

    cya 🙂



  • Ich sehe drei Möglichkeiten:
    1. Regions, wurde schon von mastercpp genannt
    2. Ein LayerdWindow, in dem irgendeine Farbe (sollte nicht benutzt werden, da man sie sonst nicht sieht) transparent ist
    3. Ein Overlay mit DirectDraw, das funktioniert aber afaik nicht mit allen Grafikkarten (ein Beispiel ist beim DDraw SDK dabei (Moskito, oder so ähnlich))



  • Also ich hab mal soein Ding programmiert, weil mich das Thema jetzt auch mal interessiert hat. Das ganze sieht so aus. Man startet das Programm und ab daan fliegt ein UFO die ganze Zeit der Maus hinterher. Natürlich nicht proportional sondern schön "anfahren" und dann "abbremsen" 😉

    Also falls ihr interessiert seit geb ich den Code her... 🙂

    cu para
    😃



  • ein paar stichworter die dir weiter helfen sollten... kleines fenster, grafik druf, mit regions den rest um die grafik ausschneiden, ein mousehook, und fertig... so ungefaehr



  • damit 😃



  • Also es läuft so: Ihr müsst praktisch nur noch eine Bitmap einfügen, wo der Teil der nicht erscheinen soll den RGB-Wert RGB(0, 255, 0) hat. Aber das ergibt sich aus dem Code

    Hier die main.cpp

    // includes
    #include <windows.h>
    #include "resource.h"
    #include "skin.h"
    
    // public
    HINSTANCE           hPubInst;       // public instance
    HRGN                hFlyerRgn;      // region
    BITMAP              hBmi;           // bitmap info
    HGDIOBJ             hOldObj;
    
    POINT pCursor;
    POINT pFlyer={0,0};
    
    // defines
    #define     TMR_FLYER       100
    
    // function to set up out flyer
    void SetupFlyer(HWND hFlyer)
    {
        // private
        float   dx;
        float   dy;
        static float    x, y;
        int     iMoveMax = 50;
    
        // get mouse coordinates
        GetCursorPos(&pCursor);
    
        // set position
        pCursor.y -= 100;
    
        // get distance
        dx = (float)abs(pCursor.x -pFlyer.x );
        dy = (float)abs(pCursor.y -pFlyer.y );
    
        // xpos
        if(dx>=1){ // no "ruckeling"
            x=dx/10;
            if(pFlyer.x < pCursor.x){
                pFlyer.x+=(int)x;
            }
            else{
                pFlyer.x-=(int)x;
            }
        }
        // ypos
        if(dy>=1){ // no "ruckeling"
            y=dy/10;
            if(pFlyer.y < pCursor.y)
                pFlyer.y+=(int)y;
            else
                pFlyer.y-=(int)y;
        }
    
        // set new position
        SetWindowPos(hFlyer, HWND_TOPMOST, pFlyer.x , pFlyer.y , 0, 0, SWP_NOSIZE);
    }
    
    // dialog window proc
    BOOL CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        // public
        HDC         hDC;
        HDC         hMemDC;
        static HBITMAP      hFlyerBmp;      // bitmap
    
        // switch our messages
        switch(uMsg){
    
        // on init
        case WM_INITDIALOG:
            // load flyer bitmap
            hFlyerBmp = LoadBitmap(hPubInst, MAKEINTRESOURCE(BMP_FLYER));
            if(hFlyerBmp==NULL){
                MessageBox(0, "Bild konnte nicht geladen werden", "ERROR", MB_OK);
    
                // quit
                PostQuitMessage(0);
            }
    
            // get bitmap info
            GetObject(hFlyerBmp, sizeof(hBmi), &hBmi);
    
            // create region of flyer
            hFlyerRgn = ScanRegion(hFlyerBmp, 0, 255, 0); // RGB(0, 255, 0) is transparent color
    
            // now, set rgn to our window
            SetWindowRgn(hDlg, hFlyerRgn, true);
    
            // set window to foreground
            SetWindowPos(hDlg, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
    
            // ok, lets set a timer
            SetTimer(hDlg, TMR_FLYER, 20, NULL);
    
            return TRUE;
    
        // on close
        case WM_CLOSE:
            PostQuitMessage(0);
            return TRUE;
    
        // on paint
        case WM_PAINT:
            PAINTSTRUCT         ps;
    
            // load bitmap
            hFlyerBmp = LoadBitmap(hPubInst, MAKEINTRESOURCE(BMP_FLYER));
    
            // begin to paint
            hDC = BeginPaint(hDlg, &ps);
                hMemDC = CreateCompatibleDC(hDC);
                hOldObj = SelectObject(hMemDC, hFlyerBmp);
                BitBlt(hDC, 0, 0, hBmi.bmWidth , hBmi.bmHeight , hMemDC, 0, 0, SRCCOPY);
    
                // cleanup
                DeleteObject(SelectObject(hMemDC, hOldObj));
                DeleteDC(hMemDC);
            // end paint
            EndPaint(hDlg, &ps);
    
            DeleteObject(hFlyerBmp);
            return TRUE;
    
        // on timer event
        case WM_TIMER:
            switch(wParam){
            case TMR_FLYER:
                // set up flyer
                SetupFlyer(hDlg);
                break;
            }
            return TRUE;
    
        // on destroy
        case WM_DESTROY:
            // delete bitmap
            DeleteObject(hFlyerBmp);
            return TRUE;
    
        }
    
        return FALSE;
    }
    
    // winapi entry point
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
    {
        // make public
        hPubInst = hInstance;
    
        // call our dialog box
        DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), 0, DlgProc);
    
        // quit
        return 0;
    }
    

    Sodele und hier die 2 "MAGISCHEN" Funktionen (skin.cpp):

    // include
    #include <windows.h>
    #include "skin.h"
    
    // function to scan a bitmap
    HRGN ScanRegion(HBITMAP pBitmap, BYTE jTranspR, BYTE jTranspG, BYTE jTranspB)
    {
      // bitmap width and height
      WORD wBmpWidth,wBmpHeight;
    
      // the final region and a temporary region
      HRGN hRgn, hTmpRgn;
    
      // 24bit pixels from the bitmap
      BYTE *pPixels = Get24BitPixels(pBitmap, &wBmpWidth, &wBmpHeight);
      if (!pPixels) return NULL;
    
      // create our working region
      hRgn = CreateRectRgn(0,0,wBmpWidth,wBmpHeight);
      if (!hRgn) { delete pPixels; return NULL; }
    
      // ---------------------------------------------------------
      // scan the bitmap
      // ---------------------------------------------------------
      DWORD p=0;
      for (WORD y=0; y<wBmpHeight; y++)
      {
        for (WORD x=0; x<wBmpWidth; x++)
        {
          BYTE jRed   = pPixels[p+2];
          BYTE jGreen = pPixels[p+1];
          BYTE jBlue  = pPixels[p+0];
    
          if (jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB)
          {
            // remove transparent color from region
            hTmpRgn = CreateRectRgn(x,y,x+1,y+1);
            CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
            DeleteObject(hTmpRgn);
          }
    
          // next pixel
          p+=3;
        }
      }
    
      // release pixels
      delete pPixels;
    
      // return the region
      return hRgn;
    }
    
    BYTE* Get24BitPixels(HBITMAP pBitmap, WORD *pwWidth, WORD *pwHeight)
    {
      // a bitmap object just to get bitmap width and height
        BITMAP bmpBmp;
    
      // pointer to original bitmap info
        LPBITMAPINFO pbmiInfo;
    
      // bitmap info will hold the new 24bit bitmap info
      BITMAPINFO bmiInfo;
    
      // width and height of the bitmap
      WORD wBmpWidth, wBmpHeight;
    
      // ---------------------------------------------------------
      // get some info from the bitmap
      // ---------------------------------------------------------
        GetObject(pBitmap, sizeof(bmpBmp),&bmpBmp);
      pbmiInfo   = (LPBITMAPINFO)&bmpBmp;
    
      // get width and height
        wBmpWidth  = (WORD)pbmiInfo->bmiHeader.biWidth;
        wBmpWidth -= (wBmpWidth%4);                       // width is 4 byte boundary aligned.
        wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;
    
      // copy to caller width and height parms
      *pwWidth  = wBmpWidth;
      *pwHeight = wBmpHeight;
      // ---------------------------------------------------------
    
        // allocate width * height * 24bits pixels
      BYTE *pPixels = new BYTE[wBmpWidth*wBmpHeight*3];
        if (!pPixels) return NULL;
    
      // get user desktop device context to get pixels from
        HDC hDC = GetWindowDC(NULL);
    
      // fill desired structure
        bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bmiInfo.bmiHeader.biWidth = wBmpWidth;
        bmiInfo.bmiHeader.biHeight = -wBmpHeight;
        bmiInfo.bmiHeader.biPlanes = 1;
        bmiInfo.bmiHeader.biBitCount = 24;
        bmiInfo.bmiHeader.biCompression = BI_RGB;
        bmiInfo.bmiHeader.biSizeImage = wBmpWidth*wBmpHeight*3;
        bmiInfo.bmiHeader.biXPelsPerMeter = 0;
        bmiInfo.bmiHeader.biYPelsPerMeter = 0;
        bmiInfo.bmiHeader.biClrUsed = 0;
        bmiInfo.bmiHeader.biClrImportant = 0;
    
      // get pixels from the original bitmap converted to 24bits
      int iRes = GetDIBits(hDC,pBitmap,0,wBmpHeight,(LPVOID)pPixels,&bmiInfo,DIB_RGB_COLORS);
    
      // release the device context
        ReleaseDC(NULL,hDC);
    
      // if failed, cancel the operation.
        if (!iRes)
      {
        delete pPixels;
        return NULL;
      };
    
      // return the pixel array
        return pPixels;
    }
    

    Dann braucht ihr halt noch ne Resource mit:

    • Bitmap, ID = BMP_FLYER
    • Dialog, ID = DLG_MAIN

    Und das wars auch schon.
    Wenn ihr zu faul seid, dann stell ich alles auf die HP.

    cu para
    😃

    PS: Wäre froh über nen Kommentar, danke!



  • hmm... sieht ja ganz gut aus
    aber ich kenn mich mit den WIN-API befehlen leider noch 0 aus...

    gibts irgendwo n gutes tut, wo die ganzen befehle und klassen vorgestellt werden ?

    dann könnt ich mir die basics erstma aneignen und dann auf deinen code zurückgreifen...
    🙂

    was meinst du eigentlich mit dialog ?
    kann ich dann einfach ne bitmap malen im paint und das verwenden ?
    wie pack ich dass dann in ne header oder besser gesagt in den code?

    bei mir ists aber dann so, jenachdem ob der cursor links oder rechts von der grafik ist, dreht der roboter sich entsprechend... d.h. ich habe 2 unterschiedliche bitmaps...
    muss ich halt dann ne bedingen machen, dass er die eine oder die andere bitmap einlädt...

    mfg haMMer



  • Auf meiner HP ist das Programm mit Quelltext, einfach mal angucken!

    cu para
    😃



  • Hmm, irgendwie stimmt was mit den Bildern bei mir nicht, die werden falsch angezeigt, auch wenn ich dein Programm starte para 😞



  • In wiefern werden sie den falsch angezeigt?
    Was für ein Betriebssystem benutzt du?



  • Win98
    Da sind so grüne Striche, wo eigentlich Transrapenz sein soll!
    Mit TransrapentBlt(...) gehts glaube ich auch 🙂



  • hmm...
    also erstmal danke an paranoiac für deinen code und deiner mühe 😉

    aber was mich jetz mal stark interessieren würde :

    könnte man das ganze nicht auch unter SDL machen anstatt mit der WinAPI ?
    wenn wir schon beim thema grafik sind, bietet sich die frage an denke ich...

    ich mein vielleicht lieg ich selber auch falsch, aber ist es nich so , dass man die WinAPI nur für fenster-anwendungen unter WINDOWS verwendet ? bzw. für gewisse Win32-console einstellungen ?

    ich mein wenn es um grafik programmierung geht, ich könnte ja auch ein 2d spiel coden, dann könnt ich doch gleich SDL nehmen oder ? oder Directx SDK...



  • @para: Ich mag dein WM_PAINT nicht! Das Bitmap lädt man in WM_CREATE oder in der WinMain. Das Gleiche gilt für das MemDC.



  • ok

    cu para
    😃



  • @Hammer: Es ist ziemlich doof, die Region bei Programmstart erstellen zu lassen. Besser ist es, sie gleich binär vorliegen zu haben. Dies kannst du einfach erreichen, indem du dir meinen RegionBuilder (suehe meine HP) runterlädst. Damit kannst du eine Region speichern und sie in dein Programm als Resource einbinden. Wie das alles geht steht in der RegionBuilder-Hilfe.



  • Nö, WebFritzi, da hast du leider unrecht. Das packt man normalerweise in WM_PAINT damit die Region so frisch wie möglich ist.



  • Original erstellt von <Hendrik>:
    Nö, WebFritzi, da hast du leider unrecht. Das packt man normalerweise in WM_PAINT damit die Region so frisch wie möglich ist.

    Du meinst wohl meinen ersten Post von den letzten beiden. Aber da hast du leider unrecht, da es hierbei nicht um Regions, sondern um Bitmaps und DCs ging. Pass das nächte mal ein wenig besser auf.



  • Nein ich meinte schon deinen Beitrag an Hammer. Wenn man die Region mit deinem Programm erstellt, ist die doch total veraltet. Man sollte die immer frisch in WM_PAINT generieren.


Anmelden zum Antworten