In the Win32 C++ application, when using the DrawLine() function, wide strokes are drawn instead of lines.

  • Thread starter Thread starter Purple_Apple
  • Start date Start date
P

Purple_Apple

Guest
Hello. I write the Win32 C ++ application. I use Visual Studio 2017 Community. I have problems of drawing lines using GDI+. First, I’ll show you what is drawing scheme I use in my application. I bring all this in a significantly reduced form.

. . . . . . . . . . .
#include <gdiplus.h>
. . . . . . . . . . .
using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")

// Drawn edge of a triangle that make up the triangulation mesh.
struct EdgeToDraw
{
EdgeToDraw() {}

EdgeToDraw(double X_begin, double Y_begin, double X_end, double Y_end)
{
Begin.X = X_begin;
Begin.Y = Y_begin;
End.X = X_end;
End.Y = Y_end;
}
// X and Y coordinates of begin vertex of drawn edge.
PointF Begin;
// X and Y coordinates of end vertex of drawn edge.
PointF End;
};
. . . . . . . . . . . . . . . . . . . . . . . . .
// The buffer of the edges of the triangles that make up the
// triangulation grid drawn in the application window.
concurrent_queue<EdgeToDraw> MeshEdgesBuffer;
// Message about redrawing of the application window.
const UINT WM_APP_DRAW_TRIMESH = WM_APP + 0;
. . . . . . . . . . . . . . . . . . . . . . . . .
// Fills the buffer of edges that make up the triangulation mesh
// drawn in the application window.
void FillMeshEdgesBuffer(Mesh* m, cancellation_token token)
{
. . . . . . . . . . . . . . . . . . . . . . . .
// To go through many edges, you need to go through all the triangles
// and look at the three edges of each of the triangles.
while (triangleloop.Tri != nullptr)
{
. . . . . . . . . . . . . . . . . . . . . .
for (triangleloop.Edge = 0; triangleloop.Edge < 3; triangleloop.Edge++)
{
. . . . . . . . . . . . . . . . . . . .
// Get the start point of the edge.
double X_begin = GetXBegin();
double Y_begin = GetYBegin();
// Get the end point of the edge.
double X_end = GetXEnd();
double Y_end = GetYEnd();

// Add an edge for the drawn triangulation mesh.
MeshEdgesBuffer.push(EdgeToDraw(X_begin, Y_begin, X_end, Y_end));
. . . . . . . . . . . . . . . . . . . .
}
. . . . . . . . . . . . . . . . . . . . . .
}
}

// Called in WM_PAINT message.
VOID OnPaint(HWND hWnd, HDC hdc)
{
Graphics* g = Graphics::FromHDC(hdc);

RECT r;
::GetClientRect(hWnd, &r);
int width = r.right - r.left;
int height = r.bottom - r.top;

// move the origin to center
g->TranslateTransform((r.right - r.left) / 2, (r.bottom - r.top) / 2);
// set the bottom-up orientation of Y
g->ScaleTransform(1, -1);
// scale; 3.5 is the maximal expected value of coordinates
g->ScaleTransform((width / 2) / 3.5, (height / 2) / 3.5);

// determine the approximative size of pixel
PointF p[2] = { {0, 0}, {1, 1} };
g->TransformPoints(CoordinateSpace::CoordinateSpaceWorld, CoordinateSpace::CoordinateSpaceDevice, p, 2);
float pw = fabsf(p[1].X - p[0].X);
float ph = fabsf(p[1].Y - p[0].Y);

// Set pen color and smmothing mode to draw lines.
Pen pen(Color(255, 0, 0, 255), 2);
g->SetSmoothingMode(SmoothingModeAntiAlias);
// Draw next edge.
EdgeToDraw* drawnEdge = new EdgeToDraw();
while (MeshEdgesBuffer.try_pop(*drawnEdge))
{
g->DrawLine(&pen, drawnEdge->Begin, drawnEdge->End);
//g->ResetTransform();
}
}

// Application window procedure.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
. . . . . . .
case IDM_TRIANGULATE:
{
// Go to asynchronous execution.
auto asyncTask = create_task([hWnd]()
{
// Get cancellation token for triangulationTask task.
cancelTriSource = cancellation_token_source();
cancellation_token token = cancelTriSource.get_token();
// Declare a triangulation mesh variable.
Mesh m;
// Declare application settings variable.
Configuration b;

// Run triangulation task.
auto triangulationTask = create_task([&m, &b, &token, hWnd]()
{
. . . . . . . . . . . . . .
// Get data to draw triangulation mesh.
FillMeshEdgesBuffer(&m, token);
// Send message about redrawing of application window.
PostMessage(hWnd, WM_APP_DRAW_TRIMESH, 0, 0);
. . . . . . . . . . . . . .
}, token).then([&m, &b](task<void> currentTask)
{
. . . . . . . . . . .
});
// Wait the completion of the triangulation task.
triangulationTask.get();
});
}
break;
. . . . . . . . . . . . .
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
. . . . . . . . .
}
break;
. . . . . . . . . . .
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code that uses hdc here...
OnPaint(hWnd, hdc);
EndPaint(hWnd, &ps);
return 0;
}
break;
case WM_APP_DRAW_TRIMESH:
InvalidateRect(hWnd, nullptr, TRUE);
break;
. . . . . . . . . . . . . . . . .
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
And here is how the application draws a triangulation mesh. Some kind of daub. Please see below. This is the problem.

1565478.png

Below is the contents of MeshEdgesBuffer:

1565479.png

As you can see from the figure, the buffer contains normal data for drawing a triangulation mesh.

But what is the reason for such a daub in the picture instead of a triangulation mesh? The only good thing here is that the shape of the outer border of this daub repeats the shape of the outer border of the triangulation mesh that was supposed to be. In this example, which I showed you, the triangulation mesh has only 29 edges. But instead of it for some reason it turns out some kind of daub. Please help to cope with this problem and that the triangulation mesh is drawn normally.

Continue reading...
 
Back
Top