amiga-virus nachprogrammieren ;-)
-
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üheaber 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.
-
Original erstellt von <Hendrik>:
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.*LOL* Genau. Damit man immer schön warten muss, oder was? So ein Blödsinn! Zu Testzwecken ist sowas vielleicht geeignet, aber nicht für die Endversion. Da sollte die Region dann binär vorliegen. Dann kann man sie meinetwegen immer wieder neu generieren, denn das geht viel schneller als das Verfahren, das para hier anwendet (immer wieder das Bitmap in ein 24-Bit-Bitmap umwandeln und dann die Region Pixel für Pixel mit CombineRgn() erstellen).
-
@Webfritzie
Da du von Testzwecken redest, ist es natürlich auch sinnvoll dir Regions jedesmal neu zu erstellen (bei jedem Start). Sonst müsste man ja immer dein Programm, welches nicht von dir ist, sondern von der Skinningpage (wo ich auch die Funktionen her hab), nehmen und dass wäre sehr kompliziert. Hat man ein Programm mal fertig ist es mit sicherheit einfacher sie als Binary vorliegen zu haben.Das man das Bild nicht in WM_PAINT läd ist mir nomalerweise auch klar, aber es ging nicht, wenn ich es einmal am Anfang lade, auch nicht wenn das Bitmap static ist. Da es nur ein Testprogramm war und innerhalb von kürzester Zeit geschrieben wurde, hab ich es halt "falsch" gemacht. Es war jediglich zur Demonstration gedacht.
para
-
zum code von para nochmal:
vorweg:
also ich hab jetz mal begonnen mich mit der winapi auseinanderzusetzen...
jetz kann ich wenigstens mit den begriffen handles und den WM_MESSAGES was anfangen
naja was ich bisher aber nur kann, sind fenster erstellen und deren inhalt gestalten... naja und mit ressourcen hab ich mich etwas beschäftigt...womit ich aber noch gar nich klarkomm sind dialoges und regions...
was genau sind dialoges und regions im vergleich zu fenstern ??
und warum werden die hier verwendet im code ?ausserdem wundert mich noch, dass para keine getmessage-schleife in der WinMain verwendet ... ? wie funktioniert das da dann ? ich mein irgendwo müssen doch die messages eingefangen werden die das os zum programm sendet ...
wäre dankbar wenn einer den code vonn para etwas erklären könnte zum thema messages einfangen und regions und dialoges...
thx
mfg haMMer