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

资源文件的定义:

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

然后是:

GDI操作
1 画点:时钟的刻度                     
画线:时钟的指针
3 画图形:时钟的刻度
   

然后是窗口处理过程:

窗口操作
1
与时钟有关的位置.坐标.半径.刻度的一系列计算。                   
2
窗口过程:包括消息的处理等
3
注册窗口类:其中有一些自定义的窗口属性,
4
建立并显示窗口:指定窗口的一些
5 消息循环:窗口的精华


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

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

 .if     eax >=12sub   eax,12.endifmov     ecx,360/12mul     ecxmovzx   ecx,@stTime.wMinuteshr     ecx,1                                ;666666666666666666666666add     eax,ecx

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

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

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

  .if     eax > ecxmov edx,ecxsub eax,ecxshr eax,1mov dwCenterX,0mov dwCenterY,eax.else   mov edx,eaxsub ecx,eaxshr ecx,1mov dwCenterX,ecxmov dwCenterY,0.endif
函数代码中dwCenterX
或dwCenterY  得到的是时钟的边框距离当前窗口的距离,在后面的
shr     edx,1mov     dwRadius,edxadd     dwCenterX,edxadd     dwCenterY,edx

代码中,经过与半径相加才得到真正的圆心的坐标。这些都是写程序时很容易犯错误的地方。

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

               

 .386.model flat,stdcalloption casemap:noneinclude         windows.inc
