我有以下内容:
程序开始运行:
输入:在 Windows 7(或更高版本)的控制台窗口中,程序要求用户输入代表点的整数:每个点的 y 和 x(二维坐标)。
输出:然后使用这些点的程序应在窗口中(在监视器上)显示点本身以及连接这些点的线。
程序停止运行
所有这些都是用 C++ 编写的,使用代码块和 GDI+。 我的问题是我似乎无法使用 GID+ 将控制台的输入连接到输出,这甚至可能吗?
我是 C++ 新手,尤其是图形方面的新手,之前没有任何编程经验。 在网上环顾四周,除了令人惊讶的低质量和关于该主题的稀缺信息外,GDI+ 是我得出的解决方案。 我想要最简单的解决方案。有什么想法吗?
#include <abrazol.h>
using namespace std;
struct koordinata {
int x;
int y;
};
int main(){
vector<koordinata> abrazol;
abrazol = koordinataszamol(); //Ignore this, it calculates with
//the coordinate points, asks the user for the x and y values
//of the points, returns a struct type (koordinata) of vector.
HDC hd;
int a=0;
for (int i=0; i<abrazol.size()-1; i++){
Drawpoint(hd,abrazol[i]);
Drawpoint(hd,abrazol[i+1]);
OnPaint(hd,abrazol[i],abrazol[i+1]);
a++;
}
OnPaint(hd,abrazol[a+1],abrazol[0]);
return 0;
}
abrazol.cpp (h)
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include <stdio.h>
#include <iostream>
#include <koordinataszamol.h>
#pragma comment (lib,"Gdiplus.lib")
using namespace Gdiplus;
VOID OnPaint(HDC hdc, koordinata pont1, koordinata pont2)
{
Graphics graphics(hdc);
Pen pen(Color(255, 0, 0, 255));
graphics.DrawLine(&pen, pont1.x, pont1.y, pont2.x, pont2.y);
}
VOID Drawpoint(HDC hdc, koordinata pont){
Graphics graphics(hdc);
Pen blackPen(Color(255, 0, 0, 0), 3);
int width = 2;
int height = 2;
graphics.DrawRectangle(&blackPen, pont.x-1, pont.y-1, width, height);
}
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
HWND hWnd;
MSG msg;
WNDCLASS wndClass;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = TEXT("GettingStarted");
RegisterClass(&wndClass);
hWnd = CreateWindow(
TEXT("GettingStarted"), // window class name
TEXT("Getting Started"), // window caption
WS_OVERLAPPEDWINDOW, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // window menu handle
hInstance, // program instance handle
NULL); // creation parameters
ShowWindow(hWnd, iCmdShow);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GdiplusShutdown(gdiplusToken);
return msg.wParam;
} // WinMain
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
switch(message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
koordinata pont1;
koordinata pont2;
OnPaint(hdc,pont1,pont2);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
} // WndProc
我怀疑我不能修改 OnPaint 函数的参数,那我应该如何从运行时参数中绘制???
最佳答案
我怀疑您在这种情况下使用 GDI+ 有什么好处。仅使用 GDI 绘图就非常简单。
至于如何在不更改 OnPaint 参数的情况下更改绘图的基本问题,它通常非常简单:您决定将数据存储在某个位置。输入数据后,您将其存储在那里。 OnPaint 从那里检索数据,并将其绘制到屏幕上。
在这种情况下,您可能希望将其设为类似 std::vector<point>
的内容, 其中point
是一种包含 x 和 y 坐标的类型。
我大致按照您的描述快速修改了一个程序,让您输入一些点,然后在窗口中绘制它们(使用我周围的窗口类来处理大部分窗口创建、初始化等)。这是一些代码:
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
struct point {
int x;
int y;
point() = default;
point(int x, int y) : x(x), y(y) { }
friend std::istream &operator>>(std::istream &is, point &p) {
return is >> p.x >> p.y;
}
};
struct Window {
virtual void OnPaint(HDC) = 0;
Window(std::string const &name) : hInstance(GetModuleHandle(NULL)) {
wndClass.style = CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = name.c_str();
RegisterClass(&wndClass);
hWnd = CreateWindow(
TEXT(name.c_str()),
TEXT(name.c_str()),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
(PVOID)this);
}
WPARAM operator()() {
MSG msg;
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
private:
HINSTANCE hInstance;
HWND hWnd;
WNDCLASS wndClass;
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
HDC hdc;
PAINTSTRUCT ps;
static Window *w;
switch (message) {
case WM_CREATE:
w = static_cast<Window *>(((CREATESTRUCT *)lParam)->lpCreateParams);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
w->OnPaint(hdc);
EndPaint(hWnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
};
class disp_window : public Window {
std::vector<point> points;
public:
disp_window(std::string const &t) : Window(t) { }
virtual void OnPaint(HDC hDC) {
if (points.empty())
return;
MoveToEx(hDC, points[0].x, points[0].y, nullptr);
for (int i = 1; i < points.size(); i++)
LineTo(hDC, points[i].x, points[i].y);
}
std::vector<point> &data() { return points; }
};
int main() {
disp_window w("Getting Started");
std::cout << "Please enter some points: ";
point p;
while (std::cin >> p)
w.data().push_back(p);
w();
}
使用 Visual C++,您可以像这样在命令行上编译它:
cl simple_win.cpp user32.lib kernel32.lib gdi32.lib
使用 MinGW,命令行看起来像这样:
g++ -std=c++11 simple_win.cpp -luser32 -l gdi32 -lkernel32
当你运行它时,它会打印出提示,然后你输入点,数字之间用空格(或制表符或回车)分隔:
Please enter some points: 1 1
100 100
100 200
200 300
^Z
(control-Z 只是让它知道输入已经结束)。
然后它会弹出一个这样的窗口:
我可能应该补充一点,这并不是真正最有效的做事方式——只是我在几分钟内拼凑出来的东西。例如,如果你要有很多点,你可能想查找 PolyLine
而不是使用 MoveTo
/LineTo
.我也懒得包含在每个点绘制正方形(或其他任何东西)的代码——将其添加到 disp_window::OnPaint
不过应该很简单。
关于c++ - 在 Windows 7 或更高版本的 C++ 中使用 GDI+ 的 : How to display points connected by lines on a monitor,?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33423157/