Welches Objekt beende ich nicht?



  • Kann mir jemand sagen Welches Objekt beende ich nicht?

    DWORD WINAPI Zeichenalgorhitmus(LPVOID lpParams)
    {
    	HWND hwnd = (HWND)lpParams;
    	HDC hdc = GetDC(hwnd);
        GetClientRect(hwnd, &rc);
        hdcMemory = CreateCompatibleDC(hdc);
        hBitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
        SelectObject(hdcMemory, hBitmap);
        PatBlt(hdcMemory, rc.left, rc.top, rc.right, rc.bottom, WHITENESS);
    	menu();//Zeichnet das Meue
        BitBlt(hdc, rc.left, rc.top, rc.right, rc.bottom, hdcMemory, 0, 0, SRCCOPY);
        DeleteObject(hBitmap);
        DeleteDC(hdcMemory);
    	DeleteObject(hdcMemory);
    	DeleteObject[code](hdc);
    	ReleaseDC(hwnd, hdc);
        Sleep(1);
        SendMessage(hwnd, WM_ZEICHNE_NEU, NULL, NULL);
    
    	return 0;
    }
    


  • Der Code lässt sich nicht übersetzen; kopiere bitte korrekt...



  • main.cpp

    #include "integrate external.h"
    #include "integrate internally.h"
    
    #include "resource.h"
    LPCSTR MainClassName = "Jump";
    std::string vision="1.0";
    #define WM_ZEICHNE_NEU              1001
    #define M_PI       3.14159265358979323846
    static long t = 0;
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg,
                             WPARAM wParam, LPARAM lParam);
    
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                       PSTR szCmdLine, int iCmdShow)
    {
        WNDCLASSEX wc;
        MSG wmsg;
        HWND hWnd;
    
        wc.cbSize           = sizeof(WNDCLASSEX);
        wc.style            = 0;
        wc.lpfnWndProc      = WndProc;
        wc.cbClsExtra       = 0;
        wc.cbWndExtra       = 0;
        wc.hInstance        = hInstance;
        wc.hIcon            = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_ICON));
        wc.hCursor          = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
        wc.lpszMenuName     = MAKEINTRESOURCE(IDR_MENU1);
        wc.lpszClassName    = MainClassName;
        wc.hIconSm          = (HICON)LoadImage(GetModuleHandle(NULL),
                                            MAKEINTRESOURCE(ID_ICON),
                                            IMAGE_ICON, 16, 16, 0);
    
        if(!RegisterClassEx(&wc))
        {
            MessageBox(NULL, "Windows Registrations Fehler", "Error!",
                       MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
    
        hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, MainClassName,
                              "JUMP",
    						  WS_VISIBLE|WS_SYSMENU,//WS_VISIBLE |WS_MINIMIZEBOX
                              CW_USEDEFAULT, CW_USEDEFAULT,
                              1280, 720, NULL, NULL, hInstance, NULL);
    
        if(hWnd == NULL)
        {
              MessageBox(NULL, "Fehler beim Erstellen des Fensters!",
                               "Error!", MB_ICONEXCLAMATION | MB_OK);
              return 0;
        }
    
        while(GetMessage(&wmsg,NULL,0,0))
        {
            TranslateMessage(&wmsg);
            DispatchMessage(&wmsg);
    
        }
        return wmsg.wParam;
    }
    int t2=1;
    DWORD WINAPI Zeichenalgorhitmus(LPVOID lpParams)
    {
    	HWND hwnd = (HWND)lpParams;
    	HDC hdc = GetDC(hwnd);
        GetClientRect(hwnd, &rc);
        hdcMemory = CreateCompatibleDC(hdc);
        hBitmap = CreateCompatibleBitmap(hdc, rc.right, rc.bottom);
        SelectObject(hdcMemory, hBitmap);
        PatBlt(hdcMemory, rc.left, rc.top, rc.right, rc.bottom, WHITENESS);
    	menu();
        BitBlt(hdc, rc.left, rc.top, rc.right, rc.bottom, hdcMemory, 0, 0, SRCCOPY);
        DeleteObject(hBitmap);
        DeleteDC(hdcMemory);
    	DeleteObject(hdcMemory);
    	DeleteObject(hdc);
    	ReleaseDC(hwnd, hdc);
        Sleep(1);
        SendMessage(hwnd, WM_ZEICHNE_NEU, NULL, NULL);
    
    	return 0;
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg,
                             WPARAM wParam, LPARAM lParam)
    {
        char string[255];
        switch (iMsg)
        {
    		case WM_CREATE:
                HANDLE hStartThread;
                hStartThread = CreateThread(NULL, NULL, Zeichenalgorhitmus, hWnd, NULL, NULL);
                break;
    		case WM_ZEICHNE_NEU:
                HANDLE hZeichenalgorhitmus;
                hZeichenalgorhitmus = CreateThread(NULL, NULL, Zeichenalgorhitmus, hWnd, NULL, NULL);
                break;
            case WM_CLOSE:
                DestroyWindow(hWnd);
                break;
            case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
            case WM_COMMAND:
                switch(LOWORD(wParam))
                {
                    case ID_FILE_OPEN:
                        LoadString(GetModuleHandle(NULL), ID_STRING_OPEN,
                                   string, sizeof(string));
                        MessageBox(hWnd, string, "Öffnen", MB_ICONINFORMATION);
                        break;
                    case ID_FILE_SAVE:
                        LoadString(GetModuleHandle(NULL), ID_STRING_SAVE,
                                   string, sizeof(string));
                        MessageBox(hWnd, string, "Speichern", MB_ICONINFORMATION);
                        break;
                    case ID_\1:
                        /*LoadString(GetModuleHandle(NULL), ID_STRING_ABOUT,
                                   string, sizeof(string));*/
                        MessageBox(hWnd, "vision: 1.0 Beta", "Über", NULL);//"vision"+vision
                        break;
                    case ID_FILE_EXIT:
                        DestroyWindow(hWnd);
                        break;
                }
                break;
    
        }
        return DefWindowProc(hWnd, iMsg, wParam, lParam);
    }
    


  • Und was ist jetzt dir Frage? Was für Probleme hast Du?



  • DeleteObject(hdcMemory);
        DeleteObject(hdc);
    

    Diese beiden Zeilen in der Funktion Zeichenalgorhitmus weglassen!



  • nach einer zeit wirt der Bildschirm Weis.
    Ich denke es linkt daran das ich ein Objekt nicht beendet habe. Weis aber nicht welches



  • MassNerder schrieb:

    DeleteObject(hdcMemory);
        DeleteObject(hdc);
    

    Diese beiden Zeilen in der Funktion Zeichenalgorhitmus weglassen!

    Wirt immer noch weis



  • Oder habe ich ein Fehler beim Zeichnen?

    bool menu(){
    	bool returnValue=false;
    	if(display=="menu"){
    	//Eingabe
    	//Verarbeitung
    	//Ausgabe(Zeichen)
    		srand(time(NULL));
    		//Hintregrund
    			SelectObject(hdcMemory, CreateSolidBrush(RGB(4,18,35)));
    			RoundRect(hdcMemory,-1,-1,1500,1000, 0, 0);
    			//Geister
    
    			SelectObject(hdcMemory, CreatePen(PS_NULL,1,NULL));
    			SelectObject(hdcMemory, CreateSolidBrush(RGB(250,250,250)));
    
    			RoundRect(hdcMemory,geistx,geisty+50,geistx+200,geisty+100, 100, 100);
    			RoundRect(hdcMemory,geistx,geisty+75,geistx+200,geisty+200, 0, 0);
    			Ellipse(hdcMemory,geistx,geisty+75,geistx+200,geisty+335);
    
    			Ellipse(hdcMemory,geistx+50,geisty,geistx+150,geisty+75);
    
    			if(geistvor==1){geistx=geistx+1;}
    			if(geistvor==0){geistx=geistx-1;}
    			if(geistx>600){geistvor=0;} 
    			if(geistx<10){geistvor=1;}
    
    			if(geistdown==1){geisty=geisty+1;}
    			if(geistdown==0){geisty=geisty-2;}
    			if(geisty>50){geistdown=0;}
    			if(geisty<30){geistdown=1;}
    			DeleteObject(hBitmap);
    		//Auswahlömöglichkeiten
    
    			SelectObject(hdcMemory, CreateSolidBrush(RGB(86,48,11)));
    			RoundRect(hdcMemory,380,50,900,150, 350, 350);
    
    			HFONT hMeineFont = CreateFont(90,0,0,0,FW_NORMAL,true,false,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,"Arial");
    			HGDIOBJ hOldFont = (HFONT)SelectObject( hdcMemory, hMeineFont ); 
    			SetBkMode(hdcMemory, TRANSPARENT);
    			SetTextColor(hdcMemory, RGB(255,255,255));
    			SetTextAlign (hdcMemory,TA_CENTER);
    			TextOut(hdcMemory, 635, 60, "Meue", sizeof("Meue")-1);
    			SelectObject( hdcMemory, hOldFont ); 
    			DeleteObject( hMeineFont ); 
    			//Bottem
    
    			//schrift
    
    	}	
    	return returnValue;
    }
    


  • Du darfst von einem non-UI-Thread nicht im UI-Thread zeichnen!
    Auch zeichnet man immer auf die Reaktion von WM_PAINT!
    Also bitte:
    - Zeichne im Thread in einen MemDc
    - Diesen übergibst Du dann an den UI-Thread
    - Dort löst Du nur ein "InvalidateRect" aus
    - Das löst ein WM_PAINT aus, worin Du dann das Bitmap zeichnest...

    Ich persönlich würde das Zeichnen auch im UI-Thread machen; nur falls Du dazu komplexe Daten brauchst; diese würde ich in einem anderen Thread holen...



  • verstehe nicht ganz was du mit MemDc meinst, kannst du mir das an einem beispiel vielleicht erklaren?



  • Kannst du mir das bitte genauer erklären. Habe noch wenig Erfahrung mit WinAPI.



  • Du bist doch 5chlau, also google es dir einfach selbst.
    WinAPI ist ja nicht gerade so neu dass es dazu nicht ca. 1 Mrd. Tutorials geben würde.



  • MC5chlau schrieb:

    Kannst du mir das bitte genauer erklären. Habe noch wenig Erfahrung mit WinAPI.

    Für jmd mit wenig Erfahrung werden hier aber bereits heftige Geschütze aufgefahren.

    Abgesehen davon, das Das Gerüst bisher garkein WM_PAINT unterstützt frage ich
    mich ob diese Dauerschleife mit dem Thread sinnvoll sein koennte (ich denke nicht;)

    DWORD WINAPI Zeichenalgorhitmus(LPVOID lpParams) 
    { 
      ...
      menu();
      ...
      SendMessage(hwnd, WM_ZEICHNE_NEU, NULL, NULL); 
    
      return 0; 
    }
    
    LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, 
                             WPARAM wParam, LPARAM lParam) 
    { 
        char string[255]; 
        switch (iMsg) 
        { 
            case WM_CREATE: 
                HANDLE hStartThread; 
                hStartThread = CreateThread(NULL, NULL, Zeichenalgorhitmus, hWnd, NULL, NULL); 
                break; 
            case WM_ZEICHNE_NEU: 
                HANDLE hZeichenalgorhitmus; 
                hZeichenalgorhitmus = CreateThread(NULL, NULL, Zeichenalgorhitmus, hWnd, NULL, NULL); 
                break; 
    ...
    

    Ich vermute, das etwas in regelmässigen Zeitabständen über den Screen bewegt
    werden soll ?

    Also würde ich einen Alarmtimer nehmen, der die Positionen berechnet und dann
    WM_PAINT aufruft. Dort sollten dann die Unterprogramme für den eigentlichen
    Zeichenkram hin.

    Die Threaderzeugung ist vermutlich unnötig.



  • Wie gesagt: Das Zeichnen muss in WM_PAINT erfolgen... alles andere führt eben zum nicht-zeichnen...


  • Mod

    SelectObject(hdcMemory, CreatePen(PS_NULL,1,NULL)); 
                SelectObject(hdcMemory, CreateSolidBrush(RGB(250,250,250)));
    

    Das erzeugt GDI-Leaks.
    Du erzeugst hier Pens/Brushes, die niemand entsorgt.
    Und die alten Pens/Brushes, die im Mem,DC drin waren werden auch nciht entfernt.

    Kein Wunder, dass am Ende der Bildschirm weiß bleibt.


Anmelden zum Antworten