Ch 18 §ó¦h³]³Æ¤º®eªºª¾ÃÑ(1)

¦b³o¤@³¹¤p¤ì°¸±N´£¤Î¦³Ãö¶ê§Îµøµ¡¡B¸ô®| ( path )¡B°Ï°ì ( region ) µ¥¥DÃD¡A¥»³¹¥½¤F±N¥Ü½d¤@­Ó®ÉÄÁµ{¦¡¡ACLOCK.ASM¡A»¡©ú³o¨Ç¥DÃD¡C


°Ï°ì ( region )

À³¥Îµ{¦¡¥i¥H¥Î©³¤Uªº API «Ø¥ß°Ï°ì ( region )¡G

CreateRectRgn¡BCreateRectRgnIndirect            «Ø¥ß¯x§Î°Ï°ì
CreateRoundRectRgn                              «Ø¥ß¶ê¨¤ªº¯x§Î°Ï°ì
CreateEllipticRgn¡BCreateEllipticRgnIndirect    «Ø¥ß¾ò¶ê©Î¶ê§Î°Ï°ì
CreatePolygonRgn¡BCreatePolyPolygonRgn          «Ø¥ß¦hÃä§Î°Ï°ì

°Ï°ì¬O¤@­Ó«Ê³¬ªº½d³ò¡A¥i¥H¸g¥Ñ¤W­±¤C­Ó API «Ø¥ß¤£¦P§Îª¬ªº°Ï°ì¡A¦pªG¦¨¥\ªº«Ø¥ß°_°Ï°ì¡A¥¦­Ì·|¶Ç¦^°Ï°ì¥N½X¡C°Ï°ì¬OÄÝ©ó GDI ª«¥ó¡A«Ø¥ß¦n°Ï°ì«á¡AÀ³¥Îµ{¦¡¥i¥H¥Î SelectObject §â°Ï°ì¿ï¤J¬Y¤@­Ó³]³Æ¤º®eùØ¡AµM«á°w¹ï³o­Ó°Ï°ì°µ³B²z¡C¸ò¨ä¥Lªº GDI ª«¥ó¤@¼Ë¡A·í¤£¦A¶·­n®É¡A¥²¶·©I¥s DeleteObject §â¥¦§R°£¡C

°Ï°ìÁÙ¦³¥t¤@­Ó¥Î³~¡A´N¬O¥Î¨Ó«Ø¥ß¯S®í§Îª¬ªºµøµ¡¡C¨ä¨BÆJ¬O¥ý«Ø¥ß¦n¤@­Ó¯S®í§Îª¬ªº°Ï°ì¡AµM«á©I¥s SetWindowRgn API «ü©wµøµ¡¬°¸Ó°Ï°ì¡A©Ò¥Hµøµ¡ªº§Îª¬´NÅܦ¨¤F¸Ó°Ï°ìªº§Îª¬¡ASetWindowRgn ªº­ì«¬¬O¡G

SetWindowRgn API

int SetWindowRgn(
    HWND    hWnd,   // handle to window whose window region is to be set
    HRGN    hRgn,   // handle to region
    BOOL    bRedraw // window redraw flag
   );

°Ñ¼Æ bRedraw ¥i¬O TRUE ©Î FALSE¡A³o­Ó°Ñ¼Æ¬O«ü³]©w¦nµøµ¡ªº°Ï°ì¤§«á¬O§_­«Ã¸¡ATRUE ¬O«ü¥ß§Y­«Ã¸¡A¥ç§Yµo°e WM_PAINT µ¹¬Oµøµ¡¡FFALSE ¬O«ü¤£¶i¦æ­«Ã¸¡C


¸ô®| ( path )

¸ô®|¨Ã¤£¬O Win32 ªº¹Ï§Îª«¥ó¡A¨Ã¨S¦³¤@­ÓºÙ¬°¸ô®|¥N½Xªº¦Wµü¡C§Ú­Ì¥i¥H¬°¨C­Ó³]³Æ¤º®e«Ø¥ß¤@­Ó¸ô®|¡A³o¨Ç¸ô®|¥i¥H¬O«Ê³¬°_¨Ó¡A¤]¥i¥H¬O¶}©ñªº¡A¤£ºÞ¬O¨º¤@ºØ¡A¹ï¨t²Î¦Ó¨¥¡A¥u°O¿ý©Ò¸g¹Lªº°²·Q½u±ø¡A¨Ã¤£°O¿ý©Ò³ò°_¨Óªº½d³ò¡C·Q­n«Ø¥ß¸ô®|®É¥i¥H¥Î BeginPath API¡A¨ä»yªk¬O

BOOL BeginPath(
    HDC hdc     // handle to device context 
   );

