На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual Basic: Общие вопросы
Здесь обсуждаются вопросы по языку Visual Basic 1-6 (а так же по схожим языкам, как, например, PowerBASIC).
Вопросы по Visual Basic .NET (это который входит в состав Visual Studio 2002/2003/2005/2008+, для тех, кто не в курсе) обсуждаются в разделе .NET.

Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что Вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются. Студенты, вам сюда: ПОМОЩЬ СТУДЕНТАМ!
4. Используйте теги [ code=vba ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Формулируйте свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной (и более) давности, без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта user posted image FAQ Раздела user posted image Кладовка user posted image Наши Исходники user posted image API-Guide user posted image Поиск по Разделу user posted image MSDN Library Online user posted image Google

Ваше мнение о модераторах: user posted image SCINER, user posted image B.V.
Модераторы: SCINER, B.V.
  
> Сущность строк в Visual Basic , Небольшое исследование на тему
    Всем привет.

    Хочу разъяснить что такое строка в Visual Basic и как она работает.

    Как извесно, строки в VB хранятся в виде BSTR (о том что это, подробно написал ANDLL здесь)
    Формат весьма универсальный.

    Однако это не единственная фишка VB в строках.
    Если быть внимательным, то можно заметить, что для получения адресов переменных используется функция VarPtr, но только не для строковых. Для них испольуется StrPtr.
    Возникает 2 резонных вопроса: почему отдельная функция? и почему StrPtr и VarPtr возвращают разные знания?

    Всё дело в том, что строка в VB это всего-лишь 4 байта, являющиеся указателем на BSTR строку, причём не на её начало, а на данные (тоесть начало BSTR строки + 4 байта)!
    Вот так всё просто и универсально.

    Функция VarPtr возвращает адрес ячейки памяти, где лежит адрес BSTR строки + 4, а функция StrPtr возвращает число из этой ячейки.
    Да и функции StrPtr физически не существует :)

    На рисунке сделал визуализацияю для упрощения понимания :)

    Кстати появляется возможность быстрого "копирования" строки или создания строк, данные в которых будут общими.
    Сообщение отредактировано: KillerXX7 -

    Прикреплённая картинка
    Прикреплённая картинка
      Цитата
      Итак, первый тип, BSTR(именно он использовуется в переменных типа String в VB6) - строка из unicode-символов, которая кончается двухбайтовым терминатором и перед которой стоит ее длина. Ввиду того, что сама строка содержит свою длину она может содержать произвольные символы.
      Во второй тип, ABSTR, VB преобразует строки перед тем как передать их в API-функции. Этот тип отличается от BSTR тем, что содержит однобайтовые символы, вместо двухбайтовых.


      Тогда вопрос: почему по умолчанию (тоесть в АПИ-вьювере) используются только *А функции (то есть принимающие строки в кодировке ASCII)? Если строки в VB изначально хранятся в Unicode формате, то не разумнее ли было бы использовать *W функции, опуская тем самым преобразование Unicode->ASCII (BSTR->ABSTR)? Поправьте меня если я что-то не так понял
        тривиальный тест:
        ExpandedWrap disabled
          Option Explicit
          Private Declare Function GetTickCount& Lib "kernel32" ()
          Const DC_ACTIVE = &H1
          Const DC_NOTACTIVE = &H2
          Const DC_ICON = &H4
          Const DC_TEXT = &H8
          Const BDR_SUNKENOUTER = &H2
          Const BDR_RAISEDINNER = &H4
          Const EDGE_ETCHED = (BDR_SUNKENOUTER Or BDR_RAISEDINNER)
          Const BF_BOTTOM = &H8
          Const BF_LEFT = &H1
          Const BF_RIGHT = &H4
          Const BF_TOP = &H2
          Const BF_RECT = (BF_LEFT Or BF_TOP Or BF_RIGHT Or BF_BOTTOM)
          Const DFC_BUTTON = 4
          Const DFC_POPUPMENU = 5            'Only Win98/2000 !!
          Const DFCS_BUTTON3STATE = &H10
          Const DT_CENTER = &H1
          Const DC_GRADIENT = &H20          'Only Win98/2000 !!
          Private Type RECT
              Left As Long
              Top As Long
              Right As Long
              Bottom As Long
          End Type
          Private Declare Function DrawCaption Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long, pcRect As RECT, ByVal un As Long) As Long
          Private Declare Function DrawEdge Lib "user32" (ByVal hdc As Long, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Long
          Private Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As Long
          Private Declare Function DrawFrameControl Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal un1 As Long, ByVal un2 As Long) As Long
          Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
          Private Declare Function DrawText2 Lib "user32" Alias "DrawTextW" (ByVal hdc As Long, ByRef lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
          Private Declare Function SetRect Lib "user32" (lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
          Private Declare Function OffsetRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long
          Dim ret As Long, i As Long
           
          Private Sub Command1_Click()
           Dim R As RECT
              'Clear the form
              Me.Cls
              'API uses pixels
              Me.ScaleMode = vbPixels
              'Set the rectangle's values
              SetRect R, 0, 0, Me.ScaleWidth, 20
              'Draw a caption on the form
              ret& = GetTickCount&
              For i = 1 To 100000
                DrawText Me.hdc, "Hello World !", Len("Hello World !"), R, DT_CENTER
              Next i
              ret& = GetTickCount& - ret&
              MsgBox Str$(ret)
          End Sub
           
          Private Sub Command2_Click()
          Dim R As RECT
          Dim strTemp As String
              'Clear the form
              Me.Cls
              'API uses pixels
              Me.ScaleMode = vbPixels
              'Set the rectangle's values
              SetRect R, 0, 0, Me.ScaleWidth, 20
              'Draw a caption on the form
              strTemp = "Hello World !"
              ret& = GetTickCount&
              For i = 1 To 100000
                DrawText2 Me.hdc, strTemp, Len(strTemp), R, DT_CENTER
              Next i
              ret& = GetTickCount& - ret&
              MsgBox Str$(ret)
          End Sub

        Выдает результаты 790 / 1200 не в пользу *W функции! Для меня это пока удивительно... К тому же выводимая абракадабра *W-функцией говорит о том, что либо VB преобразует BSTR в ABSTR независимо от вызываемой функции, либо строка уже ABSTR... Чудно однако, поясните, плиз, кто в этом разбирается, сложившуюся ситуацию, что *A-функция работает быстрее *W-функции.
        (Я вижу пока только одно объяснение: VB преобразует BSTR в ABSTR независимо от вызываемой функции)
        Сообщение отредактировано: EvgenyR_(Djoser) -
          Во первых термины
          ASCII это кодировка. A-функции от слова ANSI, это целый набор кодировок разработанный угадайте кем.
          Unicode это не кодировка. В MSDN везде пишут unicode, но вообще полезно знать что в понятие Unicode входит дофига кодировок, а windows nt использует в себе конкретно UTF-16
          Далее. Большинство(если не все) W-функций не работают в windows 98 без одного патча. Если бы VB считал что функция ожидает двухбайтовые симолы, то программ написанные на нем оказались бы весьма непотребными в течении долгого времени.
          Почему в картинке четыре нуля в конце?
          Цитата EvgenyR_(Djoser) @
          Я вижу пока только одно объяснение: VB преобразует BSTR в ABSTR независимо от вызываемой функции
          Ага. Как он должен угадывать где у тебя A-функция а где нет?
            Цитата ANDLL @
            Почему в картинке четыре нуля в конце?

            Этот вопрос к чему относится?

            Цитата ANDLL @
            Как он должен угадывать где у тебя A-функция а где нет?

            Ну мы же прямо декларим:
            Цитата EvgenyR_(Djoser) @
            Alias "DrawTextW"

            Получить последний символ в названии задекларенной функции такая уж проблема для VB?
            Цитата ANDLL @
            A-функции от слова ANSI, это целый набор кодировок разработанный угадайте кем.

            American National Standard Institute :)

            Добавлено
            А вообще надо дизасмить и смотреть :whistle: завтра так и сделаю (наверно)
              Цитата EvgenyR_(Djoser) @
              Получить последний символ в названии задекларенной функции такая уж проблема для VB?
              Буква в конце названия функции это не отражение в имени. Согласно соглашениям содержимое функции от имени не зависит. Исходя из этого дальше допрешь?

              Добавлено
              Цитата EvgenyR_(Djoser) @
              Этот вопрос к чему относится?
              Не к чему, а к кому, к автору топика.
                Данный факт кстати и получен методом великой IDA и OllyDebugger.
                В последнее время очень увлёкся внутреннестями VB :)


                Цитата EvgenyR_(Djoser) @
                Если строки в VB изначально хранятся в Unicode формате, то не разумнее ли было бы использовать *W функции, опуская тем самым преобразование Unicode->ASCII (BSTR->ABSTR)? Поправьте меня если я что-то не так понял

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

                VB на самом деле криво работает с Unicode, хотя это является его родной кодировкой.
                Данным вопросом задавались здесь (читал по диагонали поэтому не могу сказать об информативности статьи)


                Цитата ANDLL @
                Почему в картинке четыре нуля в конце?

                Да, скосячил, поправлю.
                На самом деле там должно быть 2 нулевых байта, если верить этому
                Сообщение отредактировано: KillerXX7 -
                  Строки в VB6 http://silicontaiga.ru/home.asp?artId=5110
                    Копи-пастл отсюда? Или наоборот :)
                    Впрочем неважно.
                    1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                    0 пользователей:


                    Рейтинг@Mail.ru
                    [ Script execution time: 0,0376 ]   [ 15 queries used ]   [ Generated: 15.09.25, 16:43 GMT ]