Ch 15 ±±¨î¥xµ{¦¡

Windows §@·~¨t²Î¯à¦¨¬°¤j¦h¼Æ¤H¨Ï¥Îªº§@·~¨t²Î¡A¤£¥i¿Ð¨¥ªº¡A¹Ï§Î¬É­±ªº¾Þ§@¤è«K¤Î¿Ë©M¤O¬O­«­nªº­ì¦]¡CÁöµM²{¦b¤j³¡¤Àªº Win32 µ{¦¡³£¤w¦³º}«Gªº¹Ï§Î¬É­±¡A¦ý¬O§Ú­Ì¤´µM¥i¥H¨Ï¥Î©Î¼¶¼g¥H¤å¦r¾É¦V¾Þ§@¤è¦¡ªºµ{¦¡¡C¨Ò¦p¡A¦b Windows XP ¤¤´£¨Ñ¡y©R¥O´£¥Ü¦r¤¸¡z°õ¦æ¥H¤å¦rµe­±¿é¥X©Î¿é¤Jªºµ{¦¡¡A´N¹³¥H«eªº DOS µ{¦¡¤@¼Ë¡C

³o¨Çµ{¦¡ÁöµM¨S¦³º}«Gªº¹Ï§Î¬É­±¡A¦ý¬O¤p¦Ó§Ö³t¬O¨äÀuÂI¡A©Ò¥H¤´µM¦³³\¦h¤HÁÙ¦b¨Ï¥ÎµÛ³o¨Çµ{¦¡¡A¹³¬O ping¡Bipconfig¡Bftp µ¥µ{¦¡³£¬O±`±`³Q¨Ï¥Îªº¡C³o¨Çµ{¦¡¤´µM¬O 32 ¦ì¤¸ªºµ{¦¡¡A¥¦­Ì¤]³£ÄÝ©ó PE ®æ¦¡¡A¤]¯à°õ¦æ¦h°õ¦æºü¡A¥¦­Ì°£¤F¨S¦³µØÄRªºµøµ¡¥~¡A©M¤@¯ëªº Win32 µ{¦¡¤@¼Ë¡A³o¨Çµ{¦¡ºÙ¬°¡y±±¨î¥xµ{¦¡¡z( console program¡A©ÎºÙ¡y¥D±±¥xµ{¦¡¡z)¡AŪªÌ¶·ª¾¡A¥L­Ì©M¥H«eªº DOS µ{¦¡¬O¤£¦Pªº¡C³o¤@³¹±N¤¶²Ð¦p¦ó¼¶¼g±±¨î¥xµ{¦¡¡C


­ì²z

¦b 16 ¦ì¤¸ªº DOS ¨t²ÎùØ¡A¿Ã¹õ»PÁä½L³Qµø¬°¼Ð·Ç¿é¥X¿é¤J³]³Æ¡A¥¦­Ì¬O¦b DOS ±Ò°Ê®É¡A¥Ñ DOS ¶}±Ò¡ADOS §â¥¦­Ìµø¬°ÀɮסA¨äÀÉ®×¥N½X¦­¤w¤À°t¥B©T©w¤£ÅÜ ( °Ñ¾\²Õ¦X»y¨¥²Ä 15 ³¹ )¡C·í§Ú­Ìªºµ{¦¡­n¹ï DOS ±±¨î¤Uªº¿Ã¹õÁä½L°µ¿é¥X©Î¿é¤J®É¡A¥i¹ï³o¨Ç¡yÀÉ®×¥N½X¡z°µ¿é¥X©Î¿é¤J°Ê§@¡C¨Ò¦p¡A¹ï¼Ð·Ç¿é¥X³]³Æ ( ÀÉ®×¥N½X¬° 01H ) ¼g¤J¡A·N§Y¦b¿Ã¹õ¤W¿é¥X¤å¦r¡C

Win32 ¨t²Î¤£¤@¼Ëªº¦a¤è¦b¼Ð·Ç¿é¥X¿é¤J¥N½X¤£©T©w¡A¦]¦¹¦b°µ¿é¤J©Î¿é¥X¤§«e­n¥ý¨ú±o¥¦­Ìªº¥N½X ( handle )¡A³o¶µ¤u§@¥i¥H¥Î GetStdHandle API ¨Ó°µ¡AGetStdHandle ªº­ì«¬¬O

HANDLE GetStdHandle(
  DWORD nStdHandle  // input, output, or error device
);

³o­Ó API ®Ú¾Ú nStdHandle ªº¤£¦P¡A¦b EAX ùضǦ^¼Ð·Ç¿é¥X¡B¿é¤J©Î¿ù»~¥N½X¡AnStdHandle ¥i¥H¬O¤U­±¤T­Ó¼Æ­Èªº¨ä¤¤¤§¤@¡G

  1. STD_INPUT_HANDLE¡G¨ú±o¼Ð·Ç¿é¤J¥N½X¡C
  2. STD_OUTPUT_HANDLE¡G¨ú±o¼Ð·Ç¿é¥X¥N½X¡C
  3. STD_ERROR_HANDLE¡G¨ú±o¼Ð·Ç¿ù»~¥N½X¡C

¦pªG­n¿é¤J¸ê®Æ¥i¥H¥Î ReadFile ©Î ReadConsole¡CReadConsole API ªº­ì«¬¬O¡G

BOOL ReadConsole(
  HANDLE  hConsoleInput,        // handle to a console input buffer
  LPVOID  lpBuffer,             // address of buffer to receive data
  DWORD   nNumberOfCharsToRead, // number of characters to read
  LPDWORD lpNumberOfCharsRead,  // address of number of characters read
  LPVOID  lpReserved            // reserved
);

hConsoleInput ¬O¤§«e¥Î GetStdHandle API ªº¶Ç¦^­È¡A¦¹¶Ç¦^­È·íµM±o¥Î STD_INPUT_HANDLE ¬°°Ñ¼Æ©I¥s GetStdHandle ©Ò±o¤§µ²ªG¡ClpBuffer ¬O«ü½w½Ä°Ï¦ì§}¡A¨Ï¥ÎªÌ¿é¤Jªº¸ê®Æ·|¦s¦b³o­Ó½w½Ä°ÏùØ¡A¦P®É¨t²ÎÁÙ·|¦b¸ê®Æªº³Ì«á¥[¤W´«¦æ¤ÎÂk¦ì½X ( 0ah¡A0dh )¡CnNumberOfCharsToRead ¬O«ü½w½Ä°Ï®e¶q¡ClpNumberofCharsRead ¬O¤@­Ó«ü¼Ð¡A³o­Ó«ü¼ÐÀ³¸Ó«ü¦V¤@­ÓÂù¦r²Õ ( 32 ¦ì¤¸ªø ) ÅܼơA·í ReadConsole µ²§ô®É·|¦b³o­ÓÂù¦r²ÕÅܼÆùئs©ñ¹ê»Ú¦³´X­Ó¦ì¤¸²Õ³Q©ñ¤J½w½Ä°ÏùØ¡A¦¹¦ì¤¸²Õ¼Æ¥]§t¤F´«¦æ¤ÎÂk¦ì¨â¦ì¤¸²Õ¡C¡C¦pªG¨Ï¥ÎªÌ¿é¤Jªº¦ì¤¸²Õ¼Æ ( ¥]§t 0dh¡B0ah ) ¤ñ nMumberOfCharsToRead ¤j¡A¨º»ò¶W¹Lªº³¡¥÷¡AÁöµM·|Åã¥Ü¦b¿Ã¹õ¤W¡A¦ý¬O«o¤£·|¦s©ñ¦b½w½Ä°ÏùØ¡C

¦pªG­n¦b±±¨î¥x¤W¿é¥X¤å¦r¡A«h¥Î WriteConsole¡A¨ä­ì«¬¬°¡G

BOOL WriteConsole(
  HANDLE  hConsoleOutput,        // handle to a console screen buffer
  CONST   VOID *lpBuffer,        // pointer to buffer to write from
  DWORD   nNumberOfCharsToWrite, // number of characters to write
  LPDWORD lpNumberOfCharsWritten,// pointer to number of characters written
  LPVOID  lpReserved             // reserved
);

WriteConsole ªº°Ñ¼Æ©M ReadConsole Ãþ¦ü¡A¤p¤ì°¸´N¤£¦h°µ¤¶²Ð¤F¡C©³¤U¬O¤@­Ó²³æªº±±¨î¥xµ{¦¡¡G

        .586
        .model  flat,stdcall
        option  casemap:none

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

BufferSize      equ     10h
;***********************************************************
                .data
hOutput         HANDLE  ?
hInput          HANDLE  ?
dWrittee        DWORD   ?
dRead           DWORD   ?
sName           BYTE    '½Ð¿é¤J±zªº©m¦W¡G'
sBuffer         BYTE    BufferSize dup (0)
sHowAreYou      BYTE    '¡A±z¦n¶Ü¡H'
;***********************************************************
        .code
start:  invoke  GetStdHandle,STD_OUTPUT_HANDLE
        mov     hOutput,eax
        invoke  GetStdHandle,STD_INPUT_HANDLE
        mov     hInput,eax

        invoke  WriteConsole,hOutput,offset sName,16,offset dWritten,NULL
        invoke  ReadConsole,hInput,offset sBuffer,BufferSize-2,offset dRead,NULL
        mov     edi,offset sBuffer
        mov     esi,offset sHowAreYou
        mov     al,0dh
        mov     ecx,dRead
        repne   scasb
        jne     @f              ;¨S§ä¨ì0dh¡Aªí¥Ü¿é¤J¦r¤¸¤ñBufferSize¤j
        dec     edi             ;§ä¨ì¤F0dh¡Aªí¥Ü¿é¤J¦r¤¸¤ñBufferSize¤p
        jcxz    tail            ;­YCX=0¡Aªí¥Ü0dh«ê¦n¬O½w½Ä°Ïªº³Ì«á¤@¦r¤¸
        dec     dRead
tail:   dec     dRead
@@:     mov     ecx,10          ;sHowAreYou ¦r¦êªø«×
        mov     edx,ecx
        rep     movsb
        add     edx,dRead
        invoke  WriteConsole,hOutput,offset sBuffer,edx,offset dWritten,NULL
        invoke  ExitProcess,NULL
;***********************************************************
        end     start

§â¥¦¦s¦¨ CONSOLE1.ASM «á¦A¥H¤U­±¨BÆJ²ÕĶ¡G

  1. ¶}±Ò Windows XP ªº©R¥O´£¥Ü¦r¤¸¡A¨Ã¤Á´«¨ì CONSOLE1.ASM ©Ò¦b¤l¥Ø¿ý¡C¦¹³B°²³] CONSOLE1.ASM ¦b E:\HomePage\SOURCE ¤l¥Ø¿ýùØ¡A¦]¦¹¿é¤J©³¤U«ü¥O¡G
    C:\>cd e:\homepage\source [Enter]
    C:\>e: [Enter]
    E:\HomePage\SOURCE>
  2. ³]©w¸ô®|¡A¨Ï¨ä«ü¦V ML.EXE ¤Î LINK.EXE ©Ò¦b¤l¥Ø¿ý¡C¨Ò¦p¤p¤ì°¸ªº¹q¸£¤¤¡A²ÕĶ¾¹¤Î³sµ²¾¹¦b C:\masm32\bin ¤l¥Ø¿ýùØ¡A¦b©R¥O´£¥Ü¦r¤¸¤¤¿é¤J¡G
    E:\HomePage\SOURCE>path C:\masm32\bin;%path% [Enter]
  3. ³]©w³sµ²®É²£¥Í±±¨î¥xµ{¦¡¡A³o¤@¦æ«ü¥O²o¯A¨ì ML.EXE ªº¿ï¾Ü°Ñ¼Æ¡A¶·ª`·N¤j¤p¼g¡A§_«h·|²£¥Í¿ù»~¡C¦¹¥~¡Aª`·N»s§@¨t²Î°Ñ¼Æ¥Î¡y/SUBSYSTEM:CONSOLE¡z¡A¤p¤ì°¸¦³¦n´X¦¸³£¬O¦]¬°³o­Ó°Ñ¼Æ¤U¿ù¤F¡A¦ÓµLªk³sµ²¦¨¥\¡C¦b©R¥O´£¥Ü¦r¤¸¤¤¿é¤J¡G
    E:\HomePage\SOURCE>set ml=/coff /link /SUBSYSTEM:CONSOLE [Enter]
  4. ³Ì«á²ÕĶ¤Î³sµ²­ì©lÀÉ¡G
    E:\HomePage\SOURCE>ml console1.asm
    ´N¤j¥\§i¦¨¤F¡C

§ïÅܱ±¨î¥x¥~Æ[

±±¨î¥xªº¿Ã¹õ½w½Ä°Ï

©Î³\¦U¦ìŪªÌ´¿¸gª`·N¨ì¡AXP ªº¡y©R¥O´£¥Ü¦r¤¸¡z¥k°¼¦³¤@±²¶b¡A¥i¥H¦V¤W±²°ÊÆ[¹î¤£¦b¿Ã¹õ¤Wªº¸ê®Æ¡Aªº½T¡A³oÂI©M Windows 95/98/98SE/Me ªº DOS ¼Ò¦¡©Î DOS ¨t²Î¬O¤£¦Pªº¡C¦b XP ùØ¡A§@·~¨t²Î·|¬°¡y©R¥O´£¥Ü¦r¤¸¡z¤À°t¤@¶ô¸ê®Æ°Ï°ì¡AºÙ¬°¡y±±¨î¥x¿Ã¹õ½w½Ä°Ï¡z( console screen buffer )¡A³o¶ô°Ï°ì¦s©ñµÛ´¿¸g©Î¥¿Åã¥Ü¦b©R¥O´£¥Ü¦r¤¸µøµ¡ªº¸ê®Æ¡A¦Ó¡y©R¥O´£¥Ü¦r¤¸¡zªºµøµ¡©Ò¯à¨£¨ìªº¥u¬O¨ä¤¤ªº¤@³¡¥÷¡C´N¹³§Ú­Ì¥Ñ©Ð¶¡¦Vµ¡¤á©¹¥~±æ¥h¡A¥u¯à¬Ý¨ì¬üÄR­·´ºªº¤@¤p³¡¥÷¤@¼Ë¡A°²¦pµ¡¤á¥i¦V¤W²¾©Î¤U²¾¡A¨º»ò´N¥i¯à¥i¥H¬Ý¨£¨ä¥L³¡¥÷ªº­·´º¤F¡C¥u¤£¹L¦b¹q¸£¤W¡A¨Ã¤£¬Oµøµ¡²¾°Ê¡A¦Ó¬O¥Î±²¶b§â­nÅã¥Üªº¸ê®Æ²¾¶iµøµ¡ªº½d³ò¤º¡C

¦b XP ¨t²Î¤¤¡A¤]¥i¥H¤£¥Î¡y©R¥O´£¥Ü¦r¤¸¡z¨Ó°µ¬°¤å¦r¾É¦V¬É­±¡A¥t¦³¤@®a JP Software ©Ò¥X«~ªº 4NT ¤]¬O±`¨£ªº¤å¦r¾É¦V¬É­±¡A°²³]±z¥H 4NT ¬°¤å¦r¾É¦V¬É­±ªº¸Ü¡A´N¤£ºÙ¬°¡y©R¥O´£¥Ü¦r¤¸µøµ¡¡z¤F¡AÀ³¸ÓºÙ¬°¡y4NT µøµ¡¡z¡C¤£ºÞ¬O¡y©R¥O´£¥Ü¦r¤¸µøµ¡¡z©Î¬O¡y4NT µøµ¡¡z¡A³£¥uÅã¥Ü¡y±±¨î¥x¿Ã¹õ½w½Ä°Ï¡zªº¤@³¡¥÷¤å¦r¦Ó¤w¡C

XP §Q¥Î CONSOLE_SCREEN_BUFFER_INFO µ²ºcÅé°O¿ý±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¸ê®Æ¡A©³¤U¬O¥¦ªº¦UÄæ¦ìªº»¡©ú¡G

CONSOLE_SCREEN_BUFFER_INFO  STRUCT
dwSize                      COORD       ?       ;±±¨î¥x¿Ã¹õ½w½Ä°Ï¤j¤p
dwCursorPosition            COORD       ?       ;´å¼Ð¦ì¸m
wAttributes                 WORD        ?       ;ÄÝ©Ê
srWindow                    SMALL_RECT  ?       ;±±¨î¥xµøµ¡¦ì¸m¦b¿Ã¹õ½w½Ä°Ï¨º¨à
dwMaximumWindowSize         COORD       ?       ;±±¨î¥xµøµ¡¥i¯à³Ì¤j½d³ò
CONSOLE_SCREEN_BUFFER_INFO  ENDS

ÅU¦W«ä¸q¡AdwSize ¬O±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¤j¤p¡A¥H¦æ»P¦C¨Óªí¥Ü¡A°O¿ý©ó COORD µ²ºcÅé¡A¨ä©w¸q¬°¡G

COORD   STRUCT
x       WORD      ?
y       WORD      ?
COORD   ENDS

x ªí¥Ü¾î®y¼Ð¦³´X­Ó¦r¤¸¡Ay «hªí¥ÜÁa®y¼Ð¦³´X­Ó¦r¤¸¡Cx ¥ç¥i¬Ý¦¨¤@¦C ( ¥Ñ¥ª¦Ó¥k ) ¦³´X­Ó¦r¤¸¡Ay ¤]¥i¥H¬Ý¦¨¦@¦³´X¦C¡C¤@¯ë¦Ó¨¥¡A¶}±Ò¡y©R¥O´£¥Ü¦r¤¸¡z«á¦pªG¨S¦³¯S§O§ó§ï¡A¨C¦C¥iÅã¥Ü 80 ­Ó¦r¤¸¡A¦@¦³ 300 ¦C¡C

dwCursorPosition ªí¥Ü¥Ø«e´å¼Ð¦b¨º¤@­Ó¦ì¸m¡A¥H COORD µ²ºcÅéªí¥Ü¡A¦¹³Bªº x¡By ¥Ñ¹s¶}©l¡C©Ò¥H¤@¯ë x ¤¶©ó 0 ¨ì 79 ¤§¶¡¡C

