Подсточные символы и собств элем упр

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Подсточные символы и собств элем упр

Сообщение AnarCky » 14.04.2007 (Сб) 13:04

Я уже неоднократно поднимал подобный вопрос, но так и не получил вразумительного ответа. Но вот срочняк приперло и я опять прошу помощи.

Основная цель сделать элем управ наследующий рич текст бокс и умеющее распознавать хим формулы.

Алгоритм действия таков:

- при нажатии клавиши (KeyPress или KeyDown; какой лучше?) проверяется цифра ли это
- если нет все как обычно
- если да:
- определяем символ до нее:
- буква -> делаем цифру подстрочной
- пробел -> как обычно
- ничего нет (первый символ в строке) -> как обычно
- цифра:
- если подстрочная -> делаем и эту подстрочной
- если нет -> как обычно

Основные загвоздки: как вообще сделать подстрочной, как проверить подстрочность.

Помогите, пожалуйста и срочно!
Спасибо!
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 14.04.2007 (Сб) 15:11

Поскольку это не полноценная работа с форматом RTF, не гарантируется вообще ничего.
В частности, это не будет работать при попытке задать sub для диапазона, который частично sub, а частично нет.

Код: Выделить всё
  Private Enum RtfSubSuper
    rtfSub = 0
    rtfSuper
  End Enum

  Private Function MakeStringSubSuper(ByVal s As String, ByVal Mode As RtfSubSuper) As String

    If s Is Nothing Then Throw New ArgumentException("Нефиг", "s")
    If Mode <> RtfSubSuper.rtfSub AndAlso Mode <> RtfSubSuper.rtfSuper Then Throw New ArgumentException("Нефиг", "Mode")

    Dim p, pp, c As Integer
    Dim ctf1 As Char() = {" "c, "\"c}, ctf2 As Char() = {"{"c, "}"c}
    Dim rtfs As String() = {"\sub", "\super"}

    Do
      p = s.IndexOf("\lang", pp)
      If p = -1 Then Return s

      If s.Chars(p - 1) <> "\"c Then
        p = s.IndexOfAny(ctf1, p + Len("\lang"))
        If p <> -1 Then
          c = 1
          pp = p + 1
          Do While pp < s.Length()
            pp = s.IndexOfAny(ctf2, pp)
            If pp = -1 Then Return s

            If s.Chars(pp - 1) = "\"c Then
              pp += 1
            Else
              If s.Chars(pp) = "{"c Then c += 1 Else c -= 1

              If c = 0 Then
                Return s.Substring(0, p) & rtfs(Mode) & s.Substring(p, pp - p) & "\nosupersub" & s.Substring(pp)
              End If
            End If
          Loop
        End If
      Else
        pp = p + Len("\lang")
      End If
    Loop
  End Function

  Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    RichTextBox1.SelectedRtf = MakeStringSubSuper(RichTextBox1.SelectedRtf, RtfSubSuper.rtfSub)

  End Sub
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 15.04.2007 (Вс) 19:52

Есть, кстати, корректный способ.
Но именно сейчас у меня нет времени его изложить; чуть позже.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Сообщение AnarCky » 16.04.2007 (Пн) 16:35

:shock: :shock:
В частности, это не будет работать при попытке задать sub для диапазона, который частично sub, а частично нет.


Будет время - поясни пожалуйста эти строки. Что значит "задать sub" и "диапазон sub"?

Потом что такое "As RtfSubSuper"? Что это за тип такой?
"Throw New ArgumentException("Нефиг", "Mode")" ???

Вот... остальное примерно ясно. :)
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 16.04.2007 (Пн) 16:46

Диапазон - непрерывный кусок текста.
Sub - непрерывный кусок текст, на который распространяется действие rtf-тега \sub, делающего нижний индекс.
RtfSubSuper - мой тип, который определил я для себя в моём коде моего поста.
Throw New ArgumentException - попробуй передать аргументом Mode что-то, кроме RtfSubSuper.rtfSub или RtfSubSuper.rtfSuper.
Последний раз редактировалось GSerg 16.04.2007 (Пн) 16:47, всего редактировалось 1 раз.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Сообщение AnarCky » 16.04.2007 (Пн) 19:47

Спасибо! Только еще вопрос...

RtfSubSuper - мой тип, который определил я для себя


Твой говоришь. А структуру типа не надо писать? Или как?
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 16.04.2007 (Пн) 20:01

Медитируй над кодом. Ответ настигнет тебя.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 16.04.2007 (Пн) 21:12