¨C·í©I¥s BeginPath «Ø¥ß¤@­Ó·sªº¸ô®|®É¡Aªº¸ô®|´N³Q¯}Ãa±¼¤F¡A©Ò¥H¨t²Î¥u·|¬°¨C­Ó³]³Æ¤º®eºûÅ@¤@­Ó¸ô®|¡C«Ø¥ß¸ô®|«á¡Aµ{¦¡©Ò©I¥sªº¨C­Óµe½u API ³£·|³Q·í°µ¸ô®|¦Ó³Q¨t²Î°O¿ý°_¨Ó¡A¨Ò¦p MoveToEx¡BLineTo¡BArc¡BPolyline¡K¡K¡C·í¦h¦¸©I¥sµe½uªº API «á¡A¥i¥H©I¥s CloseFigure ¨Ï¸ô®|«Ê³¬°_¨Ó¡ACloseFigure ªº»yªk¬O

BOOL CloseFigure(
    HDC hdc     // handle to device context
   );

§Ú­Ì¤]¥i¥H¦b¤@­Ó³]³Æ¤º®e¤¤¡A«Ø¥ß¦h­Ó«Ê³¬ªº¸ô®|¡A§Y¸ô®|ªº°_ÂI¥H MoveTo ©Î MoveToEx ³]©w¡AµM«á©I¥s¨ä¥Lµe½u API¡A³Ì«á©I¥s CloseFigure «Ê³¬¸ô®|¡C¦³¤F¸ô®|«á¡A§Ú­Ì¥i¥H©I¥s StrokePath ¨ÓªuµÛ¸ô®|¡A¥H·í«eµeµ§µe¥X¸ô®|¨Ó¡F¤]¥i¥H©I¥s FillPath¡A¥H·í«eµ§¨ê¶ñ¥R«Ê³¬ªº¸ô®|¡F©ÎªÌ¥i¥H©I¥s StrokeAndFillPath µe¥X¸ô®|¨Ã¶ñ¥R«Ê³¬ªº¸ô®|¡C

©³¤Uªº CLOCK.ASM µ{¦¡¤¤¡A¦bÄÁ­±¤Wø¥Xªº®É°w»P¤À°wªºµ{¦¡¤ù¬q¡A´N¬O«Ø¥ß¨â­Ó«Ê³¬ªº¸ô®|¡AµM«á©I¥s FillPath ¥H¤£¦Pµ§¨ê¶ñ¥R³o¨â­Ó¸ô®|¡C°£¦¹¤§¥~¡AÁÙ¥i¥H§Q¥Î PathToRegion §â«Ê³¬ªº¸ô®|Åܦ¨°Ï°ì¡APathToRegion ªº»yªk¬O¡G

HRGN PathToRegion(
    HDC hdc     // handle to device context
   );

PathToRegion ªºªð¦^­È¬O°Ï°ìªº¥N½X¡C·íµM¤]¥i¥H¥Î CreateRectRgn¡BCreateRoundRectRgn¡BCreateEllipticRgn µ¥¤èªkª½±µ«Ø¥ß°Ï°ì¡A¦ý¬O¥ý³]¦n«Ê³¬ªº¸ô®|¡A¦A§â³o­Ó«Ê³¬ªº¸ô®|Âà¤Æ¦¨°Ï°ì¡A¥i¥H±o¨ì½ÆÂø§Îª¬ªº°Ï°ì¡C


®ÉÄÁµ{¦¡¡ACLOCK.ASM

¤p¤ì°¸§Q¥Î¤W­±ªº­ì²z¼¶¼g¤F¤@­Ó®ÉÄÁµ{¦¡¡ACLOCK.ASM¡A°õ¦æ®Éµe­±¦p¤U¹Ï¥ª¡C¨Ï¥ÎªÌ¥i¥H§â·Æ¹«²¾¨ìÄÁ­±¤W¥ô¤@ÂI¡A¦A«ö¤U·Æ¹«¥ªÁ䤣©ñ¡A·Æ¹«´å¼Ð·|Åܦ¨¤âªº§Îª¬¡A¥i¥H©ì¦²³o­Ó¶ê§Îµøµ¡¡F¤]¥i¥H¨Ï·Æ¹«¦bÄÁ­±¤W¡A«ö¤U·Æ¹«¥kÁä¡A«K·|¥X²{¡y¼u¥X¦¡¿ï³æ¡z¡A¥i¥HÅÜ´«­I´º¹Ï©ÎÂ÷¶}µ{¦¡¡C©³¤U¬O CLOCK.RC Àɪº­ì©l½X¡G

Clock   ICON    clock02.ico
Boy     BITMAP  boy.bmp
Girl    BITMAP  girl.bmp
Dog     BITMAP  dog.bmp

¤U¹Ï¤¤ªº¥kÃä¤T±i¹Ï¬O CLOCK.RC ·|¥Î¨ìªºÂI°}¹Ï¡G


boy.bmp

girl.bmp

dog.bmp

¥kÃä¤T±i¹Ï¬O PNG ®æ¦¡¡AŪªÌ¤U¸ü«á¦Û¦æ¥Îø¹Ï³nÅé±N¨ä¦s¦¨ BMP ®æ¦¡ªº¹Ï®×ÀÉ¡C

©³¤U¬O CLOCK.ASM ªº·½½X¡G

;¶ê§Î®ÉÄÁµ{¦¡¡A¥i§ó´«­I´º°}¹Ï
        .586
        .model  flat,stdcall
        option  casemap:none

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

IDM_BOY         EQU     1000
IDM_GIRL        EQU     1001
IDM_DOG         EQU     1002
IDM_EXIT        EQU     1003
CLOCK_SIZE      EQU     200
CENTER_PONIT    EQU     CLOCK_SIZE/2-1

;*******************************************************************************
                .const
dw180           DWORD   180
dw360           DWORD   360
six             DWORD   6
five            DWORD   5
fifteen         DWORD   15
twelve          DWORD   12
sixty           DWORD   60
ptCntr          POINT   <CENTER_PONIT,CENTER_PONIT>     ;ÄÁ­±¤¤¤ßªº®y¼Ð
lpBmpString     DWORD   OFFSET szBoyBmp,OFFSET szGirlBmp,OFFSET szDogBmp
dwTimerID       DWORD   3000
szClassName     BYTE    'CLOCK_CLASS',0
szAppName       BYTE    'CLOCK',0
szClockIcon     BYTE    'Clock',0
szBoyBmp        BYTE    'Boy',0
szDogBmp        BYTE    'Dog',0
szGirlBmp       BYTE    'Girl',0
szBoy           BYTE    '«Ó­ô­I´º',0
szGirl          BYTE    '¬ü¤k­I´º',0
szDog           BYTE    '¤pª¯­I´º',0
szExit          BYTE    'Â÷¶}',0
;*******************************************************************************
                .data
hInstance       HINSTANCE       ?
hwnd            HWND            ?
hMenu           HMENU           ?       ;¼u¥X¦¡¿ï³æ¥N½X
hCursorHand     HCURSOR         ?
hBitmap         HBITMAP         ?
hdcMem          HDC             ?       ;°O¾ÐÅé³]³Æ¤º®e¥N½X
wc              WNDCLASSEX      <?>
msg             MSG             <?>
mii             MENUITEMINFO    <?>
point           POINT           <?>
ps              PAINTSTRUCT     <?>
dwScrWidth      DWORD           ?       ;¿Ã¹õ¼e«×
dwScrHigh       DWORD           ?       ;¿Ã¹õ°ª«×
dwCheckMenuItem DWORD           IDM_BOY ;¤º©wªº¿ï¶µ¬°IDM_BOY¡A¨Ï¥ÎªÌ¥i§ó§ï¦¨IDB_GIRL¡AIDM_DOG
loctime         SYSTEMTIME      <?>     ;·í¦a®É¶¡
;*******************************************************************************
        .code