wAttributes ¬O¦r¤¸ÄÝ©Ê ( ¥ç§YÃC¦â )¡A¥i¥H¬O FOREGROUND_BLUE¡BFOREGROUND_GREEN¡BFOREGROUND_RED¡BFOREGROUND_INTENSITY¡BBACKGROUND_BLUE¡BBACKGROUND_GREEN¡BBACKGROUND_RED ©M BACKGROUND_INTENSITY µ¥«O¯d¦rªº²Õ¦X¡C¨ä¹ê¥L­Ì©M¦b DOS ¤å¦r¼Ò¦¡¤¤ªº¦r¤¸ÄÝ©Ê©w¸q¬Û¦P¡A¤å¦rªºÃC¦â¡AÂÅ¡Bºñ¡B¬õ¤Î±j«×¥H¤@­Ó¦r²Õªº³Ì§C¥|­Ó¦ì¤¸ ( ²Ä 0¡ã3 ¦ì¤¸ ) ¨Óªí¥Ü¡F¤å¦rªº­I´º¤]¬O¥HÂÅ¡Bºñ¡B¬õ¤Î±j«×¡A¥H¸Ó¦r²Õªº²Ä 4¡ã7 ¦ì¤¸ªí¥Ü¡C³o¨Ç¼Æ­È©Ò¥NªíªºÃC¦â¡A¥i¥H°Ñ¦Ò²Õ¦X»y¨¥²Ä 19 ³¹¡A¥H§C«G«×¥Õ¦âÅã¥Ü©ó¶Â¦â­I´º¬°¨Ò¡A¦¹¦r²Õ­È¬° 7¡C( ¥Õ¦â¬OÂÅ¡Bºñ¡B¬õ¤T¦â²Õ¦¨¡A¶À¦â¬OÂÅ¡Bºñ¨â¦â²Õ¦¨¡K¡K)

