ÀÌ°ÍÀº 1999³â ÇÏÀÌÅÚ °ÔÀÓ Á¦ÀÛ µ¿È£È¸¿¡ ¿Ã·È´ø °­Á 2ȸºÐ ÀÔ´Ï´Ù.

#####################################################

 ¾Æ·¡ÀÇ ±ÛÀº 3 °¡ÁöÀÇ Å¸ÀÌ¸Ó (Çϵå¿þ¾îÀû, API, ¸ÖƼ¹Ìµð¾î) ¿¡ ´ëÇÑ ÀúÀÇ °ßÇØ
¿Í °³¿ä¸¦ ÀûÀº ±ÛÀÔ´Ï´Ù. ¿¹Àü¿¡ ¼¼¹Ì³ª ÇÒ ¶§ »ç¿ëÇß´ø ±ÛÀε¥  ±×³É ½âÇô µÎ±â
µµ ±×·¸°í Çؼ­ °­ÀǶõ¿¡ ¿Ã¸³´Ï´Ù.

 ±×¸®°í ¾Æ·¡ºÎÅÍ´Â Á¸ÄªÀº »ý·«ÇÏ°Ú½À´Ï´Ù.

----------------------------------------------------------------------------

1. Çϵå¿þ¾îÀû ŸÀÌ¸Ó Á¦¾î

 Windows95 ¶ó´Â ¿î¿µÃ¼Á¦´Â À¯Àú·Î ÇÏ¿©±Ý Á÷Á¢ Çϵå¿þ¾î¸¦ Á¦¾îÇÒ ¼ö ¾ø´Â ±¸Á¶
·Î µÇ¾î ÀÖ´Ù. ¿¹¸¦ µé¾î ¸Þ¸ð¸®ÀÇ 0xA000:0000 À¸·Î ¸ÅÇÎ  µÇ¾îÁ³´ø ±×·¡ÇÈ Ä«µå
¿¡ ´ëÇÑ Á¦¾î³ª 0x388 Æ÷Æ®·Î Á¤ÀÇ µÇ¾îÁ³´ø FM »ç¿îµå Ä«µå¿¡ ´ëÇÑ Á¦¾î¸¦ ÇÒ ¼ö
¾ø´Â °ÍÀÌ ¹Ù·Î ±×°ÍÀÌ´Ù. Ç×»ó ¿î¿µÃ¼Á¦ÀÇ API ¸¦ °ÅÃÄ¾ß  Á¦¾î°¡ °¡´ÉÇÏ´Ù´Â Á¡
Àº, ÇÁ·Î±×·¥ÀÇ ¾ÈÁ¤¼ºÀ̳ª °³¹ßÀڵ鿡 ´ëÇØ ³»ºÎ ĸ½¶È­·Î ÀÎÇÑ  ºü¸¥ °³¹ß ±â°£
À¸·Î ±× ÀåÁ¡ÀÌ ´ëÇ¥µÇ¾î Áú  ¼öµµ ÀÖ´Ù. ÇÏÁö¸¸ °ÔÀÓÀ̳ª ±Ã±ØÀûÀÎ  ½Ç½Ã°£ À½¾Ç
(¶Ç´Â À½¼º) ¿¬ÁÖ ÇÁ·Î±×·¥¿¡¼­´Â »ó´çÈ÷ ¼Óµµ ¸é¿¡¼­ ºÒ¸®ÇÑ °ÍÀÌ´Ù.

 ¿¹¸¦ µéÀÚ¸é »ç¿îµå Ä«µåÀÇ DMA ³ª Çϵå¿þ¾î °¡¼Ó±â´ÉÀº ÀüÇô »ç¿ëÇÒ ¼ö ¾ø°Ô µÇ
´Â °ÍÀ̱⠶§¹®¿¡ °¢ Ä«µåÀÇ ÀåÁ¡À» »ì¸®Áö ¸øÇÑ Ã¤ ¼Óµµ¸¸ ¸¹ÀÌ  Àâ¾Æ ¸Ô´Â °ñÄ©
µ¢ÀÌ·Î Àü¶ôÇÏ°Ô µÈ °ÍÀÌ´Ù.
( ¹°·Ð ±âÁ¸ °ÔÀÓ ¾÷üµéÀÇ  ºÒ¸¸À» ÇؼÒÇÏ°íÀÚ, »ç¿îµå Ä«µåÀÇ DMA  ¿Í Çϵå¿þ¾î
°¡¼ÓÀ» Áö¿øÇϱâ À§ÇØ
  MS ¿¡¼­´Â DirectSound ¶ó´Â SDK ¸¦ Á¦°øÇß´Ù. )

¾î·µç À©µµ¿ì¿¡¼­´Â ¿î¿µÃ¼Á¦¿¡¼­ Áö¿øÇÏ´Â ÇÔ¼ö ÀÌ¿Ü´Â »ç¿ëÇÒ  ¼ö ¾øÀ¸´Ï ÀÌÀü
ÀÇ µµ½º ¸®¾ó ¸ðµå¿¡¼­ÀÇ Å¸ÀÌ¸Ó Á¦¾î¸¦ ´Ù·çµµ·Ï ÇÑ´Ù.

1> »ç¿îµå Ä«µåÀÇ Á¦¾î

 ¿äÁò¿¡ ³ª¿À´Â   ¸ðµç »ç¿îµå  Ä«µåµéÀÌ  ±âº»ÀûÀ¸·Î ȣȯ   ½ÃÅ°°í ÀÖ´Â  AdLib
Compatible Àº ±× ¿ø¸®°¡ FM(Frequency Modulation)À» ±âº»À¸·Î ÇÏ°í Àֱ⠶§¹®¿¡
ÀÏÁ¤ ÁÖÆļö¸¦ ÀÏÁ¤ µô·¹ÀÌ µ¿¾È ³ª°Ô ÇÏ¸é ±×°ÍÀÌ ¹Ù·Î À½¿øÀ» ±¸¼ºÇÏ°Ô µÇ´Â ±¸
Á¶ÀÌ´Ù. Âü°í·Î MOD, S3M, IT µîÀÇ ¸ðµâÀ½¾ÇÀº °¢  À½¿øÀÌ ¸ðµâ·Î ¼ÒÇÁÆ®¿þ¾îÀûÀÎ
±¸¼ºÀ» ÇÏ°í ÀÖÀ¸¸ç MIDI ´Â Çϵå¿þ¾îÀûÀÎ À½¿øÀ» °¡Áö°í ÀÖ´Ù. ±× ¸ðµâÀ½¾ÇÀº À½
¿ø Á¤º¸°¡ ¸ðµÎ À½¾Ç ÆÄÀÏ ³»ºÎ¿¡ µé¾î°¡±â ¶§¹®¿¡ MIDI º¸´Ù ÈξÀ  ´õ Å« »çÀÌÁî
ÀÎ °ÍÀ̸ç Adlib¿ë À½¾Ç ÆÄÀÏÀÎ ROL, IMS, MDI, SOD µîÀº À½¿øÀ» '¹ðÅ©'¶ó´Â °³³ä
À¸·Î °¡Áö°í ÀÖ´Ù.

 ¾Æ·¡ÀÇ ¼Ò½º´Â ¹Ù·Î AdLib ȣȯ »ç¿îµå Ä«µå¿¡¼­ À½À» ¹ß»ý ½ÃÅ°´Â ¿ø¸®ÀÌ´Ù.