include         gdi32.inc
includelib      gdi32.lib
include         user32.inc
includelib      user32.lib
include         kernel32.inc
includelib      kernel32.libIDI_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 procLOCAL   @stRect:RECTinvoke  GetClientRect,hWinMain,addr @stRectmov     eax,@stRect.rightsub     eax,@stRect.left            ;宽度mov     ecx,@stRect.bottomsub     ecx,@stRect.top            ;高度.if     eax > ecxmov edx,ecxsub eax,ecxshr eax,1mov dwCenterX,0mov dwCenterY,eax.else   mov edx,eaxsub ecx,eaxshr ecx,1mov dwCenterX,ecxmov dwCenterY,0.endifshr     edx,1mov     dwRadius,edxadd     dwCenterX,edxadd     dwCenterY,edxret_CalcClockParam endp_CalcX          proc    _dwDegree,_dwRadiusLOCAL   @dwReturnfild    dwCenterXfild    _dwDegreefldpi   fmulfild    _dwPara180fdivp   st(1),stfsinfild    _dwRadiusfmul    faddfistp   @dwReturnmov     eax,@dwReturnret
_CalcX          endp_CalcY          proc    _dwDegree,_dwRadiusLOCAL   @dwReturnfild    dwCenterYfild    _dwDegreefldpifmulfild    _dwPara180fdivp   st(1),stfcos  fild    _dwRadiusfmulfsubp   st(1),stfistp   @dwReturnmov     eax,@dwReturnret
_CalcY          endp_DrawDot        proc    _hDC,_dwDegreeInc,_dwRadiusLOCAL   @dwNowDegree,@dwRLOCAL   @dwX,@dwYmov     @dwNowDegree,0mov     eax,dwRadiussub     eax,10mov     @dwR,eax.while  @dwNowDegree <= 360finitinvoke _CalcX,@dwNowDegree,@dwRmov    @dwX,eaxinvoke _CalcY,@dwNowDegree,@dwRmov    @dwY,eaxmov    eax,@dwXmov    ebx,eaxmov    ecx,@dwYmov    edx,ecxsub    eax,_dwRadiusadd    ebx,_dwRadiussub    ecx,_dwRadiusadd    edx,_dwRadiusinvoke Ellipse,_hDC,eax,ecx,ebx,edxmov    eax,_dwDegreeIncadd    @dwNowDegree,eax.endwret_DrawDot        endp_DrawLine       proc    _hDC,_dwDegree,_dwRadiusAdjustLOCAL   @dwRLOCAL   @dwX1,@dwY1,@dwX2,@dwY2mov     eax,dwRadiussub     eax,_dwRadiusAdjustmov     @dwR,eaxinvoke  _CalcX,_dwDegree,@dwRmov     @dwX1,eaxinvoke  _CalcY,_dwDegree,@dwRmov     @dwY1,eaxadd     _dwDegree,180invoke  _CalcX,_dwDegree,10           ;此处需注意     注意参数10mov     @dwX2,eaxinvoke  _CalcY,_dwDegree,10mov     @dwY2,eaxinvoke  MoveToEx,_hDC,@dwX1,@dwY1,NULLinvoke  LineTo,_hDC,@dwX2,@dwY2ret_DrawLine       endp_ShowTime       proc    _hWnd,_hDCLOCAL   @stTime:SYSTEMTIMEpushadinvoke  GetLocalTime,addr @stTimeinvoke  _CalcClockParaminvoke  GetStockObject,BLACK_BRUSHinvoke  SelectObject,_hDC,eaxinvoke  _DrawDot,_hDC,360/12,3invoke  _DrawDot,_hDC,360/60,1invoke  CreatePen,PS_SOLID,1,0invoke  SelectObject,_hDC,eaxinvoke  DeleteObject,eaxmovzx   eax,@stTime.wSecondmov     ecx,360/60mul     ecxinvoke  _DrawLine,_hDC,eax,15invoke  CreatePen,PS_SOLID,2,0invoke  SelectObject,_hDC,eaxinvoke  DeleteObject,eaxmovzx   eax,@stTime.wMinutemov     ecx,360/60mul     ecxinvoke  _DrawLine,_hDC,eax,20invoke  CreatePen,PS_SOLID,3,0invoke  SelectObject,_hDC,eaxinvoke  DeleteObject,eaxmovzx   eax,@stTime.wHour.if     eax >=12sub   eax,12.endifmov     ecx,360/12mul     ecxmovzx   ecx,@stTime.wMinuteshr     ecx,1                                ;666666666666666666666666add     eax,ecxinvoke  _DrawLine,_hDC,eax,30ret_ShowTime       endp_ProcWinMain    proc    uses ebx edi esi hWnd,uMsg,wParam,lParamLOCAL   @stPS:PAINTSTRUCTmov     eax,uMsg.if     eax == WM_TIMERinvoke InvalidateRect,hWnd,NULL,TRUE.elseif eax == WM_PAINTinvoke BeginPaint,hWnd,addr @stPSinvoke _ShowTime,hWnd,eaxinvoke EndPaint,hWnd,addr @stPS.elseif eax == WM_CREATEinvoke SetTimer,hWnd,ID_TIMER,1000,NULL.elseif eax == WM_CLOSEinvoke KillTimer,hWnd,ID_TIMERinvoke DestroyWindow,hWinMaininvoke PostQuitMessage,NULL.else   invoke DefWindowProc,hWnd,uMsg,wParam,lParamret.endifxor     eax,eaxret
_ProcWinMain    endp_WinMain        proc    LOCAL   @stWndClass:WNDCLASSEXLOCAL   @stMsg:MSGinvoke  GetModuleHandle,NULLmov     hInstance,eaxinvoke  RtlZeroMemory,addr @stWndClass,sizeof @stWndClassinvoke  LoadIcon,hInstance,IDI_ICON1mov     @stWndClass.hIcon,eaxmov     @stWndClass.hIconSm,eaxinvoke  LoadCursor,0,IDC_ARROWmov     @stWndClass.hCursor,eaxpush    hInstancepop     @stWndClass.hInstancemov     @stWndClass.cbSize,sizeof WNDCLASSEXmov     @stWndClass.style,CS_HREDRAW or CS_VREDRAWmov     @stWndClass.lpfnWndProc,offset _ProcWinMainmov     @stWndClass.hbrBackground,COLOR_WINDOW + 1mov     @stWndClass.lpszClassName,offset szClassNameinvoke  RegisterClassEx,addr @stWndClassinvoke  CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szClassName,\WS_OVERLAPPEDWINDOW,100,100,250,270,NULL,NULL,hInstance,NULLmov     hWinMain,eaxinvoke  ShowWindow,hWinMain,SW_SHOWNORMALinvoke  UpdateWindow,hWinMain.while  TRUEinvoke  GetMessage,addr @stMsg,NULL,0,0.break  .if eax ==0invoke  TranslateMessage,addr @stMsginvoke  DispatchMessage,addr @stMsg .endwret
_WinMain        endpstart:call    _WinMaininvoke  ExitProcess,NULLend     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。lplbLOGBRUSH,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)返回值:如果该函数执行成功,那么返回值标识一个逻辑实心刷子;如果函数失败,那么返回值为NULLCreateHatchBrush()功能:该函数可以创建一个具有指定阴影模式和颜色的逻辑刷子。原型: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()返回值:如果该函数执行成功,那么返回值标识为一个逻辑刷子,如果该函数执行失败,那么返回值为NULLCreateBrushIndirect()功能:可以创建具有指定风格、颜色和模式的逻辑刷子原型:HBRUSH CreateBrushlndirect(CONST LOGBRUSH *lplb);参数:lplb:指向LOGBRUSH结构的指针,该结构包含与刷子有关的信息。返回值:如果函数执行成功,那么返回值标识一个逻辑刷子;如果函数执行失败,则返回值为NULLSetPixel()功能:将指定坐标处的像素设为指定的颜色。原型: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 regionCONST RECT *lpRect, // address of rectangle coordinatesBOOL 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);重画时不擦除背景












 





