您的位置:首页 > 其它

win32汇编实现一个时钟

2016-04-12 16:47 260 查看
windows下的图像操作,涉及到图形的操作,我们就会想到GDI(图形设备接口),其实也就是一个大型的函数库,可以实现WINDOWS环境下的画线,画图,字体处理等操作。就如同这次分析的一个简单的时钟,我感觉可以分为如下几步:

资源文件的定义:

首先编写资源文件,这也是一个WIN32程序不可忽缺的一个环节(当然也可以不写,只不过丑陋了许多),这次资源文件只定义了一个图标文件,没有出现什么问题。

然后是:

GDI操作
1画点:时钟的刻度                     
画线:时钟的指针
3画图形:时钟的刻度
  
然后是窗口处理过程:

窗口操作
1         
与时钟有关的位置.坐标.半径.刻度的一系列计算。                   
                 
2

窗口过程:包括消息的处理等
3

注册窗口类:其中有一些自定义的窗口属性,
4

建立并显示窗口:指定窗口的一些
5
消息循环:窗口的精华


关于GDI操作基本都是使用函数对设备环境对象进行操作,需要注意的就是一些API函数的参数以及返回值情况,在画线的时候(就是在画时钟指针的时候),使用LineTo()函数时第2.3个参数的坐标是时钟指针反向延长到圆心的那一小段线段与圆心相对的那一点的坐标,在使用_CalcX()和_CalcY()函数计算该点的坐标时,半径这个参数是根据自己的习惯设置的,比如例子程序中设置的是10(单位:像素),这个参数反映的是指针反向延长超出圆心那部分的长度,这个问题当时也是很纠结,看了好久才明白。

还有一点有意思的地方,就是例子程序在画时钟的时针的时候,这几句代码:

.if eax >=12
sub eax,12
.endif
mov ecx,360/12
mul ecx
movzx ecx,@stTime.wMinute
shr ecx,1 ;666666666666666666666666
add eax,ecx

这几句代码很简洁也很精辟,首先判断如果时间是采用的24小时制的则转换为12小时制的,下面计算时针在某时的角度,一个时钟面是360度,每小时所占的角度是30度,把当前的时间:分 的数值除以二(就是二进制的右移一位:shr  ecx,1),正好当前时间的“分”的数值除以2正好和每小时所占的30度成比例,时间“分”的数值除以二作为当前分针在某小时30度区域的位置,然后再加上这时计算出来的时针在整个时钟面所处的角度,就得到当前时针的具体位置,这个写的真心精辟简洁。

另一点就是计算点的坐标时,利用的浮点运算,以前没有接触,感觉很是陌生,但是经过仔细研究后,发现计算机进行数据计算的浮点运行确实很经典,与此相关我转载了一篇写的很经典,很清晰的文章介绍浮点运算,以便以后方便学习。

在计算时钟的半径,圆心坐标的时候也就是_CalcClockParam()函数的过程,

               .if eax > ecx
mov edx,ecx
sub eax,ecx
shr eax,1
mov dwCenterX,0
mov dwCenterY,eax
.else
mov edx,eax
sub ecx,eax
shr ecx,1
mov dwCenterX,ecx
mov dwCenterY,0
.endif
函数代码中dwCenterX
或dwCenterY 得到的是时钟的边框距离当前窗口的距离,在后面的
shr edx,1
mov dwRadius,edx
add dwCenterX,edx
add dwCenterY,edx
代码中,经过与半径相加才得到真正的圆心的坐标。这些都是写程序时很容易犯错误的地方。

最后一点注意的就是在创建窗口时( CreteWindowEx()函数),这个函数的4,5,6,7,这四个参数分别代表的的是创建的窗口左上角x坐标,左上角Y坐标,右下角X坐标,右下角Y坐标。再是这里说这个,是因为以前我记得这四个坐标代表的是:窗口左上角x坐标,左上角Y坐标,窗口宽度,窗口高度。这个窗口宽度与高度是要经过左上角的坐标与右下角的坐标计算出来的,而不是直接写出来的。这些都是在写程序的时候遇见的纠结过的问题。下面看一下程序源代码:

                .386