const
   ADLIB = $388;   // ¾Öµå¸³ÀÇ Æ÷Æ® ¹øÈ£

procedure AdLibOut(Address, Data : byte); assembler;
asm
  mov dx, ADLIB
  mov al, Address
  out dx, al

            mov  cx,   6
@@LOOP1:
  in  al, dx         // »ç¿îµå Ä«µå°¡ ¸í·ÉÀ» Çؼ®ÇÏ´Â
  loop @@LOOP1       // µ¿¾È ´ë±â

  inc dx
  mov al, Data
  out dx, al
  dec dx

  mov cx, 35
@@LOOP2:
  in  al, dx         // »ç¿îµå Ä«µå°¡ ÁÖÆļö µ¥ÀÌÅ͸¦
  loop @@LOOP2       // Çؼ®ÇÏ´Â µ¿¾È ´ë±â
end;

 À§ÀÇ ¼Ò½º´Â °¢ ¸í·ÉÀÌ ÀÖ´Â Address  ¸¦ ¸ÕÀú ¾Ë¸° ÈÄ¿¡ ÁÖÆļö  Á¤º¸¸¦ º¸³»´Â
°ÍÀÌ ÀüºÎÀÌ´Ù. ÇÏÁö¸¸ ÀÌ°ÍÀ¸·Î ¸ðµç À½ÀÌ ´Ù Ç¥ÇöµÉ ¼ö  ÀÖ´Ù. °¢°¢ÀÇ ÁÖÆļö¸¦
°¢°¢ ´Ù¸¥ µô·¹À̸¦ ÅëÇØ Á¤ÀÇÇϱ⠶§¹®¿¡ ÇǾƳ뿡¼­  µå·³±îÁöÀÇ ´Ù¾çÇÑ À½¿øÀ»
ÇÕ¼ºÇØ ³¾ ¼ö ÀÖ°Ô µÇ´Â °ÍÀÌ´Ù. ( ¹°·Ð À̷л󿡼­.. )

2> ŸÀ̸ÓÀÇ Á¦¾î

 ¿ø·¡ µµ½º¿¡¼­ Áö¿øÇϴ Ŭ·°Àº 1ÃÊ¿¡ 18.2 ¹ø È£ÃâÇÏ°Ô µÇ¾î  ÀÖ´Â ½Ã½ºÅÛ ½Ã°£
À» À§ÇÑ Å¬·°ÀÌ´Ù. ÇÏÁö¸¸ À̰ͺ¸´Ù ´õ ºü¸¥ Ŭ·°À» ¿øÇÑ´Ù¸é Port 40h ºÎÅÍ Port
43h ±îÁö ÇÒ´çµÇ¾î ÀÖ´Â 8253 ĨÀ» ÀÌ¿ëÇÏ´Â ¹æ¹ýÀÌ ÀÖ´Ù. ¾Æ·¡ÀÇ ¼Ò½º´Â Ŭ·° ÁÖ
Æļö¸¦ ´Ù½Ã ¸¸µå´Â ÇÔ¼ö´Â À̸ç ÀÌ·¸°Ô ¸¸µç Ŭ·° ÁÖÆļö¿¡ ¸ÂÃ߾ delay() ³ª
sleep() °°Àº ÇÔ¼ö°¡ ÀÛµ¿ÇÏ°Ô µÈ´Ù.

 ±×·³..  Á¤È®ÇÑ Å¸ÀÌ¸Ó µô·¹À̸¦ ÁÖ±â À§ÇÑ ¹æ¹ýµµ ¾Ë¾Æ º¸ÀÚ.

const
   FREQ_8253 = 1193280;
              // ÀÌ °ªÀº 8253/8254 ĨÀÇ °íÀ¯ ÁêÆļö
procedure SetNewTimer(frequency : word);
begin
    port[$43] := $34;  // 8253 control word¸¦ ¾²°Ú´Ù´Â ¼±¾ð
       // $34 ==> 00110100
       //         | | |  +-- 2 ÁøÀÇ control type À» ¼±¾ð..
       //         | | +----- ÁÖÆļö ºñÀ²À» Á¶Á¤ ÇÏ°Ú´Ù...
       //         | +------- ·¡Ä¡ÀÇ »óÀ§, ÇÏÀ§ byte read Æ÷¸ËÀ¸·Î..
       //         +--------- ŸÀÌ¸Ó 0 ¹øÀ¸·Î.. ( ClockÀÌ ¾²´Â ŸÀ̸ÓÀÓ )
    port[$40] := (FREQ_8253 div frequency) mod 256);
    port[$40] := (FREQ_8253 div frequency) div 256);
                       // ÁÖÆļö¸¦ ³ª´« °ªÀ» Æ÷Æ®¿¡ ÇÏÀ§ 8 bit »óÀ§ 8 bit ¼ø
                       // À¸·Î ½á ³ÖÀ½.
end;

 ÀÌ·¸°Ô Ŭ·° ÃÖ¼Ò ÁÖÆļö¸¦ Á¶Á¤ÇÏ¿©¼­ ÀÎÅÍ·´Æ® 0x08¸¦ °¡·Îä¸é ÀÚ½ÅÀÇ Å¸À̸Ó
