微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Windows程序设计(资源、绘图、坐标系)

一、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句柄,若hInstance为NULL,则加载需为标准的系统自带图标。
如: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 // 绘制标识
);
diFlags:DI_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:/5000个ICO图标文件/生活用品/sword.ani");或hcurs=LoadCursorFromFile("G:\5000个ICO图标文件\生活用品\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(命令ID,1),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 Context,DC)
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 Interface,GDI)
Win32的绘图API,封装在gdi32.dll中,通过该接口给设备上下文下达绘制命令。它是一个在Windows应用程序中执行与设备无关的函数库,这些函数在不同的输出设备上产生图形以及文字输出
3. 颜色空间的使用
1.RGB :电脑显示器,每一个点颜色是3个字节24位保存 0-2^24
R - 0~255
G - 0~255
B - 0~255
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 //设置的颜色
); 返回点原来的颜色

  1. 直线的使用(直线、圆形、弧线)
    当前点:上一次绘图时的最后一点,初始为(0,0)点。
    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毫米)
    1. 坐标系映射:
      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)(仍是左上角位置)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