;-------------------------------------------------------------------------------
;¥Ñ¥b®|(¶ê¤ß¦bÄÁ­±¥¿¤¤¤ß)»P¨¤«×¡A¨D¥XÄÁ­±¤W¬Y¤@ÂIªº®y¼Ð¡C
;¿é¤J¡Ðradius¡G¥b®|
;      angle¡G»PX¶bªº§¨¨¤
;¿é¥X¡ÐEAX¡GX®y¼Ð
;      ECX¡GY®y¼Ð
CalcDot PROC    radius:DWORD,angle:DWORD
        LOCAL   val:DWORD
                        ;--st --;--st1--;--st2--;
        fild    dw180   ;  180  ;       ;       ;
        fild    angle   ;   a   ;  180  ;       ;
        fldpi           ;   pi  ;   a   ;  180  ;
        fmulp   st(1),st;  a*pi ;  180  ;       ;
        fdivr           ;api/180;       ;       ;£c=(a*pi/180)
        fld     st      ;   £c   ;   £c   ;       ;
        fsin            ; sin£c  ;   £c   ;       ;
        fimul   radius  ; rsin£c ;   £c   ;       ;
        fiadd   ptCntr.y;   Y   ;   £c   ;       ;
        fistp   val     ;   £c   ;       ;       ;
        fcos            ; cos£c  ;       ;       ;
        mov     ecx,val
        fimul   radius  ; rcos£c ;       ;       ;
        fiadd   ptCntr.x;   X   ;       ;       ;
        fistp   val
        mov     eax,val
        ret
CalcDot ENDP
;-------------------------------------------------------------------------------
;µe¥X­I´ºÂI°}¹Ï»P®ÉÄÁÄÁ­±ªº¨è«×¡C
DrawBmpAndClock PROC    hwin:HWND
        LOCAL   hDC:HDC,angle1:DWORD,angle2:DWORD
        mov     ecx,dwCheckMenuItem
        sub     ecx,IDM_BOY
        shl     ecx,2
        mov     edx,lpBmpString[ecx]    ;EDX«ü¦V¸ê·½¤¤ÂI°}¹Ïªº¦WºÙ
        INVOKE  LoadBitmap,hInstance,edx;¸ü¤JÂI°}¹Ï
        mov     hBitmap,eax
        INVOKE  GetDC,hwin              ;¨ú±o®ÉÄÁªº¸Ë¸m¤º®e
        mov     hDC,eax
        INVOKE  CreateCompatibleDC,eax  ;«Ø¥ß¬Û®eªº°O¾ÐÅé¸Ë¸m¤º®e
        mov     hdcMem,eax
        INVOKE  SelectObject,hdcMem,hBitmap
;¿ï¾Ü¶Â¦âµ§¨ê¡A¥H¨Ï¨è«×12¡B5¡B10¡B15¡K¯à¦¨¬°¶îº¡¶Â¦âªº¶êÂI
        INVOKE  GetStockObject,BLACK_BRUSH
        INVOKE  SelectObject,hdcMem,eax
        INVOKE  DeleteObject,eax
;µe¥X¨è«×¡Aangle1¨Ì§Ç¬O0¡B30¡B60¡B90¡K330¡A§Y¤À§Oªí¥Ü®ÉÄÁ¤Wªº¨è«×12¡B5¡B10¡B15¡K55
        mov     angle1,0
@@:     INVOKE  CalcDot,92,angle1
        mov     point.x,eax
        mov     point.y,ecx
        sub     point.x,4
        sub     point.y,4
        add     eax,4
        add     ecx,4
        INVOKE  Ellipse,hdcMem,point.x,point.y,eax,ecx
;angle2¬O®ÉÄÁÄÁ­±¤Wªº¤p¨è«×¡A¤]´N¬O«ü12©M5¨è«×¤§¶¡ÁÙ¦³¥|­Ó¤pªº¨è«×
        mov     angle2,6
next:           mov     eax,angle1
                add     eax,angle2
                push    eax
                INVOKE  CalcDot,92,eax
                INVOKE  MoveToEx,hdcMem,eax,ecx,NULL
                pop     eax
                INVOKE  CalcDot,97,eax
                INVOKE  LineTo,hdcMem,eax,ecx
                add     angle2,6
                cmp     angle2,30
                jb      next
        add     angle1,30
        cmp     angle1,360
        jb      @b
        INVOKE  ReleaseDC,hwin,hDC
        ret
