Last-modified: 22-Aug-95
Hope this makes it easier for Our Regular Readers ;-)
[Top of Page][Table of Contents][Top of FAQ]
At the minimum, some suggest using the DEFINT A-Z statement in leu of OPTION EXPLICIT. This statement will cause any variables which are created on the fly to be created as integers as opposed to variant (VB 3.0) or single precision (VB 1.0 and 2.0). (Integers take up less memory).
The OPTION EXPLICIT statement causes VB to 'disable' its ability to create variables on the fly. Thus, all variables must be declared using a DIM or REDIM statement. All variables not declared will cause an error when the OPTION EXPLICIT statement is used. This will eliminate bugs caused by a misspelled variable. The option works module-wide, so you can have some modules with nd some without ths option in your project.
[Top of Page][Table of Contents][Top of FAQ]
[Top of Page][Table of Contents][Top of FAQ]
Dim Va As Variant Dim In As Integer T1! = Timer For i% = 1 To 32766 Va = i% Next i% T2! = Timer Debug.Print "With variant: "; Format$((T2! - T1!),"0.0000") T1! = Timer For i% = 1 To 32766 In = i% Next i% T2! = Timer Debug.Print "With integer:; Format$((T2! - T1!),"0.0000")This test shows (on our test system) that integers are ~60% faster! However, for strings there where no real difference, or in some instances, variants were faster than strings for routines with heavy conversion usage. For the best result in your application, test your routines directly.
[Top of Page][Table of Contents][Top of FAQ]
Sub Text1_KeyPress (KeyAscii As Integer) If KeyAscii = 13 Then '13 is Key_Return KeyAscii = 0 End If End SubThis might not be a very nice thing to do, since your users usually have some intention when they press Enter. Often they will want to jump to the next control, like the Tab key does.
To have the Enter key emulate the Tab key action, you will need to add the line 'SendKeys "{tab}"' above 'KeyAscii=0' in the example above (Yes, I thought KeyAscii=9 works but it doesn't! Tab is obviously handled by Windows on a lower level).
By the way, you'll also find this in the Microsoft VB Knowledge Base (see KB Q78305 and Q85562).
Note: If MultiLine=True you will *not* want to disable the normal behaviour of the Enter key.
[Top of Page][Table of Contents][Top of FAQ]
' Code by Dan Champagne ' 4/18/94 ' This code can be used to do an incremental search in either a ' list box, dir, combo, or a file box. The following code is set ' for a file box called FILE1. To make it work with a list box, or ' a file box with a different name, change all occurences of FILE1 ' with whatever you or VB has named your list, combo, dir, or file box. ' There are two places where you will need to change these. They are ' on the last couple of lines in the KeyPress code. ' Also, thanks to John Tarr for helping debug the code. 'In a .BAS file, add the following: 'searchme$ is a global vaiable that will keep track of what the 'user has typed so far. Global searchme$ 'The following needs to be on one line. Declare Function SendMessageBystring& Lib "User" ALIAS "SendMessage" (ByVal hWnd%, ByVal wMsg%, ByVal wParam%, ByVal lParam$) Global Const WM_USER = &H400 Global Const LB_SELECTSTRING = (WM_USER + 13) Global Const LB_FINDSTRING = (WM_USER + 16) 'In File1 under keydown, add the following: 'This checks if the user has pressed the up or down arrow. 'If they have, reset searchme$ to "". If KeyCode = 40 Or KeyCode = 38 Then searchme$ = "" End If 'In File1 under lostfocus, pathchange, patternchange, and click add: 'If the user has done any of the above, reset the searchme$ 'string. searchme$ = "" 'In File1 under keypress add: Dim result& Select Case KeyAscii Case 8 'Backspace If searchme$ <> "" Then searchme$ = Left$(searchme$, Len(searchme$) - 1) Else File1.ListIndex = 0 End If KeyAscii = 0 Exit Sub Case 27 'Escape searchme$ = "" KeyAscii = 0 Exit Sub Case 13 'Enter searchme$ = "" KeyAscii = 0 Exit Sub Case Asc("a") To Asc("z"), Asc("A") To Asc("Z"), Asc("'"), Asc("."), Asc(" "), Asc("0") To Asc("9") searchme$ = searchme$ & Chr$(KeyAscii) KeyAscii = 0 End Select result& = SendMessageBystring(FILE1.hWnd, LB_FINDSTRING,0, searchme$) If result& = -1 Then searchme$ = Left$(searchme$, Len(searchme$) - 1) Else result& = SendMessageBystring(FILE1.hWnd, LB_SELECTSTRING, -1, searchme$) End If
[Top of Page][Table of Contents][Top of FAQ]
Sub Command1_KeyDown (KeyCode As Integer, Shift As Integer) If KeyCode = 9 Then If Shift = 0 Then Command2.SetFocus 'Tab=Next control ElseIf Shift = 1 Then Command3.SetFocus 'Shift-Tab=Prev.ctrl. End If End If End Sub
...etc.
[Top of Page][Table of Contents][Top of FAQ]
[Top of Page][Table of Contents][Top of FAQ]
Note that procedures are less strict about variable types when you use BYVAL. If you declare that your Sub takes a Variant, VB takes that seriously and gives a nasty "mismatch error" if you try to pass ie. a string to it. Make it ByVal (at the cost of some speed) and your sub will be more tolerant. Also note the following nasty trap: Arguments are passed by reference unless enclosed by parentheses or declared using the ByVal keyword. [VBWin Language Ref., p. 55]
[Top of Page][Table of Contents][Top of FAQ]
[Top of Page][Table of Contents][Top of FAQ]
Perhaps a more elegant and flexible way is to implement a stack with similar routines. I've done this for a math project, but this stack was rather complicated and special purpose (and inspired by HP calculators, of whihc I'm a great fan). Jan G.P. Sijm (jan.sijm@intouch.nl) have implemented some routines for general stacks:
Option Explicit 'Variable declarations required Dim m_vStack() As Variant 'Stack of variant types '* This function will pop a value of a stack of variant '* values. The value to be popped (e.g. the variable it '* is assigned to) must have one of the basic variable '* types that Visual Basic supports. The type of the '* return value is determined by the type of the variable '* it is assigned to. '* '* Input : None '* Modifies : m_vStack, Stack of variant's '* Return : Value of last pushed variant Function stkPop () As Variant Dim iM As Integer iM = UBound(m_vStack) 'Get current stack size stkPop = m_vStack(iM) 'Pop value from stack iM = iM - 1 'Decrement number of elements ReDim Preserve m_vStack(iM) As Variant End Function '* This function will push a value onto a stack of '* variant values. The value to be pushed must have one '* of the basic variable types that Visual Basic supports '* '* Input : vValue, Value to be pushed '* Modifies : m_vStack, Stack of variant's Sub stkPush (ByVal vValue As Variant) Dim iM As Integer On Error Resume Next 'Trap for undimensioned array iM = UBound(m_vStack) 'Get current array size iM = iM + 1 'Increment number of elements ReDim Preserve m_vStack(iM) As Variant m_vStack(iM) = vValue 'Push value on stack End Sub 'This is a short example of how the stack routines can be used in a 'Visual Basic program. This example will push three parameters onto 'the stack. A modal dialog is displayed. The dialog will pop the 'parameters from the stack and set edit controls with the values. Sub ShowDialog() ' Push the parameters for the dialog ' onto the stack and display the dialog ' stkPush sName stkPush sStreet stkPush sCity dlgPerson.Show MODAL End Sub Form_Load() ' Pop the parameters of this dialog from the ' stack in REVERSED ORDER and place the values ' in the appropriate edit controls. ' dfCity.Text = stkPop() dfStreet.Text = stkPop() dfName.Text = stkPop() End Sub
[Top of Page][Table of Contents][Top of FAQ]
[Top of Page][Table of Contents][Top of FAQ]
[Top of Page][Table of Contents][Top of FAQ]
PhoneNumber$ = "(123)456-7890" Open "COM2:" For Output As #1 'or COM1 Print #1, "ATDT" & PhoneNumber$ & Chr$(13) Close #1Ian Storrs
[Top of Page][Table of Contents][Top of FAQ]
Unfortunately, Microsoft has been more famous for memory barriers than anything else. This is a late descendant of the infamous 640K barrier that has been plaguing us for years. Although Windows allows the user to access several megabytes of memory, it uses two limited (64K) memory areas called User Heap and GDI Heap for some specific data structures. Go to the Help|About box in Program Manager to see the percentage of free resources in the *most* exhausted heap. If these areas are exhausted, you are out of luck. VB programs are unfortunately rather greedy on these structures. Windows 4 is supposed to free us from this limitation...
Note that every visible control (ie every button) is a window to Windows. Every new control takes up some bytes in the precious User heap.
Also, there is another way to run out of memory in Windows, not related to VB. Windows requires free Upper Memory Area (UMA, also called Upper Memory Blocks, not to be confused with High RAM, which is the first 64K of extended memory) to do certain tasks. If you use QEMM or DOS 6+ MemMaker and you have many device drivers (network, etc) this area may have been filled up before you launch Windows. You will then be unable to start applications, even though you have plenty of free RAM. The problem can be solved with careful memory setup, but this is far beyond the scope of this FAQ.
On a completely unrelated problem: When you run a program with an outline control with some ATI graphics cards, it may crash with just that error message. (see Knowledge Base [Top of Page][Table of Contents][Top of FAQ]
[Top of Page][Table of Contents][Top of FAQ]
There are two different "Zorder"'s of forms in Windows, both implemented internally as linked lists. One is for "normal" windows, the other for real "topmost" windows (like the Clock application which is distributed with MS Windows). The Zorder command above simply moves your window to the top of the "normal" window stack. To make your window truly topmost, use the SetWindowPos API call like this:
'Make these declares: Declare Function SetWindowPos Lib "user" (ByVal h%, ByVal hb%, ByVal x%, ByVal y%, ByVal cx%, ByVal cy%, ByVal f%) As Integer Global Const SWP_NOMOVE = 2 Global Const SWP_NOSIZE = 1 Global Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE Global Const HWND_TOPMOST = -1 Global Const HWND_NOTOPMOST = -2 'To set Form1 as a TopMost form, do the following: res% = SetWindowPos (Form1.hWnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS) 'if res%=0, there is an error 'To turn off topmost (make the form act normal again): res% = SetWindowPos (Form1.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS)
[Top of Page][Table of Contents][Top of FAQ]
There are a few tricks you can use to reduce line length, but unfortunately there is very little to do with DECLARE statements which can get very long.
Print your source in landscape :-/
[Top of Page][Table of Contents][Top of FAQ]
If you want to paste your picture directly into the VB program by pressing Ctrl-V when you are editing the picture property, you will have to use a semilar procedure: select the control, select the property, press Ctrl-V. If you try it again without deselecting the control first (or selecting it from the combo box), it doesn't work.
[Top of Page][Table of Contents][Top of FAQ]
The following type of controls are NOT known to be available as sw/pd/fw for Visual Basic, only as commercial toolboxes (If you feel like making any of these for VB and sharing it for a modest fee, you will become very popular!):
[Top of Page][Table of Contents][Top of FAQ]
For the first option, check out VideoSoft's $hareware VSVBX.VBX (download VSVBX.ZIP from Cica or mirrors). It has a will of its own, as you will experience, but it's generally better than trying what is described below.
For the brave (or stupid), try to write "screen resolution-smart code" in the form's Load event. If the form is resizable (normally it should be), you'll have to put some magic into the Resize event as well. There are 4 rules of thumb:
[Top of Page][Table of Contents][Top of FAQ]
On The Developer Network Library CD, you'll find the following:
VBASM is a Microsoft(R) Visual Basic(R) dynamic-link library (DLL) that helps Visual Basic programmers accomplish tasks that are difficult or impossible using Visual Basic alone. This sample application includes two programs, SNOOPER and TXTALIGN, that demonstrate the DLL's use. The DLL contains many low-level routines such as access to real and protected mode interrupts, port input/output (I/O), peek/poke, control manipulation, and so on. These routines and their associated functions include:
Control Manipulation:
Pointer and Memory
Byte/Word/Long Manipulation
I/O Access
Interrupts
Others
[Deane Gardner <deaneg@ix.netcom.com> quotes Microsoft.]
There's a shareware package for in/out routines, btw.
[Top of Page][Table of Contents][Top of FAQ]
[Top of Page][Table of Contents][Top of FAQ]
Sub Form_Load () If App.PrevInstance Then SaveTitle$ = App.Title App.Title = "... duplicate instance." 'Pretty, eh? Form1.Caption = "... duplicate instance." AppActivate SaveTitle$ SendKeys "% R", True End End If End SubAs Robert Knienider(rknienid@email.tuwien.ac.at) informed me, this piece of code WILL NOT work for non-English versions of MS Windows where the word for "Restore" does not have "R" as the underlined word. Replace the "R" in the SendKeys line above with "{ENTER}" or "~".
Note that you shouldn't prevent multiple instances of your application unless you have a good reason to do so, since this is a very useful feature in MS Windows. Windows will only load the code and dynamic link code *once*, so it (normally) uses much less memory for the later instances than the first.
[Top of Page][Table of Contents][Top of FAQ]
Make sure that the TabIndex property for the text box is 1 greater than the label's TabIndex. Since a label can't have the focus, the focus will go to the next item in the tab order, which would be the text box.
Here's any easy way to set the TabIndex for a busy form. Select the object that should be last in the tab order and then select the TabIndex property. Press 0 (zero), click on the next to last object, press 0, click on the the next object back, press 0, etc. When you're done, all of the TabIndexes will be in order, because VB increments all of the higher TabIndexes when you put in a lower number.
Many thanks to Jonathan Kinnick and Gary Weinfurther that provided the answer on the FIDO net echo VISUAL_BASIC. [Tiago Leal (Tiago.Leal@p25.f1.n283.z2.gds.nl)]
[Top of Page][Table of Contents][Top of FAQ]
drive1.refresh dir1.refresh file1.refreshin the code for the "Rescan" button (or whatever).
[Top of Page][Table of Contents][Top of FAQ]
See Article Q113590 (or Q106553) in Microsoft's VB KnowledgeBase. A short extract follows:
Declare Function DiskSpaceFree Lib "SETUPKIT.DLL" () As Long Dim free_space& ' Holds number of bytes returned from DiskSpaceFree(). ChDrive "c:" ' Change to the drive you want to test. free_space& = DiskSpaceFree()[Geir Tutturen(itfgt@nlh10.nlh.no)]
[Top of Page][Table of Contents][Top of FAQ]
ReportDesign=1 DataAccess=1[Danny Ames (dames@pic.net)]