Here is an equivalent function, but this does not require any API functions to be declared, and does not need any alterations based on the version of VB you run.
VB Code:
Option Explicit
Function RunningInVB() As Boolean
'Returns whether we are running in vb(true), or compiled (false)
Originally posted by si_the_geek Here is an equivalent function, but this does not require any API functions to be declared, and does not need any alterations based on the version of VB you run.
Your code works, however, if you use my code in an ActiveX Control/DLL, it will return true even if the AX project is not loaded in the IDE, but the project that uses the reference/component is running from VB. This can be useful if you have subclassing or whatever that you want to be able to turn off when not running fully compiled.
Laugh, and the world laughs with you. Cry, and you just water down your vodka.
I think you can like this, but i don't have vb with me to check:
VB Code:
Private Sub Command1_Click()
Dim mode
mode = App.LogMode
If mode = 0 Then
MsgBox "Running In IDE Version"
ElseIf mode = 1 Then
MsgBox "Running in Compiled Version"
End If
End Sub
1) If your post has been adequately answered please click in your post on "Mark Thread Resolved".
2) If someone has been useful to you please show your respect by rating their posts.
3) Please use [highlight="VB"] 'your code goes in here [/highlight] tags when posting code.
4) Before posting your question, make sure you checked this links: MICROSOFT MSDN -- VB FORUMS SEARCH
5)Support Classic VB - A PETITION TO MICROSOFT
I know this is a very old thread, but I like all the different approaches listed above.
Thought I'd add one more. This applies to usercontrols only
1) VB only. Not guaranteed to apply to other "IDEs": Word, Access, IE, etc
2) Your usercontrol is uncompiled and you want to know if whatever is hosting it is in design-view
Normally, we'd use Ambient.UserMode which would return False indicating the host is in design view, not run-time. However, while designing, let's say you create a second usercontrol (UC) that hosts the first UC. Everything is in design view, neither UC is compiled.
What's the problem? The 1st UC that's hosted in the 2nd UC will return Ambient.UserMode = True. This may be an issue if you are using that return value to start subclassing or API timers or something else that shouldn't be run in design view. UCs in design view are not guaranteed to get a Terminate event in design view; so subclassing, etc, should be handled carefully. You can test this by placing a debug.print statement in the control's Terminate event, then
1) On the form, right click on the form and choose menu: update controls. Debug.Prints show
2) Now open a UC code window & hit carriage return anywhere to force cross-hatching & close the UC
3) On the form, update controls again: No Debug.Prints show. Any subclassing may be crashing IDE
4) Compiled UCs get terminate events.
Solution. If you create a Private Sub Main(), in a bas module, and set your UC to start with Sub Main via the UC properties dialog, then you can use that to your advantage. Add a public boolean variable to that module and in Sub Main() set that variable to True. Where you were testing for Ambient.UserMode, now test for that public boolean's value instead.
While the UC is uncompiled and host is in design view, VB does not call the Sub Main() of the UC, but the Ambient.UserMode can change as described earlier.
Simple example
1) Start a new project (exe type)
2) Click on IDE menu: File | Add Project. This will create a group project
3) Choose Active-X Control project
4) In that Active-X project, add 1 module, set the UC's AutoRedraw to True
5) In the module, paste this code
Code:
Public g_UserMode As Boolean
Private Sub Main()
g_UserMode = True
End Sub
7) In the UC's properties, set the startup to Sub Main. IDE Menu: Project | Project2 Properties
8) Close all the UC windows opened in design view
9) Place the UC on the form. You should see that the printed lines return the same value, both in design view & run-time
When done playing, return to IDE and close all windows. Then
1) Add 1 more project to the group and make it an Active-X Control also
2) Change the control's name in the property sheet from UserControl1 to UserControl2
3) In that new UC, draw the 1st UC in it and close all IDE windows
4) Open the form in design view and draw the 2nd UC on the form
You will notice the 2 UC's display different Ambient.UserMode values in design time, but the same in run time
Insomnia is just a byproduct of, "It can't be done"
I know this thread is old but I have run the various techniques for determining whether the code is executing in the IDE or in a compiled form. In each case I put the code into a function that returned True if the code was executing in the IDE and False otherwise. The times below are the number of milliseconds required for each function to run 100 million times.
Code:
Un-compiled Compiled
vbAdvance "In_IDE" conditional compilation command 4,510 ms 196 ms
Using Debug.Assert (similar to post #4) 10,490 196
Using App.Log (see posts #5 & 6) 12,807 10,340
Debug.Print a /0 (see post #7) 42,520 7,330
Look for IDE window (see post #16) 478,000 49,600
The above techniques are all based on doing something in the IDE that doesn't exist in the compiled code. The vbAdvance method overrides a compilation constant at compile time. The others use Debug.Assert, Debug.Print and App.LogMode. It shouldn't be a surprise that those in the IDE run are slower in the checking code because 1) compiled code runs faster and 2) the code that doesn't exist in compiled mode such as Debug.Print does exists in the IDE and it takes time to run.
If for no other reason than visual styles, most of us start with Sub Main and we have general initialization code there where we can determine whether we are in the IDE or not and then save that setting for later checking. I use the 2nd technique because I don't have to set a compilation constant and because it performs just as fast in compiled code as technique #1. I do use vbAdvance for a lot of things, just not this.
Last edited by MountainMan; Nov 26th, 2017 at 10:38 PM.
Reason: Adjust for post #16 below & fix some typos.
'in a module
Public gIde As Boolean
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal lhWnd As Long, lProcessId As Long) As Long
Private Sub Main()
Dim x As Long
GetWindowThreadProcessId FindWindowA("IDEOwner", vbNullString), x 'search for VB6 IDE window and get process identifier
gIde = (GetCurrentProcessId = x)
End Sub
Last edited by hwoarang; Nov 26th, 2017 at 11:27 AM.
Performance is not really an issue when you cache the result in a global/local variable.
Set it at the start up of the application and then you only have a single boolean variable.
I agree with Arnoutdv: it doesn't matter the method, you need to store the result in a valriable. I usually use a Static variable.
Code:
Public Function InIDE() As Boolean
Static sValue As Long
If sValue = 0 Then
Err.Clear
On Error Resume Next
Debug.Print 1 / 0
If Err.Number Then
sValue = 1
Else
sValue = 2
End If
Err.Clear
End If
InIDE = (sValue = 1)
End Function
Public Function InIDE(Optional ByRef b As Boolean = True) As Boolean
' NEVER specify the Optional b when calling.
If b = True Then Debug.Assert Not InIDE(InIDE) Else b = True
End Function
It was inspired by something I saw The Trick do. It's nice in that no disk I/O is performed. And it's very fast and terse. Also, it won't tamper with the Err object. I've used maybe half-a-dozen through the years, and I think the above is best.
EDIT1: I suppose you could add a Static to it to make it slightly faster, but it's pretty fast as it is. I'll let loquat test if he likes.
Last edited by Elroy; Sep 2nd, 2019 at 01:04 PM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Private Function InIDE(Optional ByRef B As Boolean = True) As Boolean 'Very efficient function for testing whether
If B Then Debug.Assert Not InIDE(InIDE) Else B = True 'this code is running in the IDE or compiled
End Function 'Based on the original by Vesa Piittinen
You cannot make InIDE3 faster by adding a static as the single Debug.Assert eventually gets removed, so in compiled executable it gets reduced to a no-code function w/ no parameters.
The only way to beat this is if you don't call anything at all I suppose :-))
You cannot make InIDE3 faster by adding a static as the single Debug.Assert eventually gets removed, so in compiled executable it gets reduced to a no-code function w/ no parameters.
The only way to beat this is if you don't call anything at all I suppose :-))
cheers,
</wqw>
Compiled yours and Elroy's one are quite faster than mine.
Compiled, 100,000,000 iterations:
Code:
InIDE3 0.101
mine 2.226
Elroy's 0.156
global variable 0.046
Uncompiled, 100,000,000 iterations:
Code:
InIDE3 8.031
mine 4.789
Elroy's 8.304
global variable 0.507
But if speed is really an issue, the best (of course) is to use just a variable and set it up when the program starts.
PS: I didn't test others.
Last edited by Eduardo-; Sep 2nd, 2019 at 10:38 PM.