Stuart Landreth
asked on
callback messages
I am programming using an MPEG2 card and am having trouble getting callbacks from it.
The first method I tried using the CallBack function kept crashing my program when it was compiled and running outside of the VB environment.
The SDK suggestst that with VB you use a CallBack *message* rather than a *function*
The C+ code is
VCCCALL mpgCallBack ( HWND hwnd);
which i have translated to VB as
Declare Sub mpgCallback Lib "4reelaps.dll" (ByVal hwnd As Long)
in my init code, I am trying to route the messages to a window called frmMessageWindow
Call mpgCallback(frmMessageWind ow.hwnd)
but how do I go about writing the procedure to receive the messages?
from the SDK, I know it returns 3 integers: Card, Channel and Message.
For your reference, the SDK for the card i am using is is available here
http://www.visualcircuits.com/downloads/download.php?id=110
The first method I tried using the CallBack function kept crashing my program when it was compiled and running outside of the VB environment.
The SDK suggestst that with VB you use a CallBack *message* rather than a *function*
The C+ code is
VCCCALL mpgCallBack ( HWND hwnd);
which i have translated to VB as
Declare Sub mpgCallback Lib "4reelaps.dll" (ByVal hwnd As Long)
in my init code, I am trying to route the messages to a window called frmMessageWindow
Call mpgCallback(frmMessageWind
but how do I go about writing the procedure to receive the messages?
from the SDK, I know it returns 3 integers: Card, Channel and Message.
For your reference, the SDK for the card i am using is is available here
http://www.visualcircuits.com/downloads/download.php?id=110
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Could you post the code that originally crashed with the mpgCallbackFunction?
Hmm,
one may guess that the function may be prototyped incorectly if it's immediately crashing. It would be nice to know what the typedef of VCCCALL is defined as. The PDF they provide alludes to the idea that they "may" of included some samples... Have you looked to see if there are any VB samples to see if the function is prototyped correctly?
Another possibility is the DLL is posting messages to the window before the message loop is fully initalized. One could check this by putting the "Call mpgCallback(frmMessageWind ow.hwnd)" in a location where it's after the form has loaded and is visible..
Either way, once you get this running, you would want to impliment the subclassing to easily handle the custom user messages this dll will be posting to you.
Jake
one may guess that the function may be prototyped incorectly if it's immediately crashing. It would be nice to know what the typedef of VCCCALL is defined as. The PDF they provide alludes to the idea that they "may" of included some samples... Have you looked to see if there are any VB samples to see if the function is prototyped correctly?
Another possibility is the DLL is posting messages to the window before the message loop is fully initalized. One could check this by putting the "Call mpgCallback(frmMessageWind
Either way, once you get this running, you would want to impliment the subclassing to easily handle the custom user messages this dll will be posting to you.
Jake
ASKER
Further details - as per the e-mail I sent to their technical support
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- --
When I run my program from VB, it works fine.
When I compile and run my program, it crashes as soon as it starts.
"VidiZone has encountered a problems and needs to close. We are sorry for the inconvenience"
MonName: msvbvm60.dll
ModVer 6.0.96.90 Offset: 0002453c
I know this is related to the callback function.
This is my callback code which is in a module
Public Sub CallBack(ByVal CardNum As Long, ByVal ChanNum As Long, ByVal Message As Long)
On Error Resume Next
' Prevent program crash through error
Select Case Message
Case MPG_FILE_PLAY_COMPLETE
bReadyForNextTrack(ChanNum + 1) = True
' Flag that channel is ready for the next track
Case MPG_FILE_READ_START
bRefreshNeeded = True
' Flag to update track listings
End Select
End Sub
As you can see the code is not really doing anything to cause a crash other than changing some boolean values.
I have tried without the "on error" line and to no avail.
If it helps, this is the code i'm using to initialise the card.
Sub InitMPEG()
If mpgOpenDriver = DRIVER_NOT_FOUND Then
MsgBox "Driver not found."
Exit Sub
End If
Call mpgCallbackFunction(Addres sOf CallBack)
End Sub
--------------------------
When I run my program from VB, it works fine.
When I compile and run my program, it crashes as soon as it starts.
"VidiZone has encountered a problems and needs to close. We are sorry for the inconvenience"
MonName: msvbvm60.dll
ModVer 6.0.96.90 Offset: 0002453c
I know this is related to the callback function.
This is my callback code which is in a module
Public Sub CallBack(ByVal CardNum As Long, ByVal ChanNum As Long, ByVal Message As Long)
On Error Resume Next
' Prevent program crash through error
Select Case Message
Case MPG_FILE_PLAY_COMPLETE
bReadyForNextTrack(ChanNum
' Flag that channel is ready for the next track
Case MPG_FILE_READ_START
bRefreshNeeded = True
' Flag to update track listings
End Select
End Sub
As you can see the code is not really doing anything to cause a crash other than changing some boolean values.
I have tried without the "on error" line and to no avail.
If it helps, this is the code i'm using to initialise the card.
Sub InitMPEG()
If mpgOpenDriver = DRIVER_NOT_FOUND Then
MsgBox "Driver not found."
Exit Sub
End If
Call mpgCallbackFunction(Addres
End Sub
ASKER
With reference to samples:
Yes there is a VB sample demonstrating *some* of the functions described in the SDK. It works fine in the IDE, but on compilation it crashes when a file is opened (i.e. when the first callback is received)
Yes there is a VB sample demonstrating *some* of the functions described in the SDK. It works fine in the IDE, but on compilation it crashes when a file is opened (i.e. when the first callback is received)
ASKER
If this holds any clues, this is the declares.bas from the samples file
which i am also using in my project
-------------------------- ---------- ---------- ---------- ---------- ---------- ----------
Option Explicit
'This module will hold only the declares for the functionality
'contained in 4reelaps.dll
Declare Function mpgOpenDriver Lib "4reelaps.dll" () As Long
'opens connection to the kernel mode driver.
'Must be called before any other function
Declare Sub mpgCloseDriver Lib "4reelaps.dll" ()
'closes connection to the kernel mode driver.
'Must be called upon program completion, assuming mpgOpenDriver worked.
Declare Function mpgLoad Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal filename As String) As Long
'Opens an MPEG for playing on a channel. Will interupt anything currently playing.
Declare Sub mpgClose Lib "reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'stops playback and closes the file handle of the file loaded.
'Can also close superfile
Declare Sub mpgPlay Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'starts or resumes playback on a channel
Declare Sub mpgPlayAll Lib "4reelaps.dll" ()
'plays ALL channels already loaded with a file.
Declare Sub mpgStop Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'stops the selected channels.
Declare Sub mpgStopAll Lib "4reelaps.dll" ()
'stops ALL channels already playing.
Declare Sub mpgStatus Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByRef mStatus As mpgStatusStruct)
'obtains status data from a channel. (Note use of user-defined data type.)
Declare Sub mpgDiagnostic Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByRef mDiag As mpgDiagStruct)
'obtains diagnostic information from channel (Note use of user-defined data type.)
Declare Sub mpgCards Lib "4reelaps.dll" (ByRef NumCards As Long)
'get number of cards installed
Declare Sub mpgSeek Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Position As Long)
'seek to a certain position on a file
Declare Sub mpgAutoRepeat Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets repeat on
Declare Sub mpgNoRepeat Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets repeat off
Declare Sub mpgMute Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets mute on
Declare Sub mpgUnMute Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets mute off
Declare Sub mpgBlack Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets channel to show Black screen
Declare Sub mpgSetAVSync Lib "4reelaps.dll" (ByVal Enable As Boolean)
'set AV synchronization
Declare Sub mpgGetAVSync Lib "4reelaps.dll" (ByRef Enable As Boolean)
'get AV synchronization
Declare Sub mpgCallbackFunction Lib "4reelaps.dll" (ByVal ptrFunction As Any)
'declare callback function
Declare Sub mpgSetInitOnOpen Lib "4reelaps.dll" (ByVal Val As Long)
'set init. on open
Declare Sub mpgSetAuxSkip Lib "4reelaps.dll" (ByVal Val As Long)
'set aux skip(?)
Declare Sub mpgLoadNext Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal filename As String)
'loads another file for playing
'On screen display routines:
Declare Sub osdLoadBMP Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal GIFFileName As String, ByVal xPos As Long, ByVal yPos As Long, _
ByVal Mix As Long, ByVal xColor As Long)
'loads a GIF file
Declare Sub osdShow Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'shows an already loaded GIF file
Declare Sub osdHide Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'hides an already shown GIF file
Declare Sub osdSetXYMix Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal xPos As Long, ByVal yPos As Long, ByVal Mix As Long)
'Changes the position and mix values for a GIF
Declare Sub mpgSuppressHost Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Value As Long)
'stops MPEG data from being sent to decoder chip from host memory.
'0- don't supress data flow
'1-supress data flow
Declare Sub mpgSuppressChip Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Value As Long)
'stops MPEG data from being sent to host memory from hard drive.
'0- don't supress data flow
'1-supress data flow
Declare Sub mpgSetStickyFrame Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Val As Long)
'set a frame number to stop playback on, continues with the next mgpPlay
Declare Sub mpgSetCurrentFrame Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Val As Long)
'sets the current frame number for a channel
'structure for variable to send to status routine
Public Type mpgStatusStruct
FilesSize As Long 'size of loaded MPEG file
FilePosition As Long 'current MPEG file read position
System As Long 'Is this a system file(audio and video)
HSize As Long 'Horizontal size of mpeg file
VSize As Long 'vertical size
PicRate As Long 'picture rate code of file
BitRate As Long 'bitrate of file, divided by 400
TimeCode As Long 'last time code decoded
RunTime As Long 'how long MPEG file has been running
Frame As Long 'current frame being decoded
DataUnderFlows As Long 'stat-number of times decoder underflowed
DiskUnderFlows As Long 'stat-number of data from disk ran out
End Type
'structure for variable to send to diagnostic routine
Public Type mpgDiagStruct
DMACount As Long 'number of started DMA transfers to this channel
InterurptCount As Long 'number of completed DMA interrupt transfers
NumberOfSyncs As Long 'number of times the channel has had to adjust a/v sync
LastSyncCorrection As Long 'amount of last sync correction
VideoDataOnChip As Long 'on chip video data quantity
AudioDataOnChip As Long 'on-chip audi data quantity
SizeVideoBufferOnChip As Long 'on chip video buffer size
SizeAudioBufferOnChip As Long 'on-chp audio buffer size
MPEGDataInMemory As Long 'memory MPEG data quantity
SizeMPEGBufferInMemory As Long 'memory video buffer size
AudioFrequency As Long
AudioBitrate As Long
FileType As Long
reserved3 As Long
reserved4 As Long
reserved5 As Long
reserved6 As Long
reserved7 As Long
End Type
Public Const MPG_FILE_READ_COMPLETE = &H1 'message sent to callback routine
Public Const MPG_FILE_PLAY_COMPLETE = &H2 'message sent to callback routine
Public Const MPG_FILE_READ_START = &H5 'message sent to callback routine
Public Const MPG_FILE_FRAME_STICK = &H8 'message sent to callback routine
Public Const CHANNELS_PER_CARD = 4
Public Const SYNC_GROUPS = 10
Public Const HIDE_READ_ONLY_OPTION = &H4
Public Const VERIFY_FILE_EXISTS = &H1000
Public Const TIMER_INTERVAL = 50 'number of milliseconds
Public Const APP_NAME = "4ReelTimePro"
'return values
Public Const NO_ERROR = 0
Public Const DRIVER_NOT_FOUND = 1
Public Const FILE_NOT_FOUND = 3
Public Card() As clsCard 'array of card objects, each of which has a number of channels
which i am also using in my project
--------------------------
Option Explicit
'This module will hold only the declares for the functionality
'contained in 4reelaps.dll
Declare Function mpgOpenDriver Lib "4reelaps.dll" () As Long
'opens connection to the kernel mode driver.
'Must be called before any other function
Declare Sub mpgCloseDriver Lib "4reelaps.dll" ()
'closes connection to the kernel mode driver.
'Must be called upon program completion, assuming mpgOpenDriver worked.
Declare Function mpgLoad Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal filename As String) As Long
'Opens an MPEG for playing on a channel. Will interupt anything currently playing.
Declare Sub mpgClose Lib "reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'stops playback and closes the file handle of the file loaded.
'Can also close superfile
Declare Sub mpgPlay Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'starts or resumes playback on a channel
Declare Sub mpgPlayAll Lib "4reelaps.dll" ()
'plays ALL channels already loaded with a file.
Declare Sub mpgStop Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'stops the selected channels.
Declare Sub mpgStopAll Lib "4reelaps.dll" ()
'stops ALL channels already playing.
Declare Sub mpgStatus Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByRef mStatus As mpgStatusStruct)
'obtains status data from a channel. (Note use of user-defined data type.)
Declare Sub mpgDiagnostic Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByRef mDiag As mpgDiagStruct)
'obtains diagnostic information from channel (Note use of user-defined data type.)
Declare Sub mpgCards Lib "4reelaps.dll" (ByRef NumCards As Long)
'get number of cards installed
Declare Sub mpgSeek Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Position As Long)
'seek to a certain position on a file
Declare Sub mpgAutoRepeat Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets repeat on
Declare Sub mpgNoRepeat Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets repeat off
Declare Sub mpgMute Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets mute on
Declare Sub mpgUnMute Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets mute off
Declare Sub mpgBlack Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'sets channel to show Black screen
Declare Sub mpgSetAVSync Lib "4reelaps.dll" (ByVal Enable As Boolean)
'set AV synchronization
Declare Sub mpgGetAVSync Lib "4reelaps.dll" (ByRef Enable As Boolean)
'get AV synchronization
Declare Sub mpgCallbackFunction Lib "4reelaps.dll" (ByVal ptrFunction As Any)
'declare callback function
Declare Sub mpgSetInitOnOpen Lib "4reelaps.dll" (ByVal Val As Long)
'set init. on open
Declare Sub mpgSetAuxSkip Lib "4reelaps.dll" (ByVal Val As Long)
'set aux skip(?)
Declare Sub mpgLoadNext Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal filename As String)
'loads another file for playing
'On screen display routines:
Declare Sub osdLoadBMP Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal GIFFileName As String, ByVal xPos As Long, ByVal yPos As Long, _
ByVal Mix As Long, ByVal xColor As Long)
'loads a GIF file
Declare Sub osdShow Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'shows an already loaded GIF file
Declare Sub osdHide Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long)
'hides an already shown GIF file
Declare Sub osdSetXYMix Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal xPos As Long, ByVal yPos As Long, ByVal Mix As Long)
'Changes the position and mix values for a GIF
Declare Sub mpgSuppressHost Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Value As Long)
'stops MPEG data from being sent to decoder chip from host memory.
'0- don't supress data flow
'1-supress data flow
Declare Sub mpgSuppressChip Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Value As Long)
'stops MPEG data from being sent to host memory from hard drive.
'0- don't supress data flow
'1-supress data flow
Declare Sub mpgSetStickyFrame Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Val As Long)
'set a frame number to stop playback on, continues with the next mgpPlay
Declare Sub mpgSetCurrentFrame Lib "4reelaps.dll" (ByVal CardNum As Long, ByVal ChanNum As Long, _
ByVal Val As Long)
'sets the current frame number for a channel
'structure for variable to send to status routine
Public Type mpgStatusStruct
FilesSize As Long 'size of loaded MPEG file
FilePosition As Long 'current MPEG file read position
System As Long 'Is this a system file(audio and video)
HSize As Long 'Horizontal size of mpeg file
VSize As Long 'vertical size
PicRate As Long 'picture rate code of file
BitRate As Long 'bitrate of file, divided by 400
TimeCode As Long 'last time code decoded
RunTime As Long 'how long MPEG file has been running
Frame As Long 'current frame being decoded
DataUnderFlows As Long 'stat-number of times decoder underflowed
DiskUnderFlows As Long 'stat-number of data from disk ran out
End Type
'structure for variable to send to diagnostic routine
Public Type mpgDiagStruct
DMACount As Long 'number of started DMA transfers to this channel
InterurptCount As Long 'number of completed DMA interrupt transfers
NumberOfSyncs As Long 'number of times the channel has had to adjust a/v sync
LastSyncCorrection As Long 'amount of last sync correction
VideoDataOnChip As Long 'on chip video data quantity
AudioDataOnChip As Long 'on-chip audi data quantity
SizeVideoBufferOnChip As Long 'on chip video buffer size
SizeAudioBufferOnChip As Long 'on-chp audio buffer size
MPEGDataInMemory As Long 'memory MPEG data quantity
SizeMPEGBufferInMemory As Long 'memory video buffer size
AudioFrequency As Long
AudioBitrate As Long
FileType As Long
reserved3 As Long
reserved4 As Long
reserved5 As Long
reserved6 As Long
reserved7 As Long
End Type
Public Const MPG_FILE_READ_COMPLETE = &H1 'message sent to callback routine
Public Const MPG_FILE_PLAY_COMPLETE = &H2 'message sent to callback routine
Public Const MPG_FILE_READ_START = &H5 'message sent to callback routine
Public Const MPG_FILE_FRAME_STICK = &H8 'message sent to callback routine
Public Const CHANNELS_PER_CARD = 4
Public Const SYNC_GROUPS = 10
Public Const HIDE_READ_ONLY_OPTION = &H4
Public Const VERIFY_FILE_EXISTS = &H1000
Public Const TIMER_INTERVAL = 50 'number of milliseconds
Public Const APP_NAME = "4ReelTimePro"
'return values
Public Const NO_ERROR = 0
Public Const DRIVER_NOT_FOUND = 1
Public Const FILE_NOT_FOUND = 3
Public Card() As clsCard 'array of card objects, each of which has a number of channels
Everything in there looks good - sorry, I can't help you there.
I would recommend trying out the subclassing solution jacobhoover mentioned.
Best regards,
Maxim
I would recommend trying out the subclassing solution jacobhoover mentioned.
Best regards,
Maxim
Another option would be to generate the symbolic debug info for the application and attempt to debug it further with the visual c++ debugger, but judging from the error message you received you do not have that available. Either way, using callback messages in the message loop of a window would be more stable, but also more time sensitive. The main reason that the use of a callback function is so risky in VB6 is because it is NOT thread safe, and the even of a callback is actually a second thread jumping into your address space, specifically at the address of the function you passed to it. However, using the message based system, the foreign thread is just posting a message to your window which is threadsafe. The only issue is the time involved, as a message que is a FIFO buffer of sorts and if the window is flooded with other messages or is busy processing a current message it can't respond to any other messages. One could argue the use of "DoEvents" in VB6, but that is a slimy hack at best to cover for language faults and poor programming.
Jake
Jake
Call mpgCallback(frmMessageWind
tells the mpeg driver that you want the messages sent to the window 'frmMessageWindow'?
Is there a VB equivalent of OnMessage(WM_MPEG_FOO) that you could add to the 'message map'?
Also if you don't know the exact messages sent, you could use spy++ to detect them.