#include <Windows.h>
#include <commctrl.h>
#include <math.h> // 添加数学库用于箭头计算
// 全局变量存储点坐标(使用unsigned short类型)
static unsigned short Ax = 0, Ay = 0, Bx = 0, By = 0;
static BOOL pointsSet = FALSE;
// 声明绘制点函数
void Drawpixel(HDC hdc, int originX, int originY, unsigned short x, unsigned short y);
// 声明绘制箭头函数
void DrawArrow(HDC hdc, int fromX, int fromY, int toX, int toY, int arrowSize);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(
In HINSTANCE hInstance,
In_opt HINSTANCE hPrevInstance,
In LPSTR lpCmdLine,
In int nCmdShow)
{
const wchar_t CLASS_NAME[] = L"FirstQuadrantWindowClass";
WNDCLASS wc = { 0 }; wc.lpfnWndProc = WndProc; wc.hInstance = hInstance; wc.lpszClassName = CLASS_NAME; wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); RegisterClass(&wc); HWND hwnd = CreateWindowEx( 0, CLASS_NAME, L"第一象限坐标系", WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME, CW_USEDEFAULT, CW_USEDEFAULT, 636, 700, NULL, NULL, hInstance, NULL); if (hwnd == NULL) return 0; // 创建输入控件 CreateWindow(L"STATIC", L"A点 X:“, WS_CHILD | WS_VISIBLE, 20, 10, 50, 20, hwnd, NULL, hInstance, NULL); CreateWindow(L"EDIT”, L"100", WS_CHILD | WS_VISIBLE | WS_BORDER, 70, 10, 50, 20, hwnd, (HMENU)1001, hInstance, NULL); CreateWindow(L"STATIC", L"Y:“, WS_CHILD | WS_VISIBLE, 130, 10, 20, 20, hwnd, NULL, hInstance, NULL); CreateWindow(L"EDIT”, L"100", WS_CHILD | WS_VISIBLE | WS_BORDER, 150, 10, 50, 20, hwnd, (HMENU)1002, hInstance, NULL); CreateWindow(L"STATIC", L"B点 X:“, WS_CHILD | WS_VISIBLE, 220, 10, 50, 20, hwnd, NULL, hInstance, NULL); CreateWindow(L"EDIT”, L"400", WS_CHILD | WS_VISIBLE | WS_BORDER, 270, 10, 50, 20, hwnd, (HMENU)1003, hInstance, NULL); CreateWindow(L"STATIC", L"Y:“, WS_CHILD | WS_VISIBLE, 330, 10, 20, 20, hwnd, NULL, hInstance, NULL); CreateWindow(L"EDIT”, L"400", WS_CHILD | WS_VISIBLE | WS_BORDER, 350, 10, 50, 20, hwnd, (HMENU)1004, hInstance, NULL); CreateWindow(L"BUTTON", L"绘制", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 450, 8, 80, 25, hwnd, (HMENU)2000, hInstance, NULL); ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam;
}
// 从编辑框获取整数并转换为unsigned short
unsigned short GetEditUShort(HWND hwnd, int ctrlID) {
wchar_t text[32];
GetDlgItemText(hwnd, ctrlID, text, 32);
int value = _wtoi(text);
// 确保值在0-500范围内
if (value < 0) value = 0;
if (value > 500) value = 500;
return (unsigned short)value;
}
// 绘制点函数封装
void Drawpixel(HDC hdc, int originX, int originY, unsigned short x, unsigned short y) {
// 计算实际绘制位置
int winX = originX + x;
int winY = originY - y;
// 绘制点(统一使用红色) HBRUSH hRedBrush = CreateSolidBrush(RGB(255, 0, 0)); HBRUSH hOldBrush = (HBRUSH)SelectObject(hdc, hRedBrush); Ellipse(hdc, winX - 5, winY - 5, winX + 5, winY + 5); // 恢复对象并清理 SelectObject(hdc, hOldBrush); DeleteObject(hRedBrush);
}
// 绘制箭头函数
void DrawArrow(HDC hdc, int fromX, int fromY, int toX, int toY, int arrowSize) {
// 计算向量方向
double dx = toX - fromX;
double dy = toY - fromY;
// 计算向量长度 double length = sqrt(dx * dx + dy * dy); if (length < 1e-5) return; // 避免除以零 // 计算单位向量 double ux = dx / length; double uy = dy / length; // 计算箭头端点(从终点回退一点) int arrowEndX = toX - (int)(ux * 10); // 回退10像素 int arrowEndY = toY - (int)(uy * 10); // 计算垂直向量(用于箭头两侧) double perpX = -uy; double perpY = ux; // 计算箭头两侧点 int arrowLeftX = arrowEndX + (int)(perpX * arrowSize); int arrowLeftY = arrowEndY + (int)(perpY * arrowSize); int arrowRightX = arrowEndX - (int)(perpX * arrowSize); int arrowRightY = arrowEndY - (int)(perpY * arrowSize); // 绘制箭头主体 MoveToEx(hdc, fromX, fromY, NULL); LineTo(hdc, toX, toY); // 绘制箭头两侧 MoveToEx(hdc, toX, toY, NULL); LineTo(hdc, arrowLeftX, arrowLeftY); MoveToEx(hdc, toX, toY, NULL); LineTo(hdc, arrowRightX, arrowRightY);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_COMMAND: {
if (LOWORD(wParam) == 2000) { // 绘制按钮
// 获取用户输入(unsigned short类型)
Ax = GetEditUShort(hwnd, 1001);
Ay = GetEditUShort(hwnd, 1002);
Bx = GetEditUShort(hwnd, 1003);
By = GetEditUShort(hwnd, 1004);
pointsSet = TRUE; InvalidateRect(hwnd, NULL, TRUE); } break; } case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); RECT rect; GetClientRect(hwnd, &rect); int height = rect.bottom - rect.top; // 设置坐标系参数 int originX = 50; int originY = height - 80; int axisLength = 500; // 绘制坐标轴 HPEN hAxisPen = CreatePen(PS_SOLID, 2, RGB(255, 255, 255)); HPEN hOldPen = (HPEN)SelectObject(hdc, hAxisPen); MoveToEx(hdc, originX, originY, NULL); LineTo(hdc, originX + axisLength, originY); MoveToEx(hdc, originX, originY, NULL); LineTo(hdc, originX, originY - axisLength); // 绘制箭头 MoveToEx(hdc, originX + axisLength, originY, NULL); LineTo(hdc, originX + axisLength - 10, originY - 5); MoveToEx(hdc, originX + axisLength, originY, NULL); LineTo(hdc, originX + axisLength - 10, originY + 5); MoveToEx(hdc, originX, originY - axisLength, NULL); LineTo(hdc, originX - 5, originY - axisLength + 10); MoveToEx(hdc, originX, originY - axisLength, NULL); LineTo(hdc, originX + 5, originY - axisLength + 10); // 绘制刻度 for (int i = 1; i <= 10; i++) { int pos = originX + i * 50; MoveToEx(hdc, pos, originY - 5, NULL); LineTo(hdc, pos, originY + 5); MoveToEx(hdc, originX - 5, originY - i * 50, NULL); LineTo(hdc, originX + 5, originY - i * 50); } // 标注坐标轴 SetTextColor(hdc, RGB(255, 255, 255)); SetBkColor(hdc, RGB(0, 0, 0)); TextOut(hdc, originX + axisLength - 20, originY + 20, L"X", 1); TextOut(hdc, originX - 20, originY - axisLength + 10, L"Y", 1); TextOut(hdc, originX - 10, originY + 5, L"O", 1); // 如果设置了点,绘制点和连线 if (pointsSet) { // 计算实际绘制位置 int winAx = originX + Ax; int winAy = originY - Ay; int winBx = originX + Bx; int winBy = originY - By; // 使用封装函数绘制点A和点B Drawpixel(hdc, originX, originY, Ax, Ay); Drawpixel(hdc, originX, originY, Bx, By); // 绘制红色连接线(带箭头) HPEN hRedPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0)); SelectObject(hdc, hRedPen); // 使用箭头绘制函数 DrawArrow(hdc, winAx, winAy, winBx, winBy, 8); // 标记点A SetTextColor(hdc, RGB(255, 200, 200)); // 浅红色文本 SetBkMode(hdc, TRANSPARENT); // 透明背景 TextOut(hdc, winAx + 8, winAy - 8, L"A", 1); // 标记点B SetTextColor(hdc, RGB(180, 220, 255)); // 浅蓝色文本 TextOut(hdc, winBx + 8, winBy - 8, L"B", 1); // 清理资源 SelectObject(hdc, hRedPen); DeleteObject(hRedPen); } // 恢复并清理资源 SelectObject(hdc, hOldPen); DeleteObject(hAxisPen); EndPaint(hwnd, &ps); return 0; } case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, msg, wParam, lParam);
}
给该代码增加详细的注释