2012-04-06 2 views
2

В настоящее время я пытаюсь реализовать класс таймера в VBA. Для этой цели я использую функцию SetTimer и KillTimer на Windows API, ...SetTimer IDEvent проблемы с возвратом

Это интерфейс с MSDN:

UINT_PTR WINAPI SetTimer(
    __in_opt HWND hWnd, 
    __in  UINT_PTR nIDEvent, 
    __in  UINT uElapse, 
    __in_opt TIMERPROC lpTimerFunc 
); 

И это, как я объявил функцию wihtin моего VBA-модуль:

Private Declare Function SetTimer Lib "user32" (ByVal Handle As Long, _ 
               ByVal TimerIDHandle As Any, _ 
               ByVal ElapseTime As Long, _ 
               ByVal AddressOfAndYourHandlerFunctionName As Long) As Long 

               'TimerIDHandle is of Type Any so I can pass Nothing to the function 

Я тогда вызываем функцию следующим образом:

Dim TimerID As Long 

TimerID = SetTimer(Application.hWndAccessApp, ByVal 0&, Timer.Timeout, AddressOf TimeOutHandler) 

Как Vba не переменного тока cept «Null» Я попытался реализовать «ByVal 0 &». Правильно ли это? В любом случае ... Я вызываю эту функцию несколько раз из того же приложения, и функция всегда возвращает 1 в качестве идентификатора, хотя, согласно Msdn, функция должна возвращать уникальный идентификатор для каждого таймера, который создается в дескрипторе окна текущее приложение доступа.

Кроме того, когда я создал только один таймер, функция Callback получает Called, но идентификатор таймера задается как 0, тогда как функция Settimer возвращает 1 во время инициализации. Вот мой обратный вызов функции Заголовок:

Private Sub TimeOutHandler(ByVal WindowHandle As Long, _ 
          ByVal TimerMessage As Long, _ 
          ByVal TimerID As Long, _ 
          ByVal ElapsedTime As Long) 

Где я ошибаюсь?

Любая помощь очень ценится конечно ;-)

ответ

3

Он работал. Если это не удалось, оно вернет 0. Вы получите 0 для TimerID в обратном вызове, потому что вы передали 0 для аргумента nIDEvent при создании таймера. Вам нужно будет использовать значение, возвращаемое SetTimer для вызова KillTimer(). Подумайте об этом как о ручке таймера.

Вы никогда не получите этот код, работающий в 64-битном режиме, поэтому просто объявите 2-й аргумент как Long.

+0

Да, я знаю, что это сработало, но если у меня есть текущий таймер (IDEvent возвращен = 1) в окне текущего доступа и вы хотите получить второй таймер с помощью дескриптора Window, я также использовал для первого таймера, после чего SetTimer все еще возвращает 1, хотя он должен дать мне другой дескриптор IDEvent. Или я могу выбрать, какой из IDEvent я хочу? Это может вызвать проблемы, поскольку я не знаю, какие идентификаторы доступа к таймеру используют в своем окне ... Кстати: я передал NULL в SetTimer, а не 0 ;-) – TradeItEasy

+0

Если вы хотите * другой * таймер, тогда вам нужно передать различное значение для nIDEvent. Если вы используете один и тот же (0 в своем фрагменте), вы просто возвращаете тот же таймер. –

+0

Значит, это может быть любая ценность, которую я хочу? Не будут ли конфликты, если у Access есть таймеры, которые работают в своем окне, чьи идентификаторы я не знаю? – TradeItEasy

Смежные вопросы