Çڵ鷯°¡ ¸¸µé¾îÁø´Ù. ÇÏÁö¸¸ ¿©±â¿¡´Â ´ÜÁ¡ÀÌ »ý±â´Âµ¥ 18.2 ÃÊ¿¡ Çѹø¾¿ °»½ÅµÇ
°Ô µÇ¾î ÀÖ´Â PC ÀÇ ½Ã°è°¡ ´Ù¸¥ ÁÖÆļö·Î °»½ÅµÇ±â ¶§¹®¿¡ ½Ã°è°¡ »¡¶óÁö°Å³ª ´À
·ÁÁö´Â Çö»óÀÌ ¹ß»ýÇÑ´Ù. ÀÌ ¶§´Â ÀÚ½ÅÀÇ Å¸ÀÌ¸Ó Çڵ鷯  ¾È¿¡´Ù°¡ ¿ø·¡ÀÇ Ä«¿îÅÍ
¿¡ ¸Â°Ô ½Ã°è¸¦ ÀÛµ¿ ½ÃÅ°´Â ·çƾÀ» ³Ö¾î¾ß ÇÏ´Â ¹ø°Å·Î¿î ÀýÂ÷°¡ µû¸¥´Ù.

  <Âü°í> ³»ºÎ ŸÀ̸Ó
     Voice ÆÄÀÏ Ãâ·Â ÇÁ·Î±×·¥ µîÀ» º¸¸é ŸÀÌ¸Ó 2 ¹øÀ» Á¶Á¤Çϱ⵵ ÇÏ´Â °Í °°
     ´Ù. ŸÀÌ¸Ó 2 ¹øÀº ½ºÇÇÄ¿ µî¿¡ »ç¿ëµÇ´Â ŸÀ̸ÓÀε¥ ½Ã°è¿¡ ¿µÇâÀ» ÁÖÁö ¾Ê
     À¸´Ï ÀåÁ¡ÀÌ ÀÖ´Ù.. ÇÏÁö¸¸ ´ëºÎºÐÀÇ ½Ç½Ã°£ À½¾Ç ¿¬ÁÖ ·çƾ µîÀº ¸ðµÎ ŸÀÌ
     ¸Ó 0 ¹øÀ» ¾²°í ÀÖ´Ù.

3> ŸÀ̸Ӹ¦ ÅëÇÑ ½Ç½Ã°£ ¹è°æ À½¾Ç ¿¬ÁÖ

 µµ½º¿¡¼­´Â ÀÎÅÍ·´Æ® º¤Å͸¦ °¡·Îä¾î¼­ ºñ±³Àû À©µµ¿ì º¸´Ù´Â ´õ¿í Á¤¹ÐÇÑ Å¸ÀÌ
¸Ó Á¦¾î°¡ °¡´ÉÇÏ´Ù. µµ½º ÀÎÅÍ·´Æ® 0x08 ¹øÀº 18.2 Ãʸ¶´Ù Çѹø¾¿ ½Ã½ºÅÛ¿¡ ÀÇÇØ
¼­ ºÒ¸®¾îÁö´Â ÀÎÅÍ·´Æ®·Î µðÆúÆ®´Â ½Ã°£À» À§ÇÑ Ä«¿îÅ͸¦  Áõ°¡½ÃŲ ÈÄ¿¡ ÇÔ¼ö¸¦
¸®ÅÏ ½ÃÅ°´Â °ÍÀÌ´Ù. ±×·¸±â ¶§¹®¿¡ ¿ì¸®°¡ ½Ç½Ã°£À¸·Î À½¾ÇÀ» ¿¬ÁÖ ÇÏ·Á¸é ÀÌ ºÎ
ºÐÀÇ ÀÎÅÍ·´Æ® º¤Å͸¦ °¡·ÎèÀ¸·Î½á °¡´ÉÇØÁö´Â °ÍÀÌ´Ù.

 ¸ÕÀú ÃʱâÈ­ ÇÏ´Â ºÎºÐºÎÅÍ »ìÆì º¸ÀÚ.

const
   TIMER_INTERRUPT = $08;  // ŸÀÌ¸Ó ÀÎÅÍ·´Æ®¿¡ ´ëÇÑ ¹øÈ£ÀÌ´Ù.
var
   OldInt08 : procedure;   // ÀÌÀüÀÇ ÀÎÅÍ·´Æ® º¤Å͸¦ º¸°üÇϱâ À§ÇÑ ÇÔ¼öÇü Æ÷
                           // ÀÎÅÍÀÌ´Ù.

procedure ClockInterrupt; interrupt; assembler;
  // ÀÌ ÇÔ¼ö´Â ÀÎÅÍ·´Æ®°¡ °¡´ÉÇÑ void ÇÔ¼ö·Î ¼±¾ð µÇ¾î ÀÖ´Ù.

( ÃʱâÈ­ ÄÚµå   )
   getIntVec(TIMER_INTERRUPT,@OldInt08);
   // OldInt08 À̶õ º¯¼ö¿¡ ÇöÀç 0x08 ¹ø ÀÎÅÍ·´Æ® º¤Å͸¦ ÀúÀåÇÑ´Ù.
   setIntVec(TIMER_INTERRUPT,@ClockInterrupt);
   // 0x08 ¹ø ÀÎÅÍ·´Æ® º¤ÅÍ°¡ ClockInterrupt ¸¦ °¡¸®Å°°Ô ÇÑ´Ù.
   setNewTimer(298295 div basic_tempo);
   // ÇöÀçÀÇ Å¬·°À» Á¶ÀýÇÑ´Ù.

 ¹°·Ð Á¾·á ÄÚµå´Â ´ÙÀ½°ú °°ÀÌ ÃʱâÈ­ÀÇ ¹Ý´ë·Î ÇÏ¸é µÈ´Ù.

( Á¾·á ÄÚµå )
   setNewTimer(0);
   // Ŭ·° È£Ã⠺󵵸¦ µðÆúÆ®·Î ¹Ù²Û´Ù.
   setIntVec(TIMER_INTERRUPT,@OldInt08);
   // 0x08 ¹ø ÀÎÅÍ·´Æ®¸¦ ¿¹ÀüÀÇ °ÍÀ¸·Î º¹±Í ½ÃŲ´Ù.

 ÀÌ·¸°Ô Çϸé À¯Àú°¡ ÁöÁ¤ÇÑ Å¬·°À» ±âÁØÀ¸·Î 0x08 ÀÎÅÍ·´Æ®°¡ È£ÃâµÇ°Ô µÈ´Ù.
 ±×·³ ¸ÕÀú ½Ç½Ã°£ ¹è°æ À½¾ÇÀ» À§ÇÑ ÇÙ½É ÇÔ¼öÀÎ ClockInterrupt ¸¦ »ìÆì º¸±â·Î
ÇÏÀÚ.

 

var
   TimeOutFunction : function : word;
     // À½¾ÇÀ» ½ÇÁ¦ÀûÀ¸·Î ¿¬ÁÖÇÏ´Â ºÎºÐÀ¸·Î ¹Ì¸® ÇÔ¼öÀÇ Æ÷ÀÎÅÍ·Î ´ëÀԵǾî Á®
ÀÖ´Ù.
procedure ClockInterrupt; interrupt; assembler;
     // ÀÌ ÇÔ¼ö´Â ÃÖ´ëÇÑ »¡¸® ¼öÇà µÇ¾î¾ß ÇϹǷΠ¾î¼Àºí·¯·Î Á¦ÀÛ µÇ¾îÁ³´Ù.
