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) using Microsoft GDI.
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) usando Microsoft GDI..

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.

TargetRun

Problem 2
Repeat the Target application using Win32.
Repita el programa de Target 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;
}


Problem 3
Repeat the Target application using Direct2D.
Repita el programa de Target usando Direct2D.

TargetDRun

TargetD.h
#pragma once //______________________________________ TargetD.h
#include "Resource.h"
class TargetD: public Win::Window
{
public:
     TargetD()
     {
     }
     ~TargetD()
     {
     }
     Direct::Graphics graphics;
     Direct::SolidBrush brushBlack;
     . . .
};


TargetD.cpp
. . .
void TargetD::Window_Open(Win::Event& e)
{
     brushBlack.Create(graphics, 0.0f, 0.0f, 0.0f, 1.0f); // red, green, blue, alpha
}

void TargetD::Window_Paint(Win::Event& e)
{
     if (graphics.BeginDraw(hWnd, width, height, 1.0f, 1.0f, 1.0f, 1.0f) == false) return; // red, green, blue, alpha
     graphics.SetTransform(D2D1::Matrix3x2F::Identity());
     D2D1_SIZE_F size = graphics.GetSize();
     graphics.DrawLine(0.0f, 0.0f, size.width, size.height, brushBlack, 1.0f);
     . . .
     graphics.EndDraw(true);
}


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 4
Create a program called Box to draw a 3D box as shown. You can use Microsoft GDI or Microsoft Direct2D.
Cree un programa llamado Box para una dibujar una caja 3D como se muestra. Usted puede usar Microsoft GDI o Microsoft Direct2D.

BoxRun

GDI pen styles

GDI has severals pen styles: 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.
GDI tiene diversos estilos 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 using Microsoft GDI.
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. El código de abajo muestra como dibujar un rectángulo en Microsoft GDI.

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 5
Create a Window Application called Room to display the figure shown below using Microsoft GDI. The lines must be spaced 100 pixels from the window borders.
Cree un programa llamado Room para dibujar la figura mostrada debajo usando Microsoft GDI. Las líneas debe estar separadas 100 pixeles de los bordes de la ventana.

Room1

Room2

Problem 6
Create a Window Application called RoomD to display the figure shown below using Microsoft Direct2D. The lines must be spaced 100 pixels from the window borders. The figure below shows the stroke styles in Microsoft Direct2D.
Cree un programa llamado Room para dibujar la figura mostrada debajo usando Microsoft GDI. Las líneas debe estar separadas 100 pixeles de los bordes de la ventana. La figura de abajo muestra los estilos de líneas en Microsoft Direct2D.

StrokeStyle

RoomDRun

RoomD.h
#pragma once //______________________________________ RoomD.h
#include "Resource.h"
class RoomD: public Win::Window
{
public:
     RoomD()
     {
     }
     ~RoomD()
     {
     }
     Direct::Graphics graphics;
     Direct::SolidBrush brushRed;
     Direct::StrokeStyle strokeStyle;
     . . .
};


RoomD.cpp
. . .
void RoomD::Window_Open(Win::Event& e)
{
     //________________________________________________________ 1. Red brush
     brushRed.Create(graphics, 1.0f, 0.0f, 0.0f, 1.0f); // red, green, blue, alpha
     //________________________________________________________ 2. Stoke style
     D2D1_STROKE_STYLE_PROPERTIES strokeProp;
     strokeProp.startCap = D2D1_CAP_STYLE_FLAT;
     strokeProp.endCap = D2D1_CAP_STYLE_FLAT;
     strokeProp.dashCap =D2D1_CAP_STYLE_ROUND;
     strokeProp.lineJoin = D2D1_LINE_JOIN_MITER;
     strokeProp.miterLimit = 10.0f;
     strokeProp.dashStyle = D2D1_DASH_STYLE_DASH;
     strokeProp.dashOffset = 0.0f;
     strokeStyle.Create(graphics, strokeProp, nullptr, 0);
}

void RoomD::Window_Paint(Win::Event& e)
{
     if (graphics.BeginDraw(hWnd, width, height, 1.0f, 1.0f, 1.0f, 1.0f) == false) return; // red, green, blue, alpha
     graphics.SetTransform(D2D1::Matrix3x2F::Identity());
     D2D1_SIZE_F size = graphics.GetSize();
     //________________________________________ 1. Rectangle
     D2D1_RECT_F rect;
     rect.left = 100.0f;
     rect.right = size.width - 100.0f;
     . . .
     graphics.DrawRectangle(rect, brushRed, 1.0f, strokeStyle);
     //________________________________________ 2. Lines
     graphics.DrawLine(0.0f, 0.0f, 100.0f, 100.0f, brushRed, 1.0f, strokeStyle);
     . . .
     graphics.EndDraw(true);
}


