sábado, 28 de mayo de 2011

Ejemplo de grafica lineal en c

0

El siguiente código es un ejemplo de como crear una gráfica lineal como la del administrador de tareas de windows (taskmgr.exe). Para cambiar el tipo de gráfica haz clik sobre ella con el botón izquierdo del ratón.

#include <windows.h>
#include <math.h>

#define WIDTH 400
#define HEIGHT 125

HWND win = NULL;
DWORD timer = 0;
HDC specdc = 0, hdc = 0;
HBITMAP bmp = 0;
BYTE *pixels;
HPEN hPen;
unsigned int mode = 0, time = 0, pos = 0, v0, v1 = HEIGHT, grid = 0, a, b;

int sine_rand()
{
    static unsigned int values[10] = {0}, avg = 0;;
    int rn = (rand()%HEIGHT/2+sin(++time/31.416)*HEIGHT/2+HEIGHT/4);
    int index = time % 10;
    if (rn >= HEIGHT) rn = HEIGHT-1;
    else if (rn < 0) rn = 0;
    avg += rn - values[index];
    values[index] = rn;
    return avg / 10;
}

void CALLBACK Update(UINT id, UINT m, DWORD u , DWORD v, DWORD w)
{
    v0 = HEIGHT - 1 - sine_rand();

    if (mode == 0)
    {
        for (a = pos+1; a < HEIGHT * WIDTH; a += WIDTH)
            pixels[a] = 0, pixels[a+1] = 1;

        MoveToEx(specdc, pos, v1, NULL);
        LineTo(specdc, ++pos, v0);

        pos %= WIDTH;
    }
    else if (mode == 1)
    {
        BitBlt(specdc, 1, 0, WIDTH - 1, HEIGHT, specdc, 0, 0, SRCCOPY);
        for (a = 0; a < HEIGHT * WIDTH; a += WIDTH)
            pixels[a] = 0;

        MoveToEx(specdc, 1, v1, NULL);
        LineTo(specdc, 0, v0);
    }
    else //if (mode == 2)  windows taskmgr style
    {
        for (a = 0; a < HEIGHT * WIDTH; a += WIDTH)
        {
            memcpy(pixels + a, pixels + a + 1, WIDTH - 1);
            pixels[a + WIDTH - 1] = 0;
        }

        b = (grid++ % 11) ? 12*WIDTH : WIDTH;
        for (a = 0; a < HEIGHT * WIDTH; a += b)
            pixels[a+WIDTH-1] = 2;

        MoveToEx(specdc, WIDTH - 2, v1, NULL);
        LineTo(specdc, WIDTH - 1, v0);
    }
    v1 = v0;
    BitBlt(hdc, 0, 0, WIDTH, HEIGHT, specdc, 0, 0, SRCCOPY);
}

