U E D R , A S I H C RSS

MFC Study_2001/MM Timer


1. MultiMedia Timer

λ©€ν‹°λΈλ””μ–΄ 타이머에 λŒ€ν•œ μ„λͺ…을 적게 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

μ €λŠ” ZP 01 μ΄μ„ ν˜Έ μž…λ‹ˆλ‹€.

μ €λŠ” ZP 01 κ°•μΈμˆ˜ μž…λ‹ˆλ‹€.


2. κΈ°λ³Έ κ°œλ…

  • OnTimer와 SetTimer의 μ‘°ν•©μœΌλ‘œ κ΅¬ν˜„λ˜λŠ” κ°€μž₯ 일반적인 νƒ€μ΄λ¨ΈλŠ” μ •ν™•ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
    이게 λ©”μ‹œμ§€ λ°©μ‹μœΌλ‘œ κ΅¬λ™λ˜κΈ° λ•Œλ¬Έμ— λ©”μ‹œμ§€ 큐에 λ‹€λ₯Έ λ©”μ‹œμ§€κ°€ μŒ“μ΄λ©΄ κ·Έ 만큼
    μ‘°κΈˆμ”© λŠ¦μ–΄μ§€κ²Œ λœλ‹€κ³  ν•©λ‹ˆλ‹€. μ‹€μ œλ‘œλ„ 곡이 μ›€μ§μ΄λŠ” λ™μ•ˆμ— λ§‰λŒ€κΈ°λΌ λ§‰ 움직이
    λ©΄ 곡이 λΈμ„Έν•˜κ²Œ λŠλ €μ§€λŠ” 것을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.(λ‚˜λ§Œ κ·ΈλŸ°κ°€?--;)

  • 이것을 ν•΄κ²°ν•˜κΈ° μœ„ν•΄ MultiMedia TimerλΌ μ“°κ²Œ λ©λ‹ˆλ‹€. Devpiaμ—μ„œ λ³Έ 바에 μ˜ν•˜λ©΄
    MultiMedia TimerλŠ” 자체적으둜 μŠ€λ ˆλ“œλΌ λ§Œλ“ λ‹€λ„μš”. κ·Έλž˜μ„œ λ©”μ‹œμ§€κ°€ μŒ“μ΄λ“  말든
    자기 혼자 ν•  짓을 λ‹€ ν•œλŒ€λ„μš”.

2.1. κΈ°λ³Έ μ‚¬μš©λ²•

λ©€ν‹°λΈλ””μ–΄ 타이머에 κ΄€λ ¨λœ ν•¨μˆ˜λŠ” μ—¬λŸ¬κ°€μ§€μ΄λ‚˜, νƒ€μ΄λ¨ΈλΌ κ΅¬ν˜„ν•˜λŠ”λ° ν•„μš”ν•œ ν•¨μˆ˜λŠ” μ„Έκ°œμž…λ‹ˆλ‹€.

! κ·ΈλŸ¬λ‚˜ 그전에 μΆ”κ°€μ‹œμΌœμ€˜μ•Όν•  게 μžˆμŠ΅λ‹ˆλ‹€.

μ²«μ§ΈλŠ” WINMM.LIBλΌ μΆ”κ°€μ‹œμΌœμ€˜μ•Ό ν•˜κ³ 

λ‘˜μ§ΈλŠ” MMSYSTEM.H λΌ μΈν΄λ£¨λ“œ μ‹œμΌœμ€˜μ•Ό ν•©λ‹ˆλ‹€.

  • μΆ”κ°€ν•˜λŠ”λ²• :
    μ†ŒμŠ€μ— #include <mmsystem.h> λΌ λ„£κ³ 

    Project(P) - Setting(S, ALT+F7)을 눌러 Linkνƒ­μ˜ Object/Library modules:λž€μ— winmm.libλΌ μ μ–΄μ€λ‹ˆλ‹€.

2.1.1. timeSetEvent

νƒ€μ΄λ¨ΈλΌ λ°œλ™μ‹œν‚€λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.

~cpp 
MMRESULT timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent);

  • MMRESULTμ—λŠ” νƒ€μ΄λ¨Έμ˜ λ²ˆν˜Έκ°€ λ¦¬ν„΄λ©λ‹ˆλ‹€. NULL일 κ²½μš°μ—λŠ” μ‹€νŒ¨ν•œ κ²½μš°μž…λ‹ˆλ‹€.
  • uDelay : 타이머가 호좜될 간격을 λ„£μŠ΅λ‹ˆλ‹€. λ‹¨μœ„λŠ” msμž…λ‹ˆλ‹€.
  • uResolution : λŒ€κ°œ 0을 λ„£μŠ΅λ‹ˆλ‹€λ§Œ... 정확도 κ°™λ‹€κ³  ν•©λ‹ˆλ‹€.
  • lpTimeProc : CALLBACKν•¨μˆ˜μ˜ 이름을 λ„£μŠ΅λ‹ˆλ‹€.
  • dwUser : CALLBACKν•¨μˆ˜μ— 전달할 μΈμžλΌ λ„£μŠ΅λ‹ˆλ‹€.
  • fuEvent : 타이머가 ν˜ΈμΆœλ˜λŠ” 방법을 λ„£μŠ΅λ‹ˆλ‹€.
    • TIME_ONESHOT : CALLBACKν•¨μˆ˜κ°€ λ”± ν•œλ²ˆλ§Œ μ‹€ν–‰λ©λ‹ˆλ‹€.
    • TIME_PERIODIC : uDelayμ‹œκ°„μ΄ 지날 λ•Œλ§ˆλ‹€ CALLBACKν•¨μˆ˜κ°€ μ‹€ν–‰λ©λ‹ˆλ‹€.