«e­±´¿´£¤Î¡A¡y©R¥O´£¥Ü¦r¤¸¡zµøµ¡©Ò¯àÅã¥Üªº¶È¬°±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¤@³¡¥÷¡A¦Ó srWindow ´N¬O¥Î¨Óªí¥Ü©ÒÅã¥Üªº³¡¥÷¦b¨º¤@¦ì¸m¡CsrWindow ¬O¤@ SMALL_RECT µ²ºcÅé¡A¨äÄæ¦ì»¡©ú¦p¤U¡G

SMALL_RECT  STRUCT
Left        WORD    ?
Top         WORD    ?
Right       WORD    ?
Bottom      WORD    ?
SMALL_RECT  ENDS

Left¡BTop ¬O¡y©R¥O´£¥Ü¦r¤¸¡zµøµ¡¥ª¤W¨¤¦b±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¦ì¸m¡FRight¡BBottom «h¬Oµøµ¡¥k¤U¨¤¦b±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¦ì¸m¡A¥|ªÌ¬Ò±q 0 ¶}©lºâ°_¡C¦b MSDN ¤¤¡ALeft¡BTop¡BRight¡BBottom ³o¥|­ÓÄæ¦ì³£¥H SHORT ªí¥Ü¡A¨ä¹ê SHORT ³oºØ¸ê®Æ«¬ºA´N¦û¦³¤@­Ó¦r²Õ ( WORD¡A§Y 16 ¦ì¤¸ªø ) ªº¤j¤p¡C

³Ì«á¤@­Ó°Ñ¼Æ¡AdwMaximumWindowSize¡Aªí¥Ü¡y©R¥O´£¥Ü¦r¤¸¡zµøµ¡ªº³Ì¤j­È¡A³o­Ó³Ì¤j­È¬O¨Ì¾Ú±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¤j¤p¡B¦r«¬ªº¤j¤p¤Î¿Ã¹õªº¤j¤p¨Ó¨M©wªº¡C±zÀ³·í¥i¥H·Q¹³¡A­Y¬O¦r§Î¶V¤j¡B¿Ã¹õ¶V¤p¡A¨º»ò¡y©R¥O´£¥Ü¦r¤¸¡zµøµ¡©Ò¯àÅã¥Üªº½d³ò´N·|¶V¤p¡AdwMaximumWindowSize ¤]·|¶V¤p¡C©³¤U¬O¤@±i¿Ã¹õ½w½Ä°Ï©M©R¥O´£¥Ü¦r¤¸µøµ¡ªºÃö«Y¹Ï¡A¹Ï¤¤²HÂŦ⪺ªø¤è§Î©Ò®Ø°_¨Óªº¬O±±¨î¥x¿Ã¹õ½w½Ä°Ï¡A¦Ó¥H¡y©R¥O´£¥Ü¦r¤¸¡z¬°¼ÐÃDªºµøµ¡´N¬O©R¥O´£¥Ü¦r¤¸µøµ¡¡A¦¹¹Ï¤¤ªº dwCursorPosition¡A§Y´å¼Ð¦ì¸m¡A¤§­È¬° 00460004h¡FsrWindow µ²ºcÅ骺¦UÄæ¦ì¡A¥ç§Y±±¨î¥xµøµ¡¦ì¸m¡ALeft¡BTop¡BRight¡BBottom ¤À§O¬° 0000¡B002Eh¡B004Fh¡B0046h¡C

¿Ã¹õ½w½Ä°Ï©M©R¥O´£¥Ü¦r¤¸µøµ¡

±ý¨ú±o±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¸ê®Æ¡A¥i¥H¥Î GetConsoleScreenBufferInfo API¡A¨ä­ì«¬¦p¤U¡G

BOOL GetConsoleScreenBufferInfo(
  HANDLE                        hConsoleOutput,             // handle to console screen buffer
  PCONSOLE_SCREEN_BUFFER_INFO   lpConsoleScreenBufferInfo   // address of screen buffer info.
);

©I¥s GetConsoleScreenBufferInfo ¤§«e¡A±o¶Ç¤J¤@­Ó«ü¦V CONSOLE_SCREEN_BUFFER_INFO µ²ºcÅ骺¦ì§}¡A¦pªG°õ¦æ¦¨¥\¡AGetConsoleScreenBufferInfo ·|¶Ç¦^ TURE¡A¨Ã±N¦¹µ²ºcÅ骺¦UÄæ¦ì¶ñ¤J¥Ø«e¤§¼Æ­È¡C

¦pªG­n³]©w¡y©R¥O´£¥Ü¦r¤¸¡zµøµ¡¤j¤p¤Î¦ì¸m¡A«h¥Î SetConsoleWindowInfo¡A¨ä°Ñ¼Æ¬°¡G

BOOL SetConsoleWindowInfo(
  HANDLE hConsoleOutput,                // handle to console screen buffer
  BOOL   bAbsolute,                     // coordinate type flag
  CONST  SMALL_RECT *lpConsoleWindow    // address of new window rectangle
);

¦¹ API ªº²Ä¤T­Ó°Ñ¼Æ¬°¤@ SMALL_RECT µ²ºcÅé¦ì§}¡A³o­Óµ²ºcÅé«ü©w¤F­n³]©wªº¡y©R¥O´£¥Ü¦r¤¸¡zµøµ¡½d³ò¡ASMALL_RECT µ²ºcÅ餺¥]§t¤Fµøµ¡ªº¥ª¤W¨¤¤Î¥k¤U¨¤¦ì¸m¡C²Ä¤G­Ó°Ñ¼Æ¡AbAbsolute¡A¥i¥H¬° TRUE ©Î FALSE¡A«eªÌªí¥Ü¦b SMALL_RECT ©Ò¦sªºµøµ¡¤j¤p¬O¥Ñ¿Ã¹õ½w½Ä°Ïªºµ´¹ï¦ì¸m ( §Y²Ä¹s¦C¡B²Ä¹s¦æ ) ¶}©lºâ°_¡F­Y¬°«áªÌ¡A«hªí¥Ü¥Ñ²{¦bµøµ¡¦ì¸m¶}©lºâ°_¡C­Y SMALL_RECT ©Ò¦s¦ì¸m¤£¦XÅÞ¿è ( ¨Ò¦p­t¼Æ¡B¥ªÃä¦ì¸m¤ñ¥kÃä¤jµ¥µ¥ )¡A«h·|²£¥Í¿ù»~¡A¶Ç¦^ FALSE ­È¡C

SetConsoleWindowInfo ¶È¶Èªí­±¤W§ïÅܤF¡y©R¥O´£¥Ü¦r¤¸¡zµøµ¡¤j¤p¨Ã§âµøµ¡²¾¨ì±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¬Y­Ó¦ì¸m¡A¹ê»Ú¤W¨Ï¥ÎªÌ¤´µM¥i¥H¾Þ§@¥kÃ䪺±²°Ê¶b²¾°Êµøµ¡»P¿Ã¹õ½w½Ä°Ïªº¬Û¹ï¦ì¸m¡A¦pªG·Q­nÅý±²°Ê¶b¤]®ø¥¢¡A´N±o³]©w±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¤j¤p¡A¥i¥H¥Î SetConsoleScreenBufferSize ¨Ó¹F¨ì³o¥Øªº¡CSetConsoleScreenBufferSize ªº­ì«¬¬O¡G

BOOL SetConsoleScreenBufferSize(
  HANDLE  hConsoleOutput,   // handle to console screen buffer
  COORD   dwSize            // new size in character rows and cols.
);