.model flat,stdcall
option casemap:none

include windows.inc
include gdi32.inc
includelib gdi32.lib
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib

IDI_ICON1 equ 101
ID_TIMER equ 1

.data?
hInstance dd ?
hWinMain dd ?
dwCenterX dd ?
dwCenterY dd ?
dwRadius dd ?

.const
szClassName db 'Clock',0
_dwPara180 dw 180
.code

_CalcClockParam proc

LOCAL @stRect:RECT
invoke GetClientRect,hWinMain,addr @stRect
mov eax,@stRect.right
sub eax,@stRect.left ;宽度
mov ecx,@stRect.bottom
sub ecx,@stRect.top ;高度
.if eax > ecx
mov edx,ecx
sub eax,ecx
shr eax,1
mov dwCenterX,0
mov dwCenterY,eax
.else
mov edx,eax
sub ecx,eax
shr ecx,1
mov dwCenterX,ecx
mov dwCenterY,0
.endif
shr edx,1
mov dwRadius,edx
add dwCenterX,edx
add dwCenterY,edx
ret

_CalcClockParam endp

_CalcX proc _dwDegree,_dwRadius

LOCAL @dwReturn

fild dwCenterX
fild _dwDegree
fldpi
fmul
fild _dwPara180
fdivp st(1),st
fsin
fild _dwRadius
fmul
fadd
fistp @dwReturn
mov eax,@dwReturn
ret
_CalcX endp

_CalcY proc _dwDegree,_dwRadius

LOCAL @dwReturn

fild dwCenterY
fild _dwDegree
fldpi
fmul
fild _dwPara180
fdivp st(1),st
fcos
fild _dwRadius
fmul
fsubp st(1),st
fistp @dwReturn
mov eax,@dwReturn
ret
_CalcY endp

_DrawDot proc _hDC,_dwDegreeInc,_dwRadius

LOCAL @dwNowDegree,@dwR
LOCAL @dwX,@dwY

mov @dwNowDegree,0
mov eax,dwRadius
sub eax,10
mov @dwR,eax
.while @dwNowDegree <= 360
finit
invoke _CalcX,@dwNowDegree,@dwR
mov @dwX,eax
invoke _CalcY,@dwNowDegree,@dwR
mov @dwY,eax

mov eax,@dwX
mov ebx,eax
mov ecx,@dwY
mov edx,ecx
sub eax,_dwRadius
add ebx,_dwRadius
sub ecx,_dwRadius
add edx,_dwRadius
invoke Ellipse,_hDC,eax,ecx,ebx,edx
mov eax,_dwDegreeInc
add @dwNowDegree,eax
.endw
ret

_DrawDot endp

_DrawLine proc _hDC,_dwDegree,_dwRadiusAdjust

LOCAL @dwR
LOCAL @dwX1,@dwY1,@dwX2,@dwY2

mov eax,dwRadius
sub eax,_dwRadiusAdjust
mov @dwR,eax
invoke _CalcX,_dwDegree,@dwR
mov @dwX1,eax
invoke _CalcY,_dwDegree,@dwR
mov @dwY1,eax
add _dwDegree,180
invoke _CalcX,_dwDegree,10 ;此处需注意 注意参数10
mov @dwX2,eax
invoke _CalcY,_dwDegree,10
mov @dwY2,eax
invoke MoveToEx,_hDC,@dwX1,@dwY1,NULL
invoke LineTo,_hDC,@dwX2,@dwY2
ret

_DrawLine endp

_ShowTime proc _hWnd,_hDC

LOCAL @stTime:SYSTEMTIME