2.1.2. TimeProc

νƒ€μ΄λ¨Έλ‘œ λΆˆλŸ¬λ‚΄μ–΄ 직접 μ‹€ν–‰λ˜λŠ” ν•¨μˆ˜λΆ€λΆ„μž…λ‹ˆλ‹€

~cpp 
void CALLBACK TimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)

  • uID : νƒ€μ΄λ¨Έμ˜ λ²ˆν˜Έκ°€ λ„˜μ–΄μ˜΅λ‹ˆλ‹€
  • dwUser : timeSetEvent ν•¨μˆ˜μ˜ dwUser값이 λ„˜μ–΄μ˜΅λ‹ˆλ‹€.
  • λ‚˜λ¨Έμ§€ 두 λ³€μˆ˜λŠ” 쓰지 μ•ŠμŠ΅λ‹ˆλ‹€.
  • 이것은 콜백 ν•¨μˆ˜λΌμ„œ μ „μ—­ λ³€μˆ˜λ‘œ ν•΄μ•Όλœλ‹€λ„μš”. ꡳ이 클래슀 μ•ˆμ— λ„£κ³  μ‹Άλ‹€λ©΄ static으둜 μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆλ‹€.

2.1.3. timeKillEvent

μ‚¬μš©μ΄ λλ‚œ νƒ€μ΄λ¨ΈλΌ μ£½μ΄λŠ” λΆ€λΆ„μž…λ‹ˆλ‹€.

~cpp 
MMRESULT timeKillEvent(UINT uTimerID);

  • uTimerID μ—λŠ” νƒ€μ΄λ¨Έμ˜ λ²ˆν˜ΈλΌ λ„£μŠ΅λ‹ˆλ‹€.

이상이 κΈ°λ³Έ μ‚¬μš©λ²•μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

2.2. 예제

CALLBACK ν•¨μˆ˜λΌ μ „μ—­μœΌλ‘œ μ„ μ–Έν•œ 경우

~cpp 
m_TimerID=timeSetEvent(20,1,&TimerProc,(DWORD)this,TIME_PERIODIC);
  • νƒ€μ΄λ¨ΈλΌ μ‹œμž‘ν•˜λŠ” λΆ€λΆ„μž…λ‹ˆλ‹€.
  • m_TimerIDλŠ” UINTν˜• μž…λ‹ˆλ‹€.

~cpp 
void CALLBACK TimerProc(UINT uiID,UINT uiMsg,DWORD dwUser,DWORD dw1,DWORD dw2)
      {
             CAlcaDlg *pDlg=(CAlcaDlg*)AfxGetMainWnd();

	    pDlg->SendMessage(WM_MYMSG,0,0);
      }
  • 콜백 ν•¨μˆ˜λΌ μ •μ˜ν•œκ²ƒμž…λ‹ˆλ‹€. 콜백 ν•¨μˆ˜λ‚΄μ—μ„œλŠ” λ³΅μž‘ν•œ 일은 ν•˜μ§€ μ•ŠλŠ”κ²Œ 정신건강에 μ’‹λ‹€κ³  ν•©λ‹ˆλ‹€.

    κ·Έλž˜μ„œ λ©”μ‹œμ§€λ‘œ λ‚ λ € λ΄€μŠ΅λ‹ˆλ‹€. 그런데 μ „ 별루 차이점을 λͺ»λŠλΌκ² λ”κ΅°μš”..--;

    고칠것 있으면 고쳐 μ£Όμ‹œκΈΈ...

~cpp 
CAlcaDlg *pDlg = (CAlcaDlg*)AfxGetMainWnd();
        // 메인 μœˆλ„μš°μ˜ ν¬μΈν„°λΌ μ–»μ–΄μ™€μ„œ
timeKillEvent(pDlg->m_TimerID);
        // 타이머 μ’…λ£Œ

CALLBACK ν•¨μˆ˜λΌ ν΄λž˜μŠ€ ν•¨μˆ˜λ‘œ μ„ μ–Έν•œ 경우