dwSize ¬O·s³]©wªº±±¨î¥x¿Ã¹õ½w½Ä°Ï¤j¤p¡A­nª`·N±±¨î¥x¿Ã¹õ½w½Ä°Ï¤j¤pªº¦æ»P¦C¥Ñ¤@¶}©l¡A¨Ã¤£¬O¥Ñ¹s¶}©l¡C©Ò¥H¡A¦pªGµ{¦¡³]­p®v·Q­n§â©R¥O´£¥Ü¦r¤¸µøµ¡³]¬° 80 ¦æ¼e¡B10 ¦C°ª¡A¨Ã¨Ï±²°Ê¶b®ø¥¢¡A¥²¶·©I¥s¨â¶µ API¡G

srct    SMALL_RECT      <0,0,79,9>
    invoke  SetConsoleWindowInfo,hOutput,TRUE,offset srct
    invoke  SetConsoleScreenBufferSize,hOutput,0a0050h    ;§C¦ì¤¸¬O¦æ¡A°ª¦ì¤¸¬O¦C¡A50h=80d¡A0ah=10d

SetConsoleScreenBufferSize ³]©w¦¨¥\·|¶Ç¦^ TRUE¡A§_«h¶Ç¦^ FALSE¡C³]©w¥¢±Ñªº­ì¦]¡A¤j³¡¤À¬O¡y©R¥O´£¥Ü¦r¤¸¡zµøµ¡¤j¤p¤ñ±±¨î¥x¿Ã¹õ½w½Ä°ÏÁÙ¤j¡A³o®É¥i©I¥s GetLastError ¦Ó±o¨ì ERROR_INVALID_PARAMETER¡C

±±¨î¥x´å¼Ð

¦b±±¨î¥x¤¤¡A¤]¹³¦b DOS ¤@¼Ë¡A¥i¥H³]©w´å¼Ð¦ì¸m¡A¤@¦ý³]©w¦n´å¼Ð¦ì¸m¤§«á¡A©Ò¿é¥X¨ì±±¨î¥xªº¤å¦r«K·|¥Ñ¦¹¦ì¸mÅã¥Ü¥X¨Ó¡C³]©w´å¼Ð¦ì¸mªº Win32 API ¬O SetConsoleCursorPosition¡A¨ä­ì«¬¬°¡G

BOOL SetConsoleCursorPosition(
  HANDLE hConsoleOutput,   // handle to console screen buffer
  COORD  dwCursorPosition

dwCuusorPosition ¬O¤@­ÓÂù¦r²Õ¾ã¼Æ¡A¦s¦³±ý³]©wªº´å¼Ð¦ì¸m¡A¸û§Cªº 16 ¦ì¤¸¬O x ®y¼Ð¡A¸û°ªªº 16 ¦ì¤¸¬O y ®y¼Ð¡A³o¨â­Ó®y¼Ð³£¥Ñ¹s¶}©lºâ¡C°²¦p©Ò³]´å¼Ð¦ì¸m¤£¦b±±¨î¥xµøµ¡ªº½d³ò¤º¡A¦ý¤´¦b±±¨î¥x¿Ã¹õ½w½Ä°Ï½d³ò¤º¡A¨t²Î·|²¾°Ê±±¨î¥xµøµ¡¨Ï¤§¨ì´å¼Ð·s³]©wªº¦ì¸m¡F¦pªG©Ò³]©w´å¼Ð¦ì¸m¶W¥X±±¨î¥x¿Ã¹õ½w½Ä°Ï½d³ò¡A«h SetConsoleCursorPosition ·|ªð¦^ FALSE¡C¨Ò¦p·Q§â´å¼Ð³]©ó²Ä 5 ¦æ ( x=5 )¡A²Ä 2 ¦C ( y=2 )¡A¥i¥Î¤U­±¤è¦¡¡G

        invoke  SetConsoleCursorPosition,hConsoleOutput,20005h

©I¥s GetConsoleCursorInfo ¥i¥HÀò±o´å¼Ð¸ê®Æ¡A¨ä­ì«¬¬°¡G

BOOL GetConsoleCursorInfo(
  HANDLE                hConsoleOutput,         // handle to console screen buffer
  PCONSOLE_CURSOR_INFO  lpConsoleCursorInfo     // address of cursor information
);

©I¥s GetConsoleCursorInfo ®Éªº²Ä¤G­Ó°Ñ¼Æ¡AlpConsoleCursorInfo¡A¬O¤@­Ó¦ì§}«ü¼Ð¡A«ü¦V CONSOLE_CURSOR_INFO µ²ºcÅé¡C³o­Óµ²ºcÅ骺¤º®e¬O¡G

CONSOLE_CURSOR_INFO     STRUCT
dwSize          DWORD   ?
bVisible        DWORD   ?
CONSOLE_CURSOR_INFO     ENDS

dwSize ¬O«ü´å¼Ð¤j¤p¡A¥H¦Ê¤À¤ñªí¥Ü¡A¦b 1 »P 100 ¤§¶¡¡CbVisible ¬° TRUE ®É¡Aªí¥Ü´å¼Ð¥i¨£¡F¤Ï¤§¡Aªí¥Ü´å¼Ð¤£¥i¨£¡C¦p±ý³]©w´å¼Ð¸ê®Æ¡A¥i¥Î SetConsoleCursorInfo¡ASetConsoleCursorInfo ¥Îªk»P GetConsoleCursorInfo Ãþ¦ü¡A½Ð¦Û¦æ¬d¾\ MSDN¡C

±±¨î¥xªº¤å¦rÄÝ©Ê ( attribute )

©Ò¿×¡y¤å¦rªºÄÝ©Ê¡z¥i¥H¬Ý¦¨±±¨î¥x¤¤¤å¦rªºÃC¦â¡A¦p«e©Ò´£¹Lªº¡A¤å¦r¬O¥H FOREGROUND_BLUE¡BFOREGROUND_GREEN¡BFOREGROUND_RED¡BFOREGROUND_INTENSITY¡BBACKGROUND_BLUE¡BBACKGROUND_GREEN¡BBACKGROUND_RED ©M BACKGROUND_INTENSITY µ¥«O¯d¦rªº²Õ¦X¡C¦pªG­n§ïÅܱ±¨î¥x¤å¦rªºÃC¦â¡A¥i¥Î SetConsoleTextAttribute API¡A¨ä­ì«¬¦p¤U¡G

BOOL SetConsoleTextAttribute(
  HANDLE hConsoleOutput,    // handle to console screen buffer
  WORD   wAttributes        // text and background colors
);

¦b©I¥s¹L SetConsoleTextAttribute ¤§«á¡A±±¨î¥x©ÒÅã¥ÜªºÃC¦â§¡·|Åܦ¨ wAttributes ©Ò«ü©wªºÃC¦â¡A¦ý¬O¦b³o¤§«eªº¤å¦rÃC¦â¨Ã¤£·|§ïÅÜ¡C¦pªG¥u­n§ïÅܬY¤@­Ó¦r¦êªºÃC¦â¡A¥i¥Î WriteConsoleOutputAttribute¡A¨ä­ì«¬¬°¡G

BOOL WriteConsoleOutputAttribute(
  HANDLE  hConsoleOutput,         // handle to screen buffer
  CONST   WORD *lpAttribute,      // to buffer to write attributes
  DWORD   nLength,                // number of character cells
  COORD   dwWriteCoord,           // coordinates of first cell
  LPDWORD lpNumberOfAttrsWritten  // number of cells written
);

WriteConsoleOutputAttribute ¨ä¹ê¬O¦b±±¨î¥x¤¤ªº¬Y¤@­Ó¦ì¸m¼g¤J¤@¦êÄÝ©Ê¡AlpAttribute ¬O«ü¦V¤@­Ó¥ÑÄÝ©Ê©Ò²Õ¦¨ªº°}¦C ( ¥i¥H§â°}¦C¬Ý¦¨¬O¦b¤@¬q³sÄòªº°O¾ÐÅ餺ªº¸ê®Æ )¡A¦¹°}¦Cªº¨C­ÓÄݩʦû¦³¤@­Ó¦r²Õ¡CnLength ¬O lpAttribute ©Ò«üªºÄÝ©Ê°}¦Cªºªø«×¡A¥ç§Y nLength ¬O«üÄÝ©Ê°}¦C¦³´X­ÓÄÝ©Ê¡CdwWriteCoord ¬O«ü¥Ñ±±¨î¥x¨º¤@­Ó¦ì¸m¶}©l¼g¤JÄÝ©Ê¡AlpNumberOfAttrsWritten ¬O¤@­Ó¦ì§}¡A«ü¦V¤@­ÓÅܼơA¦¹ÅܼƦb WriteConsoleOutputAttribute ªð¦^®É¡A¶Ç¦^¹ê»Ú¤W¦b±±¨î¥x¼g¤F´X­ÓÄÝ©Ê¡CWriteConsoleOutputAttribute ³q±`·|©M WriteConsoleOutputCharacter °t¦X¡AWriteConsoleOutputAttribute ¬O¦b±±¨î¥x¤¤ªº¬Y¤@­Ó¦ì¸m¼g¤J¤@¦êÄÝ©Ê¡AWriteConsoleOutputCharacter «h¬O¦b¬Y¤@­Ó¦ì¸m¼g¤J¤@¦r¦ê¡A¥¦ªº°Ñ¼Æ©M WriteConsoleOutputAttribute ¬Û¦ü¡A¨ä­ì«¬¬°¡G

BOOL WriteConsoleOutputCharacter(
  HANDLE  hConsoleOutput,         // handle to screen buffer
  LPCTSTR lpCharacter,            // buffer to write characters 
  DWORD   nLength,                // number of characters to write
  COORD   dwWriteCoord,           // coordinates of first cell
  LPDWORD lpNumberOfCharsWritten  // number of cells written
);

