Zoomen in WinApi



  • Hi, ich hab volgendes problem bei einem Projet:

    ich muss ein Fraktal mit C WinApi Programmieren und dann noch paar funktionen einbauen: z.B. Zoomen mit der Linken Maustaste und mit Rechten Maustaste in anfangszustand gelanden.

    Ich hab den Fraktal gezeichnet leider weiß ich nicht wie ich eine funktion schreiben kann um es zu Zoomen.

    könnte mir jemand dabei helfen oder einfach tipps oder links schiken.

    danke an alle

    mgf Mucha 🙂



  • da gibt es unzählige möglichkeiten. aber ohne einen ansatz wie du das fraktal
    denn tatsächlich zeichnest, ob du es in mehreren threads realisierst oder
    was sonst noch, ist es schwer zu helfen 🙂 am besten schnipsel posten, dann
    kann man auch einen konkreteren lösungsansatz bieten 🙂



  • LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    RECT rect;
    PAINTSTRUCT ps;
    POINT pos;

    switch (message) /* handle the messages /
    {
    case WM_DESTROY:
    PostQuitMessage (0); /
    send a WM_QUIT to the message queue /
    break;
    case WM_PAINT:
    GetClientRect(hwnd, &rect);
    BeginPaint(hwnd, &ps);
    draw(hwnd, rect);
    EndPaint(hwnd, &ps);
    break;
    case WM_LBUTTONUP:
    GetCursorPos(&pos); // Hier weiß ich nicht wie ich den Zoom
    // und die Maus-Position an WM_Paint übergebe
    break;
    default: /
    for messages that we don't deal with */
    return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
    }



  • void draw(HWND hwnd, RECT rect)
    {
    HDC hdc = GetDC(hwnd);
    int x,y,j,iterationen;
    double x0,y0;
    COLORREF col[256];

    for(j = 0; j < 256; j++)
    {
    col[j] = RGB(j+60,(int)(j*0.2)+32,(int)(j*0.8)+20);
    }
    col[255] = RGB(0,0,0);

    for(y = 1; y < rect.bottom; y++)
    {
    for(x = 1; x < rect.right; x++)
    {
    x0 = ((double) (x3) / (double) (rect.right-rect.left)) - 2;
    y0 = ((double) (y
    2) / (double) (rect.bottom-rect.top)) - 1;

    iterationen = fract(x0,y0);
    SetPixel(hdc, x, y, col[iterationen]);
    }
    }
    ReleaseDC(hwnd, hdc);
    }



  • int fract(double x0, double y0)
    {
    double x,y,z,tmpx;
    int j = 0;

    x = x0;
    y = y0;

    while((x*x + y*y) < 4 && j < 255)
    {
    tmpx = ((x*x)-(y*y))+x0;
    y = (2*x*y)+y0;
    x = tmpx;
    j++;
    }

    return j;
    }



  • zomg, schipsel, nicht den ganzen quellcode XD. nunja, wie dem auch sei
    (es gibt übrigens code tags, die das lesen erleichtern :P) die einfachste,
    wenn auch nicht eleganteste lösung ist einen timer zu initialsieren mit:

    SetTimer(hwnd, 1, 250, zoom);
    

    250 wäre in dem fall der timeout in millisekunden. windows sendet jetzt
    alle 250 ms eine WM_TIMER message an dein programm. wie gehabt in der
    WndProc handeln:

    case WM_TIMER:
    {
    	if (wParam == 1)
    	{
    		if (bZoom)
    		{
    			// globale variablen ändern
    			// die das zeichenverhalten beeinflussen
    			SendMessage(hwnd, WM_PAINT, 0, 0); // müsste glaube ich funktionieren :P
    		}
    	}
    	return 0;
    }
    

    bZoom als bool oder integer oder was auch immer global deklarieren und bei
    linksklick umschalten:

    case WM_LBUTTONUP:
    	bZoom ^= bZoom;
    

    soweit sogut. nun musst du noch deinen code so anpassen, damit ein oder
    mehrere globale variablen das zeichnen des fraktals entsprechend beinflussen.
    tip: mauskoordinaten ebenfalls in globalen variablen speichern 🙂
    ich hoffe dass hilft weiter 🙂

    edit: oh, ich vergaß, das ist jetzt natürlich schon nahe einer animation 😛
    wenn du ein einmaligen zoom um einen bestimmten faktor haben wills, wie es wohl
    bei fraktal zeichen tools üblich ist, dann modifiziere einfach die ominösen
    globalen variablen nach dem du LBUTTONUP bekommen hast, und zeichne das fenster dann neu.



  • wir dürfen in Projekt keine globale variablen benutzen.



  • 😮 was hat das denn für einen sinn?

    dann sende dieses zeugs als parameter in der WM_PAINT message mit

    SendMessage(hwnd, WM_PAINT, lparam, wparam)
    


  • sothis_ schrieb:

    😮 was hat das denn für einen sinn?

    dann sende dieses zeugs als parameter in der WM_PAINT message mit

    SendMessage(hwnd, WM_PAINT, lparam, wparam)
    

    Kannst ja mit ne Suchmaschine fütttern, das macht Sinn! Stichwort Übersichtlichkeit. WM_PAINT explizit zu Senden, ist mitunter eine Totsünde. Außerdem sind WPARAM und LPARAM bereits vorbelegt.

    Warum verwendest Du nicht einfach statische lokale Variablen?

    Hm, was willst Du damit bezwecken? :

    bZoom ^= bZoom;
    

    Da reicht doch:

    bZoom = !bZoom;
    

    😕



  • CodeFinder schrieb:

    sothis_ schrieb:

    😮 was hat das denn für einen sinn?

    dann sende dieses zeugs als parameter in der WM_PAINT message mit

    SendMessage(hwnd, WM_PAINT, lparam, wparam)
    

    Kannst ja mit ne Suchmaschine fütttern, das macht Sinn! Stichwort Übersichtlichkeit. WM_PAINT explizit zu Senden, ist mitunter eine Totsünde. Außerdem sind WPARAM und LPARAM bereits vorbelegt.

    übersichtlichkeit ist geschmackssache 🙂
    mir konnte bisher noch keiner überzeugend plausibel machen warum
    ich auf globale variablen verzichten sollte, somit sie mitunter
    auch machmal unerlässlich sind. wenn ich damit persönlich scheller
    und effizienter mein ziel erreiche, dann benutze ich sie 🙂
    zu WM_PAINT: kann sein, weiß ich nicht :D, war nur ein schneller
    gedanke der mir im kopf rumschwirrte 😛

    CodeFinder schrieb:

    Hm, was willst Du damit bezwecken? :

    bZoom ^= bZoom;
    

    Da reicht doch:

    bZoom = !bZoom;
    

    😕

    auch das ist geschmackssache. erfüllt den selben zweck 🙂

    edit: doh! natürlich nicht 😛

    bZoom ^= 1;
    

    wäre korrekt 😃


Anmelden zum Antworten