#include <windows.h>
LRESULT CALLBACK ProceduraOkna (HWND, UINT, UINT, LONG); // deklaracja zapowiadająca

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, 
                    LPSTR lpszCmdParam, int nCmdShow)		   
{
    const char nazwa_klasy_okien[] = "MojeOkno";

    WNDCLASSEX  wndclass = {0};
    wndclass.cbSize       	= sizeof(WNDCLASSEX);
    wndclass.style        	= CS_HREDRAW | CS_VREDRAW;  
    wndclass.lpfnWndProc  	= ProceduraOkna; 
    wndclass.hInstance    	= hInstance;                
    wndclass.hCursor      	= LoadCursor (NULL, IDC_ARROW);	
    wndclass.hIcon        	= LoadIcon   (NULL, IDI_APPLICATION); 
    wndclass.hbrBackground	= (HBRUSH) GetStockObject (WHITE_BRUSH);
    wndclass.lpszClassName	= nazwa_klasy_okien;
    wndclass.hIconSm      	= LoadIcon   (NULL, IDI_APPLICATION);
    
    RegisterClassEx (&wndclass);	
    HWND hwnd = CreateWindowEx ( 0,
        nazwa_klasy_okien,
 		"Kolory",	
        WS_OVERLAPPEDWINDOW,			
        CW_USEDEFAULT, CW_USEDEFAULT, 
        CW_USEDEFAULT, CW_USEDEFAULT,
        0,
        0,
        hInstance,
        0
    );
    if (hwnd == 0)
        return -1;

    ShowWindow (hwnd, nCmdShow);			
    
    /* Typowa pętla komunikatów: */
    int result;
    MSG msg;
    while ((result = GetMessage (&msg, NULL, 0, 0) ) != 0)
    {
        if (result == -1) return -1;
        TranslateMessage (&msg);
        DispatchMessage (&msg);            
    }	                                   
    return msg.wParam;
}

/***   PROCEDURA OKNA   ***/

LRESULT CALLBACK ProceduraOkna (HWND hwnd, UINT message,
                                UINT wParam, LONG lParam)
{
  switch(message)
  {
    case WM_PAINT:
    {
      PAINTSTRUCT ps;
      HDC hdc = BeginPaint (hwnd, &ps);
      
      //Rysujemy obwódkę:
      Rectangle(hdc, 0, 0, 258, 258);

      // Jakie są rozmiary obszaru roboczego okna?
      RECT rect;
      GetClientRect (hwnd, &rect);
      
      // Rysujemy linię 0d (258, 258) do prawego dolnego narożnika okna
      MoveToEx(hdc, 258, 258, 0);
      LineTo(hdc, rect.right, rect.bottom);

      // pobieramy różne informacje o urządzeniu hdc
      int technologia = GetDeviceCaps (hdc, TECHNOLOGY); // 0..6
      int r_x = GetDeviceCaps (hdc, HORZRES);
      int r_y = GetDeviceCaps (hdc, VERTRES);
      int b_c = GetDeviceCaps (hdc, BITSPIXEL);

      const char* typ_urzadzenia [] = {"ploter", "monitor rastrowy",
          "drukarka rastrowa", "kamera rastrowa", "strumień znaków (PLP)",
          "meta-plik (VDM)", "display-file"};

      char bufor[512];
      wsprintf(bufor, "%s, %d na %d pikseli (kolor: %d bitowy)",
          typ_urzadzenia[technologia], r_x, r_y, b_c);            // ryzykowne indeksowanie
          
      // ustalamy atrybut wyświetlania tekstu
      SetTextColor(hdc, RGB(255, 0,128 ));
      
      // wyświetlamy tekst
      TextOut (hdc, 5, rect.bottom-22, bufor, strlen(bufor));

      //wypełniamy prostokąt różnymi kolorami
      for (int x = 0; x < 256; x++)
      {
          for (int y = 0; y < 256; y++)
          {
              int niebieski =  abs((x+y)/2-255);
              SetPixel( hdc, 1+x, 1+y, RGB(x, y,niebieski) );
          }
      }

      // kolejny napis
      const char info[] =
            "spróbuj teraz zmienić tryb pracy karty graficznej!";
      SetTextAlign(hdc, TA_RIGHT);
      SetTextColor(hdc, RGB(255, 0, 0));
      TextOut (hdc, rect.right - 5, 5, info, strlen(info));

      // nieodzowna instrukcja kończąca przetwarzanie WM_PAINT
      EndPaint (hwnd, &ps);
      return 0;
    }
    case WM_DESTROY:
      PostQuitMessage (0);
      return 0;
  }
  return DefWindowProc (hwnd, message, wParam, lParam);
}