¦b±±¨î¥xµ{¦¡¤¤Åª¨úÁä½L

ReadConsoleInput »P INPUT_RECORD

¤@¯ë¦b±±¨î¥xµ{¦¡¤¤¥i¥H¥Î ReadConsole ¨ÓŪ¨ú¨Ï¥ÎªÌ©Ò¿é¤Jªº«öÁä¡A¦ý¬O¦pªG­nÀò±o¯S®í«öÁä¡A¨Ò¦p¤è¦VÁä¡B¥\¯àÁä¡BShift Áäµ¥µ¥¡A´N±o¥Î ReadConsoleInput ¨ÓŪ¨úÁä½L°T®§¤F¡CReadConsoleInput °£¤F¥i¥HŪ¨úÁä½Lªº¿é¤J¥~¡A¤]¥i¥HŪ¨ú·Æ¹«¡B¿ï³æµ¥¨Æ¥ó ( event ) ªº¿é¤J¡A¨ä­ì«¬¬°¡G

BOOL ReadConsoleInput(
  HANDLE        hConsoleInput,        // handle to a console input buffer
  PINPUT_RECORD lpBuffer,             // address of the buffer for read data
  DWORD         nLength,              // number of records to read
  LPDWORD       lpNumberOfEventsRead  // address of number of records read
);

²Ä¤@­Ó°Ñ¼Æ¡AhConsoleInput¡AÅãµM¬O¨ã¦³¥i¿é¤J©Ê½èªº±±¨î¥x¥N½X¡C²Ä¤G­Ó°Ñ¼Æ¸û¬°½ÆÂø¡Aµy«á¦A»¡¡C²Ä¤T­Ó°Ñ¼Æ¡AnLength¡A¬O¥Î¨Ó«ü¥Ü ReadConsoleInput ­nŪ¨ú´Xµ§¿é¤Jªº¨Æ¥ó¡CWindows §@·~¨t²Î·|¬°±±¨î¥x«Ø¥ß¨ÃºûÅ@¤@­Ó¿é¤J½w½Ä°Ï¡A·í¦³¨Æ¥óµo¥Í®É¡A³o¨Ç¨Æ¥ó³£·|³Q¨t²Î«O¦s¦b½w½Ä°Ïùص¥µ{¦¡´£¨ú¡A¦Óµ{¦¡¥i¥H§Q¥Î ReadConsoleInput¡BReadConsole µ¥ API ´£¥X¦b¿é¤J½w½Ä°Ï¤ºªº¨Æ¥ó¡C·í¥Î ReadConsoleInput ´£¥X½w½Ä°Ï¤ºªº¨Æ¥ó®É¡A¥i¥H¦b nLength «ü©w­n´£¥Xªº¨Æ¥óªº¼Æ¥Ø¡A¦pªG nLength ©Ò«ü©wªº¨Æ¥ó¼Æ¤ñ¦b½w½Ä°Ï¤ºªº¨Æ¥ó¼Æ¤j®É¡AReadConsoleInput ¨Ã¤£·|µ¥¨ìº¡¨¬¤F nLength ©Ò«ü©wªº¨Æ¥ó¼Æ¤~ªð¦^¡A¦Ó¬O¥ß§Yªð¦^¡A¨Ã©ó lpNumberOfEventsRead ©Ò«ü¦ì§}¦s©ñ¹ê»ÚŪ¨úªº¨Æ¥ó¼Æ¡C¦ý¬O¦pªG©I¥s ReadConsoleInput ¤§«e¡A¦b½w½Ä°ÏùبèS¦³¥ô¦ó¨Æ¥ó¡A¨º»ò ReadConsoleInput ´N·|¤@ª½µ¥«Ý¡Aª½¨ì¦³¨Æ¥ó¥X²{¤~ªð¦^¡C¬°¤FÁקKµ¥«Ý¡A¥i¥H¦b©I¥s ReadConsoleInput ¤§«e¡A¥ý©I¥s GetNumberOfConsoleInputEvents ¨ÓÀˬd±±¨î¥x¿é¤J½w½Ä°ÏùجO§_¦³¿é¤J¨Æ¥ó¥¼³QŪ¨ú¡AGetNumberOfConsoleInputEvents ªº­ì«¬¬O¡G

BOOL GetNumberOfConsoleInputEvents(
  HANDLE  hConsoleInput,      // handle to console input buffer
  LPDWORD lpcNumberOfEvents   // address for number of events
);

¦pªG¦¨¥\¡A·|¶Ç¦^ TRUE¡A¨Ã©ó lpcNumberOfEvents ©Ò«ü¦ì§}¦s©ñ½w½Ä°Ï¤º©|¦³´Xµ§¨Æ¥ó¥¼³Q´£¥X¡C

¦A¦^¹LÀY¨Ó»¡ ReadConsoleInput API ªº²Ä¤G­Ó°Ñ¼Æ¡AlpBuffer¡A¥¦¬O¤@­Ó«ü¼Ð¡A«ü¦V¨Ï¥ÎªÌ¿é¤J«áªº¸ê®Æ¦s©ñ³B¡C¦pªG©ÒŪ¨úªº¨Æ¥ó¤£¥u¤@µ§¡A¨º»ò²Ä¤Gµ§¨Æ¥ó·|±µ¦b²Ä¤@µ§¨Æ¥ó¤§«á¡A´«¥y¸Ü»¡¡AlpBuffer ±`±`¬O«ü¦V¤@­Ó¥Ñ³\¦h¨Æ¥ó©Ò²Õ¦¨ªº°}¦C¡C³o­Ó°}¦C¤¤ªº¨C¤@µ§¸ê®Æ¤£ºÉ¬Û¦P¡A·|ÀHµÛµo¥Íªº¨Æ¥ó¤£¦P¡A¦Ó¦³¤£¦Pªº§Î¦¡¡A¦ý¬O¥þ³¡²Î¦X¦b INPUT_RECORD µ²ºcÅ餺¡A½è¨¥¤§¡A§Ú­Ì¤]¥i¥H»¡ lpBuffer ¬O«ü¦V INPUT_RECORD µ²ºcÅé©Ò²Õ¦¨°}¦Cªº«ü¼Ð¡CINPUT_RECORD µ²ºcÅ骺©w¸q¬O¡G

INPUT_RECORD    STRUCT
EventType       WORD    ?
Unknown         WORD    ?                                             ;µù¤@
        UNION                   event
        KeyEvent                KEY_EVENT_RECORD                <>
        MouseEvent              MOUSE_EVENT_RECORD              <>    ;µù¤G
        WindowBufferSizeEvent   WINDOW_BUFFER_SIZE_RECORD       <>
        MenuEvent               MENU_EVENT_RECORD               <>
        FocusEvent              FOCUS_EVENT_RECORD              <>
        ENDS
INPUT_RECORD    ENDS

UNION/ENDS ¬O¤@­Ó MASM 6.x ¥H«á©Ò·s¼Wªº°²«ü¥O¡A½Ð°Ñ¦Òµù¤T¡A·í¤@¨Æ¥óµo¥Í®É¡A±q UNION ¨ì ENDS ¤§¶¡ªº KeyEvent¡BMouseEvent¡BWindowBufferSizeEvent¡K¡K¤­­Óµ²ºcÅ餤¡A¥u¦³¤@­Ó¬O¦³·N¸qªº¡A¦Óµo¥Í¤F¨º¤@¨Æ¥ó³Q°O¿ý¦b EventType¡C¨Ò¦p¡A·í¨Ï¥ÎªÌ«ö¤UÁä½L¤Wªº¬Y¤@«öÁä¡AEventType ·|³Q ReadConsoleInput ³]¬° KEY_EVENT¡A¦Ó event ©Òªí¥Üªº¤º®e¬° KEY_EVENT_RECORD µ²ºcÅé¡A³o­Ó KEY_EVENT_RECORD ¤]·|³Q ReadConsoleInput ³]¬°¾A·íªº¼Æ­È¡C¨ä¥Lªº EventType »P¬Û¹ïÀ³ªºµ²ºcÅé¦C¦b¤Uªí¤¤¡G

¨Æ¡@¡@¥óEventType ºØÃþ ¼Æ­È¬Û¹ïÀ³ªºµ²ºcÅé
«ö¤U©Î©ñ¶}¬Y­Ó«öÁäKEY_EVENT 1hKEY_EVENT_RECORD
²¾°Ê·Æ¹«©Î«ö·Æ¹««ö¶sMOUSE_EVENT 2hMOUSE_EVENT_RECORD
§ó§ï±±¨î¥x¿Ã¹õ½w½Ä°Ï¤Wªº¸ê®ÆWINDOW_BUFFER_SIZE_EVENT 4hWINDOW_BUFFER_SIZE_RECORD
¨t²Î¤º¤£¨Ï¥Î¡AÀ³¤©©¿²¤MENU_EVENT 8hMENU_EVENT_RECORD
¨t²Î¤º¤£¨Ï¥Î¡AÀ³¤©©¿²¤FOCUS_EVENT 10hFOCUS_EVENT_RECORD

¦¹³B¶È»¡©ú KEY_EVENT_RECORD µ²ºcÅé¡A¨ä¾lªº½Ð¬d¾\ MSDN¡CKEY_EVENT_RECORD µ²ºcÅé³Q©w¸q¦¨¡G