asm
 MOV     AX, clock_division_low   // À¯Àú°¡ º¯°æÇÑ Å¬·°Àº ÀÌÀüÀÇ   
 ADD     clock_mode, AX           // Ŭ·°°ú´Â ÁÖÆļö°¡ ´Ù¸£±â ¶§¹®¿¡
 MOV     AX, clock_division_high  // ÀÌÀüÀÇ ÁÖÆļö¿Í µ¿±âÈ­ ½ÃÄѼ­
 ADC     AX, 0                    // OldInt08 ¸¦ ½ÇÇà ÇØ¾ß ÇÑ´Ù.
 JNZ     @@ClockInterrupt8        // ±×·¸Áö ¾ÊÀ¸¸é ½Ã°è°¡ »¡¸® °¡ ¹ö¸°´Ù.
 MOV     AL, 00100000b             
 OUT     20h, AL
 JMP     @@ClockInterrupt7

@@ClockInterrupt8:
 PUSHF                            // Ç÷¡±×¸¦ ½ºÅÿ¡ ÀúÀå
 CALL   OldInt08                  // ½Ã½ºÅÛ ½Ã°è¸¦ °¡°Ô Çϱâ À§Çؼ­
                                  // 1 ÃÊ¿¡ 18.2 ¹ø È£Ãâ
@@ClockInterrupt7:
 DEC     sound_delay              // ¾ÆÁ÷µµ À½ÀÌ µô·¹ÀÌ ÁßÀ̸é
 JNZ     @@ClockInterruptEnd      // ÇÔ¼ö¸¦ Á¾·á

@@GoUser:

 STI                              // ÀÎÅÍ·´Æ®¸¦ °¡´ÉÇÏ°Ô ÇÑ´Ù
 CALL    TimeOutFunction;         // À½¾Ç µ¥ÀÌÅ͸¦ Àаí Æ÷Æ®·Î Ãú·Â
 CLI                              // ¸ðµç ÀÎÅÍ·´Æ®¸¦ ºÒ°¡´ÉÇÏ°Ô ÇÑ´Ù

 MOV     BX, sound_delay          // if (-sound_delay < ax) break;
 NEG     BX
 CMP     BX, AX
 JB      @@ClockDelayOk

 MOV     sound_delay, 0
 JMP     @@GoUser

@@ClockDelayOk:
 ADD     sound_delay, AX

 STI

@@ClockInterruptEnd:
end;


2. API ŸÀ̸Ó

1> API ŸÀ̸ÓÀÇ °³¿ä

 Å¸À̸Ӵ ¾î¶² ÇÁ·Î±×·¥ ¾È¿¡¼­ ÁÖ±âÀûÀ¸·Î ÇàÇÏ¿© Áö´Â ÀÛ¾÷ÀÌ  ÇÊ¿äÇÒ ¶§ À¯¿ë
ÇÏ°Ô »ç¿ëµÇ´Âµ¥, 32 ºñÆ® ¿î¿µÃ¼Á¦ÀÎ Window 95¿¡¼­´Â  2,500°³ ÀÌ»óÀÇ Å¸À̸Ӹ¦
Áö¿øÇÑ´Ù.
 Å¸À̸ÓÀÇ ¼±¾ðÀº SetTimer()¿¡ ÀÇÇؼ­  ¼±¾ðÀÌ µÇ¾îÁö¸ç ±×¶§ ¾òÀº  Å¸ÀÌ¸Ó ID¸¦
ÅëÇؼ­ ¸ðµç Á¦¾î°¡ ÀÌ·ç¾îÁø´Ù.  Å¸À̸Ӱ¡ ¼±¾ðµÇ¸é ±× ŸÀ̸Ӱ¡  ÇØÁ¦µÉ ¶§±îÁö
ÁÖ±âÀûÀ¸·Î À̺¥Æ® ¶Ç´Â Äݹé ÇÔ¼ö¸¦ È£ÃâÇÏ°Ô µÇ¸ç, ÇÁ·Î±×·¥ÀÌ ³¡³ª¸é ÀÚµ¿ÀûÀ¸
·Î ŸÀ̸Ӵ Á¾·áµÈ´Ù.

2> API ŸÀ̸ÓÀÇ ¼±¾ð ¹æ¹ý

 API ŸÀ̸Ӵ ´ÙÀ½ÀÇ ¿øÇüÀ¸·Î Á¤ÀÇµÈ SetTimer() ÇÔ¼ö·Î ¼³Á¤À» ÇÑ´Ù.

   UINT  SetTimer(HWND hWnd, UINT uTimerID, UINT uInterval,
                  TIMERPROC fnTimerProc)

      hWnd        : ŸÀ̸Ӹ¦ °¡Áö°í ÀÖ´Â À©µµ¿ìÀÇ ÇÚµé, NULL ÀÏ ¶§´Â À©µµ¿ì
                    ¿¬°ü ¾øÀ½
      uTimerID    : Á¤ÀÇ ÇÏ°íÀÚ Çϴ ŸÀÌ¸Ó ¹øÈ£, 0ÀÌ¸é ½Ã½ºÅÛÀÌ ¾Ë¾Æ¼­ °áÁ¤
      uInterval   : mili second ±âÁØÀÇ À̺¥Æ® ¹ß»ý °£°Ý
      fnTimerProc : NULL À̸é WM_TIMER ¸Þ¼¼Áö ¹ß»ý, ¸¸¾à ÇÔ¼ö¶ó¸é ±× ÇÔ¼ö¸¦
                    Äݹé ÇÔ¼ö·Î.
      ¹Ýȯ°ª  -  ¼³Á¤µÇ¾îÁø ŸÀÌ¸Ó ID

 ¿©±â¼­ ¸¶Áö¸·ÀÇ fnTimerProc¿¡ ÀÇÇؼ­ ¸Þ¼¼Áö ÄݹéÀÇ ÇüÅ°¡ 2°¡Áö·Î Á¤ÇØÁø´Ù.

  1) ¸Þ¼¼Áö ¹ß»ý
    : hWnd ·Î ³Ñ°ÜÁø À©µµ¿ì ÇÚµéÀ» °¡Áø ÀνºÅϽº·Î WM_TIMER ¶ó´Â ¸Þ¼¼Áö°¡ ³Ñ
     ¾î°¡°Ô µÈ´Ù. ÇÁ·Î±×·¡¸Ó´Â ±× ¸Þ¼¼Áö¸¦ case·Î ºÐ·ùÇؼ­ ·çƾÀ» Â¥¸é µÈ´Ù.

  2) Äݹé ÇÔ¼ö
    : void CALLBACK TimerProc(HWND hWnd, UNIT uMsg, UINT idEvent, DWORD
     dwTime)À¸·Î Á¤ÀǵǾîÁø Äݹé ÇÔ¼ö¸¦ À̺¥Æ®°¡ ¹ß»ýÇϸé È£ÃâÇÑ´Ù.
    

