Pen


Tip
Pens are used to draw the borders of an object. The default pen is black. The code show below paints a black line from the left top corner (0, 0) to the point (100, 150).
Las plumas son utilizadas para pintar el contorno de los objetos. La pluma por defecto es negra. El código mostrado debajo pinta una línea negra desde la esquina superior izquierda (0, 0) al punto (100, 150).

Program.cpp
void Hello::Window_Open(Win::Event& e)
{
}

void Program::Window_Paint(Win::Event& e)
{
     CG::Gdi gdi(hWnd, true, false);
     gdi.Line(0, 0, 100, 150);
}

Line

Problem 1
Create a Window Application called Target to draw the figure shown. The width and height of the window are stored in the variables: this->width and this->height respectively.
Cree una aplicación de ventana llamado Target para dibujar la figura mostrada. El ancho y alto de la ventana están almacenados en las variables: this->width y this->height respectivamente.

Target

Problem 1a
Repeat the previous problem using Win32.
Repita el problema previo usando Win32.

Target32.cpp
//_________________________________________________ Target32.cpp
#include "stdafx.h"
#include "Target32.h"

int width = 0;
int height = 0;

ATOM     MyRegisterClass(HINSTANCE hInstance);
BOOL     InitInstance(HINSTANCE, int);
LRESULT CALLBACK     WndProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
     _In_opt_ HINSTANCE hPrevInstance,
     _In_ LPTSTR lpCmdLine,
     _In_ int nCmdShow)
{
     MSG msg;
     MyRegisterClass(hInstance);
     if (!InitInstance(hInstance, nCmdShow)) return FALSE;
     while (GetMessage(&msg, NULL, 0, 0))
     {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
     }
     return (int)msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
     WNDCLASSEX wcex;

     wcex.cbSize = sizeof(WNDCLASSEX);

     wcex.style = CS_HREDRAW | CS_VREDRAW;
     wcex.lpfnWndProc = WndProc;
     wcex.cbClsExtra = 0;
     wcex.cbWndExtra = 0;
     wcex.hInstance = hInstance;
     wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TARGET32));
     wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
     wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
     wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TARGET32);
     wcex.lpszClassName = L"Target32";
     wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

     return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
     HWND hWnd = CreateWindow(L"Target32", L"Target32", WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

     if (!hWnd) return FALSE;

     ShowWindow(hWnd, nCmdShow);
     UpdateWindow(hWnd);
     return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     PAINTSTRUCT ps;
     HDC hdc;

     switch (message)
     {
     case WM_PAINT:
          hdc = BeginPaint(hWnd, &ps);
          //
          ::MoveToEx(hdc, 0, 0, NULL);
          ::LineTo(hdc, width, height);
          //
          ::MoveToEx(hdc, 0, height, NULL);
          ::LineTo(hdc, width, 0);
          //
          ::MoveToEx(hdc, width / 2, 0, NULL);
          ::LineTo(hdc, width / 2, height);
          //
          ::MoveToEx(hdc, 0, height / 2, NULL);
          ::LineTo(hdc, width, height / 2);
          //
          EndPaint(hWnd, &ps);
          break;
     case WM_SIZE:
          width = LOWORD(lParam);
          height = HIWORD(lParam);
          break;
     case WM_DESTROY:
          PostQuitMessage(0);
          break;
     default:
          return DefWindowProc(hWnd, message, wParam, lParam);
     }
     return 0;
}


Tip
If you use Class View in a Wintempla project, you will be able to understand the CG::Gdi class that encapsulates Win32 GDI library, see figure below.
Si usted usa la Vista de Clases en un proyecto de Wintempla, usted podrá entender la clase CG::Gdi que encapsula la librería GDI de Win32, vea la figura de abajo.

GdiLineTo

Problem 2
Create a program called Box to draw a 3D box as shown.
Cree un programa llamado Box para una dibujar una caja 3D como se muestra.

Box

Box.h
#pragma once //______________________________________ Box.h
#include "resource.h"