KEY_EVENT_RECORD    STRUCT
bKeyDown            BOOL    ?       ;­Y¬° TRUE¡Aªí¥Ü«öÁä³QÀ£¤U¡FFALSE ªí¥Ü«öÁä³QÃP¶}
wRepeatCount        WORD    ?
wVirtualKeyCode     WORD    ?       ;µêÀÀÁä½X
wVirtualScanCode    WORD    ?       ;µêÀÀ±½´y½X
    UNION           uChar           ;uChar ªí¥Ü«öÁ䪺 ASCII ½X©Î¸U°ê½X
        UnicodeChar WCHAR   ?       ;¸U°ê½X¡A¤@­Ó WCHAR ¬Û·í©ó¤@­Ó¦r²Õ
        AsciiChar   CHAR    ?       ;ASCII ½X¡A¤@­Ó CHAR ¬Û·í©ó¤@­Ó¦ì¤¸²Õ
    ENDS
dwControlKeyState   DWORD   ?       ;±±¨îÁä ( ¦p Alt¡BShift¡BCtrl¡BScroll Lock µ¥Áä ) ªºª¬ºA
KEY_EVENT_RECORD    ENDS

¥ý»¡³Ì«á­±ªº dwControlKeyState¡A¥¦ªí¥Ü±±¨îÁ䪺ª¬ºA¡A¦p¤Uªí¡G

dwControlKeyState·N¸q¼Æ­È
RIGHT_ALT_PRESSED¥kÃ䪺 Alt Áä³QÀ£¤U 1h
LEFT_ALT_PRESSED¥ªÃ䪺 Alt Áä³QÀ£¤U 2h
RIGHT_CTRL_PRESSED¥kÃ䪺 Ctrl Áä³QÀ£¤U 4h
LEFT_CTRL_PRESSED¥ªÃ䪺 Ctrl Áä³QÀ£¤U 8h
SHIFT_PRESSEDShift Áä³QÀ£¤U 10h
NUMLOCK_ONNum Lock ³QÂê¦í¬°¼Æ¦rª¬ºA 20h
SCROLLLOCK_ONScroll Lock ³QÂê¦í 40h
CAPSLOCK_ONCaps Lock ³QÂê¦í¬°¤j¼gª¬ºA 80h
ENHANCED_KEYÁä½L¥k°¼ªº¼Æ¦rÁä©Î¤è¦VÁä³Q«ö¤U 100h

bKeyDown ¬°¤@Âù¦r²Õ ( §Y 32 ¦ì¤¸ ) ªø«×ªºÄæ¦ì¡A¥¦ªí¥Ü«öÁä³Q«ö¤U©ÎÃP¶}¡A­Y¬° TRUE¡Aªí¥Ü«öÁä³QÀ£¤U¡FFALSE ªí¥Ü«öÁä³QÃP¶}¡C¦b¤@¯ë±¡§Î¤U¡A¨Ò¦p¯µ®Ñ¤p©j¥´¦r®É¡A·í¦o«ö¤U¤@­ÓÁä«á·|¥ß§YÃP¶}¸ÓÁä¡A¨t²Î·|¦b¦o«ö¤U¸ÓÁä®É¡A¦b±±¨î¥x¿é¤J½w½Ä°Ïùثإߤ@µ§ INPUT_RECORD ¨Æ¥ó¡A¥B°O¿ý¸Ó«öÁ䪺¸ê®Æ bKeyDown ¬° TRUE¡F¦Ó·í¦oÃP¶}¦¹«öÁä®É¡A¨t²Î¤]·|¦A¤@¦¸°O¿ý¤@µ§ INPUT_RECORD ¨Æ¥ó¡A¦Ó¦¹®É«öÁä¨Æ¥ó¤¤ªº bKeyDown ¬° FALSE¡C¦Ü©ó«ö¤U¬Y¤@Á䤣©ñ¡A·|µo¥Í¤°»ò¨Æ¡H©Î¤S«ö¤U¬Y¤@Á䤣©ñ¡A¤S¦A«ö¤U¥t¤@Áä¡A·|µo¥Í¤°»ò¨Æ¡H¤S©Î¿é¤J¤@¤¤¤å¦r¡A·|µo¥Í¤°»ò¨Æ±¡¡H¤p¤ì°¸¤w¸g¼g¦n¤@­Óµ{¦¡¡ACONSOLE2.ASM¡AŪªÌ¥i¥H¦Û¦æ²ÕĶ«á¸Õ¸Õ¬Ý¡C

CONSOLE2.ASM

        .586
        .model  flat,stdcall
        option  casemap:none

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

INPUT_RECORD    STRUCT
EventType       WORD    ?
Unknown         WORD    ?
        UNION                   event
        KeyEvent                KEY_EVENT_RECORD                <>
        MouseEvent              MOUSE_EVENT_RECORD              <>
        WindowBufferSizeEvent   WINDOW_BUFFER_SIZE_RECORD       <>
        MenuEvent               MENU_EVENT_RECORD               <>
        FocusEvent              FOCUS_EVENT_RECORD              <> 
        ENDS
INPUT_RECORD    ENDS
nir     equ     sizeof INPUT_RECORD     ;¤@­ÓINPUT_RECORDµ²ºcÅé©Ò¦û¦ì¤¸²Õ¼Æ
;*********************************************************************
                .data
hIn             HANDLE          ?
hOut            HANDLE          ?
dRead           DWORD           ?
dWritten        DWORD           ?
idx             DWORD           ?
nIR             WORD            nir             ;¤@­ÓINPUT_RECORDµ²ºcÅé©Ò¦û¦ì¤¸²Õ¼Æ
wTime           WORD            0               ;ReadConsoleInput²Ä´X¦¸Åª¨ú
sBlank          BYTE            '         '
sBlankSize      equ             $-offset sBlank
szFmt1          BYTE            '²Ä%03d¦¸¡G',0
szFmt2          BYTE            '%04d',0
szFmt3          BYTE            ' %02X',0
ir              INPUT_RECORD    40h dup ()   ;¥Ñ40H­ÓINPUT_RECORDµ²ºcÅé©Ò²Õ¦¨ªº°}¦C
                                                ;¦s©ñ¥ÑReadConsoleInput©ÒŪ¨úªº¨Æ¥ó
buffer          BYTE            400h dup (' ')  ;¥HASCII¦r¦ê®æ¦¡¦s©ñ¨Æ¥ó³B
;*********************************************************************
        .code
;---------------------------------------------------------------------
;deal°Æµ{¦¡¬O§â40h­ÓINPUT_RECORDµ²ºcÅé©Ò²Õ¦¨ªº°}¦C¡A¥HASCII¦r¦ê®æ¦¡¦s©ñ©óbuffer³B
;¨C­ÓINPUT_RECORDµ²ºcÅ馳nIR­Ó¦ì¤¸²Õ¡A¦]¦¹¦b¦¹°Æµ{¦¡¥H¤@­Ó°j°é³B²z³onIR­Ó¦ì¤¸²Õ¡A
;¨Ã¥H
deal    proc    n_i_r:DWORD     ;n_i_r¬OReadConsoleInputŪ¨úªº¨Æ¥ó¼Æ
        LOCAL   pBuffer:DWORD   ;pBuffer¬Obufferªº«ü¼Ð¡Aªí¥Ü¨Æ¥ó¶ñ¤J¨ì¨º¤@¦ì§}
        LOCAL   counterIR:DWORD ;ReadConsoleInput©ÒŪ¨ú¸ê®Æµ§¼Æªº­p¼Æ¾¹
        LOCAL   cIRMember:WORD  ;INPUT_RECORDùزĴX­Ó¦ì¤¸²Õ
        mov     pBuffer,offset buffer
        invoke  wsprintf,offset buffer,offset szFmt1,wTime
        add     pBuffer,eax
        mov     counterIR,0
nxtIR:  cmp     counterIR,0
        jz      @f
        push    esi
        push    edi
        mov     ecx,sBlankSize
        mov     esi,offset sBlank
        add     pBuffer,ecx
        mov     edi,pBuffer
        rep     movsb
        pop     edi
        pop     esi
@@:     invoke  wsprintf,pBuffer,offset szFmt2,counterIR
        add     pBuffer,eax
        mov     cIRMember,nir
        mov     eax,counterIR   ;­pºâ²ÄcounterIR­ÓINPUT_RECORDµ²ºc
        mul     nIR             ;Åé¦bir°}¦Cªº°_©l¦ì§}¡A¨Ã«O¦s©óEAX
@@:     push    eax             ;°j°é°_©l
        movzx   ecx,byte ptr ir[eax]
        invoke  wsprintf,pBuffer,offset szFmt3,ecx
        add     pBuffer,eax
        pop     eax
        inc     eax
        dec     cIRMember
        jnz     @b              ;°j°éµ²§ô
        inc     counterIR
        mov     edx,pBuffer
        mov     word ptr [edx],0a0dh
        add     pBuffer,2
        dec     n_i_r
        jnz     nxtIR

        mov     ecx,pBuffer
        mov     edx,offset buffer
        sub     ecx,edx                 ;ªð¦^®ÉECX=­n¦L¥Xªº¦ì¤¸²Õ¼Æ
        ret