А вот это будет всегда работать (ценой требования доступа к неуправляемому коду, правда).

Код: Выделить всё

Imports System.Runtime.InteropServices


  <Security.SuppressUnmanagedCodeSecurity()> _
  Private Declare Auto Function SendMessage Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal uMsg As Integer, ByVal wParam As Integer, <Out()> ByRef lParam As IntPtr) As Integer

  Private Enum tomBool As Integer
    tomFalse = 0
    tomTrue = &HFFFFFFFF
    tomToggle = &HFF676982
    'tomUnknown
  End Enum

  Private Enum RtfSubSuper
    rtfSub = 0
    rtfSuper
  End Enum


  Private Sub MakeSelectionSubSuper(ByVal rtb As RichTextBox, ByVal IndexType As RtfSubSuper, ByVal value As tomBool)
    Dim pRichEditOle, pTextDocument As IntPtr
    Dim TextDocument, RangeObject, FontObject As Object

    Const WM_USER As Integer = &H400
    Const EM_GETOLEINTERFACE As Integer = WM_USER + 60

    Dim rtfs As String() = {"Subscript", "Superscript"}


    If rtb Is Nothing Then Throw New ArgumentNullException("rtb", "Нефиг!")
    If rtb.ReadOnly Then Throw New ArgumentException("rtb", "Не, ну а чё, с таким rtb ничего не получится этим способом...")
    If IndexType <> RtfSubSuper.rtfSub AndAlso IndexType <> RtfSubSuper.rtfSuper Then Throw New ArgumentException("Нефиг", "IndexType")
    If value <> tomBool.tomTrue AndAlso value <> tomBool.tomFalse AndAlso value <> tomBool.tomToggle Then Throw New ArgumentException("Нефиг", "value")


    If SendMessage(rtb.Handle, EM_GETOLEINTERFACE, 0, pRichEditOle) = 0 Then Exit Sub 'ну или другое чё...

    'Злостно! Но безопасно.
    Try
      Marshal.QueryInterface(pRichEditOle, New Guid("8CC497C0-A1DF-11CE-8098-00AA0047BE5D"), pTextDocument)
      If Not pTextDocument.Equals(IntPtr.Zero) Then
        Try
          TextDocument = Marshal.GetObjectForIUnknown(pTextDocument)
          Try
            RangeObject = TextDocument.GetType.InvokeMember("Selection", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.GetProperty Or Reflection.BindingFlags.Public, Nothing, TextDocument, Nothing)
            Try
              FontObject = RangeObject.GetType.InvokeMember("Font", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.GetProperty Or Reflection.BindingFlags.Public, Nothing, RangeObject, Nothing)
              Try
                FontObject.GetType.InvokeMember(rtfs(IndexType), Reflection.BindingFlags.Instance Or Reflection.BindingFlags.SetProperty Or Reflection.BindingFlags.Public, Nothing, FontObject, New Object() {value})
              Finally
                Marshal.ReleaseComObject(FontObject)
              End Try
            Finally
              Marshal.ReleaseComObject(RangeObject)
            End Try
          Finally
            Marshal.ReleaseComObject(TextDocument)
          End Try
        Finally
          Marshal.Release(pTextDocument)
        End Try
      End If
    Finally
      Marshal.Release(pRichEditOle)
    End Try

  End Sub

  Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
    MakeSelectionSubSuper(RichTextBox1, RtfSubSuper.rtfSub, tomBool.tomToggle)
  End Sub
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Сообщение AnarCky » 17.04.2007 (Вт) 12:45

:shock: :shock: :shock:
Сказать что я что то пойму в коде будет явно враньем в глаза :?

Как ОНО вообще работает? По тому алгоритму что я описал в начале? Или как-то по-другому :?:
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.04.2007 (Вт) 13:02

Оно изменяет sub/super-статус текущего выделения.

Никто не собирался писать тебе готовый код под ключ.
Это - ответ на вопрос "как сделать некий текст нижним/верхним индексом".
А определять, где какая буква и какой именно участок делать индексом, это ты сам.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Сообщение AnarCky » 17.04.2007 (Вт) 19:51

Все теперь понял. Т.е. когда мне нужно сделать текст подстрочным я просто пишу строчку:
Код: Выделить всё
MakeSelectionSubSuper(RichTextBox1, RtfSubSuper.rtfSub, tomBool.tomToggle)