DrawBmpAndClock ENDP
;-------------------------------------------------------------------------------
;­pºâ®É°w¡B¤À°w¡B¬í°wªº³»ÂI®y¼Ð¡A®É°w¡B¤À°w¦³¥|­Ó³»ÂI¡A¬í°w¦³¨â­Ó³»ÂI
;¿é¤J¡Ðvalue¡G®É¡B¤À©Î¬í
;      r¡G¶ZÂ÷ÄÁ­±¤¤¤ß¦³¦h»·
;      flag¡Gªí¥Ü²{¦b­pºâªº¬O®É°w¡B¤À°wÁÙ¬O¬í°wªº³»ÂI¡Ah¡Bm¡Bs¤À§Oªí¥Ü®É¡B¤À¡B¬í°w
;¿é¥X¡ÐEAX¡GX®y¼Ð
;      ECX¡GY®y¼Ð
CalcPinDot      PROC    value:DWORD,r:DWORD,flag:DWORD
                LOCAL   angle:DWORD
                fild    value
;¦pªGvalue¶W¹L12(­pºâ®É°w³»ÂI®É)©Î60(­pºâ¤À¡B¬í°w³»ÂI®É)¡AÀ³¨Ï¨ä¦b0¡ã11©Î0¡ã59ªº½d³ò¤º
     .IF flag=='h'
          .IF value>=12
                fisub   twelve
          .ENDIF
                ;¨Ï¤ÀÄÁ°£¥H60¦A¥[¤W®É¼Æ¡AÅܦ¨½T¹êªº®É¼Æ¡A¨Ò¦p4®É30¤ÀÅܦ¨4.5¤p®É
                fild    loctime.wMinute
                fidiv   sixty
                fadd
                fimul   five    ;®É°w¨C¤p®É¨«30«×¡A¦ý¬°¤F°t¦X¤À°w¡B¬í°w¡A¦¹³B¶È­¼¥H5
     .ELSE
          .IF value>=60
                fisub   sixty
          .ENDIF
     .ENDIF
                fisub   fifteen ;®É¡B¤À¡B¬í°w¨¤«×À³¥Ñ³q¹LÄÁ­±¤¤¤ßªº¹]««½u¶¶®É°w¶}©l
                fimul   six     ;¨C¤ÀÄÁ¨¤«×¬°6«×
                cmp     flag,'h'
                je      @f
                cmp     value,15;¤À¡B¬í°w­Y¤p©ó15¤À©Î15¬í·|ÅÜ­t¼Æ¡A¦A¥[¤W360¨Ï¤§ÅÜ¥¿
                jae     @f
                fiadd   dw360
@@:             fistp   angle
                INVOKE  CalcDot,r,angle
                ret
CalcPinDot      ENDP
;-------------------------------------------------------------------------------
DrawPin PROC    hdc:HDC
        INVOKE  GetLocalTime,OFFSET loctime
        cmp     loctime.wHour,12
        jb      @f
        sub     loctime.wHour,12
;µe®É°w¡A®É°wªø75¹Ï¯À¡A®ÉÄÁ¤¤¤ß§â®É°w¤À¦¨60¡B15¹Ï¯À¡A®É°w³Ì¼e³B¼e10­Ó¹Ï¯À
@@:     INVOKE  BeginPath,hdc
        INVOKE  CreatePen,PS_SOLID,1,0448800h
        INVOKE  SelectObject,hdc,eax
        INVOKE  DeleteObject,eax
        INVOKE  CreateSolidBrush,0448800h
        INVOKE  SelectObject,hdc,eax
        INVOKE  DeleteObject,eax
        movzx   edx,loctime.wHour
        INVOKE  CalcPinDot,edx,60,'h'
        INVOKE  MoveToEx,hdc,eax,ecx,NULL
        add     loctime.wHour,3
        movzx   edx,loctime.wHour
        INVOKE  CalcPinDot,edx,5,'h'
        INVOKE  LineTo,hdc,eax,ecx
        add     loctime.wHour,3
        movzx   edx,loctime.wHour
        INVOKE  CalcPinDot,edx,15,'h'
        INVOKE  LineTo,hdc,eax,ecx
        add     loctime.wHour,3
        movzx   edx,loctime.wHour
        INVOKE  CalcPinDot,edx,5,'h'
        INVOKE  LineTo,hdc,eax,ecx
        INVOKE  CloseFigure,hdc
        INVOKE  EndPath,hdc
        INVOKE  FillPath,hdc
;µe¤À°w¡A¤À°wªø95¹Ï¯À¡A®ÉÄÁ¤¤¤ß§â¤À°w¤À¬°75¡B20¹Ï¯À¡A¤À°w³Ì¼e³B¼e8­Ó¹Ï¯À
        INVOKE  CreatePen,PS_SOLID,1,0884400h
        INVOKE  SelectObject,hdc,eax
        INVOKE  DeleteObject,eax
        INVOKE  CreateSolidBrush,0884400h
        INVOKE  SelectObject,hdc,eax
        INVOKE  DeleteObject,eax
        INVOKE  BeginPath,hdc
        movzx   edx,loctime.wMinute
        INVOKE  CalcPinDot,edx,75,'m'
        INVOKE  MoveToEx,hdc,eax,ecx,NULL
        add     loctime.wMinute,15
        movzx   edx,loctime.wMinute
        INVOKE  CalcPinDot,edx,4,'m'
        INVOKE  LineTo,hdc,eax,ecx
        add     loctime.wMinute,15
        movzx   edx,loctime.wMinute
        INVOKE  CalcPinDot,edx,20,'m'
        INVOKE  LineTo,hdc,eax,ecx
        add     loctime.wMinute,15
        movzx   edx,loctime.wMinute
        INVOKE  CalcPinDot,edx,4,'m'
        INVOKE  LineTo,hdc,eax,ecx
        INVOKE  CloseFigure,hdc
        INVOKE  EndPath,hdc
        INVOKE  FillPath,hdc
;µe¬í°w¡A¬í°wªø110¹Ï¯À¡A®ÉÄÁ¤¤¤ß§â¬í°w¤À¬°85¡B25¹Ï¯À
        INVOKE  CreatePen,PS_SOLID,2,0ffh
        INVOKE  SelectObject,hdc,eax
        INVOKE  DeleteObject,eax
        movzx   edx,loctime.wSecond
        INVOKE  CalcPinDot,edx,85,'s'   ;­pºâ¬í°w°w¦yªº®y¼Ð
        INVOKE  MoveToEx,hdc,eax,ecx,NULL
        movzx   edx,loctime.wSecond
        add     edx,30                  ;­Y²{¦b¬°20¬í¡A¨º»ò¬í°w¤Ï¦V±N«ü¦V50¬í
        INVOKE  CalcPinDot,edx,25,'s'   ;­pºâ¤Ï¦V¬í°w°w¦y®y¼Ð
        INVOKE  LineTo,hdc,eax,ecx
        INVOKE  GetStockObject,BLACK_PEN
        INVOKE  SelectObject,hdc,eax
        INVOKE  DeleteObject,eax
        INVOKE  GetStockObject,BLACK_BRUSH
        INVOKE  SelectObject,hdc,eax
        INVOKE  DeleteObject,eax
;µe¥X¤¤¤ß¶êÂI
        mov     eax,ptCntr.x
        mov     ecx,ptCntr.y
        mov     point.x,eax
        mov     point.y,ecx
        sub     point.x,3
        sub     point.y,3
        add     eax,3
        add     ecx,3
        INVOKE  Ellipse,hdc,point.x,point.y,eax,ecx
        ret
DrawPin ENDP
;-------------------------------------------------------------------------------
WndProc         PROC    hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
                LOCAL   hRegion:HANDLE,hdc:HDC
.IF uMsg==WM_COMMAND
     .IF lParam==0
                mov     eax,wParam
          .IF ax==IDM_EXIT
                jmp     exit
          .ELSE
                push    eax
                mov     mii.fMask,MIIM_STATE
                mov     mii.fState,MFS_UNCHECKED
                INVOKE  SetMenuItemInfo,hMenu,dwCheckMenuItem,FALSE,OFFSET mii
                pop     eax
                mov     dwCheckMenuItem,eax
                mov     mii.fState,MFS_CHECKED
                INVOKE  SetMenuItemInfo,hMenu,eax,FALSE,OFFSET mii
                INVOKE  DrawBmpAndClock,hWnd
                jmp     refresh
          .ENDIF
     .ENDIF

.ELSEIF uMsg==WM_PAINT
                INVOKE  BeginPaint,hWnd,OFFSET ps
                INVOKE  BitBlt,ps.hdc,0,0,CLOCK_SIZE,CLOCK_SIZE,hdcMem,0,0,SRCCOPY
                INVOKE  DrawPin,ps.hdc
                INVOKE  EndPaint,hWnd,OFFSET ps

.ELSEIF uMsg==WM_TIMER
refresh:        INVOKE  InvalidateRect,hWnd,NULL,TRUE

.ELSEIF uMsg==WM_RBUTTONDOWN
                INVOKE  GetCursorPos,OFFSET point
                INVOKE  TrackPopupMenu,hMenu,TPM_LEFTALIGN,point.x,point.y,0,hWnd,0

.ELSEIF uMsg== WM_LBUTTONDOWN
                INVOKE  SetCursor,hCursorHand
                INVOKE  ReleaseCapture
                INVOKE  SendMessage,hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0
                INVOKE  SetCursor,wc.hCursor

.ELSEIF uMsg==WM_CREATE
        ;«Ø¥ß¨Ã³]©w¼u¥X¿ï³æ
                finit
                INVOKE  CreatePopupMenu
                mov     hMenu,eax
                mov     mii.cbSize,SIZEOF MENUITEMINFO
                mov     mii.fMask,MIIM_TYPE or MIIM_ID
                mov     mii.fType,MFT_STRING or MFT_RADIOCHECK
                mov     mii.dwTypeData,OFFSET szBoy
                mov     mii.wID,IDM_BOY
                INVOKE  InsertMenuItem,hMenu,0,TRUE,OFFSET mii
                mov     mii.dwTypeData,OFFSET szGirl
                mov     mii.wID,IDM_GIRL
                INVOKE  InsertMenuItem,hMenu,1,TRUE,OFFSET mii
                mov     mii.dwTypeData,OFFSET szDog
                mov     mii.wID,IDM_DOG
                INVOKE  InsertMenuItem,hMenu,2,TRUE,OFFSET mii
                mov     mii.fType,MFT_SEPARATOR
                INVOKE  InsertMenuItem,hMenu,3,TRUE,OFFSET mii
                mov     mii.fType,MFT_STRING
                mov     mii.dwTypeData,OFFSET szExit
                mov     mii.wID,IDM_EXIT
                INVOKE  InsertMenuItem,hMenu,4,TRUE,OFFSET mii
                mov     mii.fMask,MIIM_STATE
                mov     mii.fState,MFS_CHECKED
                INVOKE  SetMenuItemInfo,hMenu,IDM_BOY,FALSE,OFFSET mii
        ;³]©w¬°¶ê§Îµøµ¡
                INVOKE  CreateEllipticRgn,0,0,CLOCK_SIZE+1,CLOCK_SIZE+1
                mov     hRegion,eax
                INVOKE  SetWindowRgn,hWnd,eax,TRUE
                INVOKE  DeleteObject,hRegion
        ;³]©w­p®É¾¹
                INVOKE  SetTimer,hWnd,dwTimerID,1000,NULL
        ;³]©w¤º©wªº­I´º¹Ï¨Ãµe¥XÄÁ­±ªº¨è«×
                INVOKE  DrawBmpAndClock,hWnd