3> API ŸÀ̸ÓÀÇ ´ÜÁ¡

 À©µµ¿ì´Â ¸¹Àº ŸÀ̸ӵéÀÇ È£Ãâ¿¡ ÀÇÇÑ ½Ã½ºÅÛ ¸¶ºñ Çö»óÀ»  ¾ø¾Ö±â À§ÇØ ÁÖ¾îÁø
½Ã°£¿¡ ´Ü ÇÑ °³ÀÇ  Å¸ÀÌ¸Ó ¸Þ¼¼Áö(WM_TIMER)¸¸À» ¹Þ°í ³ª¸ÓÁö´Â  ¹«½ÃÇØ ¹ö¸°´Ù.
¶ÇÇÑ WM_PAINT¸¦ Á¦¿ÜÇÑ ¸ðµç À©µµ¿ìÀÇ ¸Þ¼¼Áö°¡ WM_TIMER  º¸´Ù ¿ì¼±Çϱ⠶§¹®¿¡
API ŸÀ̸Ӵ ¿ø·¡ Á¤ÇØÁø ½Ã°£°ú´Â ´Ù¼ÒÀÇ ¿ÀÂ÷°¡ ¹ß»ýÇÏ°Ô µÈ´Ù.
´ëºÎºÐÀÇ ÀÀ¿ë ÇÁ·Î±×·¥¿¡¼­´Â ÀÌ·¯ÇÑ Å¸À̸ÓÀÇ Áö¿¬¿¡ ´ëÇؼ­´Â  °£°úÇØ ¹ö¸± ¼ö
ÀÖÀ¸³ª ¸ÖƼ¹Ìµð¾î³ª °ÔÀÓÀÇ µ¿±âÈ­¿¡¼­´Â API ŸÀ̸ӷδ ¸¸Á·ÇÒ ¼ö  ¾ø´Â °Ô »ç
½ÇÀÌ´Ù.

3. ¸ÖƼ¹Ìµð¾î ŸÀ̸Ó

1> ¸ÖƼ¹Ìµð¾î ŸÀ̸ÓÀÇ °³¿ä

 Àü¼úÇÑ API Ç¥ÁØ Å¸À̸Ӵ ¸Þ¼¼Áö ¹æ½ÄÀÇ ¿ì¼± ¼øÀ§ ¶§¹®¿¡  Á¤±³ÇÑ Á¦¾î¸¦ À§ÇØ
¼­´Â º°·Î À¯¿ëÇÏÁö ¸øÇÏ´Ù. °Ô´Ù°¡ ÃÖ´ë ºóµµ¼ö°¡ ÃÊ´ç 18 ŸÀÓÀ̱⠶§¹®¿¡ ±×º¸
´Ù ´õ Á¤È®ÇÑ 1/1000 Ãʸ¦ Á¦¾îÇÒ ¼ö Àִ ŸÀ̸Ӱ¡ ¿ä±¸µÇ¾î Á³´Âµ¥ ±×°ÍÀÌ ¹Ù·Î
ÀÌ ¸ÖƼ¹Ìµð¾î ŸÀ̸ÓÀÌ´Ù. ÀÌ°ÍÀº MIDI ½ÃÄö½º ÀåÄ¡ ¶Ç´Â  ´Ù¸¥ Àü¹® Çϵå¿þ¾î¿¡
´ëÇÑ MIDI À̺¥Æ® Á¦¾îó·³ ¾ÖÇø®ÄÉÀ̼ÇÀÇ Á¤È®ÇÑ Å¸À̹ÖÀ»  ¿ä±¸ÇÒ ¶§ »ç¿ëµÇ¾î
Áø´Ù.

 ÀÌ ¸ÖƼ¹Ìµð¾î  Å¸À̸Ӱ¡ API  Å¸ÀÌ¸Ó¿Í ´Ù¸¥   Á¡À̶ó¸é Timer Event  Callback
Notification ¸ÞÄ¿´ÏÁòÀ̶ó´Â °ÍÀÌ´Ù. ( API ŸÀ̸Ӵ ¾ÖÇø®ÄÉÀÌ¼Ç  ¸Þ¼¼Áö Å¥¿¡
WM_TIMER »ðÀÔ )

2> ÇÔ¼ö ¿ä¾à

    timeGetDevCaps    Å¸À̸Ӱ¡ Áö¿øÇÏ´Â ÃÖ¼Ò ÃÖ´ë Çػ󵵸¦ ¾Ë¾Æ³½´Ù.
    timeBeginPeriod   ÃÖ¼ÒÀÇ Å¸ÀÌ¸Ó Çػ󵵸¦ °áÁ¤ÇÑ´Ù.
    timeEndPeriod     timeBeginPeriod ¿¡ ÀÇÇØ ¸¸µé¾îÁø ŸÀÌ¸Ó Çػ󵵸¦ Á¦°Å
                      ÇÑ´Ù.
    timeSetEvent      Å¸ÀÌ¸Ó À̺¥Æ®¸¦ ½ÃÀÛÇÏ°í °£°Ý¿¡ µû¶ó Äݹé ÇÔ¼ö¸¦ È£Ãâ
                      ÇÑ´Ù.
    timeKillEvent     Å¸ÀÌ¸Ó À̺¥Æ®¸¦ ³¡³½´Ù.

 ¿©±â¼­ timeBeginPeriod ¿¡ ÀÇÇØ ³Ñ°ÜÁö´Â ¹Ð¸® ÃÊ ´ÜÀ§ÀÇ ÃÖ¼Ò Å¸ÀÌ¸Ó Çػ󵵴Â
±× Çػ󵵿¡ ´ëÇÑ ID ó·³ »ý°¢ÇÒ ¼ö ÀÖÀ¸¸ç timeEndPeriod ¿¡ ÀÇÇØ Á¦°Å µÉ ¶§µµ
±× ÃÖ¼Ò Çػ󵵸¦ ³Ñ°Ü ÁÖ¾î¾ß Á¦°Å °¡´ÉÇÏ´Ù. timeSetEvent  ·Î ŸÀÌ¸Ó À̺¥Æ®¸¦
½ÃÀÛÇϱâ Àü¿¡   Ç×»ó ÃÖ¼Ò  Å¸ÀÌ¸Ó  Çػ󵵰¡ Á¤ÇØÁ®¾ß   Çϸç ŸÀÌ¸Ó  À̺¥Æ®°¡
timeKillEvent ·Î Á¦°¡ µÈ ÈÄ¿¡´Â Ç×»ó Á¦°Å µÇ¾îÁ®¾ß ÇÑ´Ù.

 ¶Ç, Á¤È®ÇÑ  ¹Ð¸®  ÃÊ ´ÜÀ§ÀÇ   ½Ã°£À» ¾ò°íÀÚ  ÇÒ ¶§´Â   timeGetSystemTime °ú