win32汇编实现一个时钟相关推荐

  1. 使用Win32汇编开发一个dll并在C#中调用

    使用RadASM,新建一个Dll Project: 下一步,默认: dll包含Def文件: 完成工程构建:都默认: 完成以后项目结构如下: asm代码: .386 .model flat, stdca ...

  2. Win32汇编学习笔记之基础篇

    基础篇 第一章 背景知识 1.1 Win32的软硬件平台 1.1.1    80x86系列处理器简史 Win32可以在多种硬件平台上运行,但使用最广泛的硬件平台是基于Intel公司80x86系列处理器 ...

  3. Win32汇编_基础

    Win32汇编_基础 包含全部段的源程序结构: .386 .model flat, stdcall Option casemap:none ;<一些include语句> .stack [堆 ...

  4. 选择“Win32汇编”的三大理由?

    选择Win32汇编的理由是什么呢? 在DOS时代,学习汇编就是学习系统底层编程的代名词,仅要成为一名入门级的汇编程序员,就需要学习从CPU结构.CPU工作方式.各种硬件的编程方法到DOS工作方式等范围 ...

  5. win32汇编实现拼接SQL语句

    字符串合并,在汇编语言,一般是用loop循环和cx寄存器,自己编程实现: 如果是win32汇编,可以使用movsb指令: 一般开发应用程序都会碰到拼接SQL语句,在C#这些语言用字符串连接的加号就可以 ...

  6. Win32汇编获取和设置文本框的内容

    看一下Win32汇编如何获取和设置文本框的内容: 资源文件如下: #include <resource.h>#define ICO_MAIN 0x1000 //图标 #define DLG ...

  7. Win32汇编扩展教程

    Win32汇编扩展教程 第一课 Win32 扩展消息框示例 在罗哥云琳的Win32消息框示例基础上,做一个扩展例子. 首先弹出消息框,2个按钮,YESNO; 点击NO,程序结束:点击YES,弹出第二个 ...

  8. C指针原理(23)-win32汇编及.NET调试

    2018-12-28 20:36:07 在WINDOWS系统能用到汇编的机会不多,基本都可以用C或C++代劳,更何况现在MICROSOFT的Visual Studio 系列工具非常强大,WINDOWS ...

  9. win32 汇编基础概念整理

    一.关于寄存器 寄存器有EAX,EBX,ECX,EDX,EDI,ESI,ESP,EBP等,似乎IP也是寄存器,但只有在CALL/RET在中会默认使用它,其它情况很少使用到,暂时可以不用理会. EAX是 ...

  10. win32汇编基础概念

    一.关于寄存器 寄存器有EAX,EBX,ECX,EDX,EDI,ESI,ESP,EBP等,似乎IP也是寄存器,但只有在CALL/RET在中会默认使用它,其它情况很少使用到,暂时可以不用理会. EAX是 ...

最新文章

  1. 如何下载咸鱼app里面的视频
  2. 详细说明通过kettke对csv文件转换的操作步骤_如何将多页面pdf分割成一页一页的PDF文件...
  3. python获取当前网页元素_Python+Selenium练习(三十)- 获取页面元素的href属性
  4. python全栈工程师薪资-Python全栈工程师为何这么火薪资这么高看了才知道
  5. iNeuLink硬件网关与iNeuOS工业互联网操作系统互联互通应用案例
  6. 腾讯视频主演角色弹幕怎么发
  7. linux下声卡的安装
  8. Android手动创建和解析Json
  9. JAVA共通関数--システム時刻を取得する(1)
  10. .Net Core中使用ref和SpanT提高程序性能
  11. Java笔记(1):final关键字
  12. 【CAD】DWF文件格式详细说明,清晰易懂
  13. 一个股票软件开发了三年的人如何画制iOS k线图
  14. 155款安卓开源项目源码整理,总有你要找的(精心收集)
  15. C语言输入一个三位数将它反向输出,输入一个三位数,将它反向输出,编程
  16. c语言弹出u盘 api,一个简单的C++编写的u盘病毒代码
  17. 7 一阶逻辑推理(11.23,11.30)
  18. delete不起作用 nsis_Delete键为什么不起作用了?
  19. c语言输入大写字母输出小写字母,C语言大写字母转换为小写字母,并输出程序...
  20. 【计算机基础】下载过的软件 on MAC 收藏夹

热门文章

  1. 扩展php-bcmath,centos安装PHP扩展(bcmath)
  2. linux安装pip3_Liunx下安装Python3.5.0版本,本地有python2.7.5,python2和3共存
  3. scatter python_Python数据可视化之scatter( )函数
  4. hashmap containsvalue时间复杂度_面试宝典:数据结构-HashMap
  5. StanfordDB class自学笔记 (九) Relational Design Theory 关系设计理论
  6. StanfordDB class自学笔记 (8) Querying XML
  7. mysql web报表_2021最新流行的Web报表工具推荐
  8. mysql创建一张日期表_MySQL创建一张日期表
  9. SpringBoot系列(7):SpringBoot启动流程源码分析()
  10. 【黑客免杀攻防】读书笔记15 - 源码免杀、C++壳的编写