Win32开拓入门(8) 画图(A)
当前位置:以往代写 > C/C++ 教程 >Win32开拓入门(8) 画图(A)
2019-06-13

Win32开拓入门(8) 画图(A)

Win32开拓入门(8) 画图(A)

副标题#e#

从本篇开始,我就不吹牛皮,那就吹吹兔皮吧。说说与画图有关的东东。

要举办绘制,首先 要获得一个DC,啥是DC呢?按字面翻译叫设备上下文,也可以翻译为设备描写表,它主要指API为我们 封装了一些与显示设备相关的交互操纵,我们这里说的是图形的绘制,自然指的是显卡。虽然,对付同 一客观事物,世界上并不存在独一的领略方案,技能上的对象最终拿来用的,不该该有硬性的去统一。 我们之中的许多人,最大的失败在于,人家说要这样领略他就绝不猜疑地这样领略,权威人士说要这样 这样,他就不颠末大脑思考地随着那样那样。

固然我的母校是名不见经传的三流大学,但回想 我的大学,很幸运,我曾经碰着几位好老师,真正的好老师,不是那些所谓的叫兽砖家。记得某位老师 说过:这本书,假如读完了你一无所获,那你太失败了;假如你把书中的内容都把握了,委曲合格;如 果你能把书中的所有概念全部推翻,你才是优秀的。

在很多环境下,我们画图都是遵循先 GetDC—–〉画图——〉ReleaseDC,DC是一种资源,用完了要释放,我们到图书馆借书,看完了要 还书。不外,在处理惩罚WM_PAINT动静时,挪用BeginPaint函数后,开始画图,画完了挪用EndPaint。虽然 这个并不违背我们前面所说的利用完HDC要释放的原理,只是BeginPaint函数会自动挪用GetDC, EndPaint会自动挪用ReleaseDC。

好的,首先我们来写几个字吧。绘制文本可以利用DrawText函 数,他的最后一个参数是文本的对齐名目,如左对齐、居中、右对齐等。

