Kann InvalidateRect folgendes verursachen?



  • Hio,

    ich rufe für ein fremdes Programm öfters "InvalidateRect" auf, da ich etwas in das Fenster "male" und wenn ich möchte dass es gelöscht wird mir nichts anderes eingefallen ist. Nur das Problem ist, das Programm verursacht nach einer ungewissen zeit ne hohe Prozessorauslastung (von dem ich die Fenster immer neuzeichnen lasse, es handelt sich dabei um mehrere Childfenster).

    Gibts vielleicht noch ne andere möglichkeit was in andere Fenster zu zeichnen / und das auch nach wunsch wieder löschen zu lassen?
    Für Strings nutze ich "TextOut" und für Bilder nutze ich die Funktion "StretchBlt".

    Bin für jeden Tip dankbar.. kenne mich nur ganz wenig mit WInApi / GDI aus..



  • könntest ja WM_PAINT an das window senden.



  • WM_PAINT täte ich nie selbst senden.

    Kannste nicht evtl. nen transparentes Fenster (WS_EX_LAYERED) über das Fremdfenster legen und darin zeichnen statt direkt ins Fremdfenster?

    Ansonsten versuch mal bei InvalidateRect() das RECT welches du verändert hast anzugeben, mit ein bisschen Glück beachtet die Anwendung das.



  • Ähm, eigentlich sollte es, bei sauberer Programmierung, nicht zu hoher Prozessorauslastung kommen. Zeig doch mal Deine Malerei (also den Code 😃 ).



  • Hehe, normal malt man auch nicht in fremden Fenstern rum 😉



  • Ok ich poste hier mal meine betreffenden Methoiden aus der DLL, die von Java benutzt wird.
    Die erste Funktion "paint" malt ein Bildchen (wird von der hdd geladen) in das fremde Fenster an Position x,y. Der String ist der Path von der Datei.
    Die Funktion writeSth schreibt einen einfachen String in das Fenster..
    Und die Dritte löscht die Malerei wieder :).

    Also ich schreibe ein Tool für Partypoker, mit dem (unter anderem) die Mucked Hands (Karten, mit denen ein Spieler verliert und nicht anzeigen möchte) angezeigt werden. Und Partypoker fängt irgendwann an rumzuspinnen (hohe Prozessorauslastung). Mein Tool bleibt ganz normal. Deshalb hab ich irgndwie das repaint im Verdacht, da ich das so pro Spiel 3-4 mal aufrufe. Aber im grunde dürfte das doch kein Problem sein.
    Die Idee mit dem transparenten Window hört sich nicht schlecht an, nur kann ich dann noch mit der Maus an gewisse Stellen klicken und erreiche damit das "Fenster drunter" ?

    Danke für die Hilfe 🙂

    JNIEXPORT void JNICALL Java_MainClass_NewJFrame_paint(JNIEnv *env, jobject obj, jint handle, jint x, jint y, jdouble scale,jstring str) {
            HWND hWnd = (HWND)handle;
    	const char *c_string = (*env)->GetStringUTFChars(env, str, 0);
    	double scaleD =(double)scale;
    	PAINTSTRUCT ps;
            HDC hdc = GetDC(hWnd); 
            HBITMAP hbm = (HBITMAP)LoadImage(
                            NULL, c_string , IMAGE_BITMAP, 
                           0,0,LR_LOADFROMFILE );
            HDC     hdcMem = CreateCompatibleDC(hdc);
            HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, hbm);
            BITMAP bm;
            GetObject(hbm, sizeof(bm), &bm);
    	SetStretchBltMode(hdc, HALFTONE);
    	SetBrushOrgEx(hdc,x,y,NULL);
    StretchBlt(hdc,x,y,bm.bmWidth*scaleD,bm.bmHeight*scaleD,hdcMem,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);      
            SelectObject(hdcMem, hbmOld);
    
    	DeleteObject (hbm);
    	DeleteDC(hdcMem);                   
            ReleaseDC (hWnd,hdc);
    
    }
    
    JNIEXPORT void JNICALL Java_MainClass_NewJFrame_WriteSth(JNIEnv *env, jobject obj, jint handle, jint size, jint c1, jint c2, jint c3, jint x, jint y, jstring str ) {
    	HWND h = (HWND)handle;
    	const char *c_string = (*env)->GetStringUTFChars(env, str, 0);
    	int l = strlen(c_string);
    	HDC hdc = GetDC(h);
    	HFONT font = CreateFont(size, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, 0, 0, 0, 0, "Verdana");
    	SelectObject(hdc,font);
    	SetBkMode(hdc, TRANSPARENT);
    	COLORREF color = RGB(c1,c2,c3);
    	SetTextColor(hdc,color);
    	TextOut(hdc,x,y,c_string,l);
    	ReleaseDC(h, hdc); 
    }
    
    JNIEXPORT void JNICALL Java_MainClass_NewJFrame_RepaintWindow(JNIEnv *env, jobject obj, jint handle) {
    
    	HWND h = (HWND)handle;
    	InvalidateRect(h,NULL,FALSE); 
    
    }
    


  • Kann mir auf die Schnelle auch nicht erklären, warum 3-4 Aufrufe pro Spiel ein Problem verursachen sollen.
    Aber die mit CreateFont () erzeugte Schrift in der Funktion "Java_MainClass_NewJFrame_WriteSth ()" solltest Du nach Gebrauch wieder freigeben :

    ...
     DeleteObject (font);
     ReleaseDC    (h, hdc);
    ...
    


  • Lumpeh schrieb:

    Die Idee mit dem transparenten Window hört sich nicht schlecht an, nur kann ich dann noch mit der Maus an gewisse Stellen klicken und erreiche damit das "Fenster drunter" ?

    Ja das geht. Bei WS_EX_LAYERED sind transparente Stellen glaube ich sogar standardmässig "durchklickbar", ansonsten muss man glaube ich nur WM_NCHITTEST oder sowas abfangen und entsprechenden Rückgabewert liefern.

    Die java-app könnte dir allerdings probs machen, Java zeichnet ihren Kram glaube ich gerne mit DirectX...



  • also das Fenster, auf das ich daann das transparente Teil drüberklicken würde, wäre ja das Pokerfenster, und das ist mit C++ oder sowas geschrieben 🙂

    gibts irgendwo ein guites tutorial / beispiel für soetwas? Das Fenster dürfte dann auch keine "ränder" usw haben, man dürfte dann garnichts davon sehen :).
    Ich hab in C noch nie ein Fenster "erschaffen" 🙂 und das muss dann ja auch alles in die DLL..



  • ich hab jetzt hier wohl ein ganz gutes Tutorial gefunden, um ein simples fenster zu zeichnen:

    http://sig9.com/articles/c-window-howto

    was muss ich jaetzt dort noch verändern, damit mein Fenster wirklich komplett durchsichtig / durcklickbar ist? Ich will auch, dass das Fenster keine Ränder usw, es soll einfach komplett durchsichtig sein 🙂

    wobei ich grade überlege.. ich möchte ja etwas auf das Fenster draufzeichnen, das soll natürlich nicht durchsichtig sein.. hmm
    es soll nur alles was nicht belegt ist, durchsichtig sein, also was bei einem normalen Fenster eben so "grau" ist..
    wie geht denn das?



  • WS_POPUP als Fensterstil erzeugt ein Fenster ohne Rahmen und ohne Titelzeile
    Ab Win2k gibts für Transparenz WS_EX_LAYERED (1. Parameter bei CreateWindowEx)
    Was da genau gemacht werden muss/kann steht in der msdn...


Anmelden zum Antworten