pushad
invoke GetLocalTime,addr @stTime
invoke _CalcClockParam
invoke GetStockObject,BLACK_BRUSH
invoke SelectObject,_hDC,eax
invoke _DrawDot,_hDC,360/12,3
invoke _DrawDot,_hDC,360/60,1
invoke CreatePen,PS_SOLID,1,0
invoke SelectObject,_hDC,eax
invoke DeleteObject,eax
movzx eax,@stTime.wSecond
mov ecx,360/60
mul ecx
invoke _DrawLine,_hDC,eax,15
invoke CreatePen,PS_SOLID,2,0
invoke SelectObject,_hDC,eax
invoke DeleteObject,eax
movzx eax,@stTime.wMinute
mov ecx,360/60
mul ecx
invoke _DrawLine,_hDC,eax,20
invoke CreatePen,PS_SOLID,3,0
invoke SelectObject,_hDC,eax
invoke DeleteObject,eax
movzx eax,@stTime.wHour
.if eax >=12
sub eax,12
.endif
mov ecx,360/12
mul ecx
movzx ecx,@stTime.wMinute
shr ecx,1 ;666666666666666666666666
add eax,ecx
invoke _DrawLine,_hDC,eax,30
ret

_ShowTime endp

_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam
LOCAL @stPS:PAINTSTRUCT

mov eax,uMsg
.if eax == WM_TIMER
invoke InvalidateRect,hWnd,NULL,TRUE
.elseif eax == WM_PAINT
invoke BeginPaint,hWnd,addr @stPS
invoke _ShowTime,hWnd,eax
invoke EndPaint,hWnd,addr @stPS
.elseif eax == WM_CREATE
invoke SetTimer,hWnd,ID_TIMER,1000,NULL
.elseif eax == WM_CLOSE
invoke KillTimer,hWnd,ID_TIMER
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWinMain endp

_WinMain proc

LOCAL @stWndClass:WNDCLASSEX
LOCAL @stMsg:MSG

invoke GetModuleHandle,NULL
mov hInstance,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
invoke LoadIcon,hInstance,IDI_ICON1
mov @stWndClass.hIcon,eax
mov @stWndClass.hIconSm,eax
invoke LoadCursor,0,IDC_ARROW
mov @stWndClass.hCursor,eax
push hInstance
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.style,CS_HREDRAW or CS_VREDRAW
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.hbrBackground,COLOR_WINDOW + 1
mov @stWndClass.lpszClassName,offset szClassName
invoke RegisterClassEx,addr @stWndClass
invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szClassName,\
WS_OVERLAPPEDWINDOW,100,100,250,270,NULL,NULL,hInstance,NULL
mov hWinMain,eax
invoke ShowWindow,hWinMain,SW_SHOWNORMAL
invoke UpdateWindow,hWinMain
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax ==0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp

start:
call _WinMain
invoke ExitProcess,NULL
end start



上面就是源代码,下面介绍一下,遇见的一些陌生的API函数:

BitBlt() (这个函数没有出现在上面程序中,因为属于GDI的常用函数才列出来)
功能:该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。
原型:
BOOL BitBlt(HDC hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,HDC hdcSrc,int nXSrc,int nYSrc,DWORD dwRop)
参数:
hdcDest:指向目标设备环境的句柄。

nXDest:指定目标矩形区域左上角的X轴逻辑坐标。

nYDest:指定目标矩形区域左上角的Y轴逻辑坐标。

nWidth:指定源和目标矩形区域的逻辑宽度。

nHeight:指定源和目标矩形区域的逻辑高度。

hdcSrc:指向源设备环境的句柄。

nXSrc:指定源矩形区域左上角的X轴逻辑坐标。

nYSrc:指定源矩形区域左上角的Y轴逻辑坐标。

dwRop:指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。

下面列出了一些常见的光栅操作代码:

BLACKNESS:表示使用与物理调色板的索引0相关的色彩来填充目标矩形区域,(对缺省的物理调色板而言,该颜色为黑色)。

DSTINVERT:表示使目标矩形区域颜色取反。

MERGECOPY:表示使用布尔型的AND(与)操作符将源矩形区域的颜色与特定模式组合一起。

MERGEPAINT:通过使用布尔型的OR(或)操作符将反向的源矩形区域的颜色与目标矩形区域的颜色合并。

NOTSRCCOPY:将源矩形区域颜色取反,于拷贝到目标矩形区域。

NOTSRCERASE:使用布尔类型的OR(或)操作符组合源和目标矩形区域的颜色值,然后将合成的颜色取反。

PATCOPY:将特定的模式拷贝到目标位图上。

