【WinAPI】箭头的绘制

【WinAPI】箭头的绘制

唯一难的地方就是箭头的绘制了。

#include <windows.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpszCmdLine, int nCmdShow)
{
    HWND hwnd;
    MSG Msg;
    WNDCLASS wndclass;
    char lpszClassName[] = "窗体";
    char lpszTitle[] = "My_Windows";

    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 = lpszClassName;

    if (!RegisterClass (&wndclass))
    {
        MessageBeep(0);
        return FALSE;
    }

    hwnd=CreateWindow(
                        lpszClassName,
                        lpszTitle,
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        CW_USEDEFAULT,
                        NULL,
                        NULL,
                        hInstance,
                        NULL
                      );
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    while(GetMessage (&Msg, NULL,0,0))
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

void CreateArrow(HDC hDC, int x1, int y1, int x2, int y2)
{
    int x21 = x2 - x1;
    int y21 = y2 - y1;
    MoveToEx(hDC, x1, y1, NULL);
    LineTo(hDC, x2, y2);
    if (x21 > 0)
    {
        int x3 = x2 - 20*cos(atan(y21/(double)x21)-acos(1.8/2));
        int y3 = y2 - 20*sin(atan(y21/(double)x21)-acos(1.8/2));
        int x4 = x2 - 20*cos(atan(y21/(double)x21)+acos(1.8/2));
        int y4 = y2 - 20*sin(atan(y21/(double)x21)+acos(1.8/2));
        LineTo(hDC, x3, y3);
        MoveToEx(hDC, x2, y2, NULL);
        LineTo(hDC, x4, y4);
    }
    else
    {
        int x3 = x2 + 20*cos(atan(y21/(double)x21)-acos(1.8/2));
        int y3 = y2 + 20*sin(atan(y21/(double)x21)-acos(1.8/2));
        int x4 = x2 + 20*cos(atan(y21/(double)x21)+acos(1.8/2));
        int y4 = y2 + 20*sin(atan(y21/(double)x21)+acos(1.8/2));
        LineTo(hDC, x3, y3);
        MoveToEx(hDC, x2, y2, NULL);
        LineTo(hDC, x4, y4);
    }

    MoveToEx(hDC, x2, y2, NULL);
}

#define EPS ((LmR+UmD)/2/50)
#define RAD (EPS*4)
#define LmR (R-L)
#define UmD (D-U)
#define L rect.left
#define R rect.right
#define U rect.top
#define D rect.bottom

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC            hDC;
    HPEN        hPen;
    HBRUSH        hBr;
    PAINTSTRUCT ps;
    RECT        rect;
    LONG        r_b1,r_b2,r_b3; // 球场大小
    LONG        Arc_d,tmp,ang_r;
    LONG        d1,p_r1,p_r2; // 暂存点
    LONG        x1,y1,x2,y2;
    int            i;
    double        a_d; // 弧度
    switch(message)
    {
    case WM_PAINT:
        hDC=BeginPaint(hwnd,&ps);
        GetClientRect(hwnd,&rect);

        //    球场的颜色
        hPen = CreatePen(PS_SOLID,1,RGB(147,190,99));
        hBr = CreateSolidBrush(RGB(147,190,99));
        SelectObject(hDC, hPen);
        SelectObject(hDC, hBr);
        Rectangle(hDC,L,U,R,D);
        DeleteObject(hPen);
        DeleteObject(hBr);

        //    球场的边界
        hPen = CreatePen(PS_SOLID,2,RGB(255,255,255));
        SelectObject(hDC, hPen);
        MoveToEx(hDC, L+EPS, U+EPS, NULL);
        LineTo(hDC, R-EPS, U+EPS);
        LineTo(hDC, R-EPS, D-EPS);
        LineTo(hDC, L+EPS, D-EPS);
        LineTo(hDC, L+EPS, U+EPS);

        //球场的圆
        Ellipse(hDC,LmR/2-RAD,UmD/2-RAD,LmR/2+RAD,UmD/2+RAD);

        MoveToEx(hDC,LmR/2,U+EPS,NULL);
        LineTo(hDC,LmR/2,D-EPS);

        // 大球门
        r_b1=(UmD-2*EPS)/5;
        MoveToEx(hDC,L+EPS,U+EPS+r_b1,NULL);
        LineTo(hDC,L+EPS+r_b1,U+EPS+r_b1);
        LineTo(hDC,L+EPS+r_b1,U+EPS+4*r_b1);
        LineTo(hDC,L+EPS,U+EPS+4*r_b1);

        MoveToEx(hDC,R-EPS,U+EPS+r_b1,NULL);
        LineTo(hDC,R-EPS-r_b1,U+EPS+r_b1);
        LineTo(hDC,R-EPS-r_b1,U+EPS+4*r_b1);
        LineTo(hDC,R-EPS,U+EPS+4*r_b1);

        // 小球门
        r_b2=r_b1/2;
        MoveToEx(hDC,L+EPS,U+EPS+2*r_b1-r_b1/5,NULL);
        LineTo(hDC,L+EPS+r_b2,U+EPS+2*r_b1-r_b1/5);
        LineTo(hDC,L+EPS+r_b2,U+EPS+3*r_b1+r_b1/5);
        LineTo(hDC,L+EPS,U+EPS+3*r_b1+r_b1/5);

        MoveToEx(hDC,R-EPS,U+EPS+2*r_b1-r_b1/5,NULL);
        LineTo(hDC,R-EPS-r_b2,U+EPS+2*r_b1-r_b1/5);
        LineTo(hDC,R-EPS-r_b2,U+EPS+3*r_b1+r_b1/5);
        LineTo(hDC,R-EPS,U+EPS+3*r_b1+r_b1/5);
        DeleteObject(hPen);

        // 球门后的小白条
        hPen=(HPEN)GetStockObject(WHITE_PEN);
        hBr=(HBRUSH)GetStockObject(WHITE_BRUSH);
        SelectObject(hDC,hPen);
        SelectObject(hDC,hBr);
        r_b3=r_b1/3;
        Rectangle(hDC,L+EPS-r_b3/10,U+EPS+2*r_b1-r_b1/5+r_b3,L+EPS,U+EPS+3*r_b1+r_b1/5-r_b3);
        Rectangle(hDC,R-EPS+r_b3/10,U+EPS+2*r_b1-r_b1/5+r_b3,R-EPS,U+EPS+3*r_b1+r_b1/5-r_b3);

        // 球门前的点,中间的点
        d1=r_b2*3/2;
        p_r1=(LmR+UmD)/2/250;
        Ellipse(hDC,LmR/2-p_r1,UmD/2-p_r1,LmR/2+p_r1,UmD/2+p_r1);
        Ellipse(hDC,L+EPS+d1-p_r1,UmD/2-p_r1,L+EPS+d1+p_r1,UmD/2+p_r1);
        Ellipse(hDC,R-EPS-d1-p_r1,UmD/2-p_r1,R-EPS-d1+p_r1,UmD/2+p_r1);
        DeleteObject(hPen);
        DeleteObject(hBr);


        //    随机点
        srand((unsigned int)time(0));
        hBr=CreateSolidBrush(RGB(36,92,150));
        SelectObject(hDC,hBr);
        a_d=(double)p_r2;
        p_r2=(LmR+UmD)/2/100;

        for (i = 0; i < 40; i++)
        {
            x1=rand()%(R-EPS)+L+EPS%(R-EPS);
            y1=rand()%(D-EPS)+U+EPS%(D-EPS);
            x2=rand()%(R-EPS)+L+EPS%(R-EPS);
            y2=rand()%(D-EPS)+U+EPS%(D-EPS);
if (x1 > R-EPS || x1 < L+EPS || x2 > R-EPS || x2 < L+EPS ||
                y1 > D-EPS || y1 < U+EPS || y2 > D-EPS || y2 < U+EPS ||
                (x1 > L+EPS && x1 < L+EPS+r_b1 && y1 < U+EPS+4*r_b1 && y1 > U+EPS+r_b1) ||
                (x1 > R-EPS-r_b1 && x1 < R-EPS && y1 < U+EPS+4*r_b1 && y1 > U+EPS+r_b1) ||
                (x2 > L+EPS && x2 < L+EPS+r_b1 && y2 < U+EPS+4*r_b1 && y2 > U+EPS+r_b1) ||
                (x2 > R-EPS-r_b1 && x2 < R-EPS && y2 < U+EPS+4*r_b1 && y2 > U+EPS+r_b1)

            ){
                i = i - 1;
                continue;
            }


            hPen=CreatePen(PS_SOLID,7,RGB(146,216,147));
            SelectObject(hDC,hPen);
            CreateArrow(hDC, x1, y1, x2, y2);
            DeleteObject(hPen);
            hPen=CreatePen(PS_SOLID,2,RGB(200,219,176));
            SelectObject(hDC,hPen);
            Ellipse(hDC,x1-p_r2,y1-p_r2,x1+p_r2,y1+p_r2);
            DeleteObject(hPen);
        }
        for (i = 0; i < 10; i++)
        {
            x1=rand()%(R-EPS)+L+EPS%(R-EPS);
            y1=rand()%(D-EPS)+U+EPS%(D-EPS);
            x2=rand()%(R-EPS)+L+EPS%(R-EPS);
if (x1 > R-EPS || x1 < L+EPS || x2 > R-EPS || x2 < L+EPS ||
                y1 > D-EPS || y1 < U+EPS || y2 > D-EPS || y2 < U+EPS ||
                (x1 > L+EPS && x1 < L+EPS+r_b1 && y1 < U+EPS+4*r_b1 && y1 > U+EPS+r_b1) ||
                (x1 > R-EPS-r_b1 && x1 < R-EPS && y1 < U+EPS+4*r_b1 && y1 > U+EPS+r_b1) ||
                (x2 > L+EPS && x2 < L+EPS+r_b1 && y2 < U+EPS+4*r_b1 && y2 > U+EPS+r_b1) ||
                (x2 > R-EPS-r_b1 && x2 < R-EPS && y2 < U+EPS+4*r_b1 && y2 > U+EPS+r_b1)

            ){
                i = i - 1;
                continue;
            }


            hPen=CreatePen(PS_SOLID,7,RGB(156,40,53));
            SelectObject(hDC,hPen);
            CreateArrow(hDC, x1, y1, x2, y2);
            DeleteObject(hPen);
            hPen=CreatePen(PS_SOLID,2,RGB(200,219,176));
            SelectObject(hDC,hPen);
            Ellipse(hDC,x1-p_r2,y1-p_r2,x1+p_r2,y1+p_r2);
            DeleteObject(hPen);
        }
        DeleteObject(hBr);

        for (i = 0; i < 5; i++)
        {
            x1=rand()%(R-EPS)+L+EPS%(R-EPS);
            y1=rand()%(D-EPS)+U+EPS%(D-EPS);
            x2=rand()%(R-EPS)+L+EPS%(R-EPS);
            y2=rand()%(D-EPS)+U+EPS%(D-EPS);
//            MoveToEx(hDC,L+EPS,U+EPS+r_b1,NULL);
//            LineTo(hDC,L+EPS+r_b1,U+EPS+r_b1);
//            LineTo(hDC,L+EPS+r_b1,U+EPS+4*r_b1);
//            LineTo(hDC,L+EPS,U+EPS+4*r_b1);
//
//            MoveToEx(hDC,R-EPS,U+EPS+r_b1,NULL);
//            LineTo(hDC,R-EPS-r_b1,U+EPS+r_b1);
//            LineTo(hDC,R-EPS-r_b1,U+EPS+4*r_b1);
//            LineTo(hDC,R-EPS,U+EPS+4*r_b1);

            if (x1 > R-EPS || x1 < L+EPS || x2 > R-EPS || x2 < L+EPS ||
                y1 > D-EPS || y1 < U+EPS || y2 > D-EPS || y2 < U+EPS ||
                (x1 > L+EPS && x1 < L+EPS+r_b1 && y1 < U+EPS+4*r_b1 && y1 > U+EPS+r_b1) ||
                (x1 > R-EPS-r_b1 && x1 < R-EPS && y1 < U+EPS+4*r_b1 && y1 > U+EPS+r_b1) ||
                (x2 > L+EPS && x2 < L+EPS+r_b1 && y2 < U+EPS+4*r_b1 && y2 > U+EPS+r_b1) ||
                (x2 > R-EPS-r_b1 && x2 < R-EPS && y2 < U+EPS+4*r_b1 && y2 > U+EPS+r_b1)

            ){
                i = i - 1;
                continue;
            }

            hPen=CreatePen(PS_SOLID,7,RGB(236,200,83));
            SelectObject(hDC,hPen);
            CreateArrow(hDC, x1, y1, x2, y2);
            DeleteObject(hPen);
            hPen=CreatePen(PS_SOLID,2,RGB(200,219,176));
            SelectObject(hDC,hPen);
            Ellipse(hDC,x1-p_r2,y1-p_r2,x1+p_r2,y1+p_r2);
            DeleteObject(hPen);
        }
        DeleteObject(hBr);

        // 边界四个弧
        ang_r=(LmR+UmD)/2/80;
        Arc(hDC,L+EPS-ang_r,U+EPS-ang_r,L+EPS+ang_r,U+EPS+ang_r,L+EPS,U+EPS+ang_r,L+EPS+ang_r,U+EPS);
        Arc(hDC,R-EPS-ang_r,U+EPS-ang_r,R-EPS+ang_r,U+EPS+ang_r,R-EPS-ang_r,U+EPS,R-EPS,U+EPS+ang_r);
        Arc(hDC,R-EPS-ang_r,D-EPS-ang_r,R-EPS+ang_r,D-EPS+ang_r,R-EPS,D-EPS-ang_r,R-EPS-ang_r,D-EPS);
        Arc(hDC,L+EPS-ang_r,D-EPS-ang_r,L+EPS+ang_r,D-EPS+ang_r,L+EPS+ang_r,D-EPS,L+EPS,D-EPS-ang_r);

        // 球门前小圆
        Arc_d=r_b1*4/5;
        tmp=Arc_d/5;
        Arc(hDC,tmp+L+EPS+r_b1-Arc_d-Arc_d/2,UmD/2-Arc_d,tmp+L+EPS+r_b1,UmD/2+Arc_d,tmp+L+EPS+r_b1,UmD/2+Arc_d,tmp+L+EPS+r_b1,UmD/2-Arc_d);
        Arc(hDC,-tmp+R-EPS-r_b1+Arc_d+Arc_d/2,UmD/2-Arc_d,-tmp+R-EPS-r_b1,UmD/2+Arc_d,-tmp+R-EPS-r_b1,UmD/2-Arc_d,-tmp+R-EPS-r_b1,UmD/2+Arc_d);

        DeleteObject(hPen);
        DeleteObject(hBr);
        EndPaint(hwnd,&ps);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    default:
        return DefWindowProc(hwnd,message,wParam,lParam);
    }
    return (0);
}

 

上一篇:如何将图片jpg/png格式转为eps格式


下一篇:学习笔记30—Windows那些事