deal    endp
;---------------------------------------------------------------------
start:  invoke  GetStdHandle,STD_OUTPUT_HANDLE
        mov     hOut,eax
        invoke  GetStdHandle,STD_INPUT_HANDLE
        mov     hIn,eax
        invoke  SetConsoleMode,eax,ENABLE_MOUSE_INPUT
get:    invoke  ReadConsoleInput,hIn,offset ir,40h,offset dRead
        inc     wTime
        cmp     dRead,0
        jz      get
        invoke  deal,dRead      ;§âReadConsoleInputŪ¨ú¨ìªº¨Æ¥ó¶ñ¤Jbuffer¦r¦ê¤¤
        invoke  WriteConsole,hOut,edx,ecx,offset dWritten,NULL

;Àˬd¨Ï¥ÎªÌ¬O§_«ö¤UEscÁä¡A¦]¨C¦¸ReadConsoleInput©ÒŪ¨úªº¨Æ¥ó¥i¯à¤£¥u¤@­Ó¡A©Ò¥H
;¥²¶·Àˬd¨C¤@­Ó¨Æ¥ó¡A¥ýÀˬd¬O§_¬°KEY_EVENT¡A­Y¬O¡A¦bÀˬd¬O§_¬°EscÁä
        mov     idx,0
nxt:    mov     eax,idx
        cmp     eax,dRead
        je      get
        inc     idx
        mul     nIR
        cmp     word ptr ir[eax],KEY_EVENT
        jne     nxt
        cmp     word ptr ir[eax+0ah],VK_ESCAPE
        jnz     nxt
        invoke  ExitProcess,NULL
;*********************************************************************
        end     start

±N¤W­z­ì©lÀɮצs¦¨ CONSOLE2.ASM «á¡A¨Ì·Ó¥H¤U¤è¦¡²ÕĶ¡A§Y¥i±o CONSOLE2.EXE¡G

E:\HomePage\SOURCE\CONSOLE>set ML=/coff /link /SUBSYSTEM:CONSOLE

E:\HomePage\SOURCE\>ml console2.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

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

/SUBSYSTEM:CONSOLE
"console2.obj"
"/OUT:console2.exe"

E:\HomePage\SOURCE>