PATPAINT:通过使用布尔OR(或)操作符将源矩形区域取反后的颜色值与特定模式的颜色合并。然后使用OR(或)操作符将该操作的结果与目标矩形区域内的颜色合并。

PATINVERT:通过使用XOR(异或)操作符将源和目标矩形区域内的颜色合并。

SRCAND:通过使用AND(与)操作符来将源和目标矩形区域内的颜色合并。

SRCCOPY:将源矩形区域直接拷贝到目标矩形区域。

SRCERASE:通过使用AND(与)操作符将目标矩形区域颜色取反后与源矩形区域的颜色值合并。

SRCINVERT:通过使用布尔型的XOR(异或)操作符将源和目标矩形区域的颜色合并。

SRCPAINT:通过使用布尔型的OR(或)操作符将源和目标矩形区域的颜色合并。

WHITENESS:使用与物理调色板中索引1有关的颜色填充目标矩形区域。(对于缺省物理调色板来说,这个颜色就是白色)

返回值:

如果函数成功,那么返回值非零;如果函数失败,则返回值为零

GetDC()

功能:

该函数检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄,以后可以在GDI函数中使用该句柄来在设备上下文环境中绘图。 GetDCEx函数是GetDC的一个扩展,它能使应用程序更多地控制在客户区域内如何或是否发生剪切

原型:

HDC GetDC(HWND hWnd);

参数:

hWnd:设备上下文环境被检索的窗口的句柄,如果该值为NULL,GetDC则检索整个屏幕的设备上下文环境。

返回值:

如果成功,返回指定窗口客户区的设备上下文环境;如果失败,返回值为Null。

ReleaseDC()

功能:

函数释放设备上下文环境(DC)供其他应用程序使用。函数的效果与设备上下文环境类型有关。它只释放公用的和设备上下文环境,对于类或私有的则无效。

原型;

int ReleaseDC(HWND hWnd, HDC hdc);

参数:

hWnd:指向要释放的设备上下文环境所在的窗口的句柄。

hDC:指向要释放的设备上下文环境的句柄。

返回值;

返回值说明了设备上下文环境是否释放;如果释放成功,则返回值为1;如果没有释放成功,则返回值为0。

MoveToEx()

功能:

本函数将当前绘图位置移动到某个具体的点,同时也可获得之前位置的坐标

原型:

WINGDIAPI BOOL WINAPI MoveToEx(

HDC hdc,

int X,

int Y,

LPPOINT lpPoint

);

参数:
HDC hdc:传入参数,设备上下文句柄。

int X:传入参数:新位置的X坐标。

int Y:传入参数:新位置的Y坐标。

LPPOINT lpPoint:传出参数:一个指向POINT结构的指针,用来存放上一个点的位置,若此参数为NULL,则不保存上一个点的位置

返回值:
返回TRUE代表移动成功,FALSE代表失败

LineTo()

功能:

用当前画笔画一条线,从当前位置(这个函数和MoveTo()函数配合使用)连到一个指定的点。这个函数调用完毕,当前位置变成x,y

原型:

WINGDIAPI BOOL WINAPI LineTo(

HDChdc,

intX,

intY,

);

参数:

hdc:设备场景句柄

X:线段终点X坐标位置,采用逻辑坐标表示。这个点不会实际画出来;它不属于线段的一部份

Y:线段终点Y坐标位置,采用逻辑坐标表示。这个点不会实际画出来;它不属于线段的一部份

返回值:
返回TRUE代表移动成功,FALSE代表失败

GetLocalTime()

功能:

用来获取当地的当前系统日期和时间
原型:

VOID GetLocalTime(

LPSYSTEMTIME lpSystemTime //address of system times structure

);

参数:
lpSystemTime: 指向一个用户自定义包含日期和时间信息的类型为 SYSTEMTIME 的变量,该变量用来保存函数获取的时间信息。

此函数会把获取的系统时间信息存储到SYSTEMTIME结构体里边

typedef struct _SYSTEMTIME

{

WORD wYear;//年

WORD wMonth;//月

WORD wDayOfWeek;//星期,0为星期日,1为星期一,2为星期二……

WORD wDay;//日

WORD wHour;//时

WORD wMinute;//分

WORD wSecond;//秒

WORD wMilliseconds;//毫秒

}SYSTEMTIME,*PSYSTEMTIME