.ELSEIF uMsg==WM_DESTROY
exit:           INVOKE  PostQuitMessage,NULL
                INVOKE  KillTimer,hWnd,dwTimerID
                INVOKE  DeleteDC,hdcMem

.ELSE
                INVOKE  DefWindowProc,hWnd,uMsg,wParam,lParam
                ret

.ENDIF
                xor     eax,eax
                ret
WndProc         ENDP
;-------------------------------------------------------------------------------
start:  INVOKE  GetModuleHandle,NULL
        mov     hInstance,eax
        mov     wc.cbSize,SIZEOF WNDCLASSEX
        mov     wc.style,CS_HREDRAW or CS_VREDRAW
        mov     wc.lpfnWndProc,OFFSET WndProc
        mov     wc.cbClsExtra,NULL
        mov     wc.cbWndExtra,NULL
        mov     wc.hInstance,eax
        INVOKE  LoadIcon,NULL,OFFSET szClockIcon
        mov     wc.hIcon,eax
        mov     wc.hIconSm,eax
        INVOKE  LoadCursor,NULL,IDC_ARROW
        mov     wc.hCursor,eax
        mov     wc.hbrBackground,COLOR_WINDOW+1
        mov     wc.lpszMenuName,NULL
        mov     wc.lpszClassName,OFFSET szClassName
        INVOKE  RegisterClassEx,OFFSET wc