class Box: public Win::Window
{
public:
     Box()
     {
     }
     ~Box()
     {
     }
     void Square(CG::Gdi& gdi, int centerX, int centerY, int sideLength);
     ...
};

Box.cpp
void Box::Window_Open(Win::Event& e)
{
}

void Box::Window_Paint(Win::Event& e)
{
     CG::Gdi gdi(hWnd, true, false);

     Square(gdi, width/2, height/2, 200);
     Square(gdi, width/2+80, height/2-80, 200);
     ...
}

void Box::Square(CG::Gdi& gdi, int centerX, int centerY, int sideLength)
{
     ...
}



Tip
There are severals pen types: PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT, PS_NULL, and PS_INSIDEFRAME. In order to use a pen different to the default pen, first a pen has to be created, and then the pen must be selected. In code shown below, a solid blue pen with a width of three pixels is created. Then, the pen is selected and a line is draw.
Existen diversos tipos de plumas: PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT, PS_NULL, y PS_INSIDEFRAME. DASH quiere decir raya y DOT punto, así, PS_DASHDOTDOT es una línea de raya, punto, punto, raya, punto, punto, et. Para usar una pluma diferente a la de defecto, primero se crea la pluma y luego se selecciona. En el ejemplo mostrado debajo se crea una pluma solida de tres pixeles de ancho, y de color azul. Después de seleccionar la pluma azul y se dibuja una línea.

BlueLine

Program.cpp
void Program::Window_Open(Win::Event& e)
{
}

void Program::Window_Paint(Win::Event& e)
{
     CG::Gdi gdi(hWnd, true, false);
     CG::Pen pen(PS_SOLID, 3, RGB(0, 0, 255));
     gdi.Select(pen);
     gdi.Line(0, 0, width, height);
}


Tip
Be careful when pens are used to draw using printer because the printer have resolutions of at least 300 pixels per inches, the width of one pixel is extremely thin.
Tengo cuidado cuando cree plumas para dibujar usando una impresora. Las impresoras tienen una resolución de más de 300 pixeles por pulgadas, un pluma de un pixel es extremadamente delgada para ser visualizada fácilmente.

Rectangle

A rectangle in GDI is a structure defined as RECT. This structure has four variables describing the sides of rectangle: left, top, right and bottom. The code shows below draws a rectangle the left
Un rectángulo en GDI es una estructura como RECT. Esta estructura tiene cuatro variables que describen los lados del rectángulo: izquierda, arriba, derecha y abajo.

Rectangle

Program.cpp
void Program::Window_Open(Win::Event& e)
{
}

void Program::Window_Paint(Win::Event& e)
{
     CG::Gdi gdi(hWnd, true, false);
     RECT rect;
     rect.left = 100;
     rect.right = 200;
     rect.top = 120;
     rect.bottom = 220;
     gdi.Rectangle(rect);
}

Tip
The code below shows some of the functions to manipulate rectangles.
El código de abajo muestra algunas de las funciones para manipular rectángulos.

Program.h
//Moves the rectangle a number of logical units)
::OffsetRect(rect, x, y);

//Increase or decrease the size of the rectangle
::InflateRect(rect, x, y);

::SetRectEmpty(rect);
::IsRectEmpty(rect);
::IntersectRect(rectDest, rect1, rect2);
::UnionRect(rectDest, rect1, rect2);

// Determines whether a point is in a rectangle
POINT pt;
RECT rect;
pt.x = 10;
pt.y = 20;
::PtInRect(&rect, pt);

// Copies the coordinates of one rectangle to another
::CopyRect

// Determines whether the two specified rectangles are equal
::EqualRect

//Determines the coordinates of a rectangle formed by subtracting one rectangle from another.
::SubtractRect


IntersectRect

It calculates the intersection of two rectangles. If the rectangles intersect, the return value is nonzero. If the rectangles do not intersect, the return value is zero. See example.
Esta calcula la intersección entre dos rectángulos. Si los rectángulos se intersectan, la función regresa un valor diferente de cero. Si los rectángulos no se intersectan, la función regresa cero. Vea el ejemplo.