返回值:

把获取的日期时间存放到指定的SYSTEMTIME结构中去。

GetStockObject()

功能:

该函式检索预定义的备用笔、刷子、字体或者调色板的句柄。

原型:

HGDIOBJ GetStockObject(int fnObject);

参数:

fnObject:指定对象的类型,该参数可取如下值之一;

BLACK_BRUSH:黑色画刷;DKGRAY_BRUSH:暗灰色画刷;

DC_BRUSH:在Windows98,Windows NT 5.0和以后版本中为纯颜色画刷,缺省色为白色,可以用SetDCBrushColor函数改变颜色,更多的信息参见以下的注释部分。

GRAY_BRUSH:灰色画刷笔;HOLLOW_BRUSH:空画刷(相当于NULL_BRUSH);

LTGRAY_BRUSH:亮灰色画刷;NULL_BRUSH:空画刷(相当于HOLLOW_BRUSH);

WHITE_BRUSH:白色画刷;

BLACK_PEN:黑色钢笔;

DC_PEN:在Windows98、Windows NT 5.0和以后版本中为纯色钢笔,缺省色为白色,使用SetDCPenColor函数可以改变色彩,更多的信息,参见下面的注释部分。

WHITE_PEN:白色钢笔;

ANSI_FIXED_FONT:在Windows中为固定间距(等宽)系统字体;

ANSI_VAR_FONT:在Windows中为变间距(比例间距)系统字体;

DEVICE_DEFAUCT_FONT:在WindowsNT中为设备相关字体;

DEFAULT_GUI_FONT:用户界面对象缺省字体,如菜单和对话框;

OEM_FIXED_FONT:原始设备制造商(OEM)相关固定间距(等宽)字体;

SYSTEM_FONT:系统字体,在缺省情况下,系统使用系统字体绘制菜单,对话框控制和文本;

SYSTEM_FIXED_FONT:固定间距(等宽)系统字体,该对象仅提供给兼容16位Windows版本;

DEFAULT_PALETTE:缺省调色板,该调色板由系统调色板中的静态色彩组成。

返回值:
如果成功,返回值标识申请的逻辑对象,如果失败,返回值为NULL。

SelectObject()

功能:

该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。

原型:

HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj)

参数:

hdc:设备上下文环境的句柄。

hgdiobj:被选择的对象的句柄,该指定对象必须由如下的函数创建。

位图:CreateBitmap, CreateBitmapIndirect, CreateCompatible Bitmap, CreateDIBitmap, CreateDIBsection(只有内存设备上下文环境可选择位图,并且在同一时刻只能一个设备上下文环境选择位图)。

画刷:CreateBrushIndirect, CreateDIBPatternBrush, CreateDIBPatternBrushPt, CreateHatchBrush, CreatePatternBrush, CreateSolidBrush。

字体:CreateFont, CreateFontIndirect。

笔:CreatePen, CreatePenIndirect。

区域:CombineRgn, CreateEllipticRgn, CreateEllipticRgnIndirect, CreatePolygonRgn, CreateRectRgn,CreateRectRgnIndirect。

返回值:
如果选择对象不是区域并且函数执行成功,那么返回值是被取代的对象的句柄;如果选择对象是区域并且函数执行成功,返回如下一值:

SIMPLEREGION:区域由单个矩形组成;

COMPLEXREGION:区域由多个矩形组成;

NULLREGION:区域为空。

如果发生错误并且选择对象不是一个区域,那么返回值为NULL,否则返回HGDI_ERROR。

CreatePen()

功能:

用指定的样式、宽度和颜色创建一个画笔

原型:

HPEN CreatePen(int nPenStyle, int nWidth, COLORREF crColor);

参数:

nPenStyle ------ Long,指定画笔样式,可以是下述常数之一

PS_SOLID ​画笔画出的是实线

PS_DASH ​画笔画出的是虚线(nWidth必须不大于1)

PS_DOT ​画笔画出的是点线(nWidth必须不大于1)

PS_DASHDOT ​ 画笔画出的是点划线(nWidth必须不大于1)

