win32 API编程之GDI绘图

一、GDI简介

1)什么是设备上下文

win32 API编程之GDI绘图

2)设备上下文类型

win32 API编程之GDI绘图

3)常见的GDI对象

win32 API编程之GDI绘图

4)windows坐标系

win32 API编程之GDI绘图

5)GDI绘图步骤

win32 API编程之GDI绘图

二、获取DC的3种方法

1)获取DC的3种方法

win32 API编程之GDI绘图

2)PAINTSTRUCT结构

win32 API编程之GDI绘图

3)BeginPaint函数

win32 API编程之GDI绘图

4)EndPaint函数

win32 API编程之GDI绘图

5)GetDC函数

win32 API编程之GDI绘图

6)GetWindowDC函数

win32 API编程之GDI绘图

7)三种方式的区别

win32 API编程之GDI绘图

8)代码实例

#include<windows.h> 


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);//可以使GetMessage返回0    
        return 0;

    case WM_PAINT:
    { 
        //1.使用BeginPaint,它能将无效区域变成有效(如果存在无效区域,系统会一直发送WM_PAINT)
        /*PAINTSTRUCT  ps;
        HDC  hdc = BeginPaint(hWnd, &ps);
        TextOut(hdc, 0, 0, L"你好啊!", lstrlen(L"你好啊!"));
        EndPaint(hWnd, &ps);*/

        //2.使用GetDC获取客户区DC,它并不能将无效区域变成有效,所以WM_PAINT一直发送,文字一直闪烁
        /*
        HDC  hdc = GetDC(hWnd);
        TextOut(hdc, 0, 0, L"你好啊!", lstrlen(L"你好啊!"));
        ReleaseDC(hWnd, hdc);
        //return 0; //去掉之后交给默认DefWindowProc处理WM_PAINT消息,会调用BeginPaint,EndPaint
        */ 

    }
    break;

    case WM_NCPAINT:
    {
        //3.获取整个窗口的DC,包括标题栏,工具条等
        HDC  hdc = GetWindowDC(hWnd);
        RECT  r = {0,0,400,20};
        HBRUSH  brh = CreateSolidBrush(RGB(255, 0, 0));
        FillRect(hdc, &r, brh);
        DeleteObject(brh);
        ReleaseDC(hWnd, hdc);//释放掉DC
        return  true;


    }break;

    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
    LPSTR lpCmdLine, int  nShowCmd)
{

    //1.注册窗口类
    WNDCLASS  wnd;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
    wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
    wnd.lpszClassName = L"MrHuang";//窗口类名
    wnd.lpszMenuName = NULL;//菜单资源名称
    wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
    wnd.hInstance = hInstance;//实例句柄
    RegisterClass(&wnd);

    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
        WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd);

    //消息循环(收到WM_QUIT消息退出)
    MSG  msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);//翻译消息
        DispatchMessage(&msg);//分发消息到窗口过程
    }
}

三、绘图函数

1)创建画笔

win32 API编程之GDI绘图

win32 API编程之GDI绘图

2)选择一个对象到数据上下文

win32 API编程之GDI绘图

3)画直线

win32 API编程之GDI绘图                                              win32 API编程之GDI绘图

4)画矩形

win32 API编程之GDI绘图

5)创建画刷

win32 API编程之GDI绘图

6)DeleteObject函数

win32 API编程之GDI绘图

7)GetStockObject函数

win32 API编程之GDI绘图

win32 API编程之GDI绘图

8)画椭圆

win32 API编程之GDI绘图

9)画饼图

win32 API编程之GDI绘图

10)写入字符串

win32 API编程之GDI绘图

11)SetBkColor函数

win32 API编程之GDI绘图

12)SetBkMode函数

win32 API编程之GDI绘图

13)DrawText函数

win32 API编程之GDI绘图

win32 API编程之GDI绘图

14)SetTextAlign函数

win32 API编程之GDI绘图

win32 API编程之GDI绘图

15)代码实例

①绘制直线、矩形、椭圆、饼图

