UpdateWindow Fehler



  • Guten Abend allerseits.
    Ich probiere hier gerade meinen eigenen Funktionsplotter zu schreiben (steckt noch in den Kinderschuhen) und ich stoße da auf folgendes Problem:

    case WM_COMMAND:
    		{
    			switch (wParam)
    			{
    			case 1:
    				DestroyWindow (hWnd);
    				break;
    			case 2:
    				plot = true;
    				UpdateWindow (hWnd);
    				break;
    			}
    		}
    

    Wenn plot auf true gesetzt wird soll in WM_PAINT der Graph gezeichnet werden (plot steht von Beginn an auf false). Wenn ich dann den Plot-Button (ID 2) gedrückt habe, müsste sich ja eigentlich das Fenster aktualisieren und der Graph gezeichnet werden, tut er aber nicht 😞 Hat jemand vielleicht eine Idee?

    Mit freundlichen Grüßen
    Robert



  • Wo genau liegt denn das Problem? Funktioniert das Zeichnen nicht, oder wird kein WM_PAINT gesendet?



  • WM_PAINT funktioniert; ich lasse ja nebenbei gleich das Koordinatensystem ausgeben, aber der Graph wird nach drücken des Button nicht gezeichnet -.-



  • D.h. dein Zeichencode wird aufgerufen, aber aus irgendeinem Grund zeichnet er nicht!? Ich fürchte, ohne den relevanten Code zu sehen, wird dir hier niemand wirklich mehr sagen können außer: Der Debugger wird dir helfen, den Grund zu finden...



  • Der Debugger sagt garnichts^^

    Aber hier mal der ganze Code, noch ein bisschen viel drin aber zum Anfang:

    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include "functions.h"
    
    //**********************************************************************
    //*								Variables							   *
    //**********************************************************************
    int width = 500;	// width of the main window
    int height = 500;	// height of the main window
    
    float xMax = 1;		// the maximum x value to show
    float yMax = 1;		// the maximum y value to show
    
    // scale the axes
    float xSc = 5*(width/(2*xMax))/3;		// scale for the x axis
    float ySc = 5*(height/(2*yMax))/3;		// scale for the y axis
    
    const char g_szClassName [] = "myWindowClass";		// the title of the main class	
    const char szTitle [] = "";							// the title of the main window (is not relevant, for it is not displayed)
    
    static HPEN RedPen, BluePen, GreenPen, YellowPen;	// define the pens
    
    HWND hButton1, hButton2, hEdit1, hEdit2, hEdit3, hEdit4;	// define the buttons, edits and so on and so forth
    HINSTANCE hInstButton;
    
    int PosX = GetSystemMetrics(0)/2 + width/4;			// the position of the window
    int PosY = GetSystemMetrics(1)/2 - 3*height/4;		// the position of the window
    
    bool plot = false;									// plot?
    
    // Step 4: the Window Procedure
    //*************************************************************************
    //*                             LRESULT CALLBACK!*						  *
    //*************************************************************************
    LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	HDC hDC;
    	PAINTSTRUCT ps;
    
        switch(msg)
    	{
    	case WM_CREATE:
    		{
    			hButton1 = CreateWindowEx (0, "BUTTON", "Beenden", WS_VISIBLE|WS_CHILD, 
    										width - 100, height - 50,100,50, hWnd, (HMENU) 1, hInstButton, NULL);
    			hButton2 = CreateWindowEx (0, "BUTTON", "PLOT", WS_VISIBLE|WS_CHILD, 
    										width - 100, 0,100,50, hWnd, (HMENU) 2, hInstButton, NULL);
    			hEdit1 = CreateWindowEx (WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD|WS_VISIBLE, 75, 10, 50, 25, hWnd, (HMENU) 3, GetModuleHandle (NULL), NULL);
    			hEdit2 = CreateWindowEx (WS_EX_CLIENTEDGE, "EDIT", "", WS_CHILD|WS_VISIBLE, 75, 40, 50, 25, hWnd, (HMENU) 4, GetModuleHandle (NULL), NULL);
    
    		} 
    
    	case WM_COMMAND:
    		{
    			switch (wParam)
    			{
    			case 1:
    				DestroyWindow (hWnd);
    				break;
    			case 2:
    				plot = true;
    				UpdateWindow (hWnd);
    				break;
    			}
    		}
    
    	case WM_PAINT:
    
    			hDC = BeginPaint (hWnd, &ps);
    			SetMapMode (hDC, MM_LOMETRIC);
    			SetViewportOrgEx (hDC, width/2, height/2, NULL);
    
    			RedPen = CreatePen (PS_SOLID, 2, RGB (255, 0,0));
    			BluePen = CreatePen (PS_SOLID, 2, RGB (0, 0,255));
    			GreenPen = CreatePen (PS_SOLID, 2, RGB (0, 255,0));	
    			YellowPen = CreatePen (PS_SOLID, 2, RGB (255, 255,0));
    
    			// Axis units 
    			//TextOut (hDC, 0,0,"0", 1);
    
    			// Draw the coordinate system!
    			for(int i = -2*width; i < 2*width; i++) 
    			{
    				SetPixel( hDC,i,0, RGB(0,0,0) );
    			}
    			for(int i=-2*ySc; i<=3*ySc*0.5; i++) 
    			{
    				SetPixel( hDC,0,i, RGB(0,0,0) );
    			}
    
    			if (plot) {
    			// Draw the Graph of function(x)
    			if (f1) {
    			for (float i = -width/2; i <= width/2;)
    			{
    				SelectObject (hDC, RedPen);
    
    				MoveToEx (hDC, (xSc*i), (ySc*function(i)), NULL);
    				LineTo (hDC,(xSc*(i+0.1)),(ySc * function(i+0.1)));
    				i = i + 0.01;
    
    			}
    			}
    
    			// Draw the Graph of function2(x)
    			if (f2) {
    			for (float i = -width/2; i <= width/2;)
    			{
    				SelectObject (hDC, BluePen);
    
    				MoveToEx (hDC, (xSc*i), (ySc*function2(i)), NULL);
    				LineTo (hDC,(xSc*(i+0.1)),(ySc * function2(i+0.1)));
    				i = i + 0.1;
    			}
    			}
    
    			// Draw the graph of function 3
    			if (f3) {
    			for (float i = -width/2; i <= width/2;)
    			{
    				SelectObject (hDC, GreenPen);
    
    				MoveToEx (hDC, (xSc*i), (ySc*function3(i)), NULL);
    				LineTo (hDC,(xSc*(i+0.1)),(ySc * function3(i+0.1)));
    				i = i + 0.1;
    			}
    			}
    
    			// Draw the graph of a parametric function
    			if (parametric) {
    			for (float i = -width/2; i <= width/2;)
    			{
    				SelectObject (hDC, YellowPen);
    
    				MoveToEx (hDC, (xSc*function2(i)), (ySc*function3(i)), NULL);
    				LineTo (hDC,(xSc*(function2(i+0.1))),(ySc * function3(i+0.1)));
    				i = i + 0.1;
    			}
    			}}
    			EndPaint (hWnd, &ps);
    
    			break;
    
    	case WM_CLOSE:
                DestroyWindow(hWnd);
            break;
        case WM_DESTROY:
                PostQuitMessage(0);
            break;
    
        default:
                return DefWindowProc(hWnd, msg, wParam, lParam);
        }
        return 0;
    }
    
    //*************************************************************************
    //*                             WINAPI WinMain							  *
    //*************************************************************************
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
        LPSTR lpCmdLine, int nCmdShow)
    {
        WNDCLASSEX wc;
        HWND hwnd;
        MSG Msg;
    
        //Step 1: Registering the Window Class
        wc.cbSize        = sizeof(WNDCLASSEX);
        wc.style         = 0;
        wc.lpfnWndProc   = WndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = hInstance;
        wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
        wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
        wc.lpszMenuName  = NULL;
        wc.lpszClassName = g_szClassName;
        wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
    
        if(!RegisterClassEx(&wc))
        {
            MessageBox(NULL, "Window Registration Failed!", "Error!",
                MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
    
        // Step 2: Creating the Window
        hwnd = CreateWindowEx(
            WS_EX_CLIENTEDGE,
            g_szClassName,
            szTitle,
            /*WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU*/ WS_POPUP,
            PosX, PosY, width, height,
            NULL, NULL, hInstance, NULL);
    
        if(hwnd == NULL)
        {
            MessageBox(NULL, "Window Creation Failed!", "Error!",
                MB_ICONEXCLAMATION | MB_OK);
            return 0;
        }
    
        ShowWindow(hwnd, nCmdShow);
        UpdateWindow(hwnd);
    
        // Step 3: The Message Loop
        while(GetMessage(&Msg, NULL, 0, 0) > 0)
        {
            TranslateMessage(&Msg);
            DispatchMessage(&Msg);
        }
        return Msg.wParam;
    }
    

    und hier die function.h

    #include <Windows.h>
    
    const float e = 2.71828;
    const float pi = 3.14159;
    
    bool f1 = false;
    bool f2 = false;
    bool f3 = false;
    bool parametric = true;
    
    float function (float var)
    {
    	return (var);
    }
    
    float function2 (float var)
    {
    	// return (pow (e,var/2*pi)*sin (var)); 
    	return sin (var);
    }
    
    float function3 (float var)
    {
    	// return (pow (e,var/2*pi)*cos (var));
    	return cos (var);
    }
    


  • Der Debugger sagt Dir alles, man muss ihn nur bedienen können.



  • -lowbyte- schrieb:

    Der Debugger sagt Dir alles, man muss ihn nur bedienen können.

    Kannst du es denn bitte mal nachcompilieren?
    Was sagt er Dir denn?


  • Mod

    Das blose Ansehen Deines Codes sagt mir, dass Du GDI Leaks ohne Ende ereugst.
    Du erzeugst Objekte, die nicht entsorgt werden.
    Du selektierst Objekte, die nicht wieder aus dem Kontext entfernst...

    Evtl. Sorgen die Leaks schon dafür, dassnichts gezeichnet wird.
    Außerdem. Woher weißt Du dass UpdateWindow nicht funktioniert?



  • ich würde bei case WM_CREATE: und case WM_COMMAND: mal noch einen break einbauen, und vielleicht hilft ja auch ein InvalidateRect vor dem UpdateWindow



  • Martin Richter schrieb:

    Du erzeugst Objekte, die nicht entsorgt werden.
    Du selektierst Objekte, die nicht wieder aus dem Kontext entfernst...

    Können Sie mir denn erklären wir man dies tut?



  • DeleteObject()

    Und dann solltest Du mal schauen was die Funktionen so zurückgeben...



  • -lowbyte- schrieb:

    DeleteObject()

    Und dann solltest Du mal schauen was die Funktionen so zurückgeben...

    Und wo baue ich das am klügsten ein, denn damit lösche ich dann doch die Objkete tatsächlich?!



  • Also ehrlich gesagt habe ich keine Lust Dir jetzt den richtigen Aufbau von GUI's zu erklären. Vielleicht hat Martin ja mehr Zeit und Lust.



  • Dan wenigstens wo ich Nachlesen kann?



  • Ich hab das früher zu meinen winapi-Zeiten immer so aufgebaut:

    // (1) Objekt erstellen:
    ///////////////////////////////////////////////////////////
    HPEN aPen=CreatePen (PS_SOLID, 2, RGB (255, 0,0));
    
    // (2) Objekt verwenden:
    ///////////////////////////////////////////////////////////
    
        // (a) Pen selektieren:
        HGDIOBJ oldPen=SelectObject(hdc,aPen);
    
        // (b) Mit aPen rumzeichnen...
    
        // (c) Pen wieder de-selektieren, indem man das vorherige Objekt wieder hinein-selektiert (Rückgabewert wäre nun aPen)
        SelectObject(hdc,oldPen);
    
    // (3) Objekt löschen:
    ///////////////////////////////////////////////////////////
    DeleteObject(aPen);
    


  • Robert96 schrieb:

    Dan wenigstens wo ich Nachlesen kann?

    Z.B. hier http://msdn.microsoft.com/en-us/library/dd162759.aspx


  • Mod

    RTFM (Read the fine MSDN)
    Zu (fast) jedem Create... gehört ein Destroy.../Delete...
    Hier CreatePen -> DeleteObject.

    Wenn man in einen DC ein Objekt selektiert (SelectObject), dann sollte man das alte Objekt merken und vor Ende der Nutzung des DCs wieder selektieren

    HGDIOBJ hOld = SelectObject(...));
    ...
    SelectObject(hOld);
    

Anmelden zum Antworten