How to extend the functions of VB standard controls
Obviously, controls in Windows provide more attributes than those in VB. Or Microsoft is too lazy, or Microsoft believes that a programmer using VB will never encounter those attributes.
For example, let's look at a common multi-line text box. It is almost similar to the edit box in Windows in terms of functionality, but with few fewer properties. For example, the edit box has an attribute used to specify the number of lines of text it contains, you can also use properties to obtain the row numbers of the first line of text displayed in the edit box (similar to the topindex in the drop-down list ).
So, how can we find these attributes that do not exist in VB? The answer is yes. It is a little troublesome, and you need to use the API again. With the help of an API function named sendmessage, we provide some useful extensions for the functions of common text boxes: you can treat each row in the text box as an element in a string array. This is useful when you want to analyze the content of a text box. For example, if you want to create an HTML editor program and want it to have color code to distinguish different code segments (similar to the VB Code Editor ), it is much easier to analyze each line than to analyze the entire text? Let's take a look at the example below.
Let's get to work...
To Use API functions, you must declare sendmessage first:
Public declare function sendmessage lib "USER32" alias "sendmessagea" (byval hwnd as long ,_
Byval wmsg as long ,_
Byval wparam as long ,_
Lparam as any) as long
You also declare the message to be sent to the text box. For example, if you want to write a function that tells you the sequence number of the first visible row in the text box, you need to make the following message declaration:
Public const em_getfirstvisibleline = & HCE
Then you can write the function:
Public Function toplineindex (txtbox as textbox) as long
Toplineindex = sendmessage (txtbox. hwnd ,_
Em_getfirstvisibleline, 0 &, 0 &)
End Function
Because em_getfirstvisibleline does not require any parameters, both wparam and lparam must be assigned 0 values. If you want to apply this function to a standard text box in a rich text box, you just need to change the parameter type of the function from textbox to RichTextBox. Remember that the row sequence number starts with 0. When the function returns 0, it indicates the first row.
The rich text box has a method getlinefromchar that can determine the row serial number of a given character number. The standard text box does not have this function. We can solve this problem through the above method. However, this time, you need to use the em_linefromchar message:
Public const em_linefromchar = & hc9
The em_linefromchar message places the serial number of the character to be passed in the wparam parameter:
Public Function getlinefromchar (txtbox as Textbox, charpos as long) as long
Getlinefromchar = sendmessage (_ txtbox. hwnd, em_linefromchar, charpos, 0 &)
End Function
Therefore, if you want to know the specific row serial number of the row where the cursor is located, you can use the following function to easily implement it:
Dim lnglineindex as long
Lnglineindex = getlinefromchar (text1, text1.selstart)
Msgbox "you are on line number" & lnglineindex + 1
In turn, you can also find the serial number of the first character in each line in the full text. The em_lineindex message can help you do this:
Public const em_lineindex = & HBB
Public Function getcharfromline (txtbox as Textbox, lineindex as long) as long
Getcharfromline = sendmessage (_
Txtbox. hwnd, em_lineindex, lineindex, 0 &)
End Function
How many lines are there in the text box? Simple: em_getlinecount is easy to handle. Similarly, because this message does not contain any parameters, we still set the wparam and lparam parameters to 0:
Public const em_getlinecount = & HbA
Public Function linecount (txtbox as textbox) as long
Linecount = sendmessage (_
Txtbox. hwnd, em_getlinecount, 0 &, 0 &)
End Function
OK, it's really easy. Let's take a look at another message: em_linelength. Return the length of the row where the character is located by specifying the number of characters in the wparam parameter:
Public const em_linelength = & HC1
Public Function linelen (txtbox as Textbox, charpos as long) as long
Linelen = sendmessage (_
Txtbox. hwnd, em_lineleength, charpos, 0 &)
End Function
Is it easy? Or you will say, this is too simple. Okay. Let's take a look at something a little more complicated. The function described below can help you extract the content of a specified row from a text box. The message is em_getline, And the row sequence number is placed in the wparam parameter. Specify a character buffer in the lparam parameter to accept the row content.
Although it sounds a bit simple, the problem is that you need to specify a maximum number of characters for the character buffer in the message and place it in the first 16 bits of the specified buffer. In addition, in the character buffer, the string format cannot be directly recognized by VB. This is because the Unicode encoding of strings recognized by VB, and the General API functions return character arrays in C. This is also a problem that is frequently encountered when Calling API functions in VB. The solution is: we need to use a byte array in the middle, and then convert the byte array into a string that can be recognized by VB.
Public const em_getline = & hc4
Public Function Getline (txtbox as Textbox, lineindex as long) as string
Dim bbuffer () as byte character array
Maximum length of dim lnglength as long
Dim sretval as string 'string to be returned
'Check whether the row number is valid
If lineindex> = linecount (txtbox)
'Call the linecount function mentioned above
Exit function' error exit
End if
'Get the row length
Lnglength = linelen (txtbox, getcharfromline (txtbox, lineindex ))
'Check whether this row has any characters
If lnglength <1 then
Exit Function
End if
'Redeclare the character array
Redim bbuffer (lnglength)
'Save the string length in the first two bytes of the buffer.
Bbuffer (0) = lnglength and 255
Bbuffer (1) = lnglength and 256
'Send message
Sendmessage txtbox. hwnd, em_getline, lineindex, bbuffer (0)
'Final encoding and conversion, and output the string
Sretval = left $ (strconv (bbuffer, vbunicode), lnglength)
Getline = sretval
End Function
We can also do a lot of similar things to extend the functions of the standard controls in VB, which will not be listed here. What's important is that you should know that VB is actually very simple on the surface, and many things can be used better by constantly exploring them. The following are some other messages for your reference:
Em_canundo: determines whether the Undo operation can be performed on the last modification. Em_undo: Restore the last modification.
Em_getmodify: determines whether the content in the text box has been changed.
Em_setmodify: manually set the modify flag. After the content of the text box is modified, the flag is automatically set to true.
More things require your own continuous accumulation. APIs are profound and profound. Only by using them can you maximize the power of VB, it can also lay a solid foundation for future transfer to VC learning.