Form_Load() doesnt allow sub to be executed VB6 - vb6

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

Related

OCIBreak analog in managed ODP.NET

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?

How to access Speech Recognition via Win32 API?

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

Stringify a method call in VBScript

I'm currently working every day with QuickTest Professional 11, which uses VBScript behind the scenes. Lately, I've started developing some of my own functions to handle common situations. I'm pretty new to VBscript, most of my programming experience is in C and Python.
I'm trying to implement Python's Try/Except in VBScript, mostly to wrap around actions like clicking links or selecting values from dropdown boxes. Here's what I have so far:
Class cls_ErrorHandler
Private bWasError
Private Sub Class_Initialize()
bWasError = False
End Sub
Private Sub IsErr
If Err.Number <> 0 Then
bWasError = True
Else
bWasError = False
End If
Err.Clear
End Sub
' If the command fails, set bWasError
Public Sub Try(strCommandToTry)
On Error Resume Next
Execute(strCommandToTry)
me.IsErr
On Error Goto 0
End Sub
Public Sub Except(strCommandInCaseOfError)
If bWasError Then
Execute(strCommandInCaseOfError)
End If
bWasError = False
End Sub
End Class
I'd like to be able to write things like this:
Set oErrorHandler = New cls_ErrorHandler
oErrorHandler.Try(Stringify(Browser("Browser Name").Page("Page Name").WebCheckBox("Checkbox Name").Set "ON"
oErrorHander.Except(Stringify(Browser("Browser Name").Page("Page Name").WebButton("Save").Click))
As far as I can tell, there really isn't any nice way to pass a function as an argument to another function in VBScript. The best way seems to be to pass a string containing the name of a function, and then feed that string into Execute() or Eval(). Objects in QuickTest Professional tend to have lots of quotation marks, so escaping them all by hand would make the code unreadable.
In C, I'd use something like this:
#define Stringify(obj) #obj
and it would be done... but nothing like that seems to exist in VBScript. Is there any way to implement this? Is there anything in VBScript that takes an object as its input and returns a string representation of that object's name? Would it be possible to write a DLL in C/C# that would provide this kind of functionality?
You can use GetRef to obtain a function/sub pointer, and call the function/sub using that pointer. See online help, it shows an example for an event handler, but you can refer to any global function or sub with GetRef, and use the variable holding the GetRef return value just like an alias for the sub/function.
Be aware, however, that there are cases you won't be able to cover with this:
You cannot use a GetRef function pointer if the current calling stack contains a
method call that is a function registered to a test object via
RegisterUserFunc.
You cannot call such a test object method from within a routine call
that was adressed via a GetRef function pointer.
Also consider using ExecuteGlobal instead of Execute so the code you pass can set global variables that the ExecuteGlobal caller can access afterwards.

Calling Latebinding Subroutine in every Subroutine

First, I would just like to state that I need to use LateBinding due my program running in different machines with different versions of excel.
I have declared a Public Sub in a module that can be called to initiate the creation of object for the excel application.
'Declare Public Excel Variable to Call from one place and easy manipulation
Public xlApp As Object
Public wb As Object
Public wb2 As Object
Public ws As Object
Public ws2 As Object
Public Sub InitializeExcel()
'Create the Excel Objects
Set xlApp = CreateObject("Excel.Application")
End Sub
And then in every Subroutine that I create which uses the excel application, I call InitializeExcel and at every end do the following:
On Error Resume Next
xlApp.Quit
Set xlApp = Nothing
Set wb = Nothing
Set wb2 = Nothing
Set ws = Nothing
Set ws2 = Nothing
My question now is this:
Do I need to call InitializeExcel on every Subroutine that needs
the excel application or can I just call it once at the start of the
application?
I have tested a few things and had these results:
InitializeExcel needs to be called every time since at the end of every Subroutine as mentioned sets the xlapp which is the Excel Application Object to Nothing
If I remove the Set xlApp = Nothing in each subroutine, then I can "re-use" the xlApp as an Excel Application Object. This however cause an issue in which the Excel Application is kept running in the background and every time I open a new Workbook, then another instance of the Excel Application runs.
So I suppose, the best way was my initial setup in which I call InitializeExcel and then set everything to Nothing at each routine the procedure was called.

Is there any way to trigger some macro after build in visual studio

I want to count how many times i built on VS.NET .
I have a plan. If i run svn commit when i build to project, i would have build count on revision number :)
I didn't write any macro which can execute a command. And i don't know visual studio is allowing to prebuild event for this kind of request.
You can use pre/post build events.
In your project properties, go to the Build events tab - there is space for both pre build and post build commands.
See this blog post on how incrementing build numbers can be done.
Yes this is possible.
Open up the Macros IDE
Open the file called environmentEvents
This file has the various DTE event objects declared and you can easily add a handler like so.
Private Sub PostBuild() Handles BuildEvents.OnBuildDone
' Your code here
End Sub
Also can use:
Dim WithEvents myTimer As Timers.Timer
Sub CustomBuild()
DTE.ExecuteCommand("Build.BuildAll")
myTimer = New Timers.Timer
myTimer.Interval = 0.05
myTimer.Start()
End Sub
Sub myTimer_Elapsed(ByVal ee As Object, ByVal dd As Timers.ElapsedEventArgs) Handles myTimer.Elapsed
If DTE.Solution.SolutionBuild.BuildState <> vsBuildState.vsBuildStateInProgress Then
myTimer.Stop()
End If
If DTE.Solution.SolutionBuild.BuildState <> vsBuildState.vsBuildStateInProgress And DTE.Solution.SolutionBuild.LastBuildInfo <> 1 Then
... build was successful ...
End If
End Sub

Resources