¥Î ReadConsoleInput Æ[¹î¦b±±¨î¥x¤¤¿é¤J¤¤¤å

¦³¤F CONSOLE2.EXE ¤§«á¡A§Ú­Ì´N¥i¥H¥Î¥¦¨Ó°µ³\¦h¨Æ¡A¨Ò¦p©³¤U¬O¥Î¥¦¦b±±¨î¥x¤¤¥Hª`­µ¿é¤Jªk¿é¤J¤@­Ó¤¤¤å¦r¡y¤@¡z¡A°õ¦æ CONSOLE2.EXE ¤§«á¡Aµe­±¬O¤@¤ùªÅ¥Õ¡A±µµÛ«ö Ctrl-Space¡A§A·|¬Ý¨ì²Ä¤@¦¸Åª¨ú®É¡A¥ªÃ䪺 Ctrl Áä³Q«ö¤U¡AµM«á±µµÛ²Ä¤G¦¸Åª¨ú¬OªÅ¥ÕÁä³Q«ö¤U¡A±µµÛ²Ä¤T¦¸¬O¥ªÃ䪺 Ctrl Áä³QÃP¶}¡A¨ì¦¹§¹¦¨¤Á´«¡yª`­µ¿é¤Jªk¡zªº°Ê§@¡A¿Ã¹õ¥ª¤U¨¤¥X²{¡yª`­µ¡@¥b¡G¡z¡A¦p¤U¹Ï¡G

±±¨î¥x¤¤¿é¤J¤¤¤å
±µµÛ«ö¤Uª`­µ¡y£¸¡zÁä¤Î²Ä¤@ÁnÁä¡Aª`­µ¡y£¸¡zÁä¬O­^¤åªº¡yU¡zÁä¡A²Ä¤@ÁnÁä¬OªÅ¥ÕÁä¡A¦]¦¹§A¨£¨ì²Ä¥|¦¸¡B²Ä¤­¦¸ªº«öÁä¨Æ¥ó¡C±µ¤U¨Ó²Ä¤»¦¸Åª¨ú½w½Ä°Ï®ÉÁöµM¨S¦³«öÁä¨Æ¥ó¡A¦ý¬O«o¬O¨t²Î¦Û¦æ­pºâ¥X¨Ï¥ÎªÌ¿é¤J¤F¤@­Ó¤¤¤å¦r¡A¦]¦¹²Ä¤»¦¸¨Æ¥óŪ¨ú¬O¨t²Î¦Û¦æ²£¥Íªº¡A¦Ó¡y¤@¡zªº BIG¡Ð5 ¬O¡yA440¡z¡A¬G¨t²Î¤À§O¶Ç·|¨â¦¸ ASCII ½X¡C


¥t¤@­Ó±±¨î¥xµ{¦¡ªº¨Ò¤l

¤p¤ì°¸¥t¥~¼g¤F¤@­Óµ{¦¡¡ACONSOLE3.ASM ¡AŪªÌ¥i±N·Æ¹«²¾¦Ü¨ä¤W¡A«ö·Æ¹«¥kÁä¿ï¥t¦s·sÀɤU¸ü¡C³o¬O¦]¬° neocities.org ¸T¤î§K¶O¥Î¤á¤W¶Ç *.ASM ÀÉ¡A¬G¦Ó±¾¦ÏÀY½æª¯¦×§â CONSOLE3.ASM §ï¦W¬° CONSOLE3.JPG¡AŪªÌ¥i±N¨ä¦W§ï¦^¨Ó¡A¨ä°õ¦æµe­±¬°¡G

³o­Ó¨Ò¤l¦³§ïÅܱ±¨î¥xµøµ¡¤j¤p¡BÅã¥Ü¤å¦rÃC¦âµ¥µ¥§Þ¥©ÅªªÌ¥i°Ñ¦Ò¬Ý¬Ý¡C


µù¤@¡G©Ò¦³ªº¤åÄm¡A¥]§t MSDN »Pºô»Úºô¸ô¤Wªº¸ê®Æ°O¸ü INPUT_RECORD µ²ºcÅ骺©w¸q¬O¡G

INPUT_RECORD    STRUCT
EventType       WORD    ?
        UNION                   event
        KeyEvent                KEY_EVENT_RECORD                <>
        MouseEvent              MOUSE_EVENT_RECORD              <>
        WindowBufferSizeEvent   WINDOW_BUFFER_SIZE_RECORD       <>
        MenuEvent               MENU_EVENT_RECORD               <>
        FocusEvent              FOCUS_EVENT_RECORD              <>
        ENDS
INPUT_RECORD    ENDS

¦ý¬O¤p¤ì°¸¥H OllyDebug Æ[¹îªºµ²ªG¬O EventType Äæ¦ì«áÁÙ¦³¤@­Ó¦r²Õ¡A¦ý¤p¤ì°¸¤£ª¾¨ä­ì¦]¡A¤]¤£ª¾¬°¤°»ò©Ò¦³¤åÄm³£¨S¦³¦¹°O¿ý¡A©Î³\½Ñ¦ì¥ý¶i½å¹Fª¾¹D¦Ó¯à¨Ó«H§iª¾¡A¤p¤ì°¸·P¿E¤£ºÉ¡C¦b¤p¤ì°¸¹q¸£¤¤ªº WINDOWS.INC ¬O©ó¥Á°ê 90 ¦~¤Q¤ë 22 ¤éµoªíªºªº 1.25a ª©¡A³oª©¤¤¨Ã¨S¦³©w¸q INPUT_RECORD µ²ºcÅé¡A¥²¶·¥Î 1.30 ª©¥H«áªº WINDOWS.INC¡A§_«h´N±o©ó­ì©lÀɤ¤¦Û¦æ©w¸q¡C

µù¤G¡G¤@¯ë±±¨î¥x¨Ã¤£±µ¦¬·Æ¹«°T®§¡A¥²¶·¥Î SetConsoleMode ±Ò°Ê¥¦¡ASetConsoleMode ªº­ì«¬¬O¡G

BOOL SetConsoleMode(
  HANDLE hConsoleHandle,  // handle to console input or screen buffer
  DWORD  dwMode           // input or output mode to set
);

¦pªG hConsoleHandle ¬O¼Ð·Ç¿é¤J¥N½X ªº¸Ü¡AdwMode ©Ò¥Nªíªº·N¸q¦p¤Uªí¡G

dwMode¼Æ­È·N¸q
ENABLE_PROCESSED_INPUT1h ¦¹ºX¼Ð§@¥Î®É¡A¥Ñ¨t²Î³B²z Ctrl-C ¨Æ¥ó¡A¦Ó¤£©ñ¤J±±¨î¥x¿é¤J½w½Ä°ÏùØ¡A¦]¦¹ ReadConsole¡BReadFile µLªkŪ¥X Ctrl-C ¨Æ¥ó¡C
ENABLE_LINE_INPUT2h ¾Ö¦³¦¹ºX¼Ð®É¡A¥u¦³¦¬¨ìÂk¦ì¦r¤¸ ( carriage return ) ®É¡AReadConsole¡BReadFile ¤~·|ªð¦^¡F§_«h¥u­n±±¨î¥x¿é¤J½w½Ä°Ï¦³¦r¤¸´N·|ªð¦^¡C¦pªG±±¨î¥x¦P®É¾Ö¦³ ENABLE_LINE_INPUT ©M ENABLE_LINE_INPUT ¨âºX¼Ð®É¡A¤£¥u Ctrl-C ¥Ñ¨t²Î³B²z¡A³s°h¦ì¡BÂk¦ì¡B´«¦æ¦r¤¸³£¥Ñ¨t²Î³B²z¡C
ENABLE_ECHO_INPUT4h ¾Ö¦³¦¹ºX¼Ðªº±±¨î¥x¥N½X¡A·|¦b ReadConsole¡BReadFile ªð¦^®É¡A©ó±±¨î¥x¿Ã¹õ½w½Ä°ÏÅã¥Ü¦r¤¸¡C¦¹ºX¼Ð¥u¦³¦b ENABLE_LINE_INPUT ¦³§@¥Î®É¤~¦³¥Î¡C
ENABLE_WINDOW_INPUT8h ¾Ö¦³¦¹ºX¼Ð®É¡AReadConsolInput ¯àŪ¨ú±±¨î¥x¿Ã¹õ½w½Ä°Ïªº¤j¤p¦]µ{¦¡§ïÅܪº¨Æ¥ó¡A¦Ó ReadConsole¡BReadFile ¤´·|©¿µø¦¹¨Æ¥ó¦ÓµLªk¨ú±o¡C
ENABLE_MOUSE_INPUT10h ·í±±¨î¥xµøµ¡¾Ö¦³¿é¤JµJÂI®É¡A·Æ¹«´å¼Ð¦b±±¨î¥xµøµ¡¤º²¾°Ê©Î«ö¤U·Æ¹«Áä®É¡A¨t²Î·|§â·Æ¹«¨Æ¥ó©ñ¤J±±¨î¥x¿é¤J½w½Ä°ÏùØ¡C¦ý¬O§Y¨Ï±±¨î¥x¾Ö¦³ ENABLE_MOUSE_INPUT ºX¼Ð¡AReadConsole¡BReadFile ¤´·|©¿µø·Æ¹«¨Æ¥ó¦ÓµLªk¨ú±o¡A¥u¥i¥Î ReadConsoleInput ¨ú±o¡C

¦pªG hConsoleHandle ¬O¼Ð·Ç¿é¥X¥N½X ªº¸Ü¡AdwMode ©Ò¥Nªíªº·N¸q¦p¤Uªí¡G

dwMode¼Æ­È·N¸q
ENABLE_PROCESSED_OUTPUT1h ¾Ö¦³¦¹ºX¼Ðªº±±¨î¥x·|¥Ñ¨t²Î³B²z°h¦ì¡B¸õ®æ¡B¹aÁn¡BÂk¦ì»P´«¦æ¦r¤¸¡C
ENABLE_WRAP_AT_EOL_OUTPUT2h ¾Ö¦³¦¹ºX¼Ð®É¡A·í WriteConsole¡BWriteFile ¹ï±±¨î¥x¿é¥X¦r¤¸©Î¾Ö¦³ ENABLE_ECHO_INPUT ªº±±¨î¥x¥H ReadConsole¡BReadFile ¦^À³¦r¤¸¡A¦Ó¥B´å¼Ð¨ì¹F±±¨î¥xµøµ¡ªº³Ì¥kÃä®É¡A´å¼Ð·|¦Û°Ê¸õ¨ì¤U¤@¦æªº¶}©l¦ì¸mÄ~Äò¿é¥X¦r¤¸¡C

µù¤T¡G

UNION/ENDS °²«ü¥O

UNION ¬O©w¸q¤@ºØ¯S®íªºÅܼƫ¬ºA©Îµ²ºcÅé¡A¨ä»yªk¬°¡G

¦WºÙ    UNION
Äæ¦ì¤@  ¸ê®Æ«¬ºA    ?
Äæ¦ì¤G  ¸ê®Æ«¬ºA    ?
¡K¡K    ¡K¡K        ¡K¡K
¦WºÙ    ENDS

¥H UNION ©w¸qªºÅܼƫ¬ºA©Îµ²ºcÅé¡AÁöµM¥i¯à¥]§t¼Æ­ÓÄæ¦ì¡A¦ý¬O©M STRUCT ( ¦³Ãö STRUCT ½Ð°Ñ¦Ò²Õ¦X»y¨¥²Ä¤Q¤E³¹ ) ¤£¦P¡C³o¨Ç¥]§t¦b UNION »P ENDS ¤§¶¡ªºÄæ¦ì³£¬O¥Ñ¦P¤@¦ì§}¶}©l¡A´«¥y¸Ü»¡¡A³o¨ÇÄæ¦ì³£¬O­«Å|ªº¡C³o­Ó·N«ä¬O»¡¦b UNION ùتºÄæ¦ìÁöµM¥i¯à¦³¦n´X­Ó¡A«o¥u¯à¿ï¾Ü¨ä¤¤¤@Äæ§@¬°¸ê®Æ¡A¦ý¬O¦]¬°¨Æ«e¤£½T©w¡A©Ò¥H¤£ª¾À³¸Ó¥Î¨º¤@­ÓÄæ¦ì¡CÁ|­Ó¨Ò¤l¨Ó»¡¡A¨Ò¦p§Ú­Ì±`§â¤@­Ó¤jµ{¦¡¤À¤uµ¹³\¦h¤H­t³d¡A¨C¤H¶È­t³d¤@¤p³¡¥÷¡C°²¦p³o­Ó¤jµ{¦¡­n¨Ï¥Î¦~¥÷§@¬°ÅܼơA¬Y¨Ç¤H¥i¯à¥Î¤¤µØ¥Á°ê 97 ¦~¡A¬Y¨Ç¤H¥i¯à¥Î¦è¤¸ 2008 ¦~¡A¨º»òµ{¦¡¥i¥H¼g¦¨³o¼Ë¡G

YEAR    UNION
ROC     DB      ?       ;¥H¥Á°ê¬ö¤¸¡A¤@­Ó¦ì¤¸²Õªø«×´N°÷¤F
AD      DW      ?       ;¥H¦è¾ä¬ö¤¸¡A­n¤@­Ó¦r²Õªø«×¤~°÷
YEAR    ENDS
;*********************************************************
.data
sale    YEAR    <>       ;µo°â¦~¥÷
;*********************************************************
.code
        ¡K¡K¡K¡K
        mov     sale.ROC,97     ;¬Y¤H¥i¯à³o¼Ë¼g
        ¡K¡K¡K¡K
        mov     sale.AD,2008    ;¥t¤@¤H¥i¯à³o¼Ë¼g

²ÕĶ¾¹²ÕĶ UNION ®É¡A·|¥Hªø«×³ÌªøªºÄæ¦ì³Ì¬°³Ì«áªº¸ê®Æªø«×¡C¥H¤W­±ªº¨Ò¤l¡A²ÕĶ¾¹·|¬° sale ÅܼƫO¯d¤@­Ó¦r²ÕªºªÅ¶¡¡CUNION ¦b«Å§i®É¡A¤]¥i¥H¦P®É´N«ü©w¨äªì©l­È¡A¦p¤U­±©Ò¥Ü¡G

sale    YEAR    <97>

UNION ¤]¥i¥H¥]§t¦b¤@­Óµ²ºcÅ餺¡A³o®É­Ô©w¸q UNION ®É¥²¶·¹³¤U­±³o¼Ë¡A§â¦WºÙ©ñ¦b UNION ¤§«á¡A¦Ó¤£¬O¤§«e¡A¨Ò¦p INPUT_RECORD ¤¤ªº event ´N¬O¦p¦¹¡G

µ²ºcÅé¦WºÙ      STRUCT
Äæ¦ì¤@          ¸ê®Æ«¬ºA    ?
¡K¡K            ¡K¡K¡K
UNION           ¦WºÙ                           ;³o´X¦æ¬O UNION ªº©w¸q
                Äæ¦ìA       ¸ê®Æ«¬ºA    ?       ;
                Äæ¦ìB       ¸ê®Æ«¬ºA    ?       ;
                ¡K¡K        ¡K¡K¡K      ¡K      ;
ENDS                                          ;¦¹¦æ UNION µ²§ô
µ²ºcÅé¦WºÙ      ENDS

¤W­±³o­Ó¨Ò¤l¤¤¡A¦bÄæ¦ìA¡BÄæ¦ìB¡K¤¤¡A¥u¯à¿ï¾Ü¨ä¤¤¤@­Ó¡A¨Ã»PÄæ¦ì¤@¡BÄæ¦ì¤G¡K§Î¦¨¤@­Óµ²ºcÅé¡C¦b MASM32 V7.0 ùتº WINDOWS.INC ©w¸q LARGE_INTEGER ¬O³o¼Ë¤lªº¡G

LARGE_INTEGER   STRUCT
    QuadPart    QWORD   ?
LARGE_INTEGER   ENDS

¦ý¬O¦b MASM32 V11 ùتº WINDOWS.INC ©w¸q LARGE_INTEGER «o¬O¹³¤U­±³o¼Ë¤lªº¡G

LARGE_INTEGER   UNION
STRUCT
        LowPart  DWORD   ?
        HighPart DWORD   ?
ENDS
QuadPart QWORD ?
LARGE_INTEGER   ENDS

¦^¨ì­º­¶¡A ¨ì²Ä¤Q¥|³¹¡A ¨ì²Ä¤Q¤»³¹