【问题标题】:GDI in C not drawing successive objectsC中的GDI不绘制连续的对象
【发布时间】:2016-10-01 22:41:59
【问题描述】:

尝试在 Windows API 中使用 C 和 GDI 创建基本绘图程序。这个想法是用户单击并拖动以创建一个矩形或任何其他选定的形状。大小由用户单击和释放的位置指定(就像任何绘图程序一样)。我遇到了一个问题,用户绘制的第一个形状将被绘制到屏幕上,但是任何连续的都不是。我最初并没有在 WM_PAINT 中绘制形状,但我在另一个线程上读到我需要这样做,所以我创建了一个结构来存储有关已绘制对象的信息,并且每次收到 WM_PAINT 消息时都会绘制这些对象。

这是我的 WM_PAINT 代码

case WM_PAINT:
{
    for (int i = 0; i < drawingcount; i++)
    {

        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hwnd, &ps);
        HPEN hMyPen = CreatePen(mydrawings[i].style, mydrawings[i].thick, RGB(0,255,0));
        HPEN hOldPen = SelectObject(hdc, hMyPen);

        if (mydrawings[i].shape == RECTANGLE)
        {
            Rectangle(hdc, mydrawings[i].start_x, mydrawings[i].start_y, mydrawings[i].end_x, mydrawings[i].end_y);
        }
        else if (mydrawings[i].shape == ELLIPSE)
        {
            Ellipse(hdc, mydrawings[i].start_x, mydrawings[i].start_y, mydrawings[i].end_x, mydrawings[i].end_y);
        }
        else if (mydrawings[i].shape == LINE)
        {
            MoveToEx(hdc, mydrawings[i].start_x, mydrawings[i].start_y, 0);
            LineTo(hdc, mydrawings[i].end_x, mydrawings[i].end_y);
        }
        SelectObject(hdc, hOldPen);
        DeleteObject(hMyPen);
        //DeleteObject(hOldPen);
        EndPaint(hwnd, &ps);
    }
}
break;

这里是 WM_LBUTTONUP(一旦用户完成绘制他们的形状)

case WM_LBUTTONUP:
{
    yendclick = GET_Y_LPARAM(lParam);
    xendclick = GET_X_LPARAM(lParam);
    mydrawings[drawingcount].shape = selected_shape;
    mydrawings[drawingcount].start_x = xclick;
    mydrawings[drawingcount].start_y = yclick;
    mydrawings[drawingcount].end_x = xendclick;
    mydrawings[drawingcount].end_y = yendclick;
    mydrawings[drawingcount].thick = thickness;
    mydrawings[drawingcount].style = style;
    drawingcount++;
    SendMessage(hwnd, WM_PAINT, wParam, lParam);
}

结构和枚举声明:

typedef enum myshape
{
    RECTANGLE,
    ELLIPSE,
    LINE,
    MAX_SHAPE
} shape;
typedef struct drawing
{
    int start_x;
    int start_y;
    int end_x;
    int end_y;
    int thick;
    int style;
    shape shape;
} drawings;

非常感谢您对此的任何指导!

【问题讨论】:

  • case WM_LBUTTONUP的大括号后面是否有break,还有其他情况吗?
  • 是的,有一个break 抱歉,我在帖子中省略了它。在此之后还有一些案例,但我将它们全部以break 终止以防止失败。
  • 我不是 Win32 专家,但将最后三个调用更改为 EndPaint(); SelectObject(); DeleteObject(); 会更有意义,似乎当前命令会在使用时删除它们。
  • 感谢您的建议!实际上,我只是通过将 HDC hdc = BeginPaint(hwnd, &amp;ps)EndPaint(hwnd, &amp;ps) 移出 for 循环来让它工作 - 现在 for 循环正在绘图内部发生,而不是每次都重新启动它。

标签: c++ c gdi


【解决方案1】:

不要使用 PostMessage WM_PAINT,而是使用 InvalidateRect 或者 UpdateWindow。也可以在这里查看:why not to send WM_PAINT manually

【讨论】:

  • 感谢您的回复!我已经用InvalidateRect 替换了我的SendMessage,但遗憾的是我仍然面临同样的问题。我也试过添加UpdateWindow(hwnd)
  • @Swemoph 问题可能出在您的逻辑上。很难说你展示的那个小代码发生了什么。
猜你喜欢
  • 2012-07-27
  • 2012-12-29
  • 1970-01-01
  • 2021-02-21
  • 2014-06-26
  • 2011-06-01
  • 1970-01-01
  • 2015-01-29
  • 1970-01-01
相关资源
最近更新 更多