PAINTSTRUCT ps;   

  
switch(msg)     
{     
case WM_PAINT:     
        BeginPaint(hwnd, &ps);

声明一个PAINTSTRUCT布局体的变量,然后传给 BeginPaint函数,之后就可以画对象了。

DrawText(ps.hdc,L"床前明月光", -1, &rect, DT_CENTER);

可是,假如我但愿文本的颜色不是默认的玄色,我们可以思量挪用 SetTextColor函数来配置颜色,之后我们绘制的所有文本都是这个颜色了,假如之后但愿改变文本的颜 色,就再次挪用SetTextColor函数。

SetTextColor(ps.hdc, RGB(0,150,255));

RGB宏可 以通过三个值来确定颜色值,这个预计不消我先容了,假如不懂RGB,可以去请教芙蓉姐姐。

我 但愿新绘制的文本在前一个文本的下一行,虽然,你大概会说,用DrawText的时候把传给它的RECT改一 下坐标就行了。这要领固然可以,但我们欠好调坐标。其实,我们假如知道文本字符的高度,那不就好 办了吗,对的,要得到文本高度,可以挪用GetTextMetrics函数。此刻我们要用的东西都齐全了。

case WM_PAINT:     
    BeginPaint(hwnd, &ps);     
    TEXTMETRIC tm;     
    // 取得与文内情关的数据     
    GetTextMetrics(ps.hdc, &tm);     
    RECT rect;     
    rect.top = 0L;     
    rect.left = ps.rcPaint.left;     
    rect.right = ps.rcPaint.right;     
    rect.bottom = rect.top + tm.tmHeight;     
    // 第一行文本     
    SetTextColor(ps.hdc, RGB(0,150,255));     
    DrawText(ps.hdc,L"床前明月光", -1, &rect, DT_CENTER);     
    // 第二行文本     
    rect.top += tm.tmHeight;     
    rect.bottom += tm.tmHeight;     
    SetTextColor(ps.hdc, RGB(220, 12, 50));     
    DrawText(ps.hdc, L"疑是地上霜", -1, &rect, DT_LEFT);     
    // 第三行文本     
    rect.top += tm.tmHeight;     
    rect.bottom += tm.tmHeight;     
    SetTextColor(ps.hdc, RGB(30,255,7));     
    DrawText(ps.hdc, L"举头望明月", -1, &rect, DT_RIGHT);     
    // 第四行文本     
    rect.top += tm.tmHeight;     
    rect.bottom += tm.tmHeight;     
    SetTextColor(ps.hdc, RGB(0,40,210));     
    DrawText(ps.hdc, L"垂头思家园", -1, &rect, DT_RIGHT);     
    EndPaint(hwnd, &ps);     
    return 0;


#p#副标题#e#

这个不难领略吧,就是每一行文本的矩形区域得顶部和底部坐标别离加上文本 的高度。

此刻可以看看结果了。

Win32开辟入门(8) 绘图(A)

接下来,我们画几条弧线。绘制弧线利用Arc函数,第一个参数是方针HDC,随后的4个参数用 于确定弧线地址的位置的矩形,最后4个参数是确定弧线的开始点和竣事点的坐标。

BOOL  

WINAPI Arc(     
      HDC hdc, //DC的句柄     
      int x1, // 矩形的左坐标     
      int y1, //矩形上坐标     
      int x2,//矩形的右坐标     
      int y2, //矩形的下坐标     
      int x3, //起点x坐标     
      int y3, //起点y坐标     
      int x4, //终点x坐标     
      int y4 //终点y坐标     
);

#p#分页标题#e#

在默认环境下,弧线是逆时针偏向的。

// 绘制弧线     
HPEN pen = CreatePen(PS_SOLID, 2, RGB(200, 100, 20));//建设笔     
// 将笔选到DC中     
auto oldObj = SelectObject(ps.hdc, pen);     
// 画弧线     
Arc(ps.hdc, 20, 100,  300, 300, 39, 110, 280, 285);     
Arc(ps.hdc, 200, 160, 390, 400, 300,350, 380,165);     
// 画完之后,把原先的笔选归去     
SelectObject(ps.hdc, oldObj);     
// 清理     
DeleteObject(pen);

上面代码将画出如下图所示的弧线。

Win32开辟入门(8) 绘图(A)

#p#副标题#e#

默认是逆时针偏向,此刻我想画顺时针偏向的弧线。看下面例子,通过SetArcDirection函数 改变弧线的偏向。

/*    
AD_COUNTERCLOCKWISE暗示逆时针偏向    
AD_CLOCKWISE暗示顺时针偏向    
*/ 
SetArcDirection(ps.hdc, AD_CLOCKWISE);     
Arc(ps.hdc, 20,150, 460,450, 90,162, 85,300);

Win32开辟入门(8) 绘图(A)

下面先容一下LineDDA函数,这个家伙不简朴,为啥?因为I它可以通过回调函数来对一条线 段中差异的点举办别离处理惩罚。其回调函数如下:

VOID CALLBACK LineDDAProc(int x, int y, LPARAM lpData);

最后 一个参数是长指针,我们可以将一个HDC的地点传给它。

因为需要回调函数,我们得先写好回调 函数,可是,在文件的前面要先声明一下,C语言的函数假如在挪用之后界说,就必需先声明,否则编 译的时候找不到。

VOID CALLBACK LineDDAProc(int x, int y, LPARAM lpData)     
{     
    // 从参数中取得HDC     
    HDC hdc = *((HDC*)lpData);     
    // 差异位置的线段配置差异的颜色     
    int type=0;     
    if(x <= 510 || y <= 200)     
    {     
        type = 0;     
    }     
    else if((x > 510 && x <= 700) ||     
        (y > 720 && y <= 360))     
    {     
        type = 1;     
    }     
    else 
    {     
        type = 2;     
    }     
         
    // 按照差异环境着色     
    switch(type)     
    {     
    case 0:     
        SetPixel(hdc,x,y,RGB(0,255,0));     
        break;     
    case 1:     
        SetPixel(hdc,x,y,RGB(0,0,255));     
        break;     
    case 2:     
        SetPixel(hdc,x,y,RGB(255,0,0));     
        break;     
    default:     
        SetPixel(hdc,x,y,RGB(255,0,0));     
    }     
}

#p#副标题#e#

接着在相应WM_PAINT动静的时候挪用LineDDA函数。

LineDDA (420,130,800,470,LineDDAProc, (LPARAM)&ps.hdc);

功效你会看到,画出来的线段是有三 种颜色的。

Win32开辟入门(8) 绘图(A)

完整的代码如下:

#include <Windows.h>     
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);     
         
VOID CALLBACK LineDDAProc(int x, int y, LPARAM lpData);     
         