Program.h
bool Program::DoTheyIntersect(const RECT& rect1, const RECT& rect2)
{
     RECT destination;
     if (::IntersectRect(&destination, &rect1, &rect2) == 0) return false;
     //if (::IntersectRect(NULL, &rect1, &rect2) == 0) return false;
     return true;
}


Problem 3
Create a Window Application called Room to display the figure shown below. The lines must be spaced 100 pixels from the window borders.
Cree un programa llamado Room para dibujar la figura mostrada debajo. Las líneas debe estar separadas 100 pixeles de los bordes de la ventana.

Room1

Room2

Problem 4
Create a program called Inflate using a Window application to draw a rectangle. The user may increase or decrease the size of the rectangle using the keys Up and Down from the keyboard. Use the events: WM_PAINT (Window_Paint) and WM_KEYDOWN (Window_Keydown). Create a RECT member variable y use la función ::InflateRect. You may use the function MyWindow.Repaint(RECT* rc, bool erase) to force Microsoft Window to call Window_Paint. The first parameter of this function may be NULL to repaint the whole window. The second parameter can be true to erase the previous window content.
Cree un programa llamado Inflate usando una aplicación de ventana para dibujar un rectángulo. El usuario puede incrementar o decrementar el tamaño del rectángulo usando las teclas de dirección Arriba y Abajo del teclado. Use los eventos: WM_PAINT (Window_Paint) y WM_KEYDOWN (Window_Keydown). Cree una variable miembro RECT y use la función ::InflateRect. Usted puede usar la función MyWindow.Repaint(RECT* rc, bool erase) para forzar a Microsoft Windows a llamar Window_Paint. El primer parámetro de esta función puede ser NULL para repintar la ventana completa. El segundo parámetro puede ser true para borrar el contenido previo de la ventana.

InflateEvents

Inflate

Inflate2

Inflate.cpp
...

void Inflate::Window_KeyDown(Win::Event& e)
{
     switch (e.wParam)
     {
     case VK_UP:
          ...
     case VK_DOWN:
          ...
     }
}

void Inflate::Window_Paint(Win::Event& e)
{
     CG::Gdi gdi(hWnd, true, false);
     RECT intersection;
     ::IntersectRect(&intersection, &rect, &gdi.GetRcPaint());
     if (::IsRectEmpty(&intersection) == TRUE) return; // Nothing to paint
     gdi.Rectangle(rect);
}


Problem 5
Create a Window Application called EyeSpider to display the figure shown below when the window is squared. Use a total of 100 lines (50 + 50).
Cree un aplicación de ventana llamada EyeSpider para dibujar la figura mostrada debajo cuando la ventana es cuadrada. Use un número total de 100 líneas (50 + 50).

EyeSpider1

EyeSpider2

EyeSpider3

Tip
The message WM_PAINT or Window_Paint event are called by the operating system when the window requires painting. In some cases, it is necessary to paint something different in the window, and to ask the operating system to call the Window_Paint function the commands this->Repaint or ::InvalidateRect must be called. Repaint takes two parameters: rcPaint and erase. To repaint the whole window rcPaint can be NULL, to erase the window use erase = true. If rcPaint is not NULL, the area described by rcPaint will be repainted.
El mensaje WM_PAINT o el evento Window_Paint son llamados por el sistema operativo cuando la ventana requiere ser pintada. En algunos casos, es necesario pintar algo diferente en la ventana, y para pedirle al sistema operativo que llame la función Window_Paint se pueden usar los comandos: this->Repaint o ::InvalidateRect. Repaint toma dos parametros: rcPaint y erase. Para repintar toda la ventana rcPaint debe ser NULL, para borrar la ventana use erase = true. Si rcPaint no es NULL, el área descrita por rcPaint será repintada.

© Copyright 2000-2019 Wintempla selo. All Rights Reserved. Sep 05 2019. Home