zoukankan      html  css  js  c++  java
  • Windows程序设计3(资源、绘图、坐标系)

    一、RC资源的使用

    • 资源相关

    资源脚本文件:*.rc文件

    编译器:RC.EXE

    • 菜单资源的使用

    1 添加菜单资源:通过菜单栏中插入(rc)菜单资源。或直接添加资源脚本到工程中。

    2 加载菜单资源

    2.1 在注册时设置菜单资源

    2.2 加载菜单资源,设置到窗口

    HMENU LoadMenu(

    HINSTANCE hInstance,  //应用程序句柄

    LPCTSTR lpMenuName  //菜单字符串资源(或菜单资源ID

    );

    MAKEINTRESOURCE宏,可以使得数字形式的资源ID,转化为字符串形式的资源ID。

    宏原型:

    LPTSTR  MAKEINTRESOURCE(

      WORD   wInteger  // 转化的整数

    );

    使用地方:

    1. CreateWindow/Ex 创建窗口时。

    如:wndclass.lpszMenuName =MAKEINTRESOURCE(IDR_MENU1);

    2.  在WM_CREATE时,通过SetMenu():

    函数原型:BOOL  SetMenu(

      HWND hWnd,  // 窗口句柄

      HMENU hMenu // 菜单句柄,可以通过LoadMenu()获得。

    );

    如:

    HMENU hMenu=LoadMenu(g_hInstance,MAKEINTRESOURCE(IDR_MENU1));

    SetMenu( hWnd , hMenu );

    获取子菜单: GetSubMenu() ;

    HMENU   GetSubMenu(

        HMENU   hMenu,  // 窗口句柄

       int   nPos      // 菜单位置,索引

    );

    二、ICO图标资源

    一个图标文件是由多个不同大小的图像组成的复合文件。(注意图标的大小)

    1 添加资源:通过新建资源文件,并在菜单栏中插入(icon)图标资源。

    2 加载

    HICON   LoadIcon(

      HINSTANCE   hInstance, // 应用程序句柄

      LPCTSTR    lpIconName   // 字符串或资源ID

    ); 成功,返回HICON句柄,hInstanceNULL,则加载需为标准的系统自带图标。

    如:wndclass.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_WINICON));

    wndclass.hIconSm=NULL;//注意此处小图标若为NULL,这样是自动加载小图标的,否则大小图标都变成了大图标了。

    3 设置

    3.1 注册窗口类时设置。

    3.2  WM_SETICON消息中设置。

    SendMessage(hWnd,WM_SETICON,wParam,lParam);

    如:

    //大图标

    SendMessage(hWnd,WM_SETICON,ICON_BIG,(LPARAM)hIcon);

    //小图标

    SendMessage(hWnd,WM_SETICON,ICON_SMALL,(LPARAM)hIcon);

      参数:

    wParam  -图标的类型,ICON_BIG/ICON_SMALL

    lParam   -图标句柄

    4 绘制图标  :DrawIcon

    BOOL   DrawIcon(

      HDC   hDC,      //设备上下文句柄

      int   X,        // 左上角坐标x

      int   Y,        // 左上角坐标y

      HICON hIcon   // 将绘制的图标句柄,可通过LoadIcon or LoadImage 获取。

    );//成功返回TRUE,失败返回FALSE

    BOOL DrawIconEx(

      HDC  hdc,                    // 设备上下文句柄

      int  xLeft,                  //左上角坐标x

      int  yTop,                   //左上角坐标y

      HICON  hIcon,                // 图标句柄

      int  cxWidth,                // 图标宽度

      int  cyWidth,                // 图标高度

      UINT  istepIfAniCur,         // 动画图标的帧数,不支持,置0.

      HBRUSH  hbrFlickerFreeDraw,  // 系统绘制,置NULL.

      UINT  diFlags                // 绘制标识

    );

    diFlagsDI_NORMAL   正常绘制(DI_IMAGE and DI_MASK的组合或运算)

      DI_IMAGE      图像部分

      DI_MASK       掩码部分

    三、CURSOR光标资源

    1  添加光标的资源

    同添加图标资源,光标的大小默认是32X32像素,每个光标有HotSpot,是当前鼠标的热点

    2  使用资源

    HCURSOR   LoadCursor(

         HINSTANCE  hInstance,  // 应用程序实例句柄

          LPCTSTR   lpCursorName  //光标资源ID

    );  //成功,返回光标句柄,失败返回NULL

    hInstance - 可以为NULL,获取系统默认的Cursor

    2.1 在注册窗口时,设置光标:(根据此窗口类创建的所有窗口都是使用此光标)

    如:

    wndclass.hCursor=LoadCursor(hInstance,MAKEINTRESOURCE(IDC_CIRCLE));

    2.2 使用SetCursor设置光标,

    HCURSOR   SetCursor(

       HCURSOR hCursor   // handle to cursor

    );

    3  WM_SETCURSOR 动态设置光标通过SetCursor()(有鼠标动作且鼠标未捕获时受到此消息)

    消息参数

    WPARAM  -  当前使用的光标句柄

    LPARAM    - LOWORD 当前区域的代码(Hit-Test code )

              HIWORD - 当前鼠标消息ID

    HCURSOR  SetCursor(

    HCURSOR  hCursor  ///光标句柄

    );//返回原光标句柄。

    4   (**.cur)文件加载光标

    HCURSOR   LoadCursorFromFile(

    LPCTSTR   lpFileName;   //文件指针或系统光标ID

    );

    如:hcurs=LoadCursorFromFile("G:/5000ICO图标文件/生活用品/sword.ani");hcurs=LoadCursorFromFile("G:\5000ICO图标文件\生活用品\sword.ani");

    四、字符串资源

    1.添加字符串表资源,在表中添加字符串

    2.加载字符串资源

    int   LoadString(

    HINSTANCE   hInstance,     // 应用程序实例句柄

    UINT   uID,               //字符串ID

    LPTSTR  lpBuffer,  //存放字符串缓冲区(BUFF)

    Int   nBufferMax // 字符串缓冲区(BUFF)长度(以字符为单位,含空字符)

    ); 成功返回字符串长度,失败返回0.

    五、字符串资源

    1  添加    添加加速键表,增加命令ID对应的加速键。

    2  使用

        2.1 加载加速键

        HACCEL  LoadAccelerators(

        HINSTANCE   hInstance,  // 模块、实例句柄

        LPCTSTR    lpTableName   // 加速键表名

         ); 成功,则返回加速键句柄,失败则返回NULL

        2.2 处理(翻译)加速键消息

        int  TranslateAccelerator(

        HWND   hWnd,       //处理消息的窗口句柄

        HACCEL   hAccTable,  //加速键句柄

        LPMSG   lpMsg       //消息

         ); 如果是加速键,返回非零。

         2.3 WM_COMMAND中响应消息,消息参数

          WPARAM - HIWORD 1表示加速键,为0表示菜单

                     LWORD  为命令ID

    处理加速键消息过程:

    TranslateAccelerator(HWND  hWnd,HACCEL   hAccTable ,LPMSG  lpMsg)

    {

    if(lpMsg->message==WM_KEYDOWN||lpMsg->message==WM_SYSKEYDOWN)

    {

    lpMsg提取按键消息;

    if(hAccTable加速键表中存在与所按键相对应的命令ID)

    {

    PostMessage(hWnd,WM_COMMAND,MAKELONG(命令ID1)NULL)

    return 1;

    }

    }

    }

    用在:

    MSG   msg={0};

    while(GetMessage(&msg,NULL,0,0))

    {

    if(!TranslateAccelerator(msg.hwnd,  AccTable   ,&msg))

    {

    TranslateMessage(&msg);

    DispatchMessage(&msg);

    }

    }

    /////最好让加速键的ID和相应菜单ID对应。另外快捷键也可以不与菜单对应,一样的做其他功能。

    六、版本资源

    通过添加VERSION资源。修改其中内容。

    七、Windows 绘图

      1. 设备上下文(Device  ContextDC)

    HDC -  DC句柄,表示绘图设备,对绘图设备的抽象。

    GDI - Windows graphics device interface   Win32提供的绘图API.

    Case WM_PAINT:

    ……….

    HDC  hdc=BeginPaint(hWnd,  &ps);//与窗口相关联

    Case WM_PRINT:

    …………

    HDC   hdc=BeginPaint(hPrinter,   &ps);//与打印机相关联的,

    2. 图形设备接口(Graphics Device InterfaceGDI)

    Win32的绘图API,封装在gdi32.dll中,通过该接口给设备上下文下达绘制命令。它是一个在Windows应用程序中执行与设备无关的函数库,这些函数在不同的输出设备上产生图形以及文字输出。

    3. 颜色空间的使用

         1.RGB  :电脑显示器,每一个点颜色是3个字节24位保存 0-2^24

    R - 0255

    G - 0255

    B - 0255

        2.CMYK  浅青(--),洋红(绿),黄(),黑。(作减法)打印机上。

    颜色深度:位/像素

    1/像素    2种颜色(黑,白)

    4/像素    16种颜色

    8/像素    256种颜色,调色板

    16/像素    R5G5B6,增强色,( R5G5B6表示红色5位绿色5,6)

    24/像素    R8G8B8,真彩色

    32位/像素    A8R8G8B8增加透明度(A8)

       颜色处理和使用

    COLORREF - 实际为DWORD类型,OxAABBGGRR.

    例如:

    Ox00000000   黑色

    Ox000000FF   纯红

    Ox0000FF00   纯绿

    Ox00FF0000   纯蓝

    Ox00FFFF00   浅青

    使用16进制挺麻烦,常使用颜色宏

    颜色的组合宏:

    RGB(r,g,b); // R/G/B  0~255

    COLORREF nColor = 0;

    赋值使用RGB宏,例如:

    nColor = RGB( 255, 0, 0 );

    获取RGB分解值,

    GetRValue/GetGValue/GetBValue

    例如:

    BYTE  nRed = GetRValue( nColor );

    BYTE   ----无符号8位整型

    4. 点的使用

    GetPixel 获取指定坐标像素点的颜色

    COLORREF  GetPixel(

    HDC  hdc,    // handle to DC

    int  nXPos,  // x-coordinate of pixel

    int  nYPos   // y-coordinate of pixel

    );

    SetPixel 设置指定坐标像素点的颜色

    COLORREF  SetPixel(

    HDC  hdc,//DC句柄

    int  X,//X坐标

    int  Y,//Y坐标

    COLORREF  crColor //设置的颜色

    ); 返回点原来的颜色

    5. 直线的使用(直线、圆形、弧线)

    当前点:上一次绘图时的最后一点,初始为(00)点。

    1.从当前点移动到目标点,并使目标点成为新的当前点。

    (MoveTo扩展为MoveToEx(),)  

    BOOL  MoveToEx(

    HDC  hdc,    //设备上下文

    Int  x, //新的坐标位置

    Int  y,

    LPPOINT  lpPoint   //当前位置

    );

    2.从当前点到指定点绘制一条直线.

    BOOL  LineTo(

      HDC  hdc,    //设备上下文 

      int  nXEnd,  //  终点坐标位置

    int  nYEnd //

    );

    3.绘制(椭)圆弧

    (绘制圆弧,只要控制好外切矩形使得为正方形即可,与画圆同样方式)

    BOOL     Arc(

      HDC  hdc,      // 设备上下文

      int  nLeftRect,   // 外切矩形左上角

      int  nTopRect,   //

      int  nRightRect,  //外切矩形右下角

    int  nBottomRect, //  

    int  nXStartArc,  //起点坐标

      int  nYStartArc,  //

      int  nXEndArc,   // 终点坐标

      int  nYEndArc    //

    );

    设置截弧方向:

    Int   SetArcDirection(

      HDC   hdc,         //设备上下文

      int   ArcDirection   // 指定截弧方向

    );//成功返回原截弧方向,失败返回0

    /// ArcDirection截弧方向:(默认为逆时针)

    AD_COUNTERCLOCKWISE(逆时针)AD_CLOCKWISE(顺时针)

    4.绘制封闭图形

    1.封闭图形:可被画刷填充的图形,由直线弧线围起的不是封闭图形。

    2.矩形:

    BOOL   Rectangle(

      HDC   hdc,         // 设备上下文

      int     nLeftRect,   // 矩形左上角

      int    nTopRect,    //

      int    nRightRect,  // 矩形右下角

      int    nBottomRect  //

    );

    3.椭圆

    BOOL    Ellipse(

    HDC hdc,        // 设备上下文

    int nLeftRect,  //外切矩形左上角

    int nTopRect,   //

    int nRightRect, //外切矩形右下角

    int nBottomRect //

    );

    4.圆角矩形

    BOOL   RoundRect(

      HDC   hdc,         //设备上下文

      int   nLeftRect,   // 左上角坐标

      int   nTopRect,    //

      int   nRightRect,  // 右下角坐标

      int   nBottomRect, //

      int   nWidth,      // 圆角椭圆的两个轴(分布于四个角上)

      int   nHeight      //

    );

    6.画笔的作用

    线的颜色、线型、线粗。

    HPEN - 画笔句柄

    1 创建画笔

    HPEN   CreatePen(

    Int  fnPenStyle, //画笔的样式

    int   nWidth, //画笔的粗细

    COLORREF   crColor //画笔的颜色

    );创建成功返回句柄,失败返回NULL

    fnPenStyle样式,

    PS_SOILD - 实心线,可以支持多个像素宽,其他线型只能是一个像素宽。

    PS_DASH   虚线

    PS_DOT   点线

    PS_DASHDOT- --点划线

    PS_DASHDOTDOT----双点划线

    PS_NULL    不可见的线

    nWidth 线宽进对PS_SOLID实线起作用。若nWidth>1,则无论fnPenStyle,去何值画出来的都是实线的了。

    2 将画笔应用到设备上下文中,同时得到设备上下文中原画笔

    HGDIOBJ   SelectObject(

    HDC    hdc,//绘图设备句柄

    HGDIOBJ   hgdiobj //GDI绘图对象句柄,画笔句柄

    );返回原来的GDI绘图对象句柄

    //注意保存原来DC当中画笔。用以恢复原画笔。

    3 绘图

    4 恢复原画笔(取出DC中的画笔)

    将原来的画笔,使用SelectObject函数,放入到设备DC中,就会将我们创建的画笔取出。SelectObject(hDc, hpenOld);//恢复原画笔

    5 释放(删除)画笔

    BOOL   DeleteObject(

    HGDIOBJ   hObject   //GDI绘图对象句柄,画笔句柄

    );//成功返回TRUE,失败返回FALSE

    过程:建立->载入->画图->取出->删除

    : HGDIOBJ  hpenOld=SelectObject(hDc, CreatePen(….));

    ……

    DeleteObject( SelectObject( hDc, hpenOld);

    //注意:永远不要删除设备上下文正在持有的GDI对象。

    //只能删除不被DC使用的画笔,所以在释放前,必须将画笔从DC中取出。

    7 画刷的使用

    画刷 - 封闭图形的填充的颜色、图案

    HBRUSH - 画刷句柄

    画刷的使用

    1 创建画刷

    CreateSolidBrush - 创建实心画刷

    HBRUSH CreateSolidBrush(

           COLORREF crColor   //画刷颜色值

    );//成功返回画刷句柄,失败返回NULL

    CreateHatchBrush - 创建填充画刷

    HBRUSH CreateHatchBrush(

        int   fnStyle,      // 阴影线风格

        COLORREF   clrref   // 阴影线颜色

    );//成功返回填充画刷,失败返回NULL

    fnStyle风格:

    HS_BDIAGONAL

    45-degree downward left-to-right hatch

    HS_CROSS

    Horizontal and vertical crosshatch

    HS_DIAGCROSS

    45-degree crosshatch

    HS_FDIAGONAL

    45-degree upward left-to-right hatch

    HS_HORIZONTAL

    Horizontal hatch

    HS_VERTICAL

    Vertical hatch

     

    2 将画刷应用到DC中

    SelectObject

    3 绘图

    4 将画刷从DC中取出

    SelectObject

    5 删除画刷

    DeleteObject

    纹理画刷:

    创建:

    HBRUSH   CreatePatternBrush(

          HBITMAP   hbmp   //位图句柄

    );//成返回画刷句柄,失败返回NULL

    其他:

    可以使用 GetStockObject 函数获取系统维护的画刷、画笔等。

    如果不使用画刷填充,需要使用NULL_BRUSH参数,获取不填充的画刷。

    GetStockObject返回的画刷不需要DeleteObject。

    9.位图的使用

    计算机图像分为:

    光栅图形 - 记录图像中每一像素点的颜色和透明度等信息。

    矢量图形 - 记录图像渲染算法、绘图指令,几何坐标等。

    Windows中的位图是一种光栅图像。

    HBITMAP - 位图句柄

    位图使用:

    1) 在资源中添加位图

    2) 从资源中加载位图

    HBITMAP LoadBitmap(

       HINSTANCE   hInstance,  //应用程序句柄

       LPCTSTR   lpBitmapName  //位图资源名

    );//成功返回位图句柄,失败返回NULL

    3) 创建与窗口设备上下文匹配的内存设备上下文

    HDC CreateCompatibleDC(

       HDC hdc   // 匹配的源设备上下文句柄

    );//成功返回内存设备上下文句柄,失败返回NULL

    4) 将位图选入内存设备上下文

    HGDIOBJ hbmpOld=SelectObject(hdcMem, hbmpNew);

    5) 将内存设备上下文中的位图成像到目标设备上下文中

    BOOL BitBlt(

      HDC hdcDest, // 目标设备上下文句柄

      int nXDest,  //目标图像左上角坐标 

      int nYDest,  //

    int nWidth,  //目标图像的宽度和高度

    int nHeight, //

      HDC hdcSrc,  // 源设备上下文句柄

      int nXSrc,   // 源图像左上角坐标

      int nYSrc,   //

    DWORD dwRop  //光栅操作码(ROP),源像素与目标像素的位运算

    );

    缩放成像:

    BOOL  StretchBlt  (

      HDC hdcDest, // 目标设备上下文句柄

      int nXDest,  //目标图像左上角坐标 

      int nYDest,  //

    int nWidth,  //目标图像的宽度和高度

    int nHeight, //

      HDC hdcSrc,  // 源设备上下文句柄

      int nXSrc,   // 源图像左上角坐标

      int nYSrc,   //

    DWORD dwRop  //光栅操作码(ROP),源像素与目标像素的位运算

    );

    6) 恢复内存设备上下文的原位图

    SelectObject(hdcMem, hbmpOld);

    7) 删除新位图

    DeleteDC(hbmpNew);

    8) 释放内存设备上下文

    DeleteDC(hdcMem);

    //获取位图的信息:

    GetObject(…,…);//可获取位图相关信息

    八、坐标系

    1. 坐标系分类:

    设备坐标系

    以像素为单位,即一个单位就是一个像素,以设备左上角为原点,X轴向右为正,Y轴向下为正的坐标系。(像素大小与成像设备有关,成像设备分辨率越高,像素点越多)

    1 屏幕坐标系 - 以当前屏幕左上角为原点坐标系。

    2 窗口坐标系 - 以窗口左上角为原点坐标系。

    3 客户区坐标系 - 以窗口的客户区左上角为原点的坐标系。

    逻辑坐标系

    GDI绘图中,都是使用逻辑坐标绘图,坐标单位、坐标原点、坐标轴的方向都可以设置。

    默认情况下,逻辑坐标系与设备坐标系重合。1逻辑=1设备,显示器:1设备=1像素,打印机:1设备=1/1440英寸(0.018毫米)

    2. 坐标系映射:

    1)映射模式

    A.确定了逻辑坐标系与设备坐标系之间的映射关系。

    B.设备做你奥西的单位不能通过代码修改但是逻辑坐标系可修改。

    Int  SetMapMode(

    HDC    hdc,    ///DC句柄

    Int fnMapMode///映射模式

    );//返回原先的映射模式

    fnMapMode 映射模式如下:

    MM_TEXT-默认(正文)模式,1逻辑单位对应1设备单位(显示器为像素),X右为正,Y下为正。

    MM_LOENGLISH-低英制模式,1逻辑单位 = 0.01英寸,X右为正,Y上为正。

    MM_HIENGLISH-高英制单位,1逻辑单位=0.001英寸,X右为正,Y上为正。

    MM_LOMETRIC-低公制单位,1逻辑单位=0.1毫米,X右为正,Y上为正。

    MM_HIMETRIC-高公制模式,1个逻辑单位=0.01毫米,X右为正,Y上为正。

    MM_TWIPS-打印机模式,1个逻辑单位=1/1440英寸,打印机使用单位。

    MM_ISOTROPIC-各向同性模式,1逻辑单位=自定义,X和Y正方向、原点可自定义,逻辑单位与设备单位的比例在水平和垂直方向上取一致。

    MM_ANISOTROPIC-各向异性模式,1逻辑单位=自定义,X和Y正方向,原点可自定义,逻辑单位与设备单位的比例在水平和垂直方向上可不一致。

    X的1个逻辑单位 = 自定义1

    Y的1个逻辑单位 = 自定义2

    2)设置逻辑单位与设备单位的比例(MM_ISOTROPIC/MM_ANISOTROPIC)

    设置逻辑:

    BOOL   SetViewportExtEx(

    HDC   hdc,//设备上下文句柄

    int   nXExtent,///设备单位X尺度

    int   nYExtent,////设备单位Y尺度

    LPSIZE  lpSize///设备单位元尺度旧比例,可为NULL

    );//成功返回TRUE,失败返回FALSE。

    设置设备:

    BOOL   SetWindowExtEx(

    HDC   hdc,//设备上下文句柄

    int   nXExtent,///逻辑单位X尺度

    int   nYExtent,////逻辑单位Y尺度

    LPSIZE  lpSize///逻辑单位元尺度旧比例,可为NULL

    );//成功返回TRUE,失败返回FALSE。

    SetViewportExtEx(hdc,1,1,NULL);

    SetWindowExtEx(hdc,2,3,NULL);

    即:X方向:1逻辑=2设备

    Y方向:1逻辑=3设备

    也等价于(只要成比例):

    SetViewportExtEx(hdc,1000,1000,NULL);

    SetWindowExtEx(hdc,2000,3000,NULL);

    另外:若设置有负值,意味自身轴方向改变了,但还是成比例。

    SetViewportExtEx(hdc,-1,1,NULL);

    SetWindowExtEx(hdc,2,-3,NULL);

     

    设置逻辑坐标原点位置:

    SetViewportOrgEx(hdc,0,32,NULL);//逻辑原点位置(0,32)。

    设置窗口(设备)坐标显示原点位置:

    SetWindowOrgEx(hdc,0,32,NULL);//设备原点位置(0,32)(仍是左上角位置)。

  • 相关阅读:
    [ZJOI2007]仓库建设(斜率dp优化)
    [HNOI2008]玩具装箱toy(斜率优化dp)
    2019牛客暑期多校训练营(第十场)F-Popping Balloons
    2019牛客暑期多校训练营(第十场)B-Coffee Chicken
    子集的生成—二进制枚举
    2019牛客暑期多校训练营(第九场)D-Knapsack Cryptosystem(思维+子集和)
    2019牛客暑期多校训练营(第九场) E-All men are brothers(并查集+组合数学)
    字符串的最小表示法
    2019牛客暑期多校训练营(第八场)
    [HDU4734] 不要62(数位dp入门)
  • 原文地址:https://www.cnblogs.com/haomiao/p/11646531.html
Copyright © 2011-2022 走看看