long FAR PASCAL WProc(HWND h, UINT m, WPARAM w, LPARAM l)
{
    switch (m)
    {
    case WM_PAINT:
    {
        RECT r;
        if (!GetUpdateRect(h, &r, 0)) return 0;
        PAINTSTRUCT p;
        HDC dc = BeginPaint(h, &p);
        if (!dc) return 0;
        BitBlt(dc, r.left, r.top, r.right-r.left, r.bottom-r.top,
               specdc, r.left, r.top, SRCCOPY);
        EndPaint(h, &p);
        return 0;
    }
    case WM_LBUTTONUP:
        mode = (mode + 1) % 3;
        memset(pixels, 0, WIDTH*HEIGHT);
        return 0;

    case WM_CREATE:
        win = h;
        hdc = GetDC(win);

        BYTE data[sizeof(BITMAPINFOHEADER) + 4*sizeof(RGBQUAD)] = {0};
        BITMAPINFO* bh = (BITMAPINFO*)data;
        RGBQUAD* pal = (RGBQUAD*)(data + sizeof(*bh));
        *bh = (BITMAPINFO){sizeof(*bh), WIDTH, HEIGHT, 1, 8, BI_RGB, 0,0,0,4,4};

        pal[0] = (RGBQUAD){0,0,0,0};
        pal[1] = (RGBQUAD){255,255,255,0};
        pal[2] = (RGBQUAD){0,100,0,0};
        pal[3] = (RGBQUAD){0,255,0,0};

        bmp = CreateDIBSection(0, bh, DIB_RGB_COLORS, (void**)&pixels, NULL, 0);
        specdc = CreateCompatibleDC(0);
        SelectObject(specdc, bmp);

        hPen = CreatePen(PS_SOLID, 1, RGB(0,255,0));
        SelectObject(specdc, hPen);

        timer = timeSetEvent(50, 20, (LPTIMECALLBACK)&Update, 0, TIME_PERIODIC);
        break;

    case WM_DESTROY:
        ReleaseDC(win, hdc);
        if (timer) timeKillEvent(timer);
        if (specdc) DeleteDC(specdc);
        if (bmp) DeleteObject(bmp);
        if (hPen) DeleteObject(hPen);
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(h, m, w, l);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev,LPSTR lpCmd, int nCmdShow)
{
    WNDCLASS wc = {0, WProc, 0, 0, hInst, 0, 0, 0, 0, "Spectrum"};

    if (!RegisterClass(&wc) || !CreateWindow("Spectrum","Ejemplo - DavidXL",
            WS_POPUPWINDOW | WS_CAPTION | WS_VISIBLE, 300, 200,
            WIDTH + 2 * GetSystemMetrics(SM_CXDLGFRAME), HEIGHT +
            GetSystemMetrics(SM_CYCAPTION) + 2*GetSystemMetrics(SM_CYDLGFRAME),
            NULL, NULL, hInst, NULL))
    {
        return 0; //Error
    }

    ShowWindow(win, SW_SHOWNORMAL);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

Comparte o puntua esta publicación ▼

jueves, 26 de mayo de 2011

Capturar pantalla en c

1

Ayer busque como hacer capturas de pantalla en C y guardarlas después en un archivo bmp, pero todos los snippets que encontré me hacían únicamente un "Screenshot" de la pantalla principal, esto quiere decir que si usamos mas de un monitor no serviría. He escrito este código que captura el área del escritorio virtual (todas las pantallas), generando una imagen como la de la tecla ImprimirPantalla o PrintScreen.

No creo que ha falta decirlo pero por si acaso, para elegir donde guardar el archivo bmp se modifica en la linea 24..
#include <windows.h>

int main()
{
    int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    int top = GetSystemMetrics(SM_YVIRTUALSCREEN);
    int left = GetSystemMetrics(SM_XVIRTUALSCREEN);
    int size = width * height * 3;
    int headerSize = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);

    BITMAPFILEHEADER bmFile = {0x4D42, headerSize + size, 0, 0, headerSize};
    BITMAPINFO bmInfo = {{sizeof(BITMAPINFOHEADER), width, height, 1, 24, BI_RGB, 
                        size, 0, 0, 0, 0}};
    LPBYTE pixels;

    HDC hdc = CreateCompatibleDC(0);
    HBITMAP hBMP = CreateDIBSection(hdc, &bmInfo, DIB_RGB_COLORS, (LPVOID*)&pixels, 
                   0, 0);
    SelectObject(hdc, hBMP);
    BitBlt(hdc, 0, 0, width, height, GetDC(0), left, top, SRCCOPY);
    DeleteDC(hdc);

    HANDLE hFile = CreateFile("c:\\Screenshot.bmp", FILE_WRITE_DATA, 0, 0, 
                   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
    if (hFile != INVALID_HANDLE_VALUE)
    {
        DWORD dwOut;
        WriteFile(hFile,&bmFile, sizeof(BITMAPFILEHEADER), &dwOut, NULL);
        WriteFile(hFile,&bmInfo, sizeof(BITMAPINFOHEADER), &dwOut, NULL);
        WriteFile(hFile, pixels, size, &dwOut, NULL);
        CloseHandle(hFile);
    }

    DeleteObject(hBMP);

    return 0;
}

Comparte o puntua esta publicación ▼