timeGetTime À» »ç¿ëÇÏ¸é µÇ´Âµ¥ ÀÌ  µÎ°³ÀÇ ÇÔ¼ö´Â API ŸÀ̸ӿ¡¼­  °°Àº ±â´ÉÀ»
ÇÏ´Â GetTickCount() ³ª GetCurrentTime() ¿Í´Â ´Þ¸® ½ÇÁúÀûÀÎ ¹Ð¸® ÃÊ Á¤º¸¸¦ Á¦
°øÇÑ´Ù.

3> ¸ÖƼ¹Ìµð¾î ŸÀ̸ÓÀÇ ´ÜÁ¡

 ÀÌ°ÍÀº »ó´çÈ÷ Á¤È®ÇÑ À̺¥Æ®¸¦ Á¦°øÇÏ´Â ¹Ý¸é¿¡ ±× ¸¸Å­  ½Ã½ºÅÛ¿¡ ¸¹Àº ºÎ´ãÀ»
ÁÖ°Ô µÇ¹Ç·Î ¿©·¯ °³ÀÇ Å¸À̸Ӹ¦  µ¿½Ã¿¡ µ¹¸®±â¿¡´Â ¸¹Àº ½Ã½ºÅÛÀÇ  ºÎÇÏ°¡ µû¸¥
´Ù.

 ¶Ç ÇϳªÀÇ ¹®Á¦´Â Äݹé ÇÔ¼öÀÇ  Á¦ÇѼº¿¡ ÀÖ´Ù. API ŸÀ̸ÓÀÇ ÄÝ¹é  ÇÔ¼ö´Â ÀϹÝ
¸Þ¼¼Áö¿Í °°ÀÌ Ã³¸® µÇ±â ¶§¹®¿¡ ¾Æ¹«·± Á¦¾àÀÌ  ¾ø¾úÀ¸³ª ¸ÖƼ¹Ìµð¾î ŸÀ̸ӿ¡¼­
´Â Äݹé ÇÔ¼ö ³»¿¡¼­ »ç¿ëÇÒ ¼ö ÀÖ´Â ÇÔ¼ö°¡ Á¤ÇØÁ® ÀÖ°í, Á¤ÇØÁø ÇÔ¼ö ÀÌ¿ÜÀÇ »ç
¿ëÀÚ ÇÔ¼ö³ª API µîÀ» È£ÃâÇÏ¸é ¿¹ÃøÇÒ ¼ö ¾ø´Â °á°ú¸¦ ÃÊ·¡ÇÏ°Ô µÈ´Ù. Á¤ÇØÁø ÇÔ
¼ö¶õ,  PostMessage(),  timeGetSystemTime(),  timeGetTime(),  timeSetEvent(),
timeKillEvent(),         midiOutShortMessage(),        midiOutLongMessage(),
OutputDebugString() ÀÌ ÀüºÎÀÌ´Ù. PostMessage()¿Í  OutputDebugString() À»  Á¦
¿ÜÇÏ°í´Â ¸ðµÎ ¸ÖƼ¹Ìµð¾î ÇÔ¼öµé »ÓÀÌ´Ù. Áï, ¸ÖƼ¹Ìµð¾î ¿ëµµ ¿Ü¿¡ ŸÀ̸Ӹ¦ »ç
¿ëÇÏ·Á¸é ¸ðµÎ PostMessage()¸¦ »ç¿ëÇÏ¿© ´Ù½Ã ¸Þ¼¼Áö¸¦ ¹ß»ýÇØ¾ß ÇÏ´Â °ÍÀÌ´Ù. (
API ŸÀÌ¸Ó º¸´Ù¾ß ºü¸£°ÚÁö¸¸ ´ë´ÜÇÑ Å¬·° ³¶ºñ´Ù. )

 

#####################################################

À̹ø Àå¿¡¼­´Â 'API ŸÀ̸Ó'¿Í '¸ÖƼ¹Ìµð¾î ŸÀ̸Ó'ÀÇ ¿ë¹ý°ú ÇÔ²²  ±× ¼º´É¿¡ ´ë
Çؼ­ ³íÇÏ°íÀÚ ÇÑ´Ù. ÀÌ °­ÁÂÀÇ ¼Ò½º´Â ¸ðµÎ µ¨ÆÄÀÌ·Î Á¦À۵ǾúÀ¸¹Ç·Î C »ç¿ëÀÚµé
Àº ¾Æ½¬¿î ´ë·Î ´«À¸·Î Àаí ÀÌÇØÇÏ½Ã±æ ¹Ù¶õ´Ù.

unit Unit1;

interface

uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
   ExtCtrls, StdCtrls;