Problem 7
Create a program called Inflate using a Window application to draw a rectangle using Microsoft GDI. 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 usando GDI. 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 8
Create a Window Application called EyeSpider to display the figure shown below using Microsoft GDI. Use a total of 100 lines (50 + 50).
Cree un aplicación de ventana llamada EyeSpider para dibujar la figura mostrada debajo Usando Microsoft GDI. 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.

Problem 9
Create a Wintempla Window application called EyeSpiderD to draw the eye spider using Microsoft 2D (observe that this project is not a DirectX application). After creating the application, open Wintempla and double click the on the GUI editor to select the events: KeyDown, Paint and Size.
Cree una aplicación de ventana de Wintempla llamada EyeSpiderD para dibujar el ojo de la araña usando Microsoft 2D (observe que este proyecto no es una aplicación de DirectX). Después de crear la aplicación, abra Wintempla y haga clic doble en el editor de la GUI para seleccionar los eventos: KeyDown, Paint y Size.

EyeSpiderDRun

EyeSpiderDEvents

EyeSpiderDKeyDown

Step A
Edit the EyeSpiderD.h file and the EyeSpiderD.cpp file as shown.
Edite el archivo EyeSpiderD.h y el archivo EyeSpiderD.cpp como se muestra.

EyeSpiderD.h
#pragma once //______________________________________EyeSpiderD.h
#include "Resource.h"

class EyeSpiderD: public Win::Window
{
public:
     EyeSpiderD()
     {
     }
     ~EyeSpiderD()
     {
     }
     Direct::Graphics graphics;
     Direct::SolidBrush brushBlue;
     Direct::SolidBrush brushBlack;
     . . .
};


EyeSpiderD.cpp
. . .
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE , LPTSTR cmdLine, int cmdShow){
     EyeSpiderD app;

     //_______________________________________________________________ Option 1. Window
     app.CreateMainWindow(L"EyeSpiderD", cmdShow, IDI_EyeSpiderD, NULL, (HBRUSH)::GetStockObject(NULL_BRUSH), hInstance);

     //_______________________________________________________________ Option 2. Full Screen (Press Escape to close)
     //app.CreateMainWindow(0, WS_POPUP | WS_VISIBLE, 0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN),
     //     L"FastView", SW_NORMAL, IDI_FastView, NULL, (HBRUSH)::GetStockObject(NULL_BRUSH), hInstance);

     return app.MessageLoop(IDC_FastView);
}

void EyeSpiderD::Window_Open(Win::Event& e)
{
     brushBlack.Create(graphics, 0.0f, 0.0f, 0.0f, 1.0f);
     brushBlue.Create(graphics, 0.0f, 0.0f, 1.0f, 1.0f);
}

void EyeSpiderD::Window_Paint(Win::Event& e)
{
     //_______________________________________________________________________________ 1. BeginDraw
     if (graphics.BeginDraw(hWnd, width, height, 1.0f, 1.0f, 1.0f, 1.0f) == false) return;
     graphics.SetTransform(D2D1::Matrix3x2F::Identity());
     //_______________________________________________________________________________ 2. Lines
     const int lineCount = 50;
     D2D1_SIZE_F size = graphics.GetSize();
     const float deltaX = size.width/(float)lineCount;
     const float deltaY = size.height/(float)lineCount;
     for (int i = 0; i < lineCount; i++)
     {
          graphics.DrawLine(. . .);
          graphics.DrawLine(. . .);
     }
     //_______________________________________________________________________________ 3. Blue rectangle
     D2D1_RECT_F rect = D2D1::RectF(size.width/2- 50.0f, size.height/2- 50.0f, size.width/2 + 50.0f, size.height/2 + 50.0f);
     graphics.FillRectangle(rect, brushBlue);
     //_______________________________________________________________________________ 4. EndDraw
     graphics.EndDraw(true);
}

void EyeSpiderD::Window_KeyDown(Win::Event& e)
{
     switch (e.wParam)
     {
     case VK_ESCAPE:
          ::DestroyWindow(hWnd);
          break;
     }
}

© Copyright 2000-2021 Wintempla selo. All Rights Reserved. Jul 22 2021. Home