클래슀 μ„ μ–Έμ‹œ timeprocν•¨μˆ˜λŠ” static 으둜 μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆλ‹€.

  • CALLBACK ν•¨μˆ˜λŠ” 클래슀 λ‚΄μ—μ„œ μ„ μ–Έ 될 κ²½μš°μ—λŠ” static으둜 μ„ μ–Έ λ˜μ–΄μ•Όν•©λ‹ˆλ‹€.

~cpp 
m_nTimerID = timeSetEvent(5, 0, (LPTIMECALLBACK)timeproc, (DWORD)this, TIME_PERIODIC);
  • m_nTimerIDλŠ” UINTν˜• μž…λ‹ˆλ‹€. 성곡할 κ²½μš°μ—λŠ” νƒ€μ΄λ¨Έμ˜ λ²ˆν˜Έκ°€ λ„˜μ–΄μ˜΅λ‹ˆλ‹€.
  • 5λŠ” 타이머가 호좜될 κ°„κ²©μž…λ‹ˆλ‹€. μ—­μ‹œ λ‹¨μœ„λŠ” ms(1/1000초)μž…λ‹ˆλ‹€.
  • thisλŠ” 이 클래슀 μΈμŠ€ν„΄μŠ€μ˜ 값을 λ„˜κ²¨μ€λ‹ˆλ‹€. 클래슀 λ‚΄λΆ€ ν•¨μˆ˜λ‘œ μ„ μ–Έν–ˆμ„ 경우λ„λŠ” μ€‘μš”ν•œ μΈμžκ°’μž…λ‹ˆλ‹€.

~cpp 
void CALLBACK CMyDlg::timeproc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2){
 CMyDlg *pDlg = (CMyDlg *)dwUser;
 pDlg->......
dwUserλŠ” timeSetEvent의 this값을 인자둜 λ°›μ•„ pDlg에 ν˜„μž¬ μΈμŠ€ν„΄μŠ€μ˜ μ£Όμ†ŒλΌ λ„£μŠ΅λ‹ˆλ‹€.
pDlgλΌ ν†΅ν•΄μ„œ μ›λž˜ 클래슀의 λͺ¨λ“  λ©”μ†Œλ“œμ™€ λ³€μˆ˜λΌ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

~cpp 
timeKillEvnet(m_nTimerID);
setTimerEventλ•Œ 얻은 νƒ€μ΄λ¨Έμ˜ λ²ˆν˜ΈλΌ μ§‘μ–΄λ„£μ–΄ νƒ€μ΄λ¨ΈλΌ μ£½μž…λ‹ˆλ‹€.

2.3. 주의점

  • CALLBACK ν•¨μˆ˜λΌ μ‚¬μš©ν• λ•Œμ˜ 주의점. (in MSDN)

    - Applications should not call any system-defined functions from inside a callback function, except for PostMessage, timeGetSystemTime, timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg, midiOutLongMsg, and OutputDebugString.

    - μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ€ 콜백 ν•¨μˆ˜ λ‚΄λΆ€λ‘œλΆ€ν„° λ‹€μŒ ν•¨μˆ˜λΌ μ œμ™Έν•˜κ³ λŠ” μ‹œμŠ€ν…œ μ •μ˜ ν•¨μˆ˜λΌ λΆ€λΌ μˆ˜κ°€ μ—†λ‹€. : PostMessage, timeGetSystemTime, timeGetTime, timeSetEvent, timeKillEvent, midiOutShortMsg, midiOutLongMsg, and OutputDebugString.

    μ™ λ§Œν•œ ν•¨μˆ˜λ“€μ€ Callbackν•¨μˆ˜ λ‚΄μ—μ„œ λΆ€λ₯΄λ©΄ μ•ˆλ©λ‹ˆλ‹€.
  • KBλ¬Έμ„œ Q130866λ²ˆμ„ μ°Έκ³ ν–ˆμŠ΅λ‹ˆλ‹€.
    CALLBACKν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ 화면을 κ°±μ‹ ν•  λ•Œμ—λŠ” Invalidte()ν•¨μˆ˜λ‚˜ user λ©”μ„Έμ§€λΌ λ§Œλ“€μ–΄μ„œ λ‚ λ €μ£Όλ©΄ λ©λ‹ˆλ‹€.


~cpp 
void CALLBACK EXPORT CTmrprocView::TimerProc(HWND hwnd, UINT msg, UINT idTimer, DWORD dwTime)
{
    CTmrprocView * pThis;
    
    if (m_thisList.Lookup(idTimer, (LPVOID &) pThis))
    {
        ASSERT(pThis->GetSafeHwnd());
        
        CDC* pDC = pThis->GetDC();
        
        wsprintf((LPSTR) pThis->m_strOutput, "CTmrprocView::TimerProc() Called. Count = %ld", ++pThis->m_cCount);
        pThis->Invalidate(TRUE);
    }
}


Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:41
Processing time 0.0296 sec