PS_DASHDOTDOT ​画笔画出的是点-点-划线(nWidth必须不大于1)

PS_NULL ​画笔不能画图

PS_INSIDEFRAME ​由椭圆、矩形、圆角矩形、饼图以及弦等生成的封闭对象框时,画线宽度向内扩展。

如指定的准确RGB颜 色不存在,就进行抖动处理

nWidth --------- Long,以逻辑单位表示的画笔的宽度

crColor -------- Long,画笔的RGB颜色

返回值:
如函数执行成功,就返回指向新画笔的一个句柄;否则返回零

DeleteObject()

功能:

该函数删除一个逻辑笔、画笔、字体、位图、区域或者调色板,释放所有与该对象有关的系统资源,在对象被删除之后,指定的句柄也就失效了。

原型:

BOOL DeleteObject(HGDIOBJ hObject)

参数:

hObject:逻辑笔、画笔、字体、位图、区域或者调色板的句柄。

返回值:

成功,返回非零值;如果指定的句柄无效或者它已被选入设备上下文环境,则返回值为零

ExtCreatePen()

功能:

创建一个扩展画笔(装饰或几何)

原型:

ExtCreatPen (

dwPenStyle , // 画笔样式

dwWidth , // 指定线宽

lplb , // 逻辑画刷变量

dwStyleCout , // 如指定了PS_USERSTYLE,则代表lpStyle数组中的条目数量

lpStyle // 指定PS_USERSTYLE的"线段/空白"对

)

参数:
dwPenStyle (Long)

画笔样式来自下述常数组的任何一个常数的组合(OR运算):

PS_COSMETIC or PS_GEOMETRIC
画笔的类型
PS_ALTERNATE, PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT, PS_DASHDOTDOT, PS_NULL, PS_USERSTYLE, PS_INSIDEFRAME
画笔的样式
PS_ENDCAP_???
画笔的笔尖
PS_JOIN_???
在图形中连接线段或在路径中连接直线的方式
dwWidth (Long)

指定线宽。几何画笔的线宽肯定是1。

lplb

LOGBRUSH,lbColor代表画笔颜色。对于装饰画笔,lbStyle为PS_SOLID;对于几何画笔,lbStyle则代表实际的样式。针对几何画笔,必须设置其他所有字体。

dwStyleCount (Long)

如指定了PS_USERSTYLE,则代表lpStyle数组中的条目数量。

lpStyle (Long)

指定PS_USERSTYLE的"线段/空白"对(原文:Line/space pairs for PS_USERSTYLE)

返回值:

如执行成功,返回一个指向扩展画笔的句柄。零表示执行出错。一旦不再需要,记得用DeleteObject将画笔删除。

CreatePenIndirect()

功能:

根据指定的LOGPEN结构创建,参数表:lpLogPen ------- LOGPEN,逻辑画笔结构。这个结构与CreatePen函数的参数非常接近。

原型:

HPEN CreatePenIndirect( _In_ const LOGPEN *lplgpn);

参数:

lpLogPen ------- LOGPEN,逻辑画笔结构

返回值:

如执行成功,返回指向新画笔的一个句柄;否则返回零

CreateSolidBrush()

功能:

该函数创建一个具有指定颜色的逻辑刷子。

初始化一个指定颜色的画刷。画笔可以随后被选为任何设备上下文的当前刷子。

参数原型:

HBRUSH CreateSolidBrush(DWORD COLOR)

返回值:

如果该函数执行成功,那么返回值标识一个逻辑实心刷子;如果函数失败,那么返回值为NULL

CreateHatchBrush()

功能:

该函数可以创建一个具有指定阴影模式和颜色的逻辑刷子。

原型:

HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref);

参数:

fnStyle:指定刷子的阴影样式。该参数可以取下列值,这些值的含义为:

HS_BDIAGONAL:表示45度向上,从左至右的阴影(/////);

HS_CROSS:水平和垂直交叉阴影(+++++);

HS_DIAGCROSS:45度交叉阴影(XXXXX);

HS_FDIAGONAL:45度向下,自左至右阴影(\\\\\\);

HS_HORIZONTAL:水平阴影(-----);

HS_VERTICAL:垂直阴影(|||||)。

cirref:指定用于阴影的刷子的前景色。

返回值:
如果函数执行成功,那么返回值标识为逻辑刷子;如果函数执行失败,那么返回值为NULL。

CreatePatternBrush()

功能:

创建具有指定位图模式的逻辑刷子,该位图不能是DIB类型的位图,DIB位图是由CreateDIBSection函数创建的

原型:

HBRUSH CreatePatternBrush()

返回值:

如果该函数执行成功,那么返回值标识为一个逻辑刷子,如果该函数执行失败,那么返回值为NULL

CreateBrushIndirect()

功能:

可以创建具有指定风格、颜色和模式的逻辑刷子

原型:

HBRUSH CreateBrushlndirect(CONST LOGBRUSH *lplb);

参数:

lplb:指向LOGBRUSH结构的指针,该结构包含与刷子有关的信息。

返回值:

如果函数执行成功,那么返回值标识一个逻辑刷子;如果函数执行失败,则返回值为NULL

SetPixel()

功能:

将指定坐标处的像素设为指定的颜色。

原型:

COLORREF SetPixel(HDC hdc, int X, int Y, COLORREF crColor);

参数:

hdc:设备环境句柄。

X:指定要设置的点的X轴坐标,按逻辑单位表示坐标。

Y:指定要设置的点的X轴坐标,按逻辑单位表示坐标。

crColor::指定要用来绘制该点的颜色

返回值:

如果函数执行成功,那么返回值就是函数设置像素的RGB颜色值。这个值可能与crColor指定的颜色有所不同,

之所以有时发生这种情况是因为没有找到对指定颜色进行真正匹配造成的。

如果函数失败,那么返回值是-1。

GetPixel()

功能:

该函数检索指定坐标点的像素的RGB颜色值。

原型:

COLORREF GetPixel(HDC hdc, int nXPos, int nYPos)

参数:

hdc:设备环境句柄。

nXPos:指定要检查的像素点的逻辑X轴坐标。

nYPos:指定要检查的像素点的逻辑Y轴坐标。

返回值:

返回值是该象像点的RGB值。如果指定的像素点在当前剪辑区之外;那么返回值是CLR_INVALID。

GetCurrentPositionEX()

功能:

该函数获取逻辑坐标中的当前位置

原型:
BOOL GetCurrentPositionEx(HDC hdc, LPPOINT lpPoint);

参数:

hdc:指向设备环境的句柄。
lpPoint:指向接收当前位置坐标的POINT结构的指针。

返回值:

如果函数调用成功,返回值为非零值,否则为零

InvaliddateRect()

功能:

该函数向指定的窗体更新区域添加一个矩形,然后窗口客户区域的这一部分将被重新绘制

原型:

BOOL InvalidateRect(

HWND hWnd, // handle of window with changed update region

CONST RECT *lpRect, // address of rectangle coordinates

BOOL bErase // erase-background flag

);

参数:

hWnd:要更新的客户区所在的窗体的句柄。如果为NULL,则系统将在函数返回前重新绘制所有的窗口, 然后发送 WM_ERASEBKGND 和 WM_NCPAINT 给窗口过程处理函数。

lpRect:无效区域的矩形代表,它是一个结构体指针,存放着矩形的大小。如果为NULL,全部的窗口客户区域将被增加到更新区域中。

bErase:指出无效矩形被标记为有效后,是否重画该区域,重画时用预先定义好的画刷。当指定TRUE时需要重画。

返回值:

函数成功则返回非零值,否则返回零值。

说明:被标记为无效矩形的区域直到WM_PAINT消息被处理完之后才会消失,或者使用ValidateRect(),ValidateRgn()函数来使之有效。当应用程序的消息队列中为空时,并且窗体要更新的区域非空时,系统会发送一个WM_PAINT消息到窗体。

这两个都用于声明客户区无效,当下一个WM_PAINT消息到来时发生重画。

其中InvalidateRect(hwnd, NULL, true);重画时将擦除背景。

InvalidateRect(hwnd, NULL, false);重画时不擦除背景


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: