View Full Version : VB How To:
ainwood Jul 01, 2002, 10:40 AM The aim of this thread is to include code demonstrating "how to" do various things in VB (or VBA at a stretch). People who know how to program in VB, please contribute (code snippets and pointing out bugs. When pointing out bugs, please do it via PM).
I suggest that short code snippets be posted as text, longer ones posted as attachments.
If anyone has any "how do I ...." type questions, please post them.
And as a starter:
How do I time how long it takes to run code?
There are two (easy) methods. Firstly, you can use the VB "Timer" function.
Dim sgl_StartTime as single
Dim sgl_EndTime as single
sgl_StartTime = Timer
'------------------------------
'Code to time goes here
'------------------------------
sgl_EndTime = Timer
msgbox "Time taken = " & sgl_EndTime - sgl_StartTime & " Seconds."
This will only give you resolution to the nearest second, which is often not that useful for code optimisation. A "better" method is to use a Windows timer function. You will need to declare this function to use it:
Public Declare Function timeGetTime Lib "winmm.dll" () As Long
Dim lng_StartTime as Long
Dim lng_EndTime as Long
lng_StartTime = TimeGetTime
'------------------------------
'Code to time goes here
'------------------------------
lng_EndTime = TimeGetTime
msgbox "Time taken = " & lng_EndTime - lng_StartTime & " milliseconds."This code will (usually) give you millisecond resultion (you can actually interrogate windows to find the actual resolution, but that can be the subject of further code!
CornMaster Jul 01, 2002, 11:01 AM As a moderate VB programmer....I'm happy to contribute. :D
Here are some VERY simple examples: (Most of my other advanced code is from help from other sources. ;))
How To Make a Command Button Enabled ONLY it there is text present in a text box.
Instructions:
Create a text box called Text1, and a Command Button called Command1.
Properties:
Set Command1 Enabled to False
Private Sub Text1_Change()
If Text1.Text = "" Then
Command1.Enabled = False
Else:
Command1.Enabled = True
End If
End Sub
How To Create Blinking Text/Controls.
Instructions:
Create a Label called Label1. Create a Timer called Timer1.
Properties:
Set Timer1 Interval to 1000 (That is a blink every second or whatever interval you want)
If Label1.Caption = "" Then
Label1.Caption = "Welcome To My Blink Program!"
ElseIf Label1.Caption = "Welcome To My Blink Program!" Then
Label1.Caption = ""
End If
Note....This will make the text on the label blink.
To make the entire label blink:
If Label1.Visible = True Then
Label1.Visible = False
ElseIf Label1.Visible = False Then
Label1.Visible = True
End If
I'm also working on a scrolling text control....but that is much more complicated that I thought. :(
ainwood Jul 02, 2002, 02:31 AM To highlight all the text within a textbox when the user clicks on it or tabs to it.
Put a textbox called "TextBox1" on a form. Put the following code
in the forms' private module:
Sub TextBox1_GotFocus()
With TextBox1
.SelStart = 0
.SelLength = Len(.Text)
End With
End Sub
This won't work in VBA, as MSForms Textbox's don't appear to have a GotFocus event.
Instead, you will have to put code the code in for both the "mousedown" event (to capture when the user clicks on the box) and the "Enter" event (to capture the user tabbing to the box).
Private Sub TextBox1_Click()
With TextBox1
.SelStart = 0
.SelLength = Len(.Text)
End With
End Sub
Private Sub TextBox1_MouseDown(ByVal Button As Integer, _
ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
With TextBox1
.SelStart = 0
.SelLength = Len(.Text)
End With
End Sub
ainwood Jul 03, 2002, 06:44 AM How to: Check whether a file exists.
The most common way to do this is with the built-in VB DIR() function. This function returns the name of the file at a specific path, and you then need to check the returned string to see if it what you wanted.
Using the windows API, it is easy to set up a function to simply return a boolean indicating whether a file exists or not:
Public Const INVALID_HANDLE_VALUE = -1
Public Const MAX_PATH = 260
Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Public Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * MAX_PATH
cAlternate As String * 14
End Type
Public Declare Function FindFirstFile Lib "kernel32" _
Alias "FindFirstFileA" (ByVal lpFileName As String, _
lpFindFileData As WIN32_FIND_DATA) As Long
Public Declare Function FindClose Lib "kernel32" _
(ByVal hFindFile As Long) As Long
Public Function FileExists(strFileName As String) As Boolean
Dim WFD As WIN32_FIND_DATA
Dim API_ReturnHandle As Long
API_ReturnHandle = FindFirstFile(strFileName, WFD)
If API_ReturnHandle <> INVALID_HANDLE_VALUE then
FileExists = True
Else
FileExists = False
End If
Call FindClose(API_ReturnHandle)
End Function
Note that in this example, the String variable passed should be the full filename and path of the file you are checking.
Once you have included this code in a .bas file somewhere, the function can then be easily called:
eg. boolCheck = FileExists("C:\Windows\Win.Ini")
CornMaster Jul 03, 2002, 08:53 AM Whoa....whoa...whoa....
There is a much simpler way to check if a file or folder exists!
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FolderExists("C:\cesplaylists\") Then
Msgbox "Folder Exists.", vbinformation, "Folder Exists"
else
Msgbox "Folder Does Not Exist.", vbcritical, "Folder Does Not Exist"
End if
To do it with a file instead of a folder:
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists("C:\cesplaylists\playlist.lst") Then
Msgbox "File Exists.", vbinformation, "File Exists"
else
Msgbox "File Does Not Exist.", vbcritical, "File Does Not Exist"
End if
ainwood Jul 08, 2002, 02:06 AM How to: Retrieve the user's name.
If you want to get the name of the logged-in user, it can be done quite easily. Again, you have to call a function from the windows API, so you need to decalre it first.
Public Declare Function GetUserName Lib "advapi32.dll" _
Alias "GetUserNameA" _
(ByVal lpBuffer As String, _
nSize As Long) As Long
Public Function ReturnUserName() As String
Dim strName As String
strName = Space$(512)
GetUserName strName, Len(strName)
ReturnUserName = Trim$(strName)
End Function
When you want to get the user's name, just call the "ReturnUserName" function, and it will return it to s tring variable.
ainwood Jul 10, 2002, 05:16 AM This code is an algorithm for a "QuickSort". It allows a (one-dimensional) array of values to be passed to it, and it will return the values in sorted order, from smallest to largest.
Public Function QuickSort(InputArray As Variant, _
Optional iLowBound As Variant, Optional iUpBound As Variant)
'The Optional parameters are needed, because the recursive part of the function
'passes different lower and upper bounds to use for the sorting process. Note that
'the IsMissing function only works for variant data types!
'Declare variables to hold the lower and upper bounds of the array
'to be sorted.
Dim iLowerBound As Integer
Dim iUpperBound As Integer
'Check whether the lower and upper bounds have been passed.
'If so, store them in the declared variables. If no, set them
'to the actual upper and lower bounds of the array.
If IsMissing(iLowBound) Then
iLowerBound = LBound(InputArray)
Else
iLowerBound = iLowBound
End If
If IsMissing(iUpBound) Then
iUpperBound = UBound(InputArray)
Else
iUpperBound = iUpBound
End If
'Declare variables to hold actual array values for sorting
Dim X As Double
Dim Y As Double
'Declare variables to hold the current array elements to check.
Dim iLower As Integer
Dim iUpper As Integer
'Set the variables to start from the lower and upper bounds
'respectively.
iLower = iLowerBound
iUpper = iUpperBound
'Set the initial array value to sort as the middle value.
X = InputArray((iLowerBound + iUpperBound) / 2)
'Now start the algorithm. Iterate until the lower array index
'being checked is equal to the upper.
While (iLower <= iUpper)
'Find the first value greater than X (the middle value),
'starting at the beginning of the array.
While (InputArray(iLower) < X And iLower < iUpperBound)
iLower = iLower + 1
Wend
'Find the first value less than X (the middle value),
'starting at the end of the array.
While (X < InputArray(iUpper) And iUpper > iLowerBound)
iUpper = iUpper - 1
Wend
'Check whether the values are "in order" - ie the larger one
'is later in the array than the smaller one. If not, swap them.
If (iLower <= iUpper) Then
'Store the larger value
Y = InputArray(iLower)
'Write the smaller one on top of the larger one.
InputArray(iLower) = InputArray(iUpper)
'Put the larger value where the smaller one was.
InputArray(iUpper) = Y
'A swap has been made. The following allows the Wend loop
'to exit, if the middle two values were swapped, and carry
'on if any other values were swapped.
iLower = iLower + 1
iUpper = iUpper - 1
End If
Wend
'This function must be iterated again, as all that has been done on the
'first run-through is to compare values with the middle value. You
'therefore have to iterate again. This requires you to iterate with the
'"unsorted" parts of the array.
If (iLowerBound < iUpper) Then QuickSort InputArray, iLowerBound, iUpper
If (iLower < iUpperBound) Then QuickSort InputArray, iLower, iUpperBound
End Function
Sub TestIt()
'This code allows the user to test the above algorithm.
Dim aAnArray(25) As Double
Dim i As Integer
For i = 1 To 25
aAnArray(i) = (Rnd() * 10) + 1
Next i
For i = 1 To 25
Debug.Print aAnArray(i)
Next i
Debug.Print "--------------------------------------------"
Call QuickSort(aAnArray)
For i = 1 To 25
Debug.Print aAnArray(i)
Next i
End Sub
CornMaster Jul 10, 2002, 08:59 AM Here is a question for you. :)
Actually....two.
1) How can I delete the first letter of a textbox (or variable) and record that letter to a variable.
2) How can I make two web browser controls "mirror" each other. This means that when you go somewhere in one....it automatically displays it in the other too.
:)
ainwood Jul 11, 2002, 02:30 AM Originally posted by CornMaster
Here is a question for you. :)
Actually....two.
1) How can I delete the first letter of a textbox (or variable) and record that letter to a variable.
This is one that I can do! You can use the "left", "right" and "len" functions.
Dim sTextString As String
Dim sFirstLetter As String
'Get text from textbox.
sTextstring = txtText1.text
'Extract first letter.
sFirstLetter = left(sTextString,1)
'Now delete the first letter from the original text string.
sTextString = Right(sTextString, Len(sTextString) - 1)
:)
Originally posted by CornMaster
2) How can I make two web browser controls "mirror" each other. This means that when you go somewhere in one....it automatically displays it in the other too.
:) :confused: Beats me! I've never worked with web browser controls. Maybe someone else browsing here can help?
The only thing I can think of is whether there is some form of _Change event that you can use in one to drive the other.
eg - something of the form:
Private Sub WebBrowser1_change()
WebBrowser2.WebAddress = webBrowser1.WebAddress
End Sub
ainwood Jul 18, 2002, 02:28 AM This post I will be appending to occasionally. The idea is to list some little idiosyncracies of VB, and show how to work around them.
1. Overflow in multiplication.
The following code will generate an overflow error:
Sub MultiplyIt()
Dim lngProduct As Long
lngProduct = 24 * 3600
msgbox lngProduct
End Sub
Why does this happen? A long variable type can store any integer value between -2,147,483,648 and 2,147,483,647. The product here is only 86400, so it should be able to be stored in the lngProduct variable, right?
The problem is that VB will calculate the product, store it in a temporary variable, then assign "lngProduct" to be equal to that temporary variable. This is where the problem lies: VB looks at the data types being multiplied, and sees that they are both of "integer" data type. It therefore creates the temporary variable of integer type to hold the result of the multiplication. Because an integer data type can only hold values from -32,768 to 32,767, the product is too large for the temporary variable, and the overflow is generated.
So how do you get around this? All you need to do is force VB to create the temporary varible as a "long". This can be done by "declaring" the value of "24" and the value of "3600" to be of Long type. To do this, just append an ampersand to the numbers:
Sub MultiplyIt()
Dim lngProduct As Long
lngProduct = 24& * 3600&
msgbox lngProduct
End Sub
The amersand tells VB that it is multiplying two "long" numbers, rather than two integers, so it creates the correct temporary variable.
ainwood Jul 24, 2002, 02:55 AM A short one this time: How to change the desktop wallpaper via code:
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" _
(ByVal uAction [color=blue]As Long, _
ByVal uParam As Long, _
ByVal lpvparam As String, _
ByVal fuWinIni As Long) As Long
Const SPIF_Updateinifile = &H1
Const spi_SetDeskWallpaper = 20
Const spif_SendWinIniChange = &H2
Sub ChangeTheWallPaper()
Dim L
L = SystemParametersInfo(spi_SetDeskWallpaper, 0&, "c:\apps\gi desktop.bmp", SPIF_Updateinifile Or spif_SendWinIniChange)
End Sub
Simply change the "c:\apps\gi desktop.bmp" to the appropriate pathname of the new wallpapaer. :)
starlifter Jul 24, 2002, 08:01 AM This is a cool thread. I don't post much to it because I don't do a lot of VB programming (or really much of any programing) at the moment. But it is very good to read!!!!
ainwood Jul 30, 2002, 04:37 AM In a VB function, you can declare an argument to be “optional”. This can be very useful for such things as letting the user supply an initial estimate.
When using an “Optional” variable, you can use the IsMissing function to determine whether or not the user has actually specified the optional value or not.
However, one problem with VB is that this IsMissing function only works for Variant data types. For any other data type, it automatically returns “False” for the IsMissing call.
For Example:
Function Check(Optional sDefaultString As String)
If IsMissing (sDefaultString) Then
sDefaultString = "Hello"
End If
Debug.Print sDefaultString
End Function
Sub CallIt()
Call Check
' Call Check("Goodbye")
End Sub
The code above has the Optional argument specified as a string. If the above code is run with the first line commented-out, it will result in “goodbye” being written to the debug window (as expected). However, if the second line is commented out (as shown above), then an empty string will be written to the debug window instead – the IsMissing call will go to the “false” case, even though the optional parameter has not been passed.
This can be “solved” in two ways. Firstly, the optional parameter can be specified as a Variant data type (declare it as variant, or don’t specify the data tyep – it will default to variant).
The other (more elegant) option is to specify the default value in the declaration line:
Function Check(Optional sDefaultString As String = “Hello”)
Debug.Print sDefaultString
End Function
The whole "IsMissing" funciton is a bit of a hang-over from earlier versions of visual basic, where optional parameters could not have default values, and had to be variant data types anyway. It is probably "better" not to use IsMissing, but if you do, the above is an issue that you should be aware of. ;)
damunzy Jul 30, 2002, 11:06 AM Cool thread...this is all above my head as I have just started learning VB (haven't really learned much besides how to operate the program itself....but I will get there someday). Got some really basic stuff to help guys like me out or would that be better handled in a different thread?
ainwood Aug 02, 2002, 08:18 AM You are probably all aware of the Macro virus protection built-in to M$ Office products. If you try and open a document with Macros, you are presented with the little dialog asking you if you want to enable or disable them, or not open the document at all.
What you may not realise, is that this macro protection only appears to work when the document is opened by double-clicking on it, or via the file / open procedure from the main application. This macro protection is circumvented if you open a file via OLE.
For example: Create a word document called “C:\Virus.doc”. In a code module for this document, add the following code:
Private Sub Document_Open()
MsgBox "Bingo!"
End Sub
In a VB application (or even Excel for example), put the following code:
Sub openword()
Dim oWordDoc [color=blue]As Object
Set oWordDoc = CreateObject("word.application")
oWordDoc.Visible = True
oWordDoc.documents.Open ("C:\virus.doc")
End Sub
When you run this code, you will see that the code quite happily opens the document and triggers the Document_Open macro.
This behaviour appears to exist with both Office ’97 and Office 2000.
ainwood Aug 06, 2002, 06:30 AM The following code will allow you to check whether a number provided is a valid credit-card number. Note that it will not tell you whether the expiry date matches or not, but it may be useful for a first check.
This function returns a simple “true” if the number is valid as a credit card number, or “false” if it is not. Note that that number must be passed to the function as a string.
Private Function IsValid(strCardNumber As String) As Boolean
Dim iCharPos As Integer
Dim iCheckSum As Integer
Dim strCharCheck As String
For iCharPos = Len(strCardNumber) To 2 Step -2
iCheckSum = iCheckSum + CInt (Mid(strCardNumber, iCharPos, 1))
strCharCheck = CStr ((Mid(strCardNumber, iCharPos - 1, 1)) * 2)
iCheckSum = iCheckSum + CInt (Left(strCharCheck, 1))
If Len(strCharCheck) > 1 Then
iCheckSum = iCheckSum + CInt(Right(strCharCheck, 1))
End If
Next iCharPos
If Len(strCardNumber) Mod 2 = 1 Then
iCheckSum = iCheckSum + CInt (Left(strCardNumber, 1))
End If
If iCheckSum Mod 10 = 0 Then
IsValid = True
Else
IsValid = False
End If
End Function
P.S. PH - A "Basics" thread is a good idea. I may try and start one later in the week / next week. :)
ainwood Aug 08, 2002, 03:38 AM If you have an array of values, and you want to set them all to zero, a lot of people simply loop through each item of the array, and set it to zero.
There is a much easier way of achieving the same thing, using the Erase Function.
Sub EraseArray()
Dim aTestArray(1000) As Long
Dim i As Integer
'Fill array with values
For i = 0 To 100
aTestArray(i) = i
Next i
'Now erase it.
Erase aTestArray
'Check that values are all "0"
For i = 0 To 100
Debug.Print aTestArray(i)
Next i
End Sub
If your array is a dynamic one, you can clear it by the Erase method, or by redimensioning it.
Sub EraseArray()
Dim aTestArray() As Long
[color=blue]Redim aTestArray(100) As Long
Dim i As Integer
'Fill array with values
For i = 0 To 100
aTestArray(i) = i
Next i
'Now erase it.
ReDim aTestArray(100)
'Check that values are all "0"
For i = 0 To 100
Debug.Print aTestArray(i)
Next i
End Sub
I recently came across an interesting method for clearing out a block of array values. Say you have an array of 10,000 values, and you want to set the values from 8000 to 9000 to zero, you can do this by directly setting the values in memory to zero.
Private Declare Sub ZeroMemory Lib "kernel32" Alias "RtlZeroMemory" _
(Destination As Any, ByVal Length As Long)
Function ClearArray()
Dim i As Integer
' Declare an array and fill it with data
Dim aTestArray(10000) As Long
For i = 0 To UBound (aTestArray)
aTestArray(i) = i
Next i
'Clear the elements from 8000 to 9000 (1001 elements) to zero
ZeroMemory aTestArray(8000), 1001 * Len (aTestArray(0))
'Check a couple of elements:
For i = 7998 To 8002
Debug.Print "Item " & i & " = " & aTestArray(i)
Next i
For i = 8998 To 9002
Debug.Print "Item " & i & " = " & aTestArray(i)
Next i
End Function
Note: This function requires that the amount of memory allocated to each array element is constant. Therefore, it will not work with variant arryas that contain variable-length strings, nor with string arrays with variable-length strings. In both cases, it will case a General Protection Fault - Save your project before you run it!
Note that it works on the amount of memory allocated to each array item, not what the actual array contains. Long, single, integer, double etc are all allocated a fixed amount of memory, regardless of what they contain. Ie – in a long array, the element storing the value “3” is allocated the same amount of memory as the element containing the value “28569”.
ainwood Aug 15, 2002, 05:43 AM Some code requires specific version of windows (especially ones looking for specific registry keys for example). The following code will return a string variable telling you which version of windows the code is being run on. :)
Public Declare Function GetVersionExA Lib "kernel32" _
(lpVersionInformation As OSVERSIONINFO) As Integer
Public Type OSVERSIONINFO
dwOSVersionInfoSize As Long
dwMajorVersion As Long
dwMinorVersion As Long
dwBuildNumber As Long
dwPlatformId As Long
szCSDVersion As String * 128
End Type
Function GetOS() As String
[color=blue]Dim osVer As OSVERSIONINFO
osVer.dwOSVersionInfoSize = Len(osVer)
Dim lngAPIReturn As Long
lngAPIReturn = GetVersionExA(osVer)
If lngAPIReturn = 0 Then
'Call failed
Debug.Print "Failed API call."
Exit Function
End If
Dim strOS As String
Select Case osVer.dwPlatformId
Case 1
Select Case osVer.dwMinorVersion
Case 0
strOS = "Win95"
Case 10
strOS = "Win98"
Case 90
strOS = "Win ME"
End Select
Case 2
Select Case osVer.dwMajorVersion
Case 3
strOS = "WinNT 3.51"
Case 4
strOS = "WinNT 4.0"
Case 5
Select Case osVer.dwMinorVersion
Case 0
strOS = "Windows 2000"
Case 1
strOS = "Windows XP"
End Select
End Select
End Select
strOS = strOS & ", " & osVer.szCSDVersion
GetOS = strOS
End Function
darkwarpblade Aug 19, 2002, 11:55 PM Hey, I was just wondering if you know how to make file from code, MSDN seems to compliced.
CornMaster Aug 20, 2002, 03:13 PM Originally posted by darkwarpblade
Hey, I was just wondering if you know how to make file from code, MSDN seems to compliced.
You mean a text file?
OR like an .ini file format?
Or a picture file?
What kind of file excatly.
darkwarpblade Aug 21, 2002, 08:28 PM I can't figure out how to make any kind, though custom(like a saved gamed) would be nice to know.
CornMaster Aug 21, 2002, 10:28 PM Well....I know how to make plain text. ASCII text. And .ini file format.
I use it for all different things.
I even created my own file format for a word processor.
It's really easy to write text files.
Essentially you create the file, and then print text to in line by line. Or you can print entire controls or variables. This can be used as a saved game if you structure it right.
Here is an example I use:
Open "C:\test.txt" For Output As #1
Print #1, "Hello"
Print #1, "This is my new text file"
Print #1, text1 'this prints the contents of a text box to the file
Print #1, 'Empty Line
Close #1 ' This closes the file (must be done to save memory.
ainwood Aug 22, 2002, 05:56 AM Following on from Corn's info on how to print to a text file, I decided to post how to read from / write to an .ini file.
.ini files were what early versions of windows and other software programs used instead of the registry that many use now. They are still quite useful for data storage on a small-scale.
An .ini file is made up of sections and keys. Each section is indicated via a square bracket around it, and each key is listed under these section headings, in the format "keyname=keyvalue".
Here is an example of what one may look like (it is stored as plain text):
;
;Note to user: DO NOT ALTER OR DELETE THIS FILE.
;
[SMS Inventory Identification]
Version=1.0
[Product Specification]
Product=Windows 2000 Professional
Version=5.0
Localization=English
ServicePackNumber=0
BitVersion=40
[Version]
DriverVer=11/14/1999,5.00.2183.1
There are various windows functions that can be used for maintenance of these files. You can read in individual values or entire sections, and write values or sections.
The following code is used to read a value from a given key in a given section of a given .ini file:
Private Declare Function GetPrivateProfileString _
Lib "kernel32" Alias "GetPrivateProfileStringA" _
(ByVal lpSectionName As String , _
ByVal lpKeyName As Any , _
ByVal lpDefault As String , _
ByVal lpReturnedString As String , _
ByVal nSize As Long , _
ByVal lpFileName As String )
As Long
Public Function GetKey(SectionName As String, KeyName As String, _
Inifile As String) As String
'Retrieves a value from an ini file corresponding
'to the section and key name passed.
Dim Success As Long
Dim nSize As Long
Dim ret As String
Dim Defaultvalue As String
Defaultvalue = "Not Found"
'call the API with the parameters passed.
'The return value is the length of the string
'in ret, including the terminating null. If a
'default value was passed, and the section or
'key name are not in the file, that value is
'returned. If no default value was passed (""),
'then success will = 0 if not found.
'Pad a string large enough to hold the data.
ret = Space$(2048)
nSize = Len(ret)
Success = GetPrivateProfileString(SectionName, KeyName, _
Defaultvalue, ret, nSize, Inifile)
If Success Then
GetKey = Left$(ret, Success)
End If
End Function
To write a new value to the file, use the following:
Private Declare Function WritePrivateProfileString _
Lib "kernel32" Alias "WritePrivateProfileStringA" _
(ByVal lpSectionName As String, _
ByVal lpKeyName As Any, _
ByVal lpString As Any, _
ByVal lpFileName As String) As Long
Function WriteKey(SectionName As String, KeyName As String, _
NewValue As String, Inifile As String)
Dim Success As Long
Success = WritePrivateProfileString(SectionName, KeyName, NewValue, Inifile)
WriteKey = Success
End Function
Another useful function is the one to delete an entire section:
Function DeleteSection(SectionName As String, Inifile As String)
WritePrivateProfileString SectionName, _
vbNullString, vbNullString, Inifile
End Function
You can modify the functions to give a return value to let you know if the operation was a success or not.
darkwarpblade Aug 23, 2002, 06:41 AM Thanks. I never did get that stuff.
apiaster Aug 24, 2002, 11:38 AM Hi, can anyone tell me how to build a webpage with Visual Basic (such as with DHTML or any other means ?) My problem is, whenever I build a webpage (ex with DHTML,) it will always create a supporting .dll or .ocx or .exe (a supporting exe not a really executable file, you still run it from the HTML document) Free websites do not support dll's etc. Also you will need to tell the person that owns the server to actually activate the .dll in its new location (by typing regsvr32 documentname.dll)
Thanks in advance
ainwood Aug 28, 2002, 02:32 AM Originally posted by apiaster
Hi, can anyone tell me how to build a webpage with Visual Basic (such as with DHTML or any other means ?) My problem is, whenever I build a webpage (ex with DHTML,) it will always create a supporting .dll or .ocx or .exe (a supporting exe not a really executable file, you still run it from the HTML document) Free websites do not support dll's etc. Also you will need to tell the person that owns the server to actually activate the .dll in its new location (by typing regsvr32 documentname.dll)
Thanks in advance
To be honest, I've never created a web-page. However, you can write a webpage in normal HTML that supports VBscript (instead of using Java as the scripting language). This may limit you to what web-browers can 'read' the page - I'm not sure if the latest netscape or the likes of opera support vbscript.
I've seen some examples of vbscript, and it is very similar to VB, so the learning curve may not be great.
I don't know whether this requires "support" files though.
Do a seach on google or similar for vbscript tutorial.
Here (http://www.intranetjournal.com/corner/wrox/progref/vbt/ch21_15.shtml) is an example tutorial, and you can see that the concepts are pretty easy. :)
Hurricane Sep 04, 2002, 06:48 AM I am making a form and have run into some problems.
There are several rows in the form, and the user has the possibility to add rows if he wants to (with a macro). Some rows have combo boxes or check boxes in them, and problems occur when these are copied. All contents and formatting works ok, but the new control boxes are exact copies of the original controls. That is, if you copy the formula C2+D2 one row down it will change to C3+D3, but the combo box will still have the SAME cell references as the original combo box. :mad:
So what I´m asking is how to make the new control unique (I guess the new control should be given a new name, now it's name is the same as the original) and how to make its cell references to point one row down from the original's?
Thanks in advance for any help. :)
ainwood Sep 05, 2002, 01:41 AM Is this in VB or VBA?
Maybe if you post your code it would help. :)
GaryNemo Sep 05, 2002, 10:20 PM Cornmaster asked, How can I make two web browser controls "mirror" each other. This means that when you go somewhere in one....it automatically displays it in the other too.
Try using Javascript. There is probably an onChange event that you could use to run a little script... In JavaScript, beware of your capitaliZation! You could perhaps just as easily use VBScript.
apiaster asked about building a dynamic webpage. I agree, dll's are a pain. Lots of hosts have enabled the .asp suffix. Try uploading your htm file, same thing exactly, as an .asp file (test.htm = test.asp). If it runs from a browser, you've got an asp interpreter!
The detailed answer to both of these questions can probably be found on Google. Whenever I need some new code, that I can't cut/paste from stuff I've already done, I just search Google.
Typical search: +asp +date +format
Or even cut/paste the error message! The amount of detailed solutions and examples out there is simply amazing!
Welcome to the Next Generation.
Hurricane Sep 06, 2002, 12:44 AM Originally posted by ainwood
Is this in VB or VBA?
Maybe if you post your code it would help. :)
VBA.
The problem is of course that I don´t have any code. :o I´m not very familiar with programming controls in VBA, so after having tried without success for a few hours, I decided to bypass the entire problem by removing the combo boxes totally.
My very simple solution now is to instead have a number of rows hidden from the start, and let the user make them visible by clicking on a button. This is the code:
Private Sub ButtonChecker()
Dim RowNumber As Integer
Select Case Application.Caller
Case "button 1"
RowNumber = 31
Do While Rows(RowNumber).EntireRow.Hidden = False
RowNumber = RowNumber + 1
Loop
If RowNumber >= 41 Then
MsgBox ("Only 10 rows available")
Else
ActiveSheet.Unprotect
Rows(RowNumber).EntireRow.Hidden = False
ActiveSheet.Protect
End If
Case "button 2"
' And so on...
I.e. the macro puts the cursor at that button's first hidden row, and then unhides one. If all rows already are visible, a message box pops up.
ainwood Sep 07, 2002, 04:58 AM Well, good that you got it working! :)
Yes, Excel does strange things with embedded controls. You will find that any "new" controls are given a new name with a sequential number on the end - you could actually use the new name to change any cell references etc. You could detect the new one by creating a collection of the old ones, and enumerating all the controls to identify the new one when its created.
BTW - it looks like you used controls from the "forms" toolbar, rather than the "control toolbox" toolbar. They are actually slightly different - the "Control Toolbox" ones are better to use with VBA, whereas the forms ones are easier to use if you don't want to have to write macros. :)
Hurricane Sep 09, 2002, 06:17 AM Originally posted by ainwood
Well, good that you got it working! :)
Yes, Excel does strange things with embedded controls. You will find that any "new" controls are given a new name with a sequential number on the end - you could actually use the new name to change any cell references etc. You could detect the new one by creating a collection of the old ones, and enumerating all the controls to identify the new one when its created.
BTW - it looks like you used controls from the "forms" toolbar, rather than the "control toolbox" toolbar. They are actually slightly different - the "Control Toolbox" ones are better to use with VBA, whereas the forms ones are easier to use if you don't want to have to write macros. :)
Any good tutorials on how to use the "control toolbox" controls out there?
ainwood Sep 09, 2002, 06:31 AM Do a search on google or other for some. I found one here. (http://www.vbatutor.com/vbatutor.htm)
If you have any problems, just let me know. I learnt just by reading other peoples' source code, and trying to learn what code does what action.
If you have any specific examples of what you want to do with excel (for example), then let me know and I can probably write you some code that you can study. :)
Hurricane Sep 09, 2002, 09:31 AM Thanks. That's how I have learned VB, too. Bump into some problem, search for other peoples solutions to similar problems and adapt it to your own problem. :)
ainwood Sep 19, 2002, 12:59 AM Here are a couple of basic functions for converting Longs to Hexadecimal and vice-versa. May be useful if you want to write utility editors etc ;)
Function LongToHex(lngLong as Long) as string
LongToHex = Hex$(lngLong)
End Function
Function HexToLong(strHex As String) as Long
HexToLong = CLng("&H" & strHex)
End Function
ainwood Sep 19, 2002, 09:35 AM Along a similar line, if you want to work with singles and doubles, it is a bit more difficult. The "easiest" way to convert "Hex" into a single etc, may actually be to just read the binary data into a variable.
For example, a "single" data type occupies 4 bytes. If you therefore read 4 bytes of data from a binary file into a variable declared as a "single", then the "conversion" has already happened.
Eg:
'Write a "single" value to a binary file.
Sub WriteIt()
Dim i As Long
i = FreeFile
Dim sglPI As Single
sglPI = 3.141592
Open "C:\apps\hex.bin" For Binary As i
Put i, , sglPI
Put i, , sglPI
Close i
End Sub
The above code simply writes two single variable to a data file. Open it with a Hex Write a "single" value to a binary file. If you now open the file with a Hex Editor, you will see that the Hex is:
D8 0F 49 40 D8 0F 49 40
Now, you want to read this back in. To illustrate the point a bit better, I will give the code to read in the second value. To do this, you just use the "Get" function, and tell it which byte to start reading from:
'Read a "single" value from a binary file.
Sub ReadIt()
Dim i As Long
i = FreeFile
Dim sglPI As Single
Open "C:\apps\hex.bin" For Binary As i
Get i, 5, sglPI
Close i
Debug.Print sglPi
End Sub
If you want to convert it the "harder" way (ie - convert a hex "string", you need to use a clever trick. You can't just use the CSng() function. Instead, you have to read the Hex into a Byte array, and then "copy" that memory onto a single variable type. This is done with user-defined types, so that the LSET function can be used.
Private Type DummySingle
Output As Single
End Type
Private Type HexBytes
TheBytes(0 To 3) As Byte
End Type
Function HexToSingle(strHex As String) As Single
'declare a byte array
Dim bytHex [color=blue]As HexBytes
Dim i As Integer
For i = 0 To 3
bytHex.TheBytes(i) = CByte("&H" & Mid(strHex, i * 2 + 1, 2))
Next i
Dim sngOutput As DummySingle
LSet sngOutput = bytHex
HexToSingle = sngOutput.Output
End Function
King of Camelot Sep 20, 2002, 10:59 PM I'm teaching myself VB a small step at a time and I can't figure out what is wrong with this code. Everything works but the part that is supposed to change the units type. The msgbox doesn't come up and the scalemode type doesn't change. Does anyone know what I'm doing wrong?
Dim Unit As String
-----------------------------------------------------
Private Sub Command2_Click()
If Unit = "Units" Then
MsgBox , "Please choose a units type."
End If
If Unit = "Pixels" Then
Form1.Main.ScaleMode = 3
End If
If Unit = "Inches" Then
Form1.Main.ScaleMode = 5
End If
If Unit = "Centimeters" Then
Form1.Main.ScaleMode = 7
End If
If Unit = "Millimeters" Then
Form1.Main.ScaleMode = 6
End If
Form1.Main.Width = Text1.Text
Form1.Main.Height = Text2.Text
Form1.Main.Enabled = True
Form1.Main.Visible = True
Unload Form2
End Sub
-----------------------------------------------------
Private Sub Command3_Click()
Unload Form2
End Sub
-----------------------------------------------------
Private Sub Timer1_Timer()
Unit = Combo1.SelText
Text1.Text = VScroll1.Value
Text2.Text = VScroll2.Value
End Sub
ainwood Sep 23, 2002, 01:40 AM One way of making your code easier to debug is to ensure that you declare all your variables in a set way. You put "i" as a prefix on integers, "cmd" as a prefix on command buttons, "cmb" as a prefix on a combo box etc.
For a bit more info to help your debugging, what is "unit"?
When you have the line 'if Unit = "Units" then', the compiler automatically looks at the default property for the object of "unit" type. If "unit" is a textbox, then that line is fine. If it is a combobox or something else, it may not work.....
I normally put the object property in even if it is the default property.
Eg. If Unit.Text = "Units" then...
Note that VB is case-sensitive. If the entered text is units rather than Units, it will not run the "true" clause.
Ooops - reading further, I see that "unit" is combo1.seltext.
the .seltext returns or sets the selected text of the control. Basically, all this does is highlight the text, as if you'd run your cursor over it!
When using comboboxes, its much easier to just work with the ListIndex of the control - in your case, this will do away with the need to have all the if statements, and the timers - you probably don't even need to command_button, if you use the _Change event for the combobox:
Private sub combo1_change()
Select case combo1.listindex
case 0
'it hasn't been changed
case 1
'pixels
Form1.Main.ScaleMode = 3
case 2
'Inches
Form1.Main.ScaleMode = 5
case 3
'Centimeters
Form1.Main.ScaleMode = 7
case 4
'Millimeters
Form1.Main.ScaleMode = 6
case else
end select
Form1.Main.Width = Text1.Text
Form1.Main.Height = Text2.Text
Form1.Main.Enabled = True
Form1.Main.Visible = True
Cartouche Bee Sep 23, 2002, 04:18 PM King of Camelot,
Another good thing to do besides ainwood's advice is to learn about the debugger. Then you can step through the code and see how the variables change or set breakpoints so you can find out when certain things are actually taking place. Learning the various ways that objects interact with each other will take you a long way toward understanding how to orchestrate the events that occur in your code. ;)
Hurricane Sep 24, 2002, 12:46 AM Ok, now I have a new question. This time I want to create a macro in MS WORD 97 that each time the document is opened increments a number by 1. This is my try at the code:
Sub Auto_open()
Dim orderNum As Integer
Selection.GoTo What:=wdGoToBookmark, Name:="myBm"
orderNum = Val(ActiveDocument.Bookmarks("myBm").Value) + 1
Selection.Delete Unit:=wdCharacter, Count:=1
Selection.InsertAfter orderNum
ActiveDocument.Bookmarks.Add Range:=Selection.Range, _
Name:="myBm"
End Sub
The selection and repacement of the bookmark works, but I only got it working for text. The .Value doesn't apparently work with the bookmarks property. :confused:
The bookmark myBm must of course be created before running the macro.
ainwood Sep 24, 2002, 01:45 AM Can I take it that you are trying to go to a bookmark that is a number, read it, increment it by one, and then write the value back?
The problem is that a bookmark is defined to be of "text" type, and doesn't have a "value" property. What you need to do is select the bookmark text, and convert that text to an integer.
Sub Auto_open()
Dim orderNum As Integer
Selection.GoTo What:=wdGoToBookmark, Name:="mybm"
ActiveDocument.Bookmarks("mybm").Select
orderNum = CInt(Selection.Text) + 1
Selection.Delete Unit:=wdCharacter, Count:=1
Selection.InsertAfter orderNum
ActiveDocument.Bookmarks.Add Range:=Selection.Range, _
Name:="mybm"
End Sub
:)
Hurricane Sep 24, 2002, 03:00 AM Great! Thanks a bunch, ainwood! :)
I really got frustrated with this one. You see, Microsoft had an example on the MSDN pages which used Autotext entries to do the thing, but it ended in an overflow error after a few tries. :mad: I mean, what kind of developers are that!
This solution is much simpler and more elegant. :)
ainwood Sep 24, 2002, 05:02 AM For reference, an "overflow" error occurs when you try to put a value into a variable of the wrong type. For example, an "integer" type can hold a maximum value of 32767. If you try and put a number greater than this into an integer data type, you get an "overflow". :)
CornMaster Sep 27, 2002, 10:47 PM ainwood.
Please check your PM's about my offer. Also, how did you format your code before to include proper vb colors :confused:
Also, I've created a replacement for the Common Dialog box. It includes saving and opening abilities and uses all native controls so it doesn't require any extra runtimes.
Here is the code if you want to browse it. :)
And I'll upload the form shortly. It's basically complete. Unless I or anyone else finds a problem.
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''
' This Form Created By: Thomas Hawkins, CornEmpire Software
' This can be used freely.
'
' Common Dialog Replacement for Open and Save Functions v1.0
' Also includes a prompt if a file exists and will be overwritten
'
' To use in your program you must call the form and then the
' style you want displayed.
' For an open file box:
' opendialog.Show
' opendialog.opendialogbox
'
' For a Save Box:
' opendialog.Show
' opendialog.savedialogbox
'
' This formats the buttons for the style you need.
'
' You will also have to configure the file types, patterns
' and open/save code
'
' *For Form_Load you will enter the default pattern and sellected
' option in the combo box. Then add all other options for the
' combo box.
' *For Combo1_Click you will need to list the patterns for each
' item added to the combo box on form load IN ORDER.
' *For openfile and savefile subs...this is where you type
' your open and save code. It will be used by the form when
' needed.
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''
Public strfilename As String, strfilepath As String, strsavefilename As String
Dim pathcheck
Private Sub openfile()
'Code to open file goes here
MsgBox strfilepath
End Sub
Private Sub savefile()
'Code to save file goes here
MsgBox strfilepath
End Sub
Public Sub opendialogbox()
opendialog.location.Caption = "Select Location"
opendialog.filetype.Caption = "Open File of Type:"
opendialog.Caption = "Open File"
opendialog.Command1(0).Caption = "Open"
opendialog.filename.Locked = True
opendialog.filelist.SetFocus
opendialog.file_name.Caption = "File Path"
End Sub
Public Sub savedialogbox()
opendialog.location.Caption = "Select Location"
opendialog.filetype.Caption = "Save File as Type:"
opendialog.Caption = "Save File"
opendialog.Command1(0).Caption = "Save"
opendialog.filename.Locked = False
opendialog.filename.SetFocus
opendialog.file_name.Caption = "Save as File Name:"
End Sub
Private Sub pathchecker()
' Checks the paths to the files to insure no double \\'s
' will be present
pathcheck = Dirlist.List(Dirlist.ListIndex)
pathcheck = UCase(pathcheck) ' Converts drive to upper case
If Command1(0).Caption = "Save" Then
If pathcheck = "A:\" Or pathcheck = "B:\" Or pathcheck = "C:\" Or pathcheck = "D:\" Or pathcheck = "E:\" Or pathcheck = "F:\" Or pathcheck = "G:\" Or pathcheck = "H:\" Or pathcheck = "I:\" Or pathcheck = "J:\" Or pathcheck = "K:\" Or pathcheck = "L:\" Or pathcheck = "M:\" Or pathcheck = "N:\" Or pathcheck = "O:\" Or pathcheck = "P:\" Or pathcheck = "Q:\" Or pathcheck = "R:\" Or pathcheck = "S:\" Or pathcheck = "T:\" Or pathcheck = "U:\" Or pathcheck = "V:\" Or pathcheck = "W:\" Or pathcheck = "X:\" Or pathcheck = "Y:\" Or pathcheck = "Z:\" Then
strfilepath = Dirlist.List(Dirlist.ListIndex) & filename.Text
Else
strfilepath = Dirlist.List(Dirlist.ListIndex) & "\" & filename.Text
End If
ElseIf Command1(0).Caption = "Open" Then
If pathcheck = "A:\" Or pathcheck = "B:\" Or pathcheck = "C:\" Or pathcheck = "D:\" Or pathcheck = "E:\" Or pathcheck = "F:\" Or pathcheck = "G:\" Or pathcheck = "H:\" Or pathcheck = "I:\" Or pathcheck = "J:\" Or pathcheck = "K:\" Or pathcheck = "L:\" Or pathcheck = "M:\" Or pathcheck = "N:\" Or pathcheck = "O:\" Or pathcheck = "P:\" Or pathcheck = "Q:\" Or pathcheck = "R:\" Or pathcheck = "S:\" Or pathcheck = "T:\" Or pathcheck = "U:\" Or pathcheck = "V:\" Or pathcheck = "W:\" Or pathcheck = "X:\" Or pathcheck = "Y:\" Or pathcheck = "Z:\" Then
strfilepath = Dirlist.List(Dirlist.ListIndex) & filelist.List(filelist.ListIndex)
Else
strfilepath = Dirlist.List(Dirlist.ListIndex) & "\" & filelist.List(filelist.ListIndex)
End If
End If
End Sub
Private Sub Combo1_Click()
'load file patterns based on item selected. ListIndex = "0"
'is the first item in the combo box. ListIndex = "1" is the
'second item, etc.
'These Indices are loaded on form load under "Load All File Types"
If Combo1.ListIndex = "0" Then
filelist.Pattern = "*.html;*.htm"
ElseIf Combo1.ListIndex = "1" Then
filelist.Pattern = "*.*"
End If
End Sub
Private Sub command1_Click(Index As Integer)
If Index = "0" Then
If Command1(0).Caption = "Open" Then
strfilename = filelist.List(filelist.ListIndex)
pathchecker
openfile
ElseIf Command1(0).Caption = "Save" Then
strsavefilename = filename.Text
pathchecker
'Checks to see if file exists, and prompts to overwrite
Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists(strfilepath) Then
If MsgBox("File Already Exists. Overwrite?", vbYesNo Or vbCritical, "File Exists") = vbYes Then
savefile
End If
Else
savefile
End If
End If
ElseIf Index = "1" Then
Unload opendialog
End If
End Sub
Private Sub Dirlist_Change()
filelist.Path = Dirlist.Path
End Sub
Private Sub Drivelist_Change()
Dirlist.Path = Drivelist.Drive
End Sub
Private Sub filelist_Click()
'On Open writes path to filename box. On save, writes file name
'to filename box.
If file_name.Caption = "File Path" Then
pathchecker
filename.Text = strfilepath
ElseIf file_name.Caption = "Save as File Name:" Then
filename.Text = filelist.List(filelist.ListIndex)
End If
End Sub
Private Sub Form_Load()
'load default file pattern/Type
filelist.Pattern = "*.html;*.htm"
Combo1.Text = "Webpages (*.html;*.htm)"
'Load All File Types
Combo1.AddItem "Webpages (*.html;*.htm)"
Combo1.AddItem "All Files (*.*)"
End Sub
ainwood Sep 28, 2002, 03:13 AM Corn,
Yep got it :D
You may want to edit you code above - its making this page rather wide :lol:.
re the colour formatting, I wrote some code that just parses the text and converts it to put the little {color=XXX} {/color} tags into the code. It doesn't work properly, so I then have to edit it a bit. I'll post it when I get back to work. Have you ever used PretyCodePrint?? It basically lets you print your code on a colour printer, plus links the For/next & If/then loops. I think you can download it at www.vbcity.com???
P.S. Like your common dialog :)
CornMaster Sep 28, 2002, 08:11 AM Nice Site. I'm going to check it out.
I downloaded a program that converts a VB file to HTML.
Going to be useful for the new resource page. :D
ainwood Oct 23, 2002, 04:20 AM Haven't had much time lately to add to this thread.
Firstly, some news! I have joined Cornmaster at "CornEmpire software". Haven't yet been able to add anything to his site yet, but come visit it (the link is in my sig :) )
Anyway, here's some code to retrieve the temporary directory:
Private Declare Function GetTempPathA Lib "kernel32" _
(ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Public Function GetTempPath() As String
Dim lngSize As Long
Dim strTemp As String
Dim lngLength As Long
strTemp = Space$(256)
lngSize = Len(strTemp)
lngLength = GetTempPathA(lngSize, strTemp)
GetTempPath = Left(strTemp, lngLength)
End Function
P.S. Corn - can you edit your sub above to decrease the width of this page :lol:
funxus Oct 30, 2002, 06:28 AM We have a lan at home, and I thought that it would be a good idea to make a program that connects the two computers. It maps drives, I can shut down the other computer and other useful/less useful stuff. I also tried to see if I got send whatever is in the clipboard to the other computer's clipboard, and it works perfect as long as the clipboard contains text. I solved the pictureproblem by saving the picture to a file and copy it to the other computer where I load it into the clipboard, which only works if the drives are mapped. Do you know any good way to send a picture (IPictureDisp) or any other class through a winsock connection.
I downloaded an example from a VB site where I could send files through winsock connections, splitting it up in chunks before sending, but I would like to transfer the picture without saving it as a file at all.
Grateful for any help:)
ainwood Nov 01, 2002, 07:28 AM Sorry, Haven't done anything like this before. If you have some sample code, I would be interested in having a look at it though :)
funxus Nov 02, 2002, 10:52 AM This is the way I do it now, I haven't tested it very much though:
Computer A:
SavePicture Clipboard.GetData(), "copypic.bmp"
FileCopy "copypic.bmp", "j:\clas\copypic.bmp"
ws.SendData "ok"
Computer B:
Dim pic As IPictureDisp
ws.GetData s
if s = "ok" then
Set pic = LoadPicture("c:\clas\copypic.bmp")
Clipboard.SetData pic
end if
As I said I have a codesample that splits the file and send it in bytes, but I still have to save it as a file. Apparently I can't send data of the type "object" with winsock.:)
funxus Nov 14, 2002, 12:20 PM If you're in to APIs you probably like to use BitBlt, but there is a VB version of this function called PaintPicture. It's a method in Picturebox, form and Printer objects and paints a part of or the whole picture in another object.
object.PaintPicture picture, x1, y1, width1, height1, x2, y2, width2, height2, opcode
Object: The object to paint the new picture in
Picture: Source picture, from a form, picturebox
x1, y1: Indicates the coordinates where to start painting the new picture
width1, height1: New picture's size. Should be omitted unless you want to resize the picture.
x2, y2: Coordinates in source picture where to start clipping the picture
width2, height2: Size of the clip from source picture.
opcode: Bitwise operations performed on the picture before painting it. E.g. vbSrcCopy, vbMergeCopy, SrcAnd
The scalemode property determines what units to measure in. E.g. points, pixels, twips, mm
destinationpic.PaintPicture sourcepic, 35, 40,10 ,15 , 0, 5, 20, 30, vbSrcAnd
This command will copy a picture from sourcepic to destinationpic. A square starting at x45 and y40 in sourcepic with the size w10 and h15 will be copied to fill a square starting at x0 and y5 in destinationpic with the size w20 and h30. The new picture will be twice as large as the old picture (20/10 and 30/15).
Opcodes can only be used with bitmaps. The opcode in this example will paint the new picture by taking a point from the source and add it to the destination with the operator AND.
11110000
10101010AND
10100101
The default opcode is SrcCopy, which paints the new picture exactly the same as the source picture.
I hope this is clear enough:)
CornMaster Nov 17, 2002, 12:04 PM Just wanted to promote my site. I added a new tutorial today. Bring the total to 3. With one custom form, and one tip.
Visit there. And e-mail any tips, files or tutorials you would like added!
http://cornempire.newezone.com
ainwood Nov 18, 2002, 10:43 AM Originally posted by CornMaster
Just wanted to promote my site. I added a new tutorial today. Bring the total to 3. With one custom form, and one tip.
Visit there. And e-mail any tips, files or tutorials you would like added!
http://cornempire.newezone.com
:goodjob: :)
ferenginar Nov 22, 2002, 07:51 AM 1) How to set up a progress bar in excel
Set up a userform "ProgressBar" with too labels on to of each other, lbFixed and lbindicate.
Add the following code to the form
Sub pcProgress(pcTitle As String, iPercent As Integer)
ProgressBar.Caption = pcTitle
lbIndicate.Width = iPercent / 100 * lbFixed.Width
DoEvents
End Sub
From main module
'Start progress Bar
for myValue = 1 to 10,000
ProgressBar.Show vbModeless
PartComplete = Int(myValue * 100 / 10,000)
TempTitle = "Current Progess"
ProgressBar.pcProgress TempTitle, PartComplete
' other code goes here
Next myValue
unload ProgressBar
' As the form is loaded vbModeless then the rest of the code will continue to execute. Label lbIndicate grows in width as myValue increases until it covers lbFixed. The form is then unloaded.
2) Use of Status bar
If you are using application.screenupdating = false to speed up your code then you might try using the status bar to keep the user informed.
application.statusbar = "Your Message"
don't forget to end sub with
application.statusbar = false
to return control to the program
ferenginar
ainwood Dec 04, 2002, 11:06 AM How to automatically select the text in a textbox when a user clicks in it:
Put the following code in the "GotFocus" event of a textbox (called "txtMyText"
Sub txtMyText_GotFocus()
txtMyText.SelStart = 0
txtMyText.SelLength = Len(txtMyText.text)
End Sub
ainwood Dec 17, 2002, 04:55 AM Some windows API calls require that you pass the handle of calling object as a parameter. However, in VBA the handle is not a standard property of an object. So what do you do?
If you want the handle to something, you can simply pass its caption to the FindWindow API. Very easy!
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Sub UserForm_Initialize()
DimlngFormHwnd As Long
lngFormHwnd = FindWindow(vbNullString, Me.Caption)
End Sub
You may even find a use for this approach in VB (getting the handle to a command button maybe?:)
greyghost Feb 01, 2003, 10:30 PM I have a few questions.
1) Is there any way to load compressed images into a VB Resource file (JPEG, GIF... files)
2) How do you get a form to be a specific shape?
I'd appreciate any help I can get!
ainwood Feb 10, 2003, 11:24 PM Re the compressed formats, it can be done, but I believe that you need a custom control.... Basically, these formats are licensed, so MS doesn't ship controls that support them - you need to pay. Not completely sure, so perhaps you can have a look on the web. :)
Getting a form to be a specific shape is do-able, but requires the use of the windows API. I'm being a bit lazy here in not giving sample code, but you can see some sample code (with comments in french :mischief: here (http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_20124209.html) :)
CornMaster Feb 12, 2003, 06:21 PM Hey...you are still alive. How come you haven't been on MSN. :p
Sirp Feb 17, 2003, 04:01 AM I have a question: In VB, how do I tell if an array is empty?
-Sirp.
ainwood Feb 18, 2003, 06:07 PM Sirp,
It really depends on what sort of array you are working with....
If you are working with a string array, it is do-able in a clever - but fast - manner. If you're not, then it is doable, but a bit slower.
Basically, for any array, just loop through from the lower bound to the upper bound and test each value.
Eg:
Private Function CheckArray(vArray() As Variant) As Boolean
Dim vTest As Variant
For Each vTest In vArray
If (vTest <> 0) Then
CheckArray = False
Exit Function
End If
Next vTest
CheckArray = True
End Function
For stringarrays, you can use the join function to check it a bit faster...
Private Function CheckStringArray(sArray() As String) As Boolean
Dim sTotal As String
sTotal = Join(sArray, "")
If Len(sTotal) = 0 Then
CheckStringArray = True
Else
CheckStringArray = False
End If
End Function
These functions will both return "true" for an empty array, false otherwise. :) I haven't tried it on control or object arrays though....
Sirp Feb 19, 2003, 02:48 AM ainwood: that's how to test if all the members of an array are empty values. I want to know if the array doesn't have any items in it at all.
i.e. code equivalent to empty() for a container in C++. Not code equivalent to
find_if(v.begin(),v.end(),identity)
in C++, like you've shown....
(apologies if you don't happen to know C++, but that's what I program in, I've just got this annoying VB code I have to interface with a COM object I wrote and it's driving me insane!)
-Sirp.
Cartouche Bee Feb 19, 2003, 11:05 AM Sirp, you should be able to use 'sizeof' to determine if any space has been allocated to the array. HTH.
Sirp Feb 19, 2003, 03:00 PM Cartouche Bee: sizeof? Is that a VB Function? What's the syntax for using it?
-Sirp.
Cartouche Bee Feb 19, 2003, 04:11 PM Originally posted by Sirp
Cartouche Bee: sizeof? Is that a VB Function? What's the syntax for using it?
-Sirp.
Ooops, I thought you were asking for C++, sizeof() could be used for C.
You can use the LBound and Ubound functions in VB to determine how many elements are in an array (you will get a trappable error at this point if the array is indeed empty with no elements, and that is rather strange for VB). If the array is truely empty (from erasing?) you will get an error if you try to access it (lets say the LBound element). Trapping the error would then be the way to determine if your array is empty.
Are you passing the array to the Com Object?
If you need a more specific solution for a particular problem, maybe PM me.
ainwood Feb 19, 2003, 04:50 PM CB is right - you can check for an uninitialised array by checking the Ubound, and then trapping the error. If an error is raised (err.number = 9) then the array is not initialised. Stupidity of VB not to have that function, but.... :rolleyes:
One special case is if you use a variant data type to hold the array: - you can then redimension the variable as an array, and use the IsEmpty function:
Sub testit()
Dim aArray As Variant
If IsEmpty(aArray) Then
Debug.Print "Empty"
Else
Debug.Print "Initialised"
End If
ReDim aArray(3) As Variant
aArray(3) = "s"
If IsEmpty(aArray) Then
Debug.Print "Empty"
Else
Debug.Print "Initialised"
End If
End Sub
Problem being that you are then using variants, so its not as efficient. Note too, that in the initial declaration, you must declare it as a variable only, not a variant array!
For the trappable error thingy:
Sub testit()
Dim aArray() As String
Debug.Print IsArrayEmpty(aArray)
ReDim aArray(5) As String
aArray(3) = "s"
Debug.Print IsArrayEmpty(aArray)
End Sub
Function IsArrayEmpty(InputArray As Variant) As Boolean
On Error GoTo ErrorHandler
If UBound(InputArray) Then
'An empty array will generate an error
End If
'else - no error so it is not populated!
IsArrayEmpty = False
Exit Function
ErrorHandler:
IsArrayEmpty = True
End Function
Note that as soon as you give an array dimensions (ie from the redim above), it becomes 'initialised', with all elements set to the default data type (eg 0 for numeric arrays, an empty string for string arrays etc). Not sure how the C++ works.
You may also want to check out the LenB function - it is as close to the C / C++ SizeOf function as you are ever going to get with VB ;)
Sirp Feb 20, 2003, 05:16 AM eek! So much code to tell if an array is empty! :) But thanks...it seems to work! Although my code just ended up having an 'isEmpty' flag.
CB: hmm....sizeof() wouldn't work in C or C++ either, since you can't have an empty array in C or C++. In fact a popular idiom to ensure a type is complete in C++ is
char type_not_fully_defined[sizeof(sometype)]
is sometype is complete, the code will compile fine and type_not_fully_defined will be optimized away since it's not referenced. If sometype is incomplete, then sizeof(sometype) is zero, making the array definition illegal, and the compiler will propagate an error, hopefully including the variable name, giving the programmer a clue as to what the problem is.
This is used to see if a type is complete before calling delete on that type for instance.
Of course, the C++ equivalent to VB arrays is the standard vector class template, but, you don't use sizeof() to find if one of them is empty either: you use the empty function.
-Sirp.
Cartouche Bee Feb 20, 2003, 09:35 AM Sirp, you a 100% correct, I normally just think of the root of an array as a pointer, so my answer was over simplified. An unassigned pointer is set to null, which essentially is an empty array in most languages. Of course you can't point to a size 0 buffer, that would be a bug. :)
Sirp Feb 20, 2003, 03:11 PM CB: well if you're using a dynamic/pointer-based array, you can't use sizeof to find the size of the array either....
char* ptr = NULL;
sizeof(ptr); //returns the size of a pointer, 4 on intel
sizeof(*ptr); //returns the same as sizeof(char) which is 1
But, I rarely use dynamic arrays directly in C++. It's far too unsafe, using standard containers normally, and builtin arrays when the speed is really necessary is far better imo.
-Sirp.
Cartouche Bee Feb 20, 2003, 05:00 PM Originally posted by Sirp
CB: well if you're using a dynamic/pointer-based array, you can't use sizeof to find the size of the array either....
either?
You can use sizeof on statically dimensioned arrays and the sizeof function will also allow you determine the sizeof the elements in the array. But... they can't be empty by your own definition cause the compiler will optimize them out or halt on a compiler error. A pointer to an empty dynamic array will be set to NULL on intialization and memory deallocation.
Anyway the crux of the problem was that you were interfacing a com object with VB, with an array, that apparently was dynamic and at times empty. Sounds like you resolved the issue by modifying the VB software. :goodjob:
funxus Feb 24, 2003, 11:44 AM I just installed Visual Studio on my new Win XP machine, but was pretty disappointed that the all the controls didn't follow the theme in windows. The theme-controls have rounder corners and for example the command buttons gets an orange border when you move the mouse over it.
I therefore checked the microsoft knowledgebase and found an example of how to do it, but according to them it wasn't really supported by VB. The annoying part was that you had to make an additional file and place it in the same folder as the exe-file, and it only works after you've compiled the file.
My idea was that it would be nice if the program itself could create that extra file, so I placed the text found in the additional file in a resourcefile, which I added to the project and programmed it to create the file in the same folder.
So, if you want XP-themecontrols in your VB program without distributing the extra file with the program, use the project below as the base of your program, and before making the exe-file comment out "exit sub" in "Form_initialize" to activate the code.
If anyone have a better solution to the problem, please help me improve it:)
funxus Feb 24, 2003, 11:45 AM Here's (http://support.microsoft.com/default.aspx?scid=kb;en-us;309366) the link to the microsoft page with the instructions.
ainwood Feb 24, 2003, 03:04 PM Funxus,
Looks good :goodjob:
What happens when you try the executable on a non-XP machine? When you call the control initialise function, does it crash or simply load whichever win 9x version of the same function?
I guess you could always wrapper this in a IfWinXP() type function :)
funxus Feb 25, 2003, 12:05 PM That shouldn't be so hard to try. I'll get to it soon :)
funxus Feb 25, 2003, 12:13 PM Yes, the program worked in Win ME, but it still creates the manifest. I guess it shouldn't be too hard to check which OS it is and only create the file if it's XP.:)
CornMaster Mar 15, 2003, 11:02 PM Winsock.
I've been messing with it...and are writing 4 different chat programs. All for different purposes. Anyway...I want to add file transfering to them.
Any tutorials?
ainwood Mar 16, 2003, 06:55 PM Originally posted by CornMaster
Winsock.
I've been messing with it...and are writing 4 different chat programs. All for different purposes. Anyway...I want to add file transfering to them.
Any tutorials?
Your wish is my command ;)
This is NOT my tutorial. can't remember where I found it, but it does give the basics. :) Hopefully its of some use. Perhaps you could weed out the rubbish and repost what you come up with? :)
|
|