2015-12-11 68 views
2

如何將timeSetEvent的回調函數定義爲實例方法?常規程序/方法指針

TUDPBC = class(TObject)           
private 
    hTimer: word; 
... 
public 
    procedure sendUDPBC; 
... 
end; 

procedure DoTimer(uTimerID, uMessage: UINT; dwUser,dw1,dw2: DWORD); stdcall; 

procedure TUDPBC.sendUDPBC; //send UDP Broadcast 
begin 
... 
    hTimer := TimeSetEvent(FTimeOut, uRes, DoTimer, 0, TIME_ONESHOT); //need DoTimer as a TUDPBC class method 
... 
end; 

回答

6

我如何定義的timeSetEvent回調函數作爲一個實例方法?

簡單的答案是,你不能。回調的簽名不是你可以改變的東西。它是由API定義,必須是simple unbound procedure with this signature

typedef void (CALLBACK *LPTIMECALLBACK)(
    UINT  uTimerID, 
    UINT  uMsg, 
    DWORD_PTR dwUser, 
    DWORD_PTR dw1, 
    DWORD_PTR dw2 
); 

什麼可以做,雖然是一個指針傳遞給timeSetEvent包含您的實例的地址。該模式運行,這樣的:

procedure TimeProcCallback(uTimerID, uMessage: UINT; dwUser,dw1,dw2: DWORD_PTR); stdcall; 
begin 
    TUDPBC(dwUser).TimeProc(uTimerID, uMessage); 
end; 

這是你傳遞給timeSetEvent回調。你的類是這樣的:

type 
    TUDPBC = class 
    private 
    FTimerID: MMRESULT; 
    procedure TimeProc(uTimerID, uMessage: UINT); 
    end; 

類的此方法將由回調函數被調用,因此可以訪問實例變量。

這樣設置定時器:

FTimerID := timeSetEvent(TimeOut, uRes, TimeProcCallback, DWORD_PTR(Self), TIME_ONESHOT); 

所以,你通過實例的地址在dwUser說法。然後傳遞給你的回調。該回調可以反過來調用實例方法。

+1

因此,'dwUser'可用於傳遞任何值,該值在計時器事件中傳回給您。這樣你就可以區分定時器。您可以使用該字段來存儲對象中的引用。 – GolezTrol