#include<windows.h> 


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);//可以使GetMessage返回0    
        return 0;

    case WM_PAINT: 
    {
        PAINTSTRUCT ps;
        //获取设备上下文句柄
        HDC   hdc = BeginPaint(hWnd, &ps);
 
        //创建画笔
        HPEN  hPen = CreatePen(PS_DASHDOT, 1, RGB(255, 0, 0));
        //将笔选入到设备上下文(使用这支笔)
        SelectObject(hdc, hPen);

        //1.画直线(两个点)
        MoveToEx(hdc, 100, 100, NULL);
        LineTo(hdc, 200, 100);

        //创建画刷
        HBRUSH hBsh = CreateSolidBrush(RGB(0, 255, 0));
        //将画刷选入到设备上下文(使用这支画刷)
        SelectObject(hdc, hBsh);
         
        //2.画矩形(正方形)
        Rectangle(hdc, 200, 200, 400, 400);


        //获取透明画刷
        HGDIOBJ hBsh2  =GetStockObject(NULL_BRUSH);
        SelectObject(hdc, hBsh2);
        Rectangle(hdc,  100, 100, 200, 150);

        //3.画椭圆(圆形)
        Ellipse(hdc, 200, 200, 400, 400);
        Ellipse(hdc, 100, 100, 200, 150);


        //4.画饼图 
/*            
        //饼图产生的步骤分解
        Ellipse(hdc, 500, 100, 800, 400); 
         //从圆心到第一个点的连线
         MoveToEx(hdc, 650, 250, NULL);
         LineTo(hdc,1000, 300);  
         //从圆心到第二个点的连线
         MoveToEx(hdc, 650, 250, NULL);
         LineTo(hdc, 400, 400);
 */        
         Pie(hdc, 500, 100, 800, 400, 1000, 300,400, 400);


        //删除GDI对象
        DeleteObject(hPen);
        DeleteObject(hBsh);

        EndPaint(hWnd, &ps);
    }
    break;

    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
    LPSTR lpCmdLine, int  nShowCmd)
{

    //1.注册窗口类
    WNDCLASS  wnd;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
    wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
    wnd.lpszClassName = L"MrHuang";//窗口类名
    wnd.lpszMenuName = NULL;//菜单资源名称
    wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
    wnd.hInstance = hInstance;//实例句柄
    RegisterClass(&wnd);

    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
        WS_OVERLAPPEDWINDOW, 100, 100, 1000, 700, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd);

    //消息循环(收到WM_QUIT消息退出)
    MSG  msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);//翻译消息
        DispatchMessage(&msg);//分发消息到窗口过程
    }
}

②写入字符串

#include<windows.h> 


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);//可以使GetMessage返回0    
        return 0;

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        //获取设备上下文句柄
        HDC   hdc = BeginPaint(hWnd, &ps);

        //改变文本的背景色
        SetBkColor(hdc, RGB(255, 0, 0));
        //设置文本背景模式 
        SetBkMode(hdc, TRANSPARENT);//透明

        //设置文本的颜色
        SetTextColor(hdc, RGB(255, 0, 0));


        //设置文本的参考点
        SetTextAlign(hdc, TA_TOP);

        //1.界面上画文本
        TextOut(hdc,250, 200, L"你好啊,这是画的文本!", lstrlen(L"你好啊,这是画的文本!"));

        //2.在矩形范围中画文本
        RECT  r = {250,400,300,500};
        Rectangle(hdc, r.left, r.top, r.right, r.bottom);
        DrawText(hdc, L"你好啊,这是画的文本!", lstrlen(L"你好啊,这是画的文本!")
            , &r,  DT_BOTTOM|DT_SINGLELINE);




        EndPaint(hWnd, &ps);
    }
    break;

    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
    LPSTR lpCmdLine, int  nShowCmd)
{

    //1.注册窗口类
    WNDCLASS  wnd;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
    wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
    wnd.lpszClassName = L"MrHuang";//窗口类名
    wnd.lpszMenuName = NULL;//菜单资源名称
    wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
    wnd.hInstance = hInstance;//实例句柄
    RegisterClass(&wnd);

    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
        WS_OVERLAPPEDWINDOW, 100, 100, 1000, 700, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd);

    //消息循环(收到WM_QUIT消息退出)
    MSG  msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);//翻译消息
        DispatchMessage(&msg);//分发消息到窗口过程
    }
}

四、双缓冲绘制技术

1)什么是双缓冲绘制技术

win32 API编程之GDI绘图

2)步骤

win32 API编程之GDI绘图

3)CreateCompatiableDC函数

win32 API编程之GDI绘图

4)CreateCompatiableBitmap函数

win32 API编程之GDI绘图

5)BitBlt函数

win32 API编程之GDI绘图

win32 API编程之GDI绘图

6)StretchBlt函数

win32 API编程之GDI绘图

7)代码实例

