
What are some tips that every VB programmer should know?
What IS an API call?
Where do I go for more VB help?
What is the difference between VBA and VB?
How do I copyright my programs?
How do I create a "floating toolbar" form?
How do I show an elapsed time greater than 24 hours?
How do I check if a MaskedEditBox control is empty?
How do I select or invert All items in a multi-select ListBox?
Where can I buy old versions of Microsoft Basic?
How do I pick a random number between 3 and 6?
How do I activate a previous instance when my program is run twice?
How do I convert between decimal, hex, and binary?
How do I specify a start-up path for VB?
How do I code a recursive power-of routine?
What is the formula for determining a leap year?
Where can I download VB?
Can I save images as JPEG?
How do I limit the text entry length in a ComboBox?
How do I send email with VB?
How do I retrieve the serial # on a peer to peer network volume?
How can I get a dialog box with "Yes", "Yes to All", and "No"?
How do I fix "Object Server" errors when using control custom properties?
How do I get the MAC address if I know the IP address?
How do I evaluate a math string?
How do I drag a PictureBox around?
How do I launch a Control Panel applet?
How do I rank search results?
How do I upload files to an ASP page using VBScript?
How do I restrict mouse movement to one area of my Form?
How do I show ToolTipText on each ListBox item?
How do I center a ListView item?
How do I edit Office document properties?
How do I emulate a ComboBox in HTML?
How do I know to use ByVal, ByRef, or As Any in API functions?
How do I determine what operating system is running?
How do I connect to another computer via the Internet for a chat app?
How do I store multiple files in a single file?
Where can I find documentation on Windows API calls?
How do I make my program run when Windows starts?
How do I show the "Open With" dialog?
How do I add Chat to my website?
How do I reference a UserControl from its subclassing module?
How do I get started with C++?
Perl search script used on BlackBeltVB.com
What are some tips that every VB programmer should know?
Private Sub Text1_Change()
Static bInHere As Boolean
If bInHere Then Exit Sub
bInHere = True
' do some stuff that changes Text1.Text
bInHere = False
End Sub
The second type of share is the object level share. That means that
the variables can be used by any procedure in the same object (Form, Module,
Class, UserControl), but not by any other object. Just define the variable in
the (General)(Declarations) section of the module (that means that
(General) appears in the left ComboBox of the code window and
(Declarations) appears in the right ComboBox.)
Option Explicit
Dim aVar As String
Private Sub Form_Load()
aVar = "Anything"
End Sub
Private Sub Form_Resize()
aVar = "Something else"
End Sub
The third type of share is what I call the Form Property Share. This
type of share applies to Forms, Classes, and UserControls and makes a variable act like a
property of the form that can be referenced from outside the form.
' Form1
Option Explicit
Public aVar As String
Private Sub Form_Load()
aVar = "Something"
End Sub
' Form2
Private Sub Form_Load()
MsgBox Form1.aVar
End Sub
The fourth type of shared variable is the most useful - the Application
Share. This type of share can only be created in a module (a .Bas
file). The application share variable can be used in any procedure in any
object in the project.
' Module1.bas
Public aVar As String
Private Sub DisplayString()
MsgBox aVar
End Sub
' Form1
Private Sub Form_Load()
MsgBox aVar
End Sub
What IS an API call?
' Module1.bas
Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
If you only need this function in a UserControl or a Form, you
need to add the Private keyword in front of the declare:
' Form1
Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Note that declare statements must go in the (General)(Declarations)
section. Once the function is declared, it becomes "part of" the Visual Basic
language and can be used like any other function - with the exception that if
you used the Private keyword, it can only be used in the object in which
it is declared. Note also that you absolutely must use the exact same
casing in theAlias text as the original function. DLL functions are
case sensitive and you will receive an error when the program attempts
to use a function that it cannot find. To use this API function with the
ListBox object to search for a string, you need to add the message
that accomplishes the search as well as the code that calls the DLL.
Const LB_FINDSTRING = &H18F
Private Sub FindString(aStr As String)
List1.ListIndex = SendMessage(List1.hWnd, LB_FINDSTRING, _
-1, ByVal aStr)
End Sub
The information needed to complete this function - the values of wParam and
lParam - are listed in the Platform SDK.
Where do I go for more VB help?
What is the difference between VB and VBA?
How do I copyright my programs?Copyright protects your program, unequivocally recognizes you (its creator) as its owner, and grants you all the rights, benefits and privileges that come with ownership. The moment you finish a program, the law recognizes that only you can decide how it is to be used.
Copyright law gives you the right to make and distribute copies of your program. With very few exceptions, anything you write today will enjoy copyright protection for your lifetime plus 70 years. Copyright protects "original works of authorship" that are fixed in a tangible program. Titles, ideas and facts can NOT be copyrighted.
Some people are under the mistaken impression that copyright is something they have to send away for, and that their program is not properly protected until they have "received" their copyright from the government. The fact is, you don't have to register your work with the Copyright Office in order for your work to be copyrighted; any program is copyrighted the moment it is created. Registration of your program does, however, offer some additional protection (specifically, the possibility of recovering punitive damages in an infringement suit) as well as legal proof of the date of copyright.
Registration is a matter of filling out an application form (for software, that's Form TX) and sending the completed form, a nonreturnable copy of the work in question and a check for $30 to the Library of Congress, Copyright Office, Register of Copyrights, 101 Independence Ave. SE, Washington DC 20559-6000.
To get answers to specific questions about copyright, call the Copyright Public Information Office at 202/707-9100. Forms can also be downloaded from http://lcweb.loc.gov/copyright -- the site also includes information on filling out the forms, general copyright information and links to other websites related to copyright issues. Instructions for copyrighting software can be read here. Note that you need Adobe Acrobat to read the copyright office's documentation.
How do I create a "floating toolbar" form that stays on top in an MDI application?
Private Declare Function SetWindowLong Lib "user32" Alias _
"SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Const GWL_HWNDPARENT = (-8)
Private Sub Form_Load()
SetWindowLong hwnd, GWL_HWNDPARENT, MDIForm1.hwnd
End Sub
How do I show an elapsed time greater than 24 hours?
Dim Start_Time As Date, cTotal As Currency
Private Sub Form_Load()
Start_Time = Now
cTotal = 23 * 3600@ + 58 * 60@ + 59 ' Previous elapsed time
End Sub
Private Sub Timer1_Timer()
Dim cAllSeconds As Currency
cAllSeconds = DateDiff("s",Start_Time,Now) + cTotal
Dim lSec As Long, lMin As Long, lHour As Long
lSec = cAllSeconds Mod 60
lMin = (cAllSeconds \ 60) Mod 60
lHour = cAllSeconds \ 3600
Label1.Caption = CStr(lHour) & ":" & Format(lMin, "00") & _
":" & Format(lSec, "00")
End Sub
How do I check if a MaskedEditBox control is empty?
Function MaskChars(aMask As String)
Dim a As String, k As Long
a = aMask
k = InStr(a, "#")
Do While k
Mid$(a, k, 1) = "_"
k = InStr(k + 1, a, "#")
Loop
k = InStr(a, "?")
Do While k
Mid$(a, k, 1) = "_"
k = InStr(k + 1, a, "?")
Loop
MaskChars = a
End Function
If meb.Text = MaskChars(meb.Mask) Then
MsgBox "MaskedEditControl is Empty!"
End If
How do I select All items in a multi-select ListBox? How do I invert the selection?
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Const LB_SETSEL = &H185
Private Sub cmdSelAll_Click()
SendMessage List1.hwnd, LB_SETSEL, True, ByVal True
End Sub
Private Sub cmdInvert_Click()
If List1.SelCount Then
SendMessage List1.hwnd, LB_SETSEL, False, ByVal True
Else
cmdSelAll_Click
End If
End Sub
Where can I buy old versions of MS Basic?
How do I pick a random number between 3 and 6?Randomize Timer RandomNum = Int(Rnd * 4) + 3
How do I activate a previous instance when my program is run a second time?
' First, test for a previous instance:
If App.PrevInstance Then
' Then, save the application title:
Dim aTitle As String
aTitle = Me.Caption
' Change this app's title:
Me.Caption = ""
' Activate the app with the title:
AppActivate aTltle
End If
If the caption might not be unique or known, store the caption of the
"running" instance in the Registry, retrieve it with the other instance
and activate that:
If App.PrevInstance Then
Me.Caption = ""
AppActivate GetSetting("ProgramName","SectionName","Instance")
End
Else
SaveSetting "ProgramName", "SectionName", "Instance", Me.Caption
End If
Delete the registry setting when the program exits.
DeleteSetting "ProgramName","SectionName","Instance"
Note that the End statement halts the program immediately, so the
DeleteSetting command won't fire, even if you place it in the Unload
event of a form that is loaded. Make sure you delete the registry setting
before using the End statement.
How do I convert between decimal, hex, and binary?
Dim lDec As Long, aHex As String, aBin As String
lDec = 121
aHex = Hex$(lDec) ' Decimal to Hex
lDec = Val("&H" & aHex) ' Hex to Decimal
' Note that it is easier to convert Hex to Binary, so convert
' from Decimal to Hex first if you need to go from Decimal
' to Binary. The fastest Binary conversion is to use a
' "lookup table".
Dim vBinTable As Variant
vBinTable = Array("0000", "0001", "0010", "0011", _
"0100", "0101", "0110", "0111", _
"1000", "1001", "1010", "1011", _
"1100", "1101", "1110", "1111")
Dim i As Integer, k As Long
For k = 1 To Len(aHex)
' Hex to Binary
i = Val("&H" & Mid$(aHex, k, 1))
aBin = aBin & vBinTable(i)
Next
' It is also easier to convert from Binary to Decimal. However,
' it isn't always feasible - both Hex and Binary in VB can represent
' much larger values than Decimal. Thus, this conversion is from
' Binary to Hex, once again using a lookup table... of a different sort.
Dim aBinTable As String, aHexTable As String
aBinTable = " 0000 0001 0010 0011 0100 0101 0110 0111" & _
" 1000 1001 1010 1011 1100 1101 1110 1111 "
aHexTable = "0123456789ABCDEF"
If Len(aBin) Mod 4 Then
' Make it an even length of 4
aBin = String$(Len(aBin) Mod 4, "0") & aBin
End If
aHex = ""
For k = 1 To Len(aBin) Step 4
i = InStr(aBinTable, " " & Mid$(aBin, k, 4))
aHex = aHex & Mid$(aHexTable, (i - 1) \ 5 + 1, 1)
Next
How do I specify a start-up path for VB?
How do I code a recursive power-of routine?
Function Power(base, exponent)
Power = 1
If exponent Then
Power = Power * base
Power = Power * Power(Power, exponent - 1)
End If
End Function
What is the formula for determinig a leap year?
Function IsLeapYear(D As Date) As Boolean
Dim lYear As Long
lYear = Year(D)
If lYear Mod 400 = 0 Then
IsLeapYear = True
ElseIf lYear Mod 100 = 0 Then
IsLeapYear = False
ElseIf lYear Mod 4 = 0 Then
IsLeapYear = True
End If
End Function
Where can I download VB?
Can I save images as JPEG?
How do I limit the text entry length in a ComboBox?
Private Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Const EM_LIMITTEXT = &HC5
Const GW_CHILD = 5
Private Sub Form_Load()
SendMessage GetWindow(Combo1.hwnd, GW_CHILD), EM_LIMITTEXT, _
5, ByVal 0
End Sub
How do I send email with VB?
Use the MAPI controls:
With MAPISession1
.LogonUI = True
.UserName = "guest"
.Password = "password"
.SignOn
End With
With MAPIMessages1
.SessionID = MAPISession1.SessionID
.Compose
.RecipDisplayName = "yourname@yourisp.com"
.RecipAddress = "yourname@yourisp.com"
.MsgSubject = "Test"
.MsgNoteText = "Did it work?"
.AddressResolveUI = True
.ResolveName
.Send False
End With
MAPISession1.SignOff
How do I retrieve the drive serial number on a peer to peer network volume?
Private Declare Function CloseHandle Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" _
(ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Const INFINITE = -1&
Private Const SYNCHRONIZE = &H100000
Private Sub Form_Load()
Dim aPath As String, aComspec As String
Dim aStr As String, aSerial As String
Dim lTask As Long, lHandle As Long
Dim aShell As String
aPath = App.Path: If Right$(aPath, 1) <> "\" Then _
aPath = aPath & "\"
aComspec = Environ$("COMSPEC")
If aComspec = "" Then aComspec = "command.com"
If Mid$(aPath, 2, 1) = ":" Then aShell = Left$(aPath, 2) & "\"
lTask = Shell(aComspec & " /c dir " & aShell & _
" >" & aPath & "\disk.txt", vbHide)
lHandle = OpenProcess(SYNCHRONIZE, False, lTask)
WaitForSingleObject lHandle, INFINITE
CloseHandle lHandle
Open aPath & "\disk.txt" For Input As 1
aStr = Input$(LOF(1), 1)
Close 1
aSerial = Mid$(aStr, InStr(aStr, "Serial Number is ") + _
Len("Serial Number is "))
aSerial = Left$(aSerial, InStr(aSerial, vbCrLf) - 1)
MsgBox "Volume Serial Number is " & aSerial
Kill aPath & "\disk.txt"
End Sub
How can I get a dialog box with "Yes", "Yes to All", and "No"?
Public frmCaller As Form
In the calling Form's (General)/(Declarations) section, put:
Public lDialogResult As Long
Where you need to call the dialog, use:
Set frmDialog.frmCaller = Me
frmDialog.Show vbModal
Select Case lDialogResult
Case vbYes
Case vbNo
Case -1
End Select
The code for the buttons in frmDialog is:
Private Sub cmdYes_Click()
frmCaller.lDialogResult = vbYes
Unload Me
End Sub
Private Sub cmdNo_Click()
frmCaller.lDialogResult = vbNo
Unload Me
End Sub
Private Sub cmdYesAll_Click()
frmCaller.lDialogResult = -1
Unload Me
End Sub
How do I fix "Object Server" errors when using control custom properties?The message arises when VB iterates through all the components in the system which are classed as controls and finds one which has not been registered correctly, or in a way not understood by VB. This will usually be some other component and not one you normally use in VB. Culprits for introducing such components can include controls created by the VB5 Control Creation Edition, controls installed by Visual Interdev 1 and I believe the ActiveX Control Pad (this happened to me). Usually, you can ignore the error message(s), and use the controls with VB with no problem (and also in Visual Interdev if that was the culprit which introduced the components which cause the error). However, you get this error message for each component that VB cannot understand, so if you have to go through a lot of these messages before the control list is displayed, it is worth fixing this (see details below).
Knowledge Base articles which describe the problem include:
Q161827 (at http://support.microsoft.com/support/kb/articles/Q161/8/27.asp)
Q166681 (at http://support.microsoft.com/support/kb/articles/Q166/6/81.ASP)
These articles recommend using the latest version of REGCLEAN to fix the problem.
I discovered another article about a utility which you can download to specifically fix the problem. This is:
Q196296 (at http://support.microsoft.com/support/kb/articles/Q196/2/96.ASP)
How do I get the MAC address if I know the IP address?
Shell Environ$("COMSPEC") & " /c arp -a >mac.txt", vbHiddenFocus
DoEvents
Dim f As Integer, aMac As String
f = FreeFile
Open "mac.txt" For Input As f
aMac = Input$(Lof(f), f)
Close f
----------- Mac.txt
Interface: 123.45.103.177 on Interface 2
Internet Address Physical Address Type
123.45.100.1 00-a0-c9-6f-99-23 dynamic
123.45.100.2 00-e0-29-05-ce-84 dynamic
123.45.100.16 00-a0-c9-6f-c0-ac dynamic
123.45.100.18 00-a0-c9-6f-df-53 dynamic
123.45.100.65 00-90-27-24-fb-dc dynamic
-----------
How do I evaluate a math string?This article contains an example program that evaluates a numeric expression contained in a string, mimicking the operators, built-in functions, and order of evaluation used by Microsoft Basic language products.
The example program listed below accepts number constants written as decimal numbers with an optional fraction. For example, it accepts "123" and "123.4". It is possible to modify the program to recognize hexadecimal, scientific notation, or other formats.
This example program also recognizes the following functions: ABS, ATN, COS, EXP, FIX, INT, LOG, RND, SNG, SIN, SQR, and TAN.
Steps to Create Example ProgramRun Visual Basic, or from the File menu, choose New Project (press ALT, F, N) if Visual Basic is already running. Form1 will be created by default.
Add a text box (Text1) and a command button (Command1) to Form1.
Delete the text in the Text property of Text1 to make it empty.
Enter the following code in the Command1_Click event procedure:
Private Sub Command1_Click ()
Dim n As Double
If e_eval(Text1.Text, n) Then
MsgBox n
End If
End Sub
Add the following code in the (General)(Declaration) section of Form1:
Dim e_input As String ' Expression input string. Dim e_tok As String ' Current token kind. Dim e_spelling As String ' Current token spelling. Dim e_error As Integer ' Tells if syntax error occurred. ' e_eval ' Evaluate a string containing an infix numeric expression. ' If successful, return true and place result in. ' This is the top-level function in the expression evaluator. Function e_eval (ByVal s As String, value As Double) As Integer ' Initialize. e_error = 0 e_input = s Call e_nxt ' Evaluate. value = e_prs(1) ' Check for unrecognized input. If e_tok <> "" And Not e_error Then MsgBox "syntax error, token = '" + e_spelling + "'" e_error = -1 End If e_eval = Not e_error End Function ' e_prs ' Parse an expression, allowing operators of a specified ' precedence or higher. The lowest precedence is 1. ' This function gets tokens with e_nxt and recursively ' applies operator precedence rules. Function e_prs (p As Integer) As Double Dim n As Double ' Return value. Dim fun As String ' Function name. ' Parse expression that begins with a token (precedence 12). If e_tok = "num" Then ' number. n = Val(e_spelling) Call e_nxt ElseIf e_tok = "-" Then ' unary minus. Call e_nxt n = -e_prs(11) ' Operand precedence 11. ElseIf e_tok = "not" Then ' logical NOT. Call e_nxt n = Not e_prs(6) ' Operand precedence 6. ElseIf e_tok = "(" Then ' parentheses. Call e_nxt n = e_prs(1) Call e_match(")") ElseIf e_tok = "id" Then ' Function call. fun = e_spelling Call e_nxt Call e_match("(") n = e_prs(1) Call e_match(")") n = e_function(fun, n) Else If Not e_error Then MsgBox "syntax error, token = '" + e_spelling + "'" e_error = -1 End If End If ' Parse binary operators. Do While Not e_error If 0 Then ' To allow ElseIf . ElseIf p <= 11 And e_tok = "^" Then Call e_nxt: n = n ^ e_prs(12) ElseIf p <= 10 And e_tok = "*" Then Call e_nxt: n = n * e_prs(11) ElseIf p <= 10 And e_tok = "/" Then Call e_nxt: n = n / e_prs(11) ElseIf p <= 9 And e_tok = "\" Then Call e_nxt: n = n \ e_prs(10) ElseIf p <= 8 And e_tok = "mod" Then Call e_nxt: n = n Mod e_prs(9) ElseIf p <= 7 And e_tok = "+" Then Call e_nxt: n = n + e_prs(8) ElseIf p <= 7 And e_tok = "-" Then Call e_nxt: n = n - e_prs(8) ElseIf p <= 6 And e_tok = "=" Then Call e_nxt: n = n = e_prs(7) ElseIf p <= 6 And e_tok = "<" Then Call e_nxt: n = n < e_prs(7) ElseIf p <= 6 And e_tok = ">" Then Call e_nxt: n = n > e_prs(7) ElseIf p <= 6 And e_tok = "<>" Then Call e_nxt: n = n <> e_prs(7) ElseIf p <= 6 And e_tok = "<=" Then Call e_nxt: n = n <= e_prs(7) ElseIf p <= 6 And e_tok = ">=" Then Call e_nxt: n = n >= e_prs(7) ElseIf p <= 5 And e_tok = "and" Then Call e_nxt: n = n And e_prs(6) ElseIf p <= 4 And e_tok = "or" Then Call e_nxt: n = n Or e_prs(5) ElseIf p <= 3 And e_tok = "xor" Then Call e_nxt: n = n Xor e_prs(4) ElseIf p <= 2 And e_tok = "eqv" Then Call e_nxt: n = n Eqv e_prs(3) ElseIf p <= 1 And e_tok = "imp" Then Call e_nxt: n = n Imp e_prs(2) Else Exit Do End If Loop e_prs = n End Function ' e_function. ' Evaluate a function. This is a helper function to simplify ' e_prs. Function e_function (fun As String, arg As Double) As Double Dim n As Double Select Case LCase$(fun) Case "abs": n = Abs(arg) Case "atn": n = Atn(arg) Case "cos": n = Cos(arg) Case "exp": n = Exp(arg) Case "fix": n = Fix(arg) Case "int": n = Int(arg) Case "log": n = Log(arg) Case "rnd": n = Rnd(arg) Case "sgn": n = Sgn(arg) Case "sin": n = Sin(arg) Case "sqr": n = Sqr(arg) Case "tan": n = Tan(arg) Case Else If Not e_error Then MsgBox "undefined function '" + fun + "'" e_error = -1 End If End Select e_function = n End Function ' e_nxt ' Get the next token into e_tok and e_spelling and remove the ' token from e_input. ' This function groups the input into "words" like numbers, ' operators and function names. Sub e_nxt () Dim is_keyword As Integer Dim c As String ' Current input character. Dim is_id% e_tok = "" e_spelling = "" ' Skip whitespace. Do c = Left$(e_input, 1) e_input = Mid$(e_input, 2) Loop While c = " " Or c = vbTab Or c = vbCr Or c = vbLf Select Case LCase$(c) ' Number constant. Modify this to support hexadecimal, etc. Case "0" To "9", "." e_tok = "num" Do e_spelling = e_spelling + c c = Left$(e_input, 1) e_input = Mid$(e_input, 2) Loop While (c >= "0" And c <= "9") Or c = "." e_input = c + e_input ' Identifier or keyword. Case "a" To "z", "_" e_tok = "id" Do e_spelling = e_spelling + c c = LCase$(Left$(e_input, 1)) e_input = Mid$(e_input, 2) is_id% = (c >= "a" And c <= "z") is_id% = is_id% Or c = "_" Or (c >= "0" And c <= "9") Loop While is_id% e_input = c + e_input ' Check for keyword. is_keyword = -1 Select Case LCase$(e_spelling) Case "and" Case "eqv" Case "imp" Case "mod" Case "not" Case "or" Case "xor" Case Else: is_keyword = 0 End Select If is_keyword Then e_tok = LCase$(e_spelling) End If ' Check for <=, >=, <>. Case "<", ">" e_tok = c c = Left$(e_input, 1) If c = "=" Or c = ">" Then e_tok = e_tok + c e_input = Mid$(e_input, 2) End If ' Single character token. Case Else e_tok = c End Select If e_spelling = "" Then e_spelling = e_tok End If End Sub ' e_match ' Check the current token and skip past it. ' This function helps with syntax checking. Sub e_match (token As String) If Not e_error And e_tok <> token Then MsgBox "expected " + token + ", got '" + e_spelling + "'" e_error = -1 End If Call e_nxt End Sub
Press F5 to run the program. Type an expression into Text1 such as "1+2*3^4". Click Command1.
How do I drag a PictureBox around?
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
lParam As Any) As Long
Const WM_NCLBUTTONDOWN = &HA1
Const HTCAPTION = 2
Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
ReleaseCapture
SendMessage Picture1.hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0
End Sub
How do I launch a Control Panel Applet?Shell "rundll32.exe shell32.dll,Control_RunDLL inetcpl.cpl,,0", 5Control Panel applets are .CPL and are in the \windows\system directory (or winnt\system32).
How do I rank search results?With thanks to Joe Celko.
I wanted to rank my search results and sort them by rank. For instance, if a search word was part of a document title, that would likely have more relevance than a word in the body of a document.
In the database in question (on wugnet.com's site), I have, for instance, a shareware pick of the week table that includes title, "blurb", and body fields. A "blurb" is a short description returned from a search and/or the front page.
A ranking system might be keyword in the:
title, blurb, and body - 100% match
title and blurb - 90%
title and body - 80%
blurb and body - 70%
title - 60%
blurb - 50%
body - 40%
Apparently, Access 97 has the ability to use LIKE in the ORDER BY clause:
SELECT * FROM table ORDER BY title LIKE %VB% DESC
However, SQL Server (and generic SQL) does not have this capability. Fortunately, it has another, better way.
When I create my temporary table of search results, I also create a integer field named "rank". If you aren't using temp tables, then you would create a permanent new field named "rank". SQL's "CASE" statement allows you to dynamically assign rank based on each record:
The above Access 97 order in standard SQL would be:
SELECT *, CASE WHEN title LIKE '%VB%' THEN 1 ELSE 0 END AS rank FROM table ORDER BY rank DESC
For a multi-field ranking, you would use:
SELECT *, CASE WHEN (title LIKE '%VB%' AND blurb LIKE '%VB%' AND body LIKE '%VB%') THEN 100 WHEN (title LIKE '%VB%' AND blurb LIKE '%VB%') THEN 90 END AS rank FROM table ORDER BY rank DESC
Broken down into more readable form, it would be:
SELECT *,
CASE
WHEN (title LIKE '%VB%' AND
blurb LIKE '%VB%' AND
body LIKE '%VB%') THEN 100
WHEN (title LIKE '%VB%' AND
blurb LIKE '%VB%') THEN 90
END AS rank
FROM table ORDER BY rank DESC
How do I upload files to an ASP page using VBScript?There are a lot of companies out there trying to sell ActiveX objects for uploading files to Active Server Pages. However, it's really quite simple to write a bit of VBScript to handle the uploads for yourself. The Request object has all the uploaded data.
<!--
HTML for the upload form
'uploadform.html'
-->
<html><body>
<form action="upload.asp" method="post" enctype="multipart/form-data">
<input type=file name="file1" size=20><br>
<input type=file name="file2" size=20><br>
<input type=submit>
</body></html>
<!--
ASP Code for the upload
'upload.asp'
-->
<html><body>
<%
' This code is needed to "initialize" the retrieved data
Dim q
q = Chr(34)
' All data
Dim aAllDataB, aAllData, x, aHdr
aAllDataB = Request.BinaryRead(Request.TotalBytes)
' It comes in as unicode, so convert it to ascii
For x = 1 To LenB(aAllDataB)
aAllData = aAllData & Chr(AscB(MidB(aAllDataB, x, 1)))
Next
' The "header" is a unique string generated by the system to indicate
' the beginning and end of file data
aHdr = Left(aAllData, Instr(aAllData,vbCrLf)+1)
%>
<%
' Here's where your code goes.
' In this example, "file1" and "file2" are the field names
' specified within the form of the upload submission page.
Response.Write "file1: Filename = " & GetFilename("file1") & "<br>"
Response.Write GetFileData("file1") & "<br><br>"
Response.Write "file2: Filename = " & GetFilename("file2") & "<br>"
Response.Write GetFileData("file2") & "<br><br>"
' Writing out the file data like this only looks okay when
' the uploaded file is some kind of text - images and things
' like that probably just need to be saved or otherwise
' acted upon.
Response.Write Replace(aAllData,vbCrLf,"<br>")
Dim aFilename
' aFilename equates to the original filename, except saved
' in the root path of the server. The root path must have
' Change rights for the default internet user.
aFilename = Server.MapPath("\") & "\" & GetFileName("file1")
Call SaveFile("file1", aFilename)
aFilename = Server.MapPath("\") & "\" & GetFileName("file2")
Call SaveFile("file2", aFilename)
%>
</body></html>
<%
' These are functions used to retrieve the data
Function GetFileName(aField)
Dim x2, i
x = Instr(aAllData, aHdr & "Content-Disposition: form-data; name=" & q &
aField & q)
x = Instr(x, aAllData, "filename=" & q)
x2 = Instr(x, aAllData, vbCrLf)
For i = x2 To x Step -1
If Mid(aAllData,i,1) = "\" Then
x = i - 9
Exit For
End If
Next
GetFileName = Mid(aAllData, x+10, x2-(x+11))
End Function
Function GetFileData(aField)
Dim x2
x = Instr(aAllData, aHdr & "Content-Disposition: form-data; name=" & q &
aField & q)
x = Instr(x, aAllData, vbCrLf)
x = Instr(x+1, aAllData, vbCrLf)
x = Instr(x+1, aAllData, vbCrLf) + 2
x2 = Instr(x, aAllData, Left(aHdr,Len(aHdr)-2))
GetFileData = Mid(aAllData, x+2, x2-x-4)
End Function
Function SaveFile(aField, aFilename)
Dim FSO, TS
Set FSO = server.CreateObject("Scripting.FileSystemObject")
Set TS = FSO.CreateTextFile(aFilename, True, False)
TS.Write GetFileData(aField)
TS.Close
Set TS = Nothing
Set FSO = Nothing
End Function
%>
How do I restrict mouse movement to one area of my Form?The ClipCursor API function allows you to define a screen coordinate rectangle and restrict mouse cursor movements to that area.
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function ClipCursor Lib "user32" Alias "ClipCursor" _
(lpRect As Any) As Long
Private Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" _
(ByVal hwnd As Long, lpRect As RECT) As Long
Dim r As RECT
GetWindowRect Frame1.hWnd, r ' Restrict movement to control Frame1
ClipCursor r
To restore the cursor movement to the full screen:
ClipCursor ByVal 0
How do I show ToolTipText on each ListBox item?You must use the MouseMove event to modify the ToolTipText of the entire control based on the Index that the mouse is currently over:
Const LB_GETITEMHEIGHT = &H1A1
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Private Sub List1_MouseMove(Button As Integer, Shift As Integer, _
X As Single, Y As Single)
Static bSet As Boolean, lPrevIndex As Long
Dim lY As Long, lHeight As Long, lIndex As Long
lY = Y \ Screen.TwipsPerPixelY
lHeight = SendMessage(List1.hWnd, LB_GETITEMHEIGHT, 0, ByVal 0)
lIndex = lY \ lHeight + List1.TopIndex
If Not bSet Or lPrevIndex <> lIndex Then
bSet = True
lPrevIndex = lIndex
' Set the tooltiptext to whatever you need for each index.
' Here I'm just setting it to the item's text.
List1.ToolTipText = List1.List(lIndex)
End If
End Sub
How do I center a ListView item?Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, lParam As Any) As Long
Private Const LVM_FIRST = &H1000
Private Const LVM_SCROLL = (LVM_FIRST + 20)
Private Sub CenterSelectedItem()
Dim LI As ListItem, lCenterPos As Long, _
lSelTop As Long, lNumToScroll As Long
Set LI = ListView1.GetFirstVisible
lCenterPos = (ListView1.Height - LI.Top) \ 2
lSelTop = ListView1.SelectedItem.Top
lNumToScroll = ((lSelTop - lCenterPos) \ (LI.Height))
If lNumToScroll < 0 Then lNumToScroll = lNumToScroll - 1
lNumToScroll = lNumToScroll * Screen.TwipsPerPixelY
SendMessage ListView1.hwnd, LVM_SCROLL, 0, ByVal lNumToScroll
ListView1.SetFocus
End Sub
How do I edit Office document properties?
How do I emulate a ComboBox in HTML
<html><body>
<form name='test'>
<input type=text size=20 name='tex' onKeyUp='HandleIt(this)'><br>
<select name='sel' size=4>
<option value='Number 1'>Number 1</option>
<option value='Anything'>Anything</option>
<option value='Writing'>Writing</option>
</select>
</form>
<script>
function HandleIt(txt) {
var i;
var a = ""
a = txt.value;
a = a.toUpperCase();
if (a.length == 0) {
document.test.sel.selectedIndex = -1;
return;
}
var b = "";
for (i=0; i<document.test.sel.length; i++) {
b = document.test.sel[i].value;
b = b.toUpperCase();
if (b.substr(0,a.length) == a) {
document.test.sel.selectedIndex = i;
return;
}
}
}
</script>
</body></html>
How do I know when to use ByVal, ByRef, As Any, etc... in API functions?
Declare Function SystemParametersInfo Lib "user32" Alias _
"SystemParametersInfoA" (ByVal uAction As Long, _
ByVal uParam As Long, ByVal lpvParam As Any, _
ByVal fuWinIni As Long) As Long
The lpvParam variable is declared ByVal lpvParam As Any, which
is impossible. The correct declaration is:
Declare Function SystemParametersInfo Lib "user32" Alias _
"SystemParametersInfoA" (ByVal uAction As Long, _
ByVal uParam As Long, lpvParam As Any, _
ByVal fuWinIni As Long) As Long
without the ByVal keyword. Note that without ByVal, the
ByRef keyword is assumed. Unknown variable types can only
by passed ByReference.Okay, so what does it mean? When any variable except a variable length string (Dim aStr As String) is passed ByVal, the value of the variable is passed rather than a pointer to the value of the variable. In general, only Long Integer variables are passed ByVal. The exception is variable length strings. They must always be passed ByVal. If you are ever returning information into a variable length string, then it must be pre-allocated. That is, you must fill it with spaces.
Dim aStr As String, lBufSize As Long
lBufSize = 1024
aStr = Space$(lBufSize)
It is unlikely you will ever pass a blank string. If the procedure asks for a
NULL string, that's very different from a blank string. This passes a BLANK
string:
Call Something("")
While these pass a NULL string:
Call Something(vbNullString)
Call Something(ByVal 0)
A blank string passes a valid pointer to a blank string, while vbNullString
passes a "null pointer", or Ascii 0.Back to ByVal and ByRef - you must use ByRef (except for variable length strings again) anytime you must pass a Type structure or whenever a value is going to be saved to the variable that is passed. Some function declarations in the Win32api.txt file specify a Type structure in the parameter list. However, VB forces you to then use that Type structure anytime you call the function, and there are times you might want to pass a NULL instead. For example, the InvalidateRect API function has the parameter lpRect As RECT. If you want to invalidate the entire window, you can pass a NULL, but VB's declare doesn't let you. So what you do is declare the function differently:
Declare Function InvalidateRect Lib "user32" Alias "InvalidateRect" _
(ByVal hwnd As Long, lpRect As Any, _
ByVal bErase As Long) As Long
To pass a NULL to any variable declared ByRef (remember, the ByRef
is assumed if ByVal is not specified), then use ByVal 0:
InvalidateRect hWnd, ByVal 0, True
As you see, you can specify ByVal (and ByRef) on the function
call line, overriding the Declare setting. Note that if I'd used this:
InvalidateRect hWnd, 0, True
then the ByRef is assumed, and the 0 "variable" is passed as a
valid pointer to a temporary variable containing the value of "0". Thus what
I would actually be passing is a valid Long Integer pointer instead
of a NULL (or for that matter, instead of a valid RECT structure).
To summarize - use ByVal to pass most Long Integers and all Variable Length Strings. If you need to return a value in the variable or if you need to pass a Type structure, then use ByRef.
How do I determine what operating system is running?
How do I connect to another computer via the Internet for a chat application?
How do I store multiple files, such as an entire web site, in a single file?
' General / Declarations section
Private Type IdxType
Filename As String
Length As Long
Pointer As Long
End Type
' *** Save a bunch of files to a single file ***
' First, gather the filenames
Dim NumIndex As Long, aFile As String, aPath As String
aPath = "c:\pathtopages\"
aFile = Dir$(aPath & "*.*")
Do While Len(aFile)
NumIndex = NumIndex + 1
aFile = Dir$
Loop
ReDim Idx(1 To NumIndex) As IdxType
NumIndex = 0
aFile = Dir$(aPath & "*.*")
Do While Len(aFile)
NumIndex = NumIndex + 1
Idx(NumIndex).FileName = aPath & aFile
aFile = Dir$
Loop
' Next, save the index information so that
' the pointers will be accurate.
Dim aDat As String
Open "website.dat" For Binary As 1
Put 1,,NumIndex
Put 1,,Idx()
' Then combine into a single file, saving
' the pointer and length information as you go.
Dim k As Long
For k = 1 To NumIndex
Idx(k).Pointer = Loc(1) + 1
Open Idx(k).FileName For Binary As 2
Idx(k).Length = Lof(2)
aDat = Space$(Lof(2))
Get 2,,aDat
Close 2
Put 1,,aDat
Next
' Finally, save the full index. The NumIndex variable
' is a Long Integer, so the index info starts at position
' 5 (VB uses a base 1 on files).
Put 1,5,Idx()
Close 1
' *** To retrieve the information, first load the index.
Dim NumIndex As Long, aDat As String
Open "filename.dat" For Binary As 1
Get 1,,NumIndex
ReDim Idx(1 To NumIndex) As IdxType
Get 1,,Idx()
' Then search for the page you want and recreate it.
' Note that the path is saved with the filename - you can
' modify the filename gathering code so that it is easier
' to retrieve the file to a different location.
Dim k As Long
For k = 1 To NumIndex
If Idx(k).FileName = "filename.jpg" Then
aDat = Space$(Idx(k).Length)
Get 1,Idx(k).Pointer,aDat
Open Idx(k).Filename For Binary As 2
Put 2,,aDat
Close 2
Exit For
End If
Next
Close 1
Where can I find documentation on Windows API calls?
How do I make my program run when Windows starts?
Private Const READ_CONTROL = &H20000
Private Const STANDARD_RIGHTS_READ = (READ_CONTROL)
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_NOTIFY = &H10
Private Const SYNCHRONIZE = &H100000
Private Const STANDARD_RIGHTS_WRITE = (READ_CONTROL)
Private Const KEY_SET_VALUE = &H2
Private Const KEY_CREATE_SUB_KEY = &H4
Private Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or _
KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
Private Const KEY_WRITE = ((STANDARD_RIGHTS_WRITE Or KEY_SET_VALUE Or _
KEY_CREATE_SUB_KEY) And (Not SYNCHRONIZE))
Private Const HKEY_LOCAL_MACHINE = &H80000002
Private Const ERROR_SUCCESS = 0&
Private Const REG_SZ = 1 ' Unicode nul terminated string
Private Declare Function RegCloseKey Lib "advapi32.dll" _
(ByVal hKey As Long) As Long
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias _
"RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, _
ByVal ulOptions As Long, ByVal samDesired As Long, _
phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias _
"RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, _
ByVal lpReserved As Long, lpType As Long, lpData As Any, _
lpcbData As Long) As Long
Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias _
"RegSetValueExA" (ByVal hKey As Long, ByVal lpValueName As String, _
ByVal Reserved As Long, ByVal dwType As Long, lpData As Any, _
ByVal cbData As Long) As Long
The following code will create the registry entry:
Dim hKey As Long, aData As String, lSize As Long
If RegOpenKeyEx(HKEY_LOCAL_MACHINE, _
"software\microsoft\windows\currentversion\run", 0, _
KEY_WRITE, hKey) = ERROR_SUCCESS Then
aData = "c:\mypath\myprogram.exe"
lSize = Len(aData)
If RegSetValueEx(hKey, "MyApp", 0, REG_SZ, ByVal aData, _
lSize) = ERROR_SUCCESS Then
MsgBox aData & " written"
End If
RegCloseKey hKey
End If
The following code will read the registry entry:
Dim hKey As Long, aData As String, lType As Long, lSize As Long
If RegOpenKeyEx(HKEY_LOCAL_MACHINE, _
"software\microsoft\windows\currentversion\run", 0, KEY_READ, _
hKey) = ERROR_SUCCESS Then
lSize = 128
aData = Space$(lSize)
If RegQueryValueEx(hKey, "MyApp", 0, lType, ByVal aData, _
lSize) = ERROR_SUCCESS Then
If lSize Then
aData = Left$(aData, lSize - 1)
MsgBox aData & " read"
End If
End If
RegCloseKey hKey
End If
How do I show the "Open With" dialog?
Private Sub Form_Load()
MsgBox Command$
End
End Sub
that would display the command line and compiled it to Rundll32.exe. I tried
replacing the system executable on my Windows 2K system, but Microsoft's
security won't allow it - every time you delete or rename that system file,
Windows restores it. So I switched to my Windows 98 system and tried it there.
Bingo, worked the first time, and I have the command line parameters needed
to display the "Open With" dialog:
Shell "rundll32 shell32.dll,OpenAs_RunDLL c:\temp\filename.ext"
How do I add Chat to my website?
How do I reference a UserControl from its subclassing module?
How do I get started with C++?