2008-09-14 12 views
9

Mam starą, starszą wersję aplikacji VB6, która używa formantu edycji DHTML jako edytora HTML. Sterowanie edycją Microsoft DHTML, a.k.a. DHTMLEd, jest prawdopodobnie niczym więcej niż formantem IE z wewnętrzną wewnętrzną edycją IE.Kod powodujący, że kontrolka DHTMLEd zamienia proste cytaty na kręcone cytaty.

Chciałbym zmodyfikować aplikację, aby zaimplementować inteligentne cytaty, takie jak Word. W szczególności, " jest zastąpiony « lub » i « jest zastąpiony » lub ' w miarę jak jest on wpisany, a jeżeli użytkownik naciśnie Ctrl Z natychmiast po wymianie, jest wraca do bycia prosto cytat.

Czy ktoś ma kod, który robi?

Jeśli nie masz kod DHTML/VB6, ale mają kod JavaScript, który działa w przeglądarce z REGI contentEditable dodatki, które można używać też

Odpowiedz

14

Oto wersja VB6:

Private Sub DHTMLEdit1_onkeypress() 
    Dim e As Object 
    Set e = DHTMLEdit1.DOM.parentWindow.event 
    'Perform smart-quote replacement' 
    Select Case e.keyCode 
    Case 34: 'Double-Quote' 
     e.keyCode = 0 
     If IsAtWordEnd Then 
      InsertDoubleUndo ChrW$(8221), ChrW$(34) 
     Else 
      InsertDoubleUndo ChrW$(8220), ChrW$(34) 
     End If 
    Case 39: 'Single-Quote' 
     e.keyCode = 0 
     If IsAtWordEnd Then 
      InsertDoubleUndo ChrW$(8217), ChrW$(39) 
     Else 
      InsertDoubleUndo ChrW$(8216), ChrW$(39) 
     End If 
    End Select 
End Sub 

Private Function IsLetter(ByVal character As String) As Boolean 
    IsLetter = UCase$(character) <> LCase$(character) 
End Function 

Private Sub InsertDoubleUndo(VisibleText As String, HiddenText As String) 
    Dim selection As Object 
    Set selection = DHTMLEdit1.DOM.selection.createRange() 
    selection.Text = HiddenText 
    selection.moveStart "character", -Len(HiddenText) 
    selection.Text = VisibleText 
End Sub 

Private Function IsAtWordEnd() As Boolean 

    Dim ch As String 
    ch = PreviousChar 
    IsAtWordEnd = (ch <> " ") And (ch <> "") 

End Function 

Private Function PreviousChar() As String 

    Dim selection As Object 
    Set selection = m_dom.selection.createRange() 
    selection.moveStart "character", -1 
    PreviousChar = selection.Text 

End Function 

Uwaga: to rozwiązanie wstawia dodatkowy poziom w łańcuchu cofania. Na przykład, wpisanie "To jest test" daje łańcuch "To jest test" -> "To jest test" ->"To jest test ->" -> "(dodatkowy poziom pogrubiony). Aby usunąć ten dodatkowy poziom, musisz zaimplementować rozwiązanie w rodzaju PostMessage+subclassing, które nie wymaga anulowania natywnego naciśnięcia klawisza:

edycja: nie zapomnij dołączyć DHTML Editing Control redistributable, jeśli kierujesz reklamy na system Windows Vista.

+1

Wow! Dzięki! Dobra robota! Pracował po raz pierwszy. Nadal go trochę poprawię, żeby poradzić sobie z kilkoma dziwnymi przypadkami, ale to jest wspaniałe. –

+4

Przy okazji, uwielbiam implementację IsLetter() ... prawdziwa perła programistyczna! –

+1

Dzięki za pochwałę; nigdy nie myślałem, że usłyszę coś takiego z legendy programowania :) Odnośnie IsLettera: Zamiast tego użyj IsCharAlphaW lub innej metody obsługującej Unicode. Moja implementacja była szybka i brudna, żeby nie umniejszać mięsa z mojej odpowiedzi :) – rpetrich