#include<windows.h>
#include<CommCtrl.h> 


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);//可以使GetMessage返回0    
        return 0;

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC   hdc = BeginPaint(hWnd, &ps);
 
         //1.创建兼容内存DC,此时它的大小时1X1,很小,不能绘制
        HDC  hMemDC=CreateCompatibleDC(hdc);

        //2.创建兼容位图,提供绘画区域
        HBITMAP hMemBmp = CreateCompatibleBitmap(hdc, 100, 100);

        //3.把兼容位图选到兼容内存DC中,此刻DC的大小与位图一致,可以绘制
        SelectObject(hMemDC, hMemBmp);

        //4.在兼容内存DC上进行绘图操作
        SetTextColor(hMemDC, RGB(255, 0, 0));
        TextOut(hMemDC, 0, 0, L"双缓冲技术绘制!", lstrlen(L"双缓冲技术绘制!")); 
        Rectangle(hMemDC, 30, 30, 80, 80);

        //5.把内存DC中的图像一次性画到窗口DC上
         //不拉伸
         BitBlt(hdc, 0, 0, 100, 100, hMemDC, 0, 0, SRCCOPY);
        
         //拉伸(目标矩形大于源矩形)
         StretchBlt(hdc, 0, 0, 400, 400, hMemDC, 0, 0,100,100, SRCCOPY);
         //压缩(目标矩形小于源矩形)
         StretchBlt(hdc, 0, 0, 50, 50, hMemDC, 0, 0, 100, 100, SRCCOPY);


         //释放资源
         DeleteDC(hMemDC);
         DeleteObject(hMemBmp);


        EndPaint(hWnd, &ps);
    }
    break;

    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
    LPSTR lpCmdLine, int  nShowCmd)
{

    //1.注册窗口类
    WNDCLASS  wnd;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
    wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
    wnd.lpszClassName = L"MrHuang";//窗口类名
    wnd.lpszMenuName = NULL;//菜单资源名称
    wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
    wnd.hInstance = hInstance;//实例句柄
    RegisterClass(&wnd);

    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
        WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd);

    //消息循环(收到WM_QUIT消息退出)
    MSG  msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);//翻译消息
        DispatchMessage(&msg);//分发消息到窗口过程
    }
}

五、绘制位图

1)什么是位图

win32 API编程之GDI绘图

2)位图绘制的步骤

win32 API编程之GDI绘图

3)LoadImage函数

win32 API编程之GDI绘图

win32 API编程之GDI绘图

4)SetStrechBltMode函数

win32 API编程之GDI绘图

win32 API编程之GDI绘图

5)代码实例

#include<windows.h>
#include<CommCtrl.h> 


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
    WPARAM wParam, LPARAM lParam)
{
    switch (Msg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);//可以使GetMessage返回0    
        return 0;

    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        HDC   hdc = BeginPaint(hWnd, &ps);

        //1.创建内存兼容DC(1px  X  1px)
        HDC  hMemDC = CreateCompatibleDC(hdc);

        //2.加载位图资源
        HBITMAP hBmp= (HBITMAP)LoadImage(NULL, L"bg.bmp", IMAGE_BITMAP, 800, 800, LR_LOADFROMFILE);

        //3.把位图选入到兼容内存DC
        SelectObject(hMemDC, hBmp);

        //添加水印
        TextOut(hMemDC, 100, 100, L"乱涂乱画", lstrlen(L"乱涂乱画"));
         
        //设置图像拉伸模式
        //SetStretchBltMode(hdc, COLORONCOLOR);//删除多余像素
        SetStretchBltMode(hdc, HALFTONE); 

        //4.将兼容DC中的图像一次性拷贝到窗口DC上
         //BitBlt(hdc, 0, 0, 800, 800, hMemDC, 0, 0, SRCCOPY);
        //完整显示
         StretchBlt(hdc, 0, 0, 400, 400, hMemDC, 0, 0, 800,800,SRCCOPY);

        //5.释放DC与位图资源
        DeleteObject(hBmp);
        DeleteDC(hMemDC);
      
        EndPaint(hWnd, &ps);
    }
    break;

    }

    return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
    LPSTR lpCmdLine, int  nShowCmd)
{

    //1.注册窗口类
    WNDCLASS  wnd;
    wnd.cbClsExtra = 0;
    wnd.cbWndExtra = 0;
    wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
    wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
    wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
                                                //wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
    wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
    wnd.lpszClassName = L"MrHuang";//窗口类名
    wnd.lpszMenuName = NULL;//菜单资源名称
    wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
    wnd.hInstance = hInstance;//实例句柄
    RegisterClass(&wnd);

    //创建窗口(返回之前发送WM_CREATE)
    HWND    hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
        WS_OVERLAPPEDWINDOW, 100, 100, 400, 400, NULL, NULL, hInstance, NULL);

    //显示窗口
    ShowWindow(hWnd, nShowCmd);
    //更新窗口(发送WM_PAINT)
    UpdateWindow(hWnd);

    //消息循环(收到WM_QUIT消息退出)
    MSG  msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);//翻译消息
        DispatchMessage(&msg);//分发消息到窗口过程
    }
}

 

上一篇:记一次.Net Core通过GDI+在CentOS 7(Docker)环境中绘图报错The type initializer for 'Gdip' threw an excepti


下一篇:cassandra表中主键的类型