type
   TForm1 = class(TForm)
      Edit1       : TEdit;        // ŸÀÌ¸Ó ÄݹéµÈ ȸ¼ö Ãâ·Â
      Edit2       : TEdit;        // ÃÊ´ç Äݹé ȸ¼ö
      Button1     : TButton;      // ŸÀÌ¸Ó Á¾·á ¹öÆ°
      StaticText1 : TStaticText;  // ¶óº§ 1
      StaticText2 : TStaticText;  // ¶óº§ 2
      Panel1      : TPanel;       // ÇöÀç ¼³Á¤µÈ Äݹé ÁÖ±â Ãâ·Â
      procedure FormShow(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
      procedure Button1Click(Sender: TObject);

   private
      FTimerID: word;
      Fms     : word;
      FCouter : integer;
      FTime   : longint;
   end;

var
   Form1 : TForm1;

implementation

{$R *.DFM}

// API ŸÀÌ¸Ó Äݹé ÇÔ¼ö
procedure TimerProc(handle : hWnd; uMessage,
                    idEvent : word; dwTime : DWORD);
var
   f : real;
   s : string;
begin
   inc(Form1.FCouter);
   str(Form1.FCouter,s);
   Form1.Edit1.Text := s;

   f := (Form1.FCouter * 1000) / (GetCurrentTime - Form1.FTime);
   str(f : 6 : 3,s);
   Form1.Edit2.Text := s;  // ÃÊ´ç Äݹé ȸ¼ö Ãâ·Â

   if Form1.FCouter = 0 then begin
      Form1.FTime := GetCurrentTime;  // Äݹé Ä«¿îÆ®ÀÇ ÃʱâÈ­
   end;
end;

procedure TForm1.FormShow(Sender: TObject);
var
   s        : string;
begin
   Fms := 100;  // ŸÀÌ¸Ó Áֱ⸦ 100ms ¸¶´Ù ÇÑ ¹ø¾¿ È£ÃâµÇ°Ô ÇÑ´Ù.
   FTimerID := SetTimer(handle,0,Fms,@TimerProc);
                // ŸÀ̸Ӹ¦ ¼³Á¤ÇÑ´Ù.
   if FTimerID = 0 then begin
      raise Exception.Create('SetTimer() Error !!');
      Close;
      Exit;     // ¿¡·¯ ó¸® ·çƾ
   end;

   str(Fms,s);
   Panel1.Caption := 'ŸÀÌ¸Ó ¼³Á¤ :' + s + 'ms';

   FCouter := -1;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
   if FTimerID <> 0 then begin
      KillTimer(handle,FTimerID);
                // ŸÀÌ¸Ó ÇØÁ¦
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Close;
end;

end.

¾Æ·¡´Â Æû¿¡ ´ëÇÑ Text ÆÄÀÏÀÌ´Ù. Form ¿¡¼­ ¿À¸¥ÂÊ ¹öÆ°À» ´©¸£¸é »ý±â´Â ¸Þ´º¿¡
¼­ View as Text ¸¦ ¼±ÅÃÇÑ ÈÄ¿¡ ¾Æ·¡ÀÇ ¼Ò½º·Î ´ëüÇÏ°í ´Ù½Ã  ¿À¸¥ÂÊ ¹öÆ°À» ´­
·¯¼­ View as Form À» ¼±ÅÃÇÏ¸é ¿ø·¡ÀÇ Form ÀÌ Çü¼ºµÇ°Ô µÈ´Ù.

object Form1: TForm1
  Left = 276
  Top = 145
  Width = 124
  Height = 214
  Caption = 'Form1'
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OnDestroy = FormDestroy
  OnShow = FormShow
  PixelsPerInch = 96
  TextHeight = 13
  object Edit1: TEdit
    Left = 0
    Top = 56
    Width = 113
    Height = 21
    ImeName = 'Çѱ¹¾î(ÇѱÛ)'
    TabOrder = 0
  end
  object Edit2: TEdit
    Left = 0
    Top = 104
    Width = 113
    Height = 21
    ImeName = 'Çѱ¹¾î(ÇѱÛ)'
    TabOrder = 1
  end
  object Button1: TButton

   Left = 24
    Top = 144
    Width = 75
    Height = 25
    Caption = 'Stop !!'
    TabOrder = 2
    OnClick = Button1Click
  end
  object StaticText1: TStaticText
    Left = 0
    Top = 40
    Width = 116
    Height = 17
    Alignment = taCenter
    Caption = 'ŸÀÌ¸Ó Äݹé È£Ãâ'
    Font.Charset = HANGEUL_CHARSET
    Font.Color = clWindowText
    Font.Height = -13
    Font.Name = 'µ¸¿òü'
    Font.Style = []
    ParentFont = False
    TabOrder = 3
  end
  object StaticText2: TStaticText
 Left = 8
    Top = 88
    Width = 102
    Height = 17
    Caption = 'ÃÊ´ç Äݹé ȸ¼ö'
    Font.Charset = HANGEUL_CHARSET
    Font.Color

= clWindowText
    Font.Height = -13
    Font.Name = 'µ¸¿òü'
    Font.Style = []
    ParentFont = False
    TabOrder = 4
  end
  object Panel1: TPanel
    Left = 0
    Top = 0
    Width = 116
    Height = 25
    Align = alTop
    BevelInner = bvLowered
    Font.Charset = HANGEUL_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'µ¸¿òü'
    Font.Style = []
    ParentFont = False
    TabOrder = 5
  end
end

À§ÀÇ ¼Ò½º°¡ ÀÌÇØ µÇ¾ú´Ù¸é Á÷Á¢ ½ÇÇà ½ÃÄÑ º¸ÀÚ. ¿ì¸®´Â óÀ½¿¡  Å¸ÀÌ¸Ó Äݹé ÁÖ
±â¸¦ 100ms ·Î ¼³Á¤Çß°í, ¿¹»óµÇ¾îÁö´Â ÃÊ´ç Äݹé ȸ¼ö´Â 10¹øÀÌ´Ù.
ÇÏÁö¸¸ ½ÇÁ¦·Î 1 ºÐ Á¤µµ ½ÇÇà  ½ÃÄѺ¸¸é ÃÊ´ç 9.036 ¹øÀÇ ÄݹéÀÌ  ÀÌ·ç¾î Áø´Ù´Â
°ÍÀ» ¾Ë ¼ö ÀÖ´Ù ( ÆæƼ¾ö 2 266Mz ¿¡¼­ ½ÇÇè ). ÀÌ°ÍÀº API  Å¸À̸Ӱ¡ ¿ì¸®°¡ ¿ø
ÇÏ´Â °Í ÀÌÇÏÀÇ ¼º´ÉÀ» ³½´Ù´Â °ÍÀ» ¸»ÇØ ÁÖ°í Àִµ¥, ÀÌ  °á°ú´Â ´ÙÀ½¿¡ È®ÀÎÇØ
º¼ ¸ÖƼ¹Ìµð¾î ŸÀ̸ÓÀÇ Á¤È®µµ¿¡ ºñÇØ ¸¹Àº Â÷À̸¦ º¸ÀδÙ.

----------------------------------------------------------------------------

±×·³, ´ÙÀ½Àº ¸ÖƼ¹Ìµð¾î ŸÀ̸ÓÀÇ ¼º´ÉÀ» Æò°¡ÇÏ´Â ¿¹Á¦ÀÌ´Ù.
Æû¿¡ ´ëÇÑ °ÍÀº À§ÀÇ API ŸÀ̸ÓÀÇ Æû°ú°°ÀÌ ¾²¸é µÈ´Ù.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, mmSystem;

const
   USR_TIMER_ELAPSED = WM_USER+100;
type
   TForm1 = class(TForm)
      Edit1       : TEdit;        // ŸÀÌ¸Ó ÄݹéµÈ ȸ¼ö Ãâ·Â
      Edit2       : TEdit;        // ÃÊ´ç Äݹé ȸ¼ö
      Button1     : TButton;      // ŸÀÌ¸Ó Á¾·á ¹öÆ°
      StaticText1 : TStaticText;  // ¶óº§ 1
      StaticText2 : TStaticText;  // ¶óº§ 2
      Panel1      : TPanel;       // ÇöÀç ¼³Á¤µÈ Äݹé ÁÖ±â Ãâ·Â
      procedure FormShow(Sender: TObject);
      procedure FormDestroy(Sender: TObject);
      procedure Button1Click(Sender: TObject);

   private
      FTimerID: UINT;
      Fms     : UINT;
      FCouter : integer;
      FTime   : longint;

      procedure EditCallback(var M : TMessage); message USR_TIMER_ELAPSED;
         // »ç¿ëÀÚ ¸Þ½ÃÁö¸¦ ¹Þ±â À§ÇÑ ¸Þ½ÃÁö ó¸® ·çƾ
   end;

var
   Form1 : TForm1;

implementation

{$R *.DFM}

procedure TForm1.EditCallback(var M : TMessage);
var
   f : real;
   s : string;
begin
   inc(Form1.FCouter);
   str(Form1.FCouter,s);
   Form1.Edit1.Text := s;

   f := (Form1.FCouter * 1000) / (GetCurrentTime - Form1.FTime);
   str(f : 6 : 3,s);
   Form1.Edit2.Text := s;  // ÃÊ´ç Äݹé ȸ¼ö Ãâ·Â

   if Form1.FCouter = 0 then begin
      Form1.FTime := GetCurrentTime;  // Äݹé Ä«¿îÆ®ÀÇ ÃʱâÈ­
   end;
end;

procedure TimerProc(uTimer, uMessage : UNIT; dwUser, dw1, dw2 :  DWORD); stdcall;
begin
   PostMessage(dwUser,USR_TIMER_ELAPSED,0,0);
      // ¸ÖƼ¹Ìµð¾î ŸÀÌ¸Ó Äݹé ÇÔ¼ö¿¡´Â ´ëºÎºÐÀÇ API°¡ »ç¿ë ºÒ°¡ÇÏ´Ù.
      // ±×·¯¹Ç·Î ´Ù½Ã ¸Þ½ÃÁö¸¦ »ç¿ëÀÚ ¸Þ½ÃÁö ·çƾÀ¸·Î µ¹·Á¾ß ÇÑ´Ù.
end;

procedure TForm1.FormShow(Sender: TObject);
var
   s        : string;
   TimeCaps : TTimeCaps;
begin
   Fms := 100;  // ŸÀÌ¸Ó Áֱ⸦ 100ms ¸¶´Ù ÇÑ ¹ø¾¿ È£ÃâµÇ°Ô ÇÑ´Ù.
   if timeGetDevCaps(@TimeCaps,sizeof(TimeCaps)) <> TIMERR_NOERROR then
      raise Exception.Create('<timeGetDevCaps> Error !!');
      // ŸÀÌ¸Ó µð¹ÙÀ̽º¿¡ ´ëÇÑ Á¤º¸¸¦ ¾ò¾î ¿Â´Ù.

   if Fms < TimeCaps.wPeriodMin then
      Fms := TimeCaps.wPeriodMin; // ½ÇÁ¦ °¡´ÉÇÑ È£Ãâ Áֱ⺸´Ù ÀÛÀ¸¸é
   if Fms > TimeCaps.wPeriodMax then
      Fms := TimeCaps.wPeriodMax; // ½ÇÁ¦ °¡´ÉÇÑ È£Ãâ Áֱ⺸´Ù Å©¸é

   timeBeginPeriod(Fms); // ŸÀÌ¸Ó Áֱ⸦ ÁöÁ¤ÇÑ´Ù.
   FTimerID := timeSetEvent(Fms,Fms,@TimerProc,integer(handle),
                            TIME_PERIODIC);
      // ŸÀ̸Ӹ¦ ¼³Á¤ÇÑ´Ù. Äݹé ÇÔ¼ö¸¦ ÁöÁ¤ÇÏ°í, TIME_PERIODIC¸¦ »ç¿ëÇÏ¿©
      // ÁÖ±âÀûÀ¸·Î °è¼Ó È£ÃâµÇ°Ô ¸¸µç´Ù.
     
   if FTimerID = 0 then begin
       timeEndPeriod(Fms);
       raise Exception.Create('<timeSetEvent> Error !!');
       Close;
       Exit; // ¿¡·¯ ó¸® ·çƾ
   end;

   str(Fms,s);
   Panel1.Caption := 'ŸÀÌ¸Ó ¼³Á¤ :' + s + 'ms';

   FCouter := -1;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
   if FTimerID <> 0 then begin
      timeKillEvent(FTimerID); // ŸÀ̸Ӹ¦ ÇØÁ¦ÇÑ´Ù.
      timeEndPeriod(Fms);      // ŸÀÌ¸Ó Áֱ⸦ ÇØÁ¦ÇÑ´Ù.
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Close;
end;

end.

À§ÀÇ ¼Ò½º¸¦ ½ÇÇàÇØ º¸¸é Ç×»ó 0.005 ÃÊ Á¤µµÀÇ ¿ÀÂ÷¸¸À» °¡Áö°í  ÃÊ´ç 10 ȸ¶ó´Â
Äݹé ȸ¼ö¸¦ °è¼Ó À¯ÁöÇÑ´Ù. ( 10.000 Ãʸ¦ ±âÁØÀ¸·Î Áøµ¿ÇÑ´Ù°í º¸´Â °Ô ³ªÀ» °Í
°°´Ù. )
ÀÌ·¸µí ¸ÖƼ¹Ìµð¾î ŸÀ̸Ӵ ½Ã½ºÅÛ ÀÚ¿øÀ» ¸¹ÀÌ ¸Ô´Â ´ë½Å Á¤È®ÇÑ Å¸ÀÌ¸Ó Á¦¾î°¡
°¡´ÉÇϹǷΠ´ëºÎºÐÀÇ Á¤¹Ð ÀÛ¾÷À̳ª ½Ç½Ã°£ ¹è°æÀ½¾Ç Ãâ·Â¿¡ ¾²ÀÌ°Ô µÈ´Ù.

Á÷Á¢ ´«À¸·Î È®ÀÎÇß´Ù¸é ¾Æ¸¶µµ  API ŸÀÌ¸Ó¿Í ¸ÖƼ¹Ìµð¾î ŸÀ̸ӿ¡  ´ëÇÑ ÀûÀýÇÑ
¿ë¹ýÀÌ ¶°¿Ã¶úÀ¸¸®¶ó°í º»´Ù. ±×¸®°í  ³ª¸ÓÁö È°¿ë¿¡ ´ëÇÑ °ÍÀº  ÀüÀûÀ¸·Î ´ç½ÅÀÇ
¸òÀÎ °ÍÀÌ´Ù.........

                                              ------------- SMgal ( ¾È¿µ±â )