int WINAPI WinMain(HINSTANCE hTheApp,     
                    HINSTANCE hPrevApp,     
                    LPSTR cmdline,     
                    int nShow)     
{     
    WNDCLASS wc = {   };     
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);     
    wc.hInstance = hTheApp;     
    wc.lpfnWndProc = WindowProc;     
    wc.lpszClassName = L"MyApp";     
    wc.style = CS_HREDRAW | CS_VREDRAW;     
             
    RegisterClass(&wc);     
    HWND hwnd = CreateWindow(L"MyApp",     
        L"我的应用措施",     
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,     
        35,     
        28,     
        600,     
        500,     
        NULL,     
        NULL,     
        hTheApp,     
        NULL);     
    if(hwnd == NULL)     
        return -1;     
    // 动静轮回     
    MSG msg;     
    while(GetMessage(&msg, NULL, 0, 0))     
    {     
        TranslateMessage(&msg);     
        DispatchMessage(&msg);     
    }     
}     
         
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)     
{     
    PAINTSTRUCT ps;     
    switch(msg)     
    {     
    case WM_DESTROY:     
        PostQuitMessage(0);     
        return 0;     
    case WM_PAINT:     
        BeginPaint(hwnd, &ps);     
        TEXTMETRIC tm;     
        // 取得与文内情关的数据     
        GetTextMetrics(ps.hdc, &tm);     
        RECT rect;     
        rect.top = 0L;     
        rect.left = ps.rcPaint.left;     
        rect.right = ps.rcPaint.right;     
        rect.bottom = rect.top + tm.tmHeight;     
        // 第一行文本     
        SetTextColor(ps.hdc, RGB(0,150,255));     
        DrawText(ps.hdc,L"床前明月光", -1, &rect, DT_CENTER);     
        // 第二行文本     
        rect.top += tm.tmHeight;     
        rect.bottom += tm.tmHeight;     
        SetTextColor(ps.hdc, RGB(220, 12, 50));     
        DrawText(ps.hdc, L"疑是地上霜", -1, &rect, DT_LEFT);     
        // 第三行文本     
        rect.top += tm.tmHeight;     
        rect.bottom += tm.tmHeight;     
        SetTextColor(ps.hdc, RGB(30,255,7));     
        DrawText(ps.hdc, L"举头望明月", -1, &rect, DT_RIGHT);     
        // 第四行文本     
        rect.top += tm.tmHeight;     
        rect.bottom += tm.tmHeight;     
        SetTextColor(ps.hdc, RGB(0,40,210));     
        DrawText(ps.hdc, L"垂头思家园", -1, &rect, DT_RIGHT);     
        // 绘制弧线     
        HPEN pen = CreatePen(PS_SOLID, 3, RGB(200, 100, 20));//建设笔     
        // 将笔选到DC中     
        auto oldObj = SelectObject(ps.hdc, pen);     
        // 画弧线     
        /*Arc(ps.hdc, 20, 100,  300, 300, 39, 110, 280, 285);    
        Arc(ps.hdc, 200, 160, 390, 400, 300,350, 380,165);*/ 
         
        /*    
        AD_COUNTERCLOCKWISE暗示逆时针偏向    
        AD_CLOCKWISE暗示顺时针偏向    
        */ 
        SetArcDirection(ps.hdc, AD_CLOCKWISE);     
        Arc(ps.hdc, 20,150, 300,450, 90,162, 85,300);     
        // 画完之后,把原先的笔选归去     
        SelectObject(ps.hdc, oldObj);     
        // 清理     
        DeleteObject(pen);     
        // 分段线条     
        LineDDA(420,130,800,470,LineDDAProc, (LPARAM)&ps.hdc);     
        EndPaint(hwnd, &ps);     
        return 0;     
    }     
    return DefWindowProc(hwnd, msg, wParam, lParam);     
}     
         
VOID CALLBACK LineDDAProc(int x, int y, LPARAM lpData)     
{     
    // 从参数中取得HDC     
    HDC hdc = *((HDC*)lpData);     
    // 差异位置的线段配置差异的颜色     
    int type=0;     
    if(x <= 510 || y <= 200)     
    {     
        type = 0;     
    }     
    else if((x > 510 && x <= 700) ||     
        (y > 720 && y <= 360))     
    {     
        type = 1;     
    }     
    else 
    {     
        type = 2;     
    }     
         
    // 按照差异环境着色     
    switch(type)     
    {     
    case 0:     
        SetPixel(hdc,x,y,RGB(0,255,0));     
        break;     
    case 1:     
        SetPixel(hdc,x,y,RGB(0,0,255));     
        break;     
    case 2:     
        SetPixel(hdc,x,y,RGB(255,0,0));     
        break;     
    default:     
        SetPixel(hdc,x,y,RGB(255,0,0));     
    }     
}

    关键字:

在线提交作业