Gör din egen AutoList
Förord
AutoList, - detta koncept känner du säkert igen från utvecklingsmiljön i Visual Basic, en lista med ordförslag som du har tillgång till för att snabba upp ditt kodskrivande. Gör man en egen texteditor eller något liknande så kan det vara så att man vill ha en sån här i sitt program, att visa och dölja en listbox är inga problem, det svåra är att placera den på ditt formulär
Introduktion
Det du behöver på ditt formulär är:1 st RichTextBox med namnet txtText
1 st PictureBox med namnet picTextSize
1 st ListBox med namnet lstAutoList
Jag kommer att bifoga en zip-fil som innehåller ett enkelt exempel.
Första steget, storleken på ListBoxen
Listboxen som kommer upp ska ju helst inte vara för stor och heller inte för liten. I mitt exempel gör jag ListBoxen lika bred som den längsta texten i listan och max tre rade hög. Först ska man fylla listan och deklarera variablerna man vill använda (i mitt exempel gör jag det i Form_Load händelsen).
Dim i As Integer
Dim curOrdLangd As Integer
Dim maxOrdLangd As Integer
Dim maxOrd As String
Dim antRader As Integer
lstAutoList.AddItem "Här"
lstAutoList.AddItem "kan"
lstAutoList.AddItem "du"
lstAutoList.AddItem "lägga in meningar"
lstAutoList.AddItem "eller"
lstAutoList.AddItem "ord!"
För att listan ska bli snygg ska vi göra den så bred så att allting i en rad för plats, för att göra detta måste vi ta reda på den längsta posten i listan, vi gör detta genom att loopa igenom och kolla radlängden och lägga det längsta i en variabel vid namn "maxOrd":
For i = 0 To lstAutoList.ListCount - 1
curOrdLangd = Len(lstAutoList.List(i))
If curOrdLangd > maxOrdLangd Then
maxOrdLangd = Len(lstAutoList.List(i))
maxOrd = lstAutoList.List(i)
End If
Next i
Nästa steg blir att ta reda på hur många rader som finns och hur många vi vill skall synas:
If lstAutoList.ListCount > 3 Then
antRader = 4
Else
antRader = lstAutoList.ListCount + 1
End If
Om listan haft två rader hade "antRader" blivit 3. Om listan haft tolv rader hade "antRader" blivit 4.
Nästa steg är att översätta "maxOrd" och "antRader" till en storlek som VB förstår, för att göra detta skall vi använda PictureBoxen. En PictureBox har metoderna TextHeight och TextWidth, som returnerar höjd och bredd på texten du skickar in.
Först får vi göra så att Pictureboxen har samma teckensnitt som ListBoxen, annars kan vi ju inte få ut bredden på texten!
picTextSize.Font = lstAutoList.Font
picTextSize.FontSize = lstAutoList.FontSize
picTextSize.FontBold = lstAutoList.FontBold
picTextSize.FontItalic = lstAutoList.FontItalic
Nu ska vi räkna ut bredden på det längsta ordet + utrymme för en eventuell scrollbar och sätta så att listboxen är så bred:
lstAutoList.Width = picTextSize. _
TextWidth(maxOrd) + 400
Sen ska vi ha ut hur mycket höjden på det antal rader är och ge listboxen den höjden:
lstAutoList.Height = picTextSize. _
TextHeight("Ord") * antRader
Nu har listboxen fått sin storlek och den ska döljas för att sedan tas fram när man vill använda den
lstAutoList.Visible = False
Steg två, visa den vid behov
Man kan ha många sätt att ta fram listboxen, jag har valt att visa den när man trycker ned Ctrl + D i RichTextBoxen, men först några deklarationer:
Dim firstVisibleLine As Integer
Dim currentline As Integer
Dim visibleLinesToCurrent As Integer
Dim lineHeight As Integer
Dim lineWidth As Integer
Dim lineStart As Integer
Dim thislinetext As String
Jag kommer att använda mig av API-funktionen SendMessage för att ta reda på markörens position i texten, du deklarerar funktionen och de konstanter vi skall använda såhär:
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_GETFIRSTVISIBLELINE = &HCE
Const EM_LINEFROMCHAR = &HC9
Const EM_LINELENGTH = &HC1
Const EM_LINEINDEX = &HBB
Ta reda på vad som trycks ner
Som sagt skall vi visa listboxen när Ctrl+D trycks ner, för att fånga detta:
If Shift = 2 And KeyCode = 68 Then
Räkna ut placeringen
För att få reda på placeringen på höjdenmåste vi veta:- Vilken rad är den första som är synlig?
- Vilken rad är jag på?
- Hur hög är varje rad?
Men först skall vi ställa om PictureBoxen så den har samma teckensnitt som RichTextBoxen, det gör vi på samma sätt som vi gjorde med listboxen:
picTextSize.Font = txtText.Font
picTextSize.FontSize = txtText.Font.Size
picTextSize.FontBold = txtText.Font.Bold
picTextSize.FontItalic = txtText.Font.Italic
Nu ska vi ta reda på vad listboxens Top egenskap ska vara, det blir:
(raden jag är på) - (första synliga raden) * (höjden på varje rad) + hur långt ner på formuläret RichTextboxen är:
firstVisibleLine = SendMessage _
(txtText.hwnd, EM_GETFIRSTVISIBLELINE, 0, 0&) + 1
currentline = SendMessage(txtText.hwnd, _
EM_LINEFROMCHAR, -1&, ByVal 0&) + 1
visibleLinesToCurrent = currentline - firstVisibleLine
lineHeight = picTextSize.TextHeight("HEJ")
lineHeight = (lineHeight * visibleLinesToCurrent) _
+ txtText.Top
Nu ska vi ta reda på hur långt vi är från radens början:
bredden på texten från där markören står till radens start:
lineStart = SendMessage(txtText.hwnd, _
EM_LINEINDEX, currentline - 1, ByVal 0&)
lineStart = lineStart + 1
thislinetext = _
Mid(txtText.Text, lineStart, _
txtText.SelStart - lineStart + 1)
lineWidth = picTextSize.TextWidth(thislinetext)
Nu ska vi visa listboxen på våra ovanstående koordinater och ge den fokus:
lstAutoList.Visible = True
lstAutoList.Top = (CDbl(lineHeight))
lstAutoList.Left = txtText.Left + lineWidth + 350
lstAutoList.SetFocus
Placera ut texten i listboxen
I mitt exempel använda "Enter" för att lägga in texten och "Esc" för att stänga listan + att markören skall sätta sig på rätt ställe efter att man tryckt "Enter" eller "Esc":
Dim cPos As Integer
Dim inText As String
If KeyCode = 13 Then
cPos = txtText.SelStart
inText = lstAutoList.Text
txtText.Text = Left(txtText.Text, _
txtText.SelStart) & lstAutoList.Text & _
" " & Right(txtText.Text, _
Len(txtText.Text) - txtText.SelStart)
lstAutoList.Visible = False
txtText.SelStart = cPos + Len(inText) + 1
End If
If KeyCode = 27 Then
cPos = txtText.SelStart
lstAutoList.Visible = False
txtText.SelStart = cPos
End If
Nu har du gjort din alldeles egna AutoList-funktion, gick det inte riktigt som du tänkt dig så finns det ett exempel att ladda ner här: exempel.zip (41kb)
0 Kommentarer