Тогда возникает еще пара вопросов:
1) как можно програмно выделить какую-то часть текста?
2) "RichTextBox1" можно заменить на имя пользовательского элем упр (напр UserControl1)?
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.04.2007 (Вт) 19:57

AnarCky писал(а):Т.е. когда мне нужно сделать текст подстрочным я просто пишу строчку:

Т.е. ты даже не посмотрел, какие бывают допустимые значения третьего параметра.

AnarCky писал(а):Тогда возникает еще пара вопросов:

1) Если ты не знаешь даже этого, не пиши этот контрол. Впрочем, я могу из соображений любопытства даже сделать так, чтобы этот метод принимал начальный и конечный символ. Интересно, поможет ли это тебе.
2) Производным от rtb - да, остальными нет. Если бы я писал контрол для ввода формул, я бы унаследовал его от rtb и поместил бы этот код внутри него.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Сообщение AnarCky » 17.04.2007 (Вт) 20:13

Ну... я понял, что ты в процедуру передал параметр value загадочного типа tomBool. Потом при подстановке параметра делаешь непонятно что. я не связываю как зависят tomToggle (равный вот этому вот: &HFF676982) и tomBool

1) Дык для установки выделения должно быть какое-то св-во, метода или еще что-нибудь... ? или я просто что-то не правильно понимаю? Я уж как-нибудь сделаю сам чтоб выделение "накладывалось" на определенные символы... просто как

2) А я собственно так и собираюсь. Не с нуля ж мне контрол делать :D

Ты вправе смеятся над моей тупостью. Смейся... Только объясни, пожалуйста :)
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 17.04.2007 (Вт) 20:18

Т.е. ты совсем не знаешь, что такое enum. Чюдесно.
Причём не только не знаешь, но и даже не хочешь перевести имена tomToggle и остальные на русский.

1) Так же, как в текстбоксе, в ричтекстбоксе, в VB6, где угодно.


Ха ха.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Сообщение AnarCky » 18.04.2007 (Ср) 12:41

Не поверишь я знаю что такое enum. Перечисления... Я о них токо читал но никогда не работал. С трудом понимаю зачем они, но о факте существования знаю.

Все теперь про tomBool.tomToogle понял :) это я ступил. Но что это такое tomToogle = &HFF676982. Это константа для API ?

tom это префикс или что? Toogle кажется переключатель хотя ручаться не стану. (словаря нет под рукой) Bool это что от Boolean (логический)?

1) А как? :D :D
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 18.04.2007 (Ср) 13:59

Затем, чтобы было удобно. Чтобы бы список допустимых значений для параметра функции.

Это константа для API.

tom - это префикс. Придуманный не мной. Toggle - переключить (догадайся, что делает).

1) Так же!
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Сообщение AnarCky » 18.04.2007 (Ср) 19:23

1) ты издеваешься? Скажи просто какой метод и что ему надо и все.
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 18.04.2007 (Ср) 19:54

1) Я не издеваюсь. Rather, я глубоко убеждён, что если бы ты всё-таки просмотрел список свойств этого контрола, ты бы нашёл нужное.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Сообщение AnarCky » 18.04.2007 (Ср) 20:11

Какого контрола? rtb что-ль?
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 18.04.2007 (Ср) 20:15

Rtb чтоль.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

AnarCky
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 229
Зарегистрирован: 20.11.2006 (Пн) 20:12
Откуда: Россия, Екатеринбург.

Сообщение AnarCky » 04.05.2007 (Пт) 19:59

Все. Плюс минус разобрлся как работает.
Остался последний (надеюсь последний :D ) вопрос:
Как узнать является ли строка\символ подстрочным?
Компьютеры были придуманы чтобы исправлять ошибки людей. Но кто же тогда будет исправлять ошибки компьютера?..

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 04.05.2007 (Пт) 20:04

В центре моего кода строчка
Код: Выделить всё
FontObject.GetType.InvokeMember(rtfs(IndexType), Reflection.BindingFlags.Instance Or Reflection.BindingFlags.SetProperty Or Reflection.BindingFlags.Public, Nothing, FontObject, New Object() {value})


Если её заменить на
Код: Выделить всё
somevar = FontObject.GetType.InvokeMember(rtfs(IndexType), Reflection.BindingFlags.Instance Or Reflection.BindingFlags.GetProperty Or Reflection.BindingFlags.Public, Nothing, FontObject, Nothing)
(что почти одно и то же), то она вернёт состояние подстрочности.
somevar должна быть As tomBool.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 47

    TopList