I'm trying to update a very old VB6 program to provide Speech Recognition.
I'm thinking the best way to do this is by accessing the Win32 API for Speech Recognition.
Looked for this on MS documentation. Looks like previously this would be done via the SAPI 5.3 per this question which has been deprecated and replaced by MS Agent, which itself is deprecated.
http://msdn.microsoft.com/en-us/library/ms720589(VS.85).aspx
The above link is old (because I used it 10 years ago), but is valid. You basically create the appropriate objects, possibly create a grammar in their format, and then create events on the RC object, below:
The below method "works", but it wasn't very impressive. Also, it led us to have to create our own MsgBox function, since we needed to automate everything... And, since you can't just tell Windows to "click" the OK button of a standard message box (unless you want to muck around even more APIs), you have to control even more aspects of your software.
It did work, but I'm not sure anyone ever used it.
Public WithEvents RC As SpSharedRecoContext
Public myGrammar, b As ISpeechRecoGrammar
Private Sub Form_Load()
On Error GoTo EH
Set RC = New SpSharedRecoContext
Set myGrammar = RC.CreateGrammar
myGrammar.CmdLoadFromFile "sol.xml", SLODynamic
myGrammar.CmdSetRuleIdState 0, SGDSActive
EH:
If Err.Number Then ShowErrMsg
End Sub
Private Sub RC_FalseRecognition(ByVal StreamNumber As Long, ByVal StreamPosition As Variant, ByVal Result As SpeechLib.ISpeechRecoResult)
'Label1.Caption = "(no recognition)"
End Sub
Private Sub RC_Recognition(ByVal StreamNumber As Long, ByVal StreamPosition As Variant, ByVal RecognitionType As SpeechLib.SpeechRecognitionType, ByVal Result As SpeechLib.ISpeechRecoResult)
'Label1.Caption = Result.PhraseInfo.GetText
End Sub
Private Sub RC_StartStream(ByVal StreamNumber As Long, ByVal StreamPosition As Variant)
'Label2.Caption = Val(StreamNumber)
End Sub
Related
I'm trying to migrate to managed ODP.NET, but I'm having problems with the OCIBreak.
Friend Shared Sub Break(dbConn As OracleConnection)
Dim ContextHandle = DirectCast(dbConn.GetType.GetProperty("ServiceContextHandle", ref.BindingFlags.Instance Or ref.BindingFlags.NonPublic).GetValue(dbConn, Nothing), Runtime.InteropServices.SafeHandle)
Dim ErrorHandle = DirectCast(dbConn.GetType.GetProperty("ErrorHandle", ref.BindingFlags.Instance Or ref.BindingFlags.NonPublic).GetValue(dbConn, Nothing), Runtime.InteropServices.SafeHandle)
OCIBreak(ContextHandle, ErrorHandle)
End Sub
<Runtime.InteropServices.DllImport("oci.dll", CallingConvention:=Runtime.InteropServices.CallingConvention.Cdecl)>
Private Shared Function OCIBreak(Context As Runtime.InteropServices.SafeHandle, ErrorHandle As Runtime.InteropServices.SafeHandle) As Integer
End Function
What I found out, you can partially emulate it using following code.
Private Sub Cancel(conn As OracleConnection)
Using cmd = New OracleCommand("", conn)
cmd.Cancel()
End Using
End Sub
I expect this to work, because OracleCommand.Cancel cancels currently running command, which is not necessarily this one (docs).
And it actually does work this way - but only for SELECT-queries, it doesn't cancel PL/SQL-blocks or stored procedures. It is still possible to cancel those, but only via the corresponding OracleCommand-instance.
Is it possible to achieve somehow? Maybe there is a way to get that currently running command from oracle connection object?
I can't get this to work. It says string constant expected...
Dim const path As String = "\Windows\System32\user32"
Private Declare Function CallWindowProcW Lib path...
Any suggestions?
As was said, you can't do that. If you use a path to a library it must be hard-coded.
However, if you don't use a hard-coded path there's a defined order in which Windows will look for for the library. It will search the app directory, the current dir, the Windows and System dirs, and along the current Path. If you put your DLL in any of those places, and omit the hard-coded path in the reference, it will be found (what order they're searched in varies by Windows version and by where it's documented).
There's one other possibility. If a DLL is already loaded in memory, Windows will reuse the loaded copy. So you can omit the path if you first load the DLL yourself, and for that you can use a string variable. Check out the docs for LoadLibrary. You do have to keep a handle and free the library yourself using FreeLibrary.
Private Declare Function CallWindowProcW Lib "User32" ...
Test it
Declare Statement
Example
The following example declares an external reference to a Function procedure that returns the current user name. It then calls the external procedure GetUserNameA as part of the getUser procedure.
Declare Function getUserName Lib "advapi32.dll" Alias "GetUserNameA" (
ByVal lpBuffer As String, ByRef nSize As Integer) As Integer
Sub getUser()
Dim buffer As String = New String(CChar(" "), 25)
Dim retVal As Integer = getUserName(buffer, 25)
Dim userName As String = Strings.Left(buffer, InStr(buffer, Chr(0)) - 1)
MsgBox(userName)
End Sub
While working on a vb6 project, I found that I could not execute a sub (contained in an external module) using form_load(). Here is what the code looked like:
Private Sub Form_Load()
ExampleSubroutine
End Sub
At the time, I circumvented this problem by using form_activate() instead to start up the form:
Private Sub form_activate()
ExampleSubroutine
End Sub
However, this means that whenever the program switches to a different form and returns to the main form, the sub is run again. I do not want this. Is there a way to execute the sub using form_load()? Thanks.
It may be because PictureBox hasn't been fully loaded then. One way to use Activate event is have Static Boolean and then set it once it hits the first time.
Private Sub Form_Activate()
Static BeenHere as Boolean
If Not BeenHere Then
ExampleSub
BeenHere = True
End If
End Sub
I need to mimic the adress book control in an Outlook VSTO project. It would be much simpler to use the real control, isn't it?
So, do you know a way to expose the address book control, and get what's selected within, of course?
Edit: Never mind, re-creating a basic version of the control will be way easyer.
Solution: third party Redemption library offer this feature.
RedemptionLoader.RDOSession.AddressBook.ShowAddressBook(...)
You don't need to use a third party addin. you can do it with this:
http://msdn.microsoft.com/en-us/library/office/ff868361.aspx
this code below is in VBA but you can easily convert it to C#:
Sub SelectRecipients()
Dim oMsg As MailItem
Set oMsg = Application.CreateItem(olMailItem)
Dim oDialog As SelectNamesDialog
Set oDialog = Application.Session.GetSelectNamesDialog
With oDialog
.InitialAddressList = _
Application.Session.GetGlobalAddressList
.Recipients = oMsg.Recipients
If .Display Then
'Recipients Resolved
oMsg.Subject = "Hello"
oMsg.Send
End If
End With
End Sub
I'm trying to come up with a VB6 test app that calls InternetCheckConnection.
In my test app, InternetCheckConnection always returns false regardless of the URL I use. I copied and pasted this code from a larger spaghetti-code app, but in the spaghetti-code, InternetCheckConnection seems to work fine, returns true.
Is there some other function I have to call first in order for InternetCheckConnection to work?
I was able to get InternetCheckConnection to work correctly by including the full address for a website, including "http://". For example, using "www.google.com" returned False, but "http://www.google.com" returned true.
Try using the InternetGetConnectedState function.
Private Declare Function InternetGetConnectedState Lib "wininet.dll" (ByRef lpSFlags As Long, ByVal dwReserved As Long) As Long
Dim blnInternetConnected as Boolean
Dim Flags as long
blnInternetConnected = InternetGetConnectedState(Flags, 0&)
Perhaps, in the "spaghetti-code" app, InternetCheckConnection is relying on the state of some global variable you are not aware of. Is that possible?