![]() |
Why does timeGetDevCaps fail?
Why does timeGetDevCaps fail in the VBA sub below?
And when it fails, why does it return TIMERR_NOCANDO instead of TIMERR_STATUS? (Or so it seems.) (I suspect the latter is simply a defect either in the documentation or in the library implementation. Other related functions do return TIMERR_NOCANDO.) According to "man pages" and header files that I found in Google searches, timeGetDevCaps and related identifiers are defined as follows. MMRESULT timeGetDevCaps( LPTIMECAPS ptc, UINT cbtc ) Parameters: ptc: Pointer to a TIMECAPS structure. cbtc: Size, in bytes, of the TIMECAPS structure. Return Values Returns TIMERR_NOERROR if successful or TIMERR_STRUCT if it fails to return the timer device capabilities. Requirements and Library: Same as timeGetTime et al, which seem to work just fine. Related declarations: alias UINT MMRESULT struct TIMECAPS { UINT wPeriodMin; UINT wPeriodMax; } alias TIMECAPS* PTIMECAPS, LPTIMECAPS const TIMERR_BASE=96 const TIMERR_NOERROR=0 const TIMERR_NOCANDO=(TIMERR_BASE+1) // 97 const TIMERR_STRUCT=(TIMERR_BASE+33) // 129 Of course, I cannot say for sure whether those related declarations -- especially the TIMERR constant -- apply to my system. But I assume they do. I am using MSWin XP Pro (32-bit), Excel 2003 with VB 6.3. On the off-chance that the DLL integer is different from the VBA integer -- unlikely, I know, but I am used to ILP32 archtectures where int and long (and pointer) are 32-bit -- I tried calling timeGetDevCaps with cbtc set to 8 instead of 4. Not surprisingly, I get run-time error 49 (bad DLL calling convention). My VBA code.... Type TIMECAPS min As Integer max As Integer End Type Public Declare Function timeGetDevCaps Lib "winmm" (ByRef tcaps As TIMECAPS, ByVal sz As Integer) As Integer Public Declare Function timeBeginPeriod Lib "winmm" (ByVal msec As Integer) As Integer Public Declare Function timeEndPeriod Lib "winmm" (ByVal msec As Integer) As Integer Public Declare Function timeGetTime Lib "winmm" () As Long Public Declare Sub Sleep Lib "kernel32" (ByVal msec As Long) Private Sub testWinmm() Dim tc As TIMECAPS Dim x As Integer Dim st As Long, et As Long, dt As Long '*****ERROR: timeGetDevCaps does not return 0 tc.min = -123: tc.max = -456 x = timeGetDevCaps(tc, 4) Debug.Print "timeGetDevCaps="; x; _ " min="; IIf(tc.min = -123, "UNCHANGED ", tc.min); _ " max="; IIf(tc.max = -456, "UNCHANGED", tc.max) 'Everything else works (i.e. does not return error status) x = timeBeginPeriod(1) Debug.Print "timeBeginPeriod="; x x = timeEndPeriod(1) Debug.Print "timeEndPeriod="; x st = timeGetTime() Call Sleep(1000) et = timeGetTime() dt = et - st Debug.Print "st="; st; " et="; et; " dt="; dt End Sub |
Why does timeGetDevCaps fail?
joeu2004;269503 Wrote: Why does timeGetDevCaps fail in the VBA sub below? And when it fails, why does it return TIMERR_NOCANDO instead of TIMERR_STATUS? (Or so it seems.) (I suspect the latter is simply a defect either in the documentation or in the library implementation. Other related functions do return TIMERR_NOCANDO.) According to "man pages" and header files that I found in Google searches, timeGetDevCaps and related identifiers are defined as follows. MMRESULT timeGetDevCaps( LPTIMECAPS ptc, UINT cbtc ) Parameters: ptc: Pointer to a TIMECAPS structure. cbtc: Size, in bytes, of the TIMECAPS structure. Return Values Returns TIMERR_NOERROR if successful or TIMERR_STRUCT if it fails to return the timer device capabilities. Requirements and Library: Same as timeGetTime et al, which seem to work just fine. Related declarations: alias UINT MMRESULT struct TIMECAPS { UINT wPeriodMin; UINT wPeriodMax; } alias TIMECAPS* PTIMECAPS, LPTIMECAPS const TIMERR_BASE=96 const TIMERR_NOERROR=0 const TIMERR_NOCANDO=(TIMERR_BASE+1) // 97 const TIMERR_STRUCT=(TIMERR_BASE+33) // 129 Of course, I cannot say for sure whether those related declarations -- especially the TIMERR constant -- apply to my system. But I assume they do. I am using MSWin XP Pro (32-bit), Excel 2003 with VB 6.3. On the off-chance that the DLL integer is different from the VBA integer -- unlikely, I know, but I am used to ILP32 archtectures where int and long (and pointer) are 32-bit -- I tried calling timeGetDevCaps with cbtc set to 8 instead of 4. Not surprisingly, I get run-time error 49 (bad DLL calling convention). My VBA code.... Type TIMECAPS min As Integer max As Integer End Type Public Declare Function timeGetDevCaps Lib "winmm" (ByRef tcaps As TIMECAPS, ByVal sz As Integer) As Integer Public Declare Function timeBeginPeriod Lib "winmm" (ByVal msec As Integer) As Integer Public Declare Function timeEndPeriod Lib "winmm" (ByVal msec As Integer) As Integer Public Declare Function timeGetTime Lib "winmm" () As Long Public Declare Sub Sleep Lib "kernel32" (ByVal msec As Long) Private Sub testWinmm() Dim tc As TIMECAPS Dim x As Integer Dim st As Long, et As Long, dt As Long '*****ERROR: timeGetDevCaps does not return 0 tc.min = -123: tc.max = -456 x = timeGetDevCaps(tc, 4) Debug.Print "timeGetDevCaps="; x; _ " min="; IIf(tc.min = -123, "UNCHANGED ", tc.min); _ " max="; IIf(tc.max = -456, "UNCHANGED", tc.max) 'Everything else works (i.e. does not return error status) x = timeBeginPeriod(1) Debug.Print "timeBeginPeriod="; x x = timeEndPeriod(1) Debug.Print "timeEndPeriod="; x st = timeGetTime() Call Sleep(1000) et = timeGetTime() dt = et - st Debug.Print "st="; st; " et="; et; " dt="; dt End Sub Hello joeu2004, I made the necessary changes to your code to make it work. The biggest change was changing from Integer (16 bit) to Long (32 bit). Unless you are working with Windows 3.1 or know for certain a value can be an Integer in the API declaration, use Long types. I also included the constants for error detection, in case you may to include error handling in your code. ------------------------------------------------------- Type TIMECAPS PeriodMin As Long PeriodMax As Long End Type Private Declare Function timeGetDevCaps Lib "winmm" (ByRef tcaps As TIMECAPS, ByVal sz As Integer) As Integer Private Declare Function timeBeginPeriod Lib "winmm" (ByVal msec As Long) As Long Private Declare Function timeEndPeriod Lib "winmm" (ByVal msec As Long) As Long Private Declare Function timeGetTime Lib "winmm" () As Long Private Declare Sub Sleep Lib "kernel32" (ByVal msec As Long) Private Const TIMERR_NOERROR As Long = 0 Private Const TIMERR_BASE As Long = 96 Private Const TIMERR_NOCANDO As Long = TIMERR_BASE + 1 Private Const TIMERR_STRUCT As Long = TIMERR_BASE + 33 Private Sub testWinmm() Dim tc As TIMECAPS Dim x As Long Dim st As Long, et As Long, dt As Long x = timeGetDevCaps(tc, Len(tc)) tc.PeriodMin = -123: tc.PeriodMax = -456 Debug.Print "timeGetDevCaps="; x; _ " min="; IIf(tc.PeriodMin = -123, "UNCHANGED ", tc.PeriodMin); _ " max="; IIf(tc.PeriodMax = -456, "UNCHANGED", tc.PeriodMax) 'Everything else works (i.e. does not return error status) x = timeBeginPeriod(1) Debug.Print "timeBeginPeriod="; x x = timeEndPeriod(1) Debug.Print "timeEndPeriod="; x st = timeGetTime() Call Sleep(1000) et = timeGetTime() dt = et - st Debug.Print "st="; st; " et="; et; " dt="; dt End Sub ------------------------------------------------------- -- Leith Ross Sincerely, Leith Ross 'The Code Cage' (http://www.thecodecage.com/) ------------------------------------------------------------------------ Leith Ross's Profile: http://www.thecodecage.com/forumz/member.php?userid=75 View this thread: http://www.thecodecage.com/forumz/sh...ad.php?t=75162 |
Why does timeGetDevCaps fail?
On Mar 13, 8:17 pm, Leith Ross
wrote: joeu2004;269503 Wrote: [....] On the off-chance that the DLL integer is different from the VBA integer -- unlikely, I know, but I am used to ILP32 archtectures where int and long (and pointer) are 32-bit -- I tried calling timeGetDevCaps with cbtc set to 8 instead of 4. Not surprisingly, I get run-time error 49 (bad DLL calling convention). [....] The biggest change was changing from Integer (16 bit) to Long (32 bit). So my intuition was right after all(!). I made the mistake of changing only cbtc. In hindsight, that was foolish of me. If that had worked, I would have clobbered memory. Klunk! Unless you are working with Windows 3.1 or know for certain a value can be an Integer in the API declaration, use Long types. Thanks for the tip. It should not be hard for me to remember ;-). ----- original posting ----- On Mar 13, 8:17*pm, Leith Ross wrote: joeu2004;269503 Wrote: Why does timeGetDevCaps fail in the VBA sub below? And when it fails, why does it return TIMERR_NOCANDO instead of TIMERR_STATUS? *(Or so it seems.) (I suspect the latter is simply a defect either in the documentation or in the library implementation. *Other related functions do return TIMERR_NOCANDO.) According to "man pages" and header files that I found in Google searches, timeGetDevCaps and related identifiers are defined as follows. MMRESULT timeGetDevCaps( LPTIMECAPS ptc, UINT cbtc ) Parameters: ptc: * *Pointer to a TIMECAPS structure. cbtc: *Size, in bytes, of the TIMECAPS structure. Return Values Returns TIMERR_NOERROR if successful or TIMERR_STRUCT if it fails to return the timer device capabilities. Requirements and Library: Same as timeGetTime et al, which seem to work just fine. Related declarations: alias UINT MMRESULT struct TIMECAPS { UINT wPeriodMin; UINT wPeriodMax; } alias TIMECAPS* PTIMECAPS, LPTIMECAPS const TIMERR_BASE=96 const TIMERR_NOERROR=0 const TIMERR_NOCANDO=(TIMERR_BASE+1) * *// 97 const TIMERR_STRUCT=(TIMERR_BASE+33) * * *// 129 Of course, I cannot say for sure whether those related declarations -- especially the TIMERR constant -- apply to my system. *But I assume they do. *I am using MSWin XP Pro (32-bit), Excel 2003 with VB 6.3. On the off-chance that the DLL integer is different from the VBA integer -- unlikely, I know, but I am used to ILP32 archtectures where int and long (and pointer) are 32-bit -- I tried calling timeGetDevCaps with cbtc set to 8 instead of 4. *Not surprisingly, I get run-time error 49 (bad DLL calling convention). My VBA code.... Type TIMECAPS min As Integer max As Integer End Type Public Declare Function timeGetDevCaps Lib "winmm" (ByRef tcaps As TIMECAPS, ByVal sz As Integer) As Integer Public Declare Function timeBeginPeriod Lib "winmm" (ByVal msec As Integer) As Integer Public Declare Function timeEndPeriod Lib "winmm" (ByVal msec As Integer) As Integer Public Declare Function timeGetTime Lib "winmm" () As Long Public Declare Sub Sleep Lib "kernel32" (ByVal msec As Long) Private Sub testWinmm() Dim tc As TIMECAPS Dim x As Integer Dim st As Long, et As Long, dt As Long '*****ERROR: timeGetDevCaps does not return 0 tc.min = -123: tc.max = -456 x = timeGetDevCaps(tc, 4) Debug.Print "timeGetDevCaps="; x; _ " min="; IIf(tc.min = -123, "UNCHANGED ", tc.min); _ " max="; IIf(tc.max = -456, "UNCHANGED", tc.max) 'Everything else works (i.e. does not return error status) x = timeBeginPeriod(1) Debug.Print "timeBeginPeriod="; x x = timeEndPeriod(1) Debug.Print "timeEndPeriod="; x st = timeGetTime() Call Sleep(1000) et = timeGetTime() dt = et - st Debug.Print "st="; st; " et="; et; " dt="; dt End Sub Hello joeu2004, I made the necessary changes to your code to make it work. The biggest change was changing from Integer (16 bit) to Long (32 bit). Unless you are working with Windows 3.1 or know for certain a value can be an Integer in the API declaration, use Long types. I also included the constants for error detection, in case you may to include error handling in your code. ------------------------------------------------------- Type TIMECAPS PeriodMin As Long PeriodMax As Long End Type Private Declare Function timeGetDevCaps Lib "winmm" (ByRef tcaps As TIMECAPS, ByVal sz As Integer) As Integer Private Declare Function timeBeginPeriod Lib "winmm" (ByVal msec As Long) As Long Private Declare Function timeEndPeriod Lib "winmm" (ByVal msec As Long) As Long Private Declare Function timeGetTime Lib "winmm" () As Long Private Declare Sub Sleep Lib "kernel32" (ByVal msec As Long) Private Const TIMERR_NOERROR As Long = 0 Private Const TIMERR_BASE As Long = 96 Private Const TIMERR_NOCANDO As Long = TIMERR_BASE + 1 Private Const TIMERR_STRUCT As Long = TIMERR_BASE + 33 Private Sub testWinmm() Dim tc As TIMECAPS Dim x As Long Dim st As Long, et As Long, dt As Long x = timeGetDevCaps(tc, Len(tc)) tc.PeriodMin = -123: tc.PeriodMax = -456 Debug.Print "timeGetDevCaps="; x; _ " min="; IIf(tc.PeriodMin = -123, "UNCHANGED ", tc.PeriodMin); _ " max="; IIf(tc.PeriodMax = -456, "UNCHANGED", tc.PeriodMax) 'Everything else works (i.e. does not return error status) x = timeBeginPeriod(1) Debug.Print "timeBeginPeriod="; x x = timeEndPeriod(1) Debug.Print "timeEndPeriod="; x st = timeGetTime() Call Sleep(1000) et = timeGetTime() dt = et - st Debug.Print "st="; st; " et="; et; " dt="; dt End Sub ------------------------------------------------------- -- Leith Ross Sincerely, Leith Ross 'The Code Cage' (http://www.thecodecage.com/) ------------------------------------------------------------------------ Leith Ross's Profile:http://www.thecodecage.com/forumz/member.php?userid=75 View this thread:http://www.thecodecage.com/forumz/sh...ad.php?t=75162 |
All times are GMT +1. The time now is 06:30 PM. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
ExcelBanter.com