2015-09-14 22 views
0

應該KillTimer是否被指定的計時器的相同進程調用?KillTimer - 無意中銷燬另一個進程的計時器

+0

@ USER1 https://msdn.microsoft.com/en-us/library/windows/desktop/ms644903%28v=vs.85%29.aspx沒有關於銷燬另一個進程的計時器。 – RepeatUntil

+1

'SetTimer'文檔很清楚'hWnd'必須屬於調用線程。 'KillTimer'似乎很可能會有相同的限制。 –

+0

我不太確定在這種情況下「無意中」這個詞應該是什麼意思。你是否在「意外」殺死計時器? –

回答

3

是的,KillTimer應該被調用與調用SetTimer的過程相同的過程。但是,儘管文檔清楚地表明調用線程在調用SetTimer時需要擁有該窗口,但似乎並沒有針對KillTimer執行相同的實施。它甚至沒有說殺手必須是相同的過程,更不用說同一個線程。因此,什麼應該發生和什麼必須發生是兩件不同的事情。

Raymond Chen wrote in his blog in 2012 about killing timers,並且在評論中有幾條聲明說定時器只能從原始進程中被殺死。這些言論沒有受到質疑,但事實證明很容易通過實驗反駁它們。

以下命令行程序顯示可以從其他進程中終止計時器。在沒有參數的情況下運行一次,它會創建一個計時器並開始使用計時器ID打印消息。將該ID傳遞給程序的第二次調用,並且第二個實例將終止第一個實例的計時器。它會報告成功,並且第一個實例將停止打印消息(因爲它不再接收定時器消息)。

#include <iostream> 
#include <sstream> 
#include <windows.h> 

int main(int argc, char* argv[]) 
{ 
    if (argc > 1) { 
     std::istringstream in(argv[1]); 
     UINT timerid; 
     in >> timerid; 
     if (!KillTimer(NULL, timerid)) { 
      DWORD err = GetLastError(); 
      std::cout << "KillTimer error (" << err << ")" << std::endl; 
     } 
     else { 
      std::cout << "KillTimer success" << std::endl; 
     } 
    } else { 
     UINT timerid = SetTimer(NULL, 0, 1000, NULL); 
     std::cout << "Get timer ID " << timerid << std::endl; 
     MSG msg; 
     while (GetMessage(&msg, NULL, 0, 0)) { 
      if (msg.message == WM_TIMER) { 
       std::cout << "Got WM_TIMER " << msg.wParam << std::endl; 
      } 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 
    } 
    return 0; 
} 

(進程是在64位的Windows 7虛擬機,使用Visual Studio 2015年編譯運行32位,因爲這是我在其他任何語言等效代碼應該很容易複製。)