;¨ú±o¿Ã¹õ¼e«×¤Î°ª«×¡A¨Ã´î¥hÄÁ­±¤j¤p¡A¦A°£¥H¤G¡A¨Ï®ÉÄÁ©ñ¦b¿Ã¹õ¥¿¤¤¥¡
        INVOKE  GetSystemMetrics,SM_CXSCREEN
        sub     eax,CLOCK_SIZE
        shr     eax,1
        push    eax
        INVOKE  GetSystemMetrics,SM_CYSCREEN
        sub     eax,CLOCK_SIZE
        pop     edx
        shr     eax,1
        INVOKE  CreateWindowEx,NULL,OFFSET szClassName,OFFSET szAppName,\ 
                WS_POPUP or WS_SYSMENU,edx,eax,CLOCK_SIZE,CLOCK_SIZE,0,\
                NULL,hInstance,NULL 
        mov     hwnd,eax
        INVOKE  ShowWindow,eax,SW_SHOWDEFAULT
        INVOKE  LoadCursor,NULL,IDC_HAND
        mov     hCursorHand,eax
        INVOKE  UpdateWindow,hwnd
.WHILE TRUE
        INVOKE  GetMessage,OFFSET msg,NULL,0,0
.BREAK .IF !eax
        INVOKE  TranslateMessage,OFFSET msg
        INVOKE  DispatchMessage,OFFSET msg
.ENDW
        mov     eax,msg.wParam
        INVOKE  ExitProcess,eax
;*******************************************************************************
        END     start

­n¥¿½Tªº²ÕĶ CLOCK.ASM ¥²¶·¥ý§â boy.bmp¡Bgirl.bmp¡Bdog.bmp¡Bclock02.ico¡Bclock.asm ©M clock.rc ¤»­ÓÀɮשñ¦b¦P¤@­Ó¤l¥Ø¿ýùØ¡A¨Ò¦p³£©ñ¦b¡yE:\HomePage\SOURCE\CLOCK¡z¤l¥Ø¿ýùØ¡AµM«á¦b XP ®à­±¶}±Ò¡y¶}©l¡z¡B¡y©Ò¦³µ{¦¡¡z¡B¡yªþÄÝÀ³¥Îµ{¦¡¡z¡B¡y©R¥O´£¥Ü¦r¤¸¡z¡A¿é¤J¤U­±«ü¥O¡G

E:\HomePage\SOURCE\CLOCK>rc clock.rc [Enter]

E:\HomePage\SOURCE\CLOCK>ml clock.asm /link clock.res [Enter]
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

 Assembling: clock.asm
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/SUBSYSTEM:WINDOWS
"clock.obj" /DEBUG
"/OUT:clock.exe"
"clock.res"

E:\HomePage\SOURCE\CLOCK>

³o¼Ë´N¥i¥H±o¨ì CLOCK.EXE ÀÉ¡C¦pªGŪªÌ·Q¸Õ¸Õ¡A¤p¤ì°¸§â clock02.ico¡Bclock.asm ©M clock.rc ¤T­ÓÀÉ®×À£ÁY¦¨ CLOCK.RAR ÀÉ¡A¦Ü©ó³Ñ¤Uªº¤T­ÓÂI°}¹Ï¥i±q¤Wªí¤¤¤U¸ü¡A±N³o¤»­ÓÀɮשñ¦b¦P¤@¤l¥Ø¿ý¨Ì¤Wªk²ÕĶ§Y¥i±o CLOCK.EXE¡C


¨S¦³¼ÐÃDÄæ¡A¦p¦ó²¾°Êµøµ¡¡H

CLOCK.EXE µ{¦¡¨Ã¨S¦³¼ÐÃDÄæ¡A¦ý¬O¤p¤ì°¸«o§Æ±æ¦pªG¨Ï¥ÎªÌ§â·Æ¹«²¾¨ì CLOCK ªº¶ê§Îµøµ¡¤W­±¡A¨ÃÀ£¤U·Æ¹«¥ªÁä¡A¤´¯à²¾°Ê CLOCK µøµ¡¡A¤p¤ì°¸¨Ï¥Îªº¤èªk¬O´ÛÄF Windows §@·~¨t²Î¡C¦b´¶³qªº±¡§Î¤U¡A·Æ¹«´å¼Ð¦ì©ó¤u§@°Ï¦Ó¨Ï¥ÎªÌ«ö¤U·Æ¹«¥ªÁä®É¡A§@·~¨t²Î·|µo°e WM_LBUTTONDOWN µ¹µøµ¡¡ACLOCK «o¦b³B²z WM_LBUTTONDOWN °T®§®É°½°½¦aµo°e WM_NCLBUTTONDOWN °T®§µ¹¦Û¤v¡AÅý¨t²Î¥H¬°¨Ï¥ÎªÌ¬O¦b«D¤u§@°ÏùØ«ö¤U¤F·Æ¹«¥ªÁä¡C

WM_NCLBUTTONDOWN °T®§

·í·Æ¹«´å¼Ð¦b«D¤u§@°ÏùØ¡A¦p¼ÐÃDÄæ¡BÃä®Ø¡A¦Ó¨Ï¥ÎªÌ¤S«ö¤U·Æ¹«¥ªÁä®É¡A¨t²Îµo°e WM_NCLBUTTONDOWN µ¹¸Óµøµ¡¡C³o®É­Ô¡AlParam ¬O«ü¦V POINT µ²ºcÅ骺¦ì§}¡A³o­Óµ²ºcÅé¥H¿Ã¹õ¥ª¤W¨¤¬°°Ñ¦ÒÂI¡A¦s©ñ·Æ¹«´å¼Ð¦b¿Ã¹õ¤Wªº¦ì¸m¡CwParam °Ñ¼Æ«h¬O¥Nªí hit-test values¡A¨ä³¡¥÷·N¸q¦p¤Uªí¡G

¼Æ­È ·N¡@¸q¼Æ­È ·N¡@¸q
HTBOTTOM´å¼Ð¦b©³Ãä®Ø HTBOTTOMLEFT´å¼Ð¦b¥ª¤U¨¤Ãä®Ø
HTBOTTOMRIGHT´å¼Ð¦b¥k¤U¨¤Ãä®Ø HTCAPTION´å¼Ð¦b¼ÐÃDÄæ
HTHSCROLL´å¼Ð¦b¤ô¥­±²¶b HTLEFT´å¼Ð¦b¥ªÃä®Ø
HTMENU´å¼Ð¦b¿ï³æ¤W HTBOTTOMRIGHT´å¼Ð¦b¥k¤U¨¤Ãä®Ø
HTSYSMENU´å¼Ð¦b¨t²Î¿ï³æ HTREDUCE´å¼Ð¦bÁY¤p²°

¦b COLCK.ASM ùØ¡A¤p¤ì°¸¦b³B²z WM_LBUTTONDOWN °T®§®É¡Aµo°e¥H HTCAPTION ¬°°Ñ¼Æªº WM_NCLBUTTONDOWN °T®§¡A´ÛÄF Windows §@·~¨t²Î¡A¦p¤U­±µ{¦¡¡G

.ELSEIF uMsg == WM_LBUTTONDOWN
                INVOKE  SetCursor,hCursorHand
                INVOKE  ReleaseCapture
                INVOKE  SendMessage,hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0   ;´ÛÄF§@·~¨t²Î¡A¨Ï¨ä¥H¬°¨Ï¥ÎªÌ¦b¼ÐÃDÄæ«ö¤U·Æ¹«¥ªÁä
                INVOKE  SetCursor,wc.hCursor

SetCursor

SetCursor ·|§ïÅܷƹ«´å¼Ðªº§Îª¬¡A¨ä­ì«¬¬O¡G

HCURSOR SetCursor(
    HCURSOR     hCursor         // handle of cursor
   );

°Ñ¼Æ hCursor ¬O CreateCursor¡BLoadCursor ©Î LoadImage ©Ò¶Ç¦^ªº´å¼Ð¥N½X¡A¦pªG¦¹°Ñ¼Æ¬O NULL¡A¨º»ò´å¼Ð´N·|®ø¥¢¡CCLOCK.ASM ¦b³B²z WM_LBUTTONDOWN °T®§ªº²Ä¤@±ø«ü¥O§â·Æ¹«´å¼ÐÅܦ¨¤â§Î¡A³o­Ó´å¼Ð§Îª¬¬O¨t²Î¤w¸g¹w¥ý©w¸q¹Lªº¡A¥iª½±µ¨Ï¥Î¡C³B²z WM_LBUTTONDOWN ³Ì«á¤@±ø«ü¥O¬O©I¥s SetCursor «ì´_¦¨­ì¨Ó½bÀYªº´å¼Ð§Îª¬¡C


µe¥X®É°w¡B¤À°w

¦]¬°®É°w¡B¤À°wªºªø«×¬O©T©wªº¡A¦ý¦b¤£¦Pªº®É¶¡»P¾î®y¼Ðªº§¨¨¤¬O¤£¦Pªº¡A½Ð°Ñ¦Ò¥k¹Ï¡A°²³]°w¦y¨«¨ì A ÂI¡AA ÂI»PÄÁ­±¤¤¤ß O ÂIªº¶ZÂ÷¬O r¡A¥B OA »P¾î®y¼Ðªº§¨¨¤¬°£K¡A¥i¥H±oª¾¦b¤ô¥­¤è¦V A ÂI»P O ÂI¬Û¶Z rcos£K¡A««ª½¤è¦V¬Û¶Z rcos£K¡A©Ò¥HÄÁ­±¤W»P¤¤¤ß¬Û¶Z r ªº¥ô¤@ÂI®y¼Ð¬°¡G

X¡×¤¤¤ßÂIªº X ®y¼Ð¡Ïrcos£K
Y¡×¤¤¤ßÂIªº Y ®y¼Ð¡Ïrsin£K

³o¥ó¤u§@¥Ñ CalcDot °Æµ{¦¡§¹¦¨¡C

¤£ºÞ¬Oµe®É°w¤]¦n¡AÁÙ¬O¤À°w¤]¦n¡A³£»Ý­n­pºâ¥|­Ó³»ÂI¡C¨Ò¦p°²³]¥k¹Ï¬O 4¡G20 ¤Àªº®É­Ô¡A¤À°w©Ò¦b¦ì¸m¡A¨º»ò¥²¶·§â A¡BB¡BC¡BD ¥|ÂI³s°_¨Ó§Î¦¨¤@­Ó«Ê³¬¸ô®|¡A¦A©I¥s FillPath ¶ñº¡²`ÂŦâ§Y¥i¡CA ÂIªº®y¼Ð¨Ã¤£Ãø¨D¡A¦ý¬O¤p¤ì°¸Á٧Ʊæ¦b¶i¦æø»s®É°w©Î¤À°w®É¡A¥u­n¥H´X®É´X¤À¬°°Ñ¼Æ©I¥s°Æµ{¦¡­pºâ°w¦y¦yºÝªº®y¼Ð§Y¥i¡A°²³]³o­Óµe°w¦y¦yºÝªº°Æµ{¦¡¦W¬° CalcPinDot¡A¨º»ò­n­pºâ 4¡G20 ¤À¤À°w«eºÝ®y¼Ð¡A¥u­n¥Î

        INVOKE  CalcPinDot,75,20,'m'

©I¥s CalcPinDot §Y¥i¡A75 ¬O¤À°w«eºÝªø«×¡A¡y20¡zªí¥Ü 20 ¤À¡A¡y'm'¡zªí¥Ü¤À°w¡ACalcPinDot ·|§â­pºâ©Ò±oªº X ®y¼Ð¡BY ®y¼Ð¤À§O¦s©ó EAX¡BECX ¨Ã¶Ç¦^¨Ó¡C­pºâ B¡BC¡BD ¤TÂIªº®y¼Ð¤ñ¸û³Â·Ð¡A¦ý¬O§Ú­Ì¥i¥H³o¼Ë·Q¡G·í¤À°w¬° 20 ¤À®É¡AOB ÂI»P OA ««ª½¡A©Ò¥H¥i¥H§â B ÂI«ä¦Ò¦¨¬O 35 ¤À®É¡A¤À°w«eºÝ¦ì¸m¡A¦ý¬Oªø«×«h¤£¨ì 75¡A¤p¤ì°¸°²³]¤À°w¼e¬° 8¡A¬G OB ªºªø«×¬° 4¡C¦P²z¡AC ÂI¥i¥H·Q¦¨¬O 55 ¤À®É¤À°w«eºÝ¦ì¸m¡A¦ý¬Oªø«×«h¬° 15¡C´«¥y¸Ü»¡¡A¤À°w B ÂI¤ñ A ÂI¦h 15 ¤ÀÄÁ¡AC ÂI¤ñ A ÂI¦h 30 ¤ÀÄÁ¡AD ÂI¤ñ A ÂI¦h 45 ¤ÀÄÁ¡C©Ò¥H¦pªG¤w¸g¨ú±o®É¶¡¡A¨Ã¦s©ó loctime µ²ºcÅé«á¡A¥i¥H¥Î¥H¤Uµ{¦¡¤ù¬qµe¥X¶ñº¡¤À°wªº¹Ï§Î¡G

        movzx   edx,loctime.wMinute
        INVOKE  CalcPinDot,edx,75,'m'           ;­pºâ A ÂI®y¼Ð
        INVOKE  MoveToEx,hdc,eax,ecx,NULL
        add     loctime.wMinute,15
        movzx   edx,loctime.wMinute
        INVOKE  CalcPinDot,edx,4,'m'           ;­pºâ B ÂI®y¼Ð
        INVOKE  LineTo,hdc,eax,ecx
        add     loctime.wMinute,15
        movzx   edx,loctime.wMinute
        INVOKE  CalcPinDot,edx,20,'m'           ;­pºâ C ÂI®y¼Ð
        INVOKE  LineTo,hdc,eax,ecx
        add     loctime.wMinute,15
        movzx   edx,loctime.wMinute
        INVOKE  CalcPinDot,edx,4,'m'           ;­pºâ D ÂI®y¼Ð
        INVOKE  LineTo,hdc,eax,ecx
        INVOKE  CloseFigure,hdc

¦^¨ì­º­¶¡A ¨ì²Ä¤Q¤C³¹¡A ¨ì²Ä¤Q¤E³¹