1
votes

I'm trying to draw sine wave using win32 api. I done this.

hDC = GetDC(hWnd);

while (TRUE)
{
    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        DispatchMessage(&msg);
    }

    if (msg.message == WM_QUIT)
        break;

    wavefunc(hWnd, hDC);
}

void wavefunc(HWND hWnd, HDC hDC)
{
    double full = 2 * pi * _freq;
    static double _x = 0;
    short int _y = 0;

    short _y = (short)(sin(_x / _freq)*_amp) + 300;
    if (_x >= full)
        _x -= full;
    SetPixel(hDC, 600, _y, blue);
    ScrollWindow(hWnd, -1, 0, NULL, NULL);
    Sleep(_sTime);
    _x++;
}

Now i'm trying to figure out how to draw cartesian system. But with no result.

I have a window which is scrolled at each sin value.

I try to draw to lines on hdc. When window is scrolled there is no way to stop hdc to not scroll.

Then i create another hDc from windows but no succes. How to do this? The problem is to have window scrolling but with some point fixes..

2
Windows performs all the translations for you, assuming that your viewport is properly set up (see SetViewportExtEx and SetViewportOrgEx). This is explained in great detail at Transformation of Coordinate Spaces. - IInspectable
i don't think this is what i want...i want only to draw two fixed lines... - user5692672
That's the easy part: MoveToEx and LineTo. If you want to make your life harder than it needs to be, calculate the mapping from world coordinates to device coordinates yourself. Or have the system do it for you (as mentioned in my previous comment). - IInspectable
I already add this lines: SelectObject(hDC, hBluePen); MoveToEx(hDC, 0, 0, NULL); static int x = 250; static int y = 250; LineTo(hDC, x, y); x++; y++;. ...and the problem is that after scrolling windows the anterior lines remain... - user5692672
This is the nefast effect...sinewave - user5692672

2 Answers

2
votes

The way to do this is to paint everything all at once: clear the window, draw the grid, and then draw the entire waveform (not just the next point) over the grid. To make the waveform scroll, you keep redrawing with a different offset for the waveform.

To avoid flicker, you will likely need to do some double-buffering.

Typical WinAPI programs paint the window when handling the WM_PAINT command. The WM_PAINT message is generated when any or all of the window is invalid and needs to be repainted. Each time you scroll the window, you're creating an invalid region, but since you're ignoring the WM_PAINT message, nothing happens.

2
votes

Here is how I would animate the sin() function:

Create a bitmap (the size of your window) and draw your static parts on it (axis, title, labels, etc.).

Create another bitmap (the height of your sin() and the width of your window + the width of the sin()’s period at your scale), and draw sin() on it.

In the wavefunc(), get the precise time and calculate the offset for your sin bitmap.

Use BitBlt() function to first blit the static part onto your window’s DC, then use TransparentBlt() to paint the sin, starting at pre-calculated offset.