purebasic.info

PureBasic forum
Текущее время: Чт июл 19, 2018 10:51 am

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 50 ]  На страницу Пред.  1, 2, 3, 4  След.
Автор Сообщение
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Вт июн 19, 2018 6:16 pm 
Не в сети
док

Зарегистрирован: Вс июл 05, 2009 5:55 pm
Сообщений: 90
Благодарил (а): 1 раз.
Поблагодарили: 2 раз.
Пункты репутации: 0
AZJIO писал(а):
проверил как будет падать без ini
не обязательно падать, достаточно предварительно установить значения переменных, а если ини файла ненайдет то остануться прежние значения переменных, а можно и создать файл если ненайдет ини файла.

_________________
искатель истины


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Вт июн 19, 2018 7:01 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6322
Благодарил (а): 19 раз.
Поблагодарили: 189 раз.
Пункты репутации: 48
AZJIO писал(а):
как будет падать без ini, и добавил проверки как положено. Мало ли, в друг доступ будет ограничен для записи, и теперь любые кнопки нажимай, не вызывает проблем.

Есть же параметр специальной, если ini недоступен:
DefaultValue - Значение по умолчанию для возврата, если ключ не найден или файл настроек не был открыт правильно (например, файл отсутствует).

_________________
read-only


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Вт июн 19, 2018 7:37 pm 
Не в сети
док

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 183
Благодарил (а): 19 раз.
Поблагодарили: 32 раз.
Пункты репутации: 0
Это просто другой способ и сложный, карпеть над каждым отдельным параметром, когда можно ничего не делать, прога сама компилирует ini-файл в себя. Карпеть над каждым параметром имеет смысл, если для проги они архиважны, например позиция и размер окна от предыдущего запуска. В моём же случае ini-файлы для примера, когда пользователь скопировал DLL не подумав, что ему нужны ini и вставил плаг себе, и тут он вдруг не работает или работает но непонятно откуда берёт данные которые не возможно изменить, как он цвет изменит. А с ini-файл он поймёт ка он устроен.
И к тому же я в курсе про дефолтные параметры, несколько лет как, ведь в AutoIt3 используется такой же виндовый ini, тот же движок, я с ними уже "несколько собак съел".

У меня другая идея, хотя сложная, повторить CreationTheme. Так как регулировка индикатора меняет цвет, то это красивее получится на Scintilla, чем на RTF


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Вт июн 19, 2018 9:34 pm 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6322
Благодарил (а): 19 раз.
Поблагодарили: 189 раз.
Пункты репутации: 48
AZJIO писал(а):
прога сама компилирует ini-файл в себя.


В себя то без проблем. А вот из себя не факт, что система даст записать в свою папку. Не все Системы сейчас лояльны к таким фортелям, писать файлы в программную папку, да на системный диск.
Так что папочка C:\Users\ имя_рек будет надежнее. Но юзер тогда не увидит содержимого файла ini - не узнает о его существовании. Дилемма...
AZJIO писал(а):
У меня другая идея, хотя сложная

Как возможно на такой радуге программы то писать?
Воистину, раскраска редактора в стиле PureBasic просто замечательная, спасибо Фреду, что не допустил такого непотребства :D
Хотя и включил возможность настроить цвета под любой вкус.

_________________
read-only


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Вт июн 19, 2018 10:52 pm 
Не в сети
док

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 183
Благодарил (а): 19 раз.
Поблагодарили: 32 раз.
Пункты репутации: 0
kvitaliy писал(а):
Воистину, раскраска редактора в стиле PureBasic просто замечательная, спасибо Фреду, что не допустил такого непотребства :D

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

kvitaliy писал(а):
Так что папочка C:\Users\ имя_рек будет надежнее

по идее плаг изначально ставиться в AppData и путь относительно плага как бы стандартизирован. Исключение: если юзер засунет прогу в портабле-варианте в программную папку, там файл doLocalConf.xml определяет хранение всех настроек в своей папке. Это проблема пользователя и у него ничего не будет работать и ничего не будет сохраняться, только если он ещё додумается её под админом запускать как решение проблемы


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Ср июн 20, 2018 5:52 am 
Не в сети
МОДЕРАТОР

Зарегистрирован: Вт дек 05, 2006 8:46 am
Сообщений: 6322
Благодарил (а): 19 раз.
Поблагодарили: 189 раз.
Пункты репутации: 48
AZJIO писал(а):
не обвинять синий в том что он не красный.

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

Я начинал в DOS c GW-Basic, так там было три вида выделения: ВСЕ БОЛЬШИЕ БУКВЫ, все маленькие, Первая Буква Большая. Этого было достаточно.

_________________
read-only


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Ср июн 20, 2018 6:09 am 
Не в сети
док

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 183
Благодарил (а): 19 раз.
Поблагодарили: 32 раз.
Пункты репутации: 0
kvitaliy писал(а):
Проблема в количестве выделяемых элементов, когда каждый знак препинания, каждая цифра выделяется, как прыщ. В глазах рябит. Это очень утомляет и отвлекает от основной цели редактора - программировать.
Для меня это как инструмент помогающий восприятию данных, отличает один тип ключевых слов от других. Похожие типы можно отличать с небольшой разницей. Когда раньше читаешь справку AutoIt3 и там написано @error, помню меня это ломало, что за @error, это ключевое слово или ошибка в тексте, и когда я намеренно подсветил все зарегистрированные в языке ключевые слова, стало понятно, что это не опечатка, а ключевое слово, а когда добавил ещё и ссылку на каждое ключевое слово, то переходил быстро к описанию его и боковой кнопкой мыши возвращался к ранее читаемому. Это в итоге позволило быстро учится, но уже не для меня, а для тех кто будет читать в первый раз.

kvitaliy писал(а):
Так что папочка C:\Users\ имя_рек будет надежнее. Но юзер тогда не увидит содержимого файла ini - не узнает о его существовании.
Я забыл, плаг ставится стандартно в программную папку (при установке точно), а в случае доустановки при проблеме записи предлагает установить в AppData. В общем надо исправить это срочно, указав экпорт ini на старте в AppData. Пока только надеюсь пользователи догадались куда поместить конфиги.

Исправил, перезалил. Теперь ссылки в первом посте, чтобы легче искать.

Осталось ещё определить активное окно при двухоконном режиме, сейчас постоянно работает в ScintillaMainHandle, а надо ещё определять ScintillaSecondHandle.

Новая проблема, если текст с кодировкой ANSI, то не подсвечивает русский текст. По крайней мере определил с помощью SCI_GETCODEPAGE, которая при ANSI выдаёт 0, а при UTF-8 (16-LE, 16-BE) выдаёт 65001

Почитал о SCI_ENCODEDFROMUTF8, которая по описанию перекодирует текст из UTF-8 в кодировку, в которой сейчас находится документ в котором искать. Но не пойму, там в качестве параметров указатели на строки.


Последний раз редактировалось AZJIO Ср июн 20, 2018 11:42 am, всего редактировалось 1 раз.

Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Ср июн 20, 2018 11:03 am 
Не в сети
док

Зарегистрирован: Вс июл 05, 2009 5:55 pm
Сообщений: 90
Благодарил (а): 1 раз.
Поблагодарили: 2 раз.
Пункты репутации: 0
AZJIO писал(а):
Карпеть над каждым параметром
мой пример с чтением INI файла незаставит тебя потеть над каждым параметром.
Ведь ты и так извлекаеш его с INI и розтыкиваеш по переменным, а если файл или ненайдется то автоматом пропишет по умолчанию, а не только когда ключа ненашел :D , проверял,
менял файл чтения на левое название и параметры по умолчанию получил, и никаких ошибок и вылетов проги, а потом прога сама при сохранении запишет все. что надо(проверял на пурике 5.21)
вот сылка viewtopic.php?f=1&t=4894#p89451, тебе на твой вопрос в другом посту про ини.

_________________
искатель истины


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Ср июн 20, 2018 11:38 am 
Не в сети
док

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 183
Благодарил (а): 19 раз.
Поблагодарили: 32 раз.
Пункты репутации: 0
balex1978 писал(а):
вот сылка viewtopic.php?f=1&t=4894#p89451, тебе на твой вопрос в другом посту про ини.
Я прочитал, не переживай, просто ты не прочитал вопрос. Остальное отвлечение от темы, как чекбоксы задавать и дефолтное ставить лучше создать новую тему. По крайней мере как ставить чекбоксы я бы поспорил. Там всего два значения 1 и 0 и проверять их намного проще чем проверять шестнадцатериный формат числа например, с заказной шириной.

--------------------------
такой код попробовал, не помогло. Нужно текст, который в ANSI (в строке состояния) осуществить подсвечивание русского текста.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
*sciptr = SendMessage_(NppData\_scintillaMainHandle, #SCI_GETDIRECTPOINTER, 0, 0) ; хендл окна scintilla
If ScintillaMsg(*sciptr, #SCI_GETCODEPAGE) = 0
        *MemoireID = AllocateMemory(5000) ; Выделяем память на 5000 символов (а символ какой длины?)
        If *MemoireID ; Если указатель получен, то
                *MemID_res = AllocateMemory(5000) ; Выделяем память на 5000 символов (а символ какой длины?)
                If *MemID_res ; Если указатель получен, то
                        PokeS(*MemoireID, regex1$)  ; Записываем текст в область памяти в юникоде, так как компилируем в юникоде
                        ; ScintillaMsg(*sciptr, #SCI_SETLENGTHFORENCODE, -1)           
                        ScintillaMsg(*sciptr, #SCI_ENCODEDFROMUTF8, *MemoireID, *MemID_res)            
                        regex1$ = PeekS(*MemID_res)            ; Считываем значение из области памяти
                        ; regex1$ = PeekS(*MemID_res, -1, #PB_Ascii)            ; Считываем значение из области памяти
                        FreeMemory(*MemID_res)
                EndIf
                FreeMemory(*MemoireID)
        EndIf
EndIf
 


я тут сделал 2 выделенных указателя на память, чтобы они не мешали друг-другу. Как я понял первый параметр SCI_ENCODEDFROMUTF8 это входные данные, второй параметр выходные.
Нужен ANSI,а не ASCII (PB_Ascii). Если у нас определяется длина по #Null, нужно ли как то дописывать это в конец строки? Судя по таблице разница только в расположении.

Натестировался с AllocateMemory, пришлось перезагружать комп, конт. меню проводника пропало.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Чт июн 21, 2018 11:38 am 
Не в сети
док

Зарегистрирован: Вс июл 05, 2009 5:55 pm
Сообщений: 90
Благодарил (а): 1 раз.
Поблагодарили: 2 раз.
Пункты репутации: 0
AZJIO оК

_________________
искатель истины


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Чт июн 21, 2018 12:19 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11206
Благодарил (а): 4 раз.
Поблагодарили: 421 раз.
Цитата:
SCI_ENCODEDFROMUTF8(const char *utf8, char *encoded)
SCI_SETLENGTHFORENCODE(int bytes)

SCI_ENCODEDFROMUTF8 converts a UTF-8 string into the document's encoding which is useful for taking the results of a find dialog, for example, and receiving a string of bytes that can be searched for in the document. Since the text can contain nul bytes, the SCI_SETLENGTHFORENCODE method can be used to set the length that will be converted. If set to -1, the length is determined by finding a nul byte. The length of the converted string is returned.
Входной параметр должен быть в UTF-8, а не в юникоде (UCS2). Кодировка выходного параметра неуказанна.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
*sciptr = SendMessage_(NppData\_scintillaMainHandle, #SCI_GETDIRECTPOINTER, 0, 0) ; хендл окна scintilla
If ScintillaMsg(*sciptr, #SCI_GETCODEPAGE) = 0
  *MemoireID = UTF8(regex1$)
  If *MemoireID
    *MemID_res = AllocateMemory(5000)
    If *MemID_res
      ScintillaMsg(*sciptr, #SCI_ENCODEDFROMUTF8, *MemoireID, *MemID_res)
      regex1$ = PeekS(*MemID_res)
      FreeMemory(*MemID_res)
    EndIf
    FreeMemory(*MemoireID)
  EndIf
EndIf



AZJIO писал(а):
Нужен ANSI,а не ASCII
https://ru.wikipedia.org/wiki/Американский_национальный_институт_стандартов
ANSI содержит только английские буквы и знаки препинания (7-ми битная кодировка). Кириллица и другие национальные алфавиты не поддерживаются.

_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Чт июн 21, 2018 12:33 pm 
Не в сети
док

Зарегистрирован: Вс июл 05, 2009 5:55 pm
Сообщений: 90
Благодарил (а): 1 раз.
Поблагодарили: 2 раз.
Пункты репутации: 0
Пётр пока ты тут подскажи, а то запамятовал, есть масив Dim v$(50) адрес на элемент масива @v$(10), но насколько я помню строковой масив содержит список адресов на переменные, как узнать адрес этого списка? по адресу @v$(0) уже идут строки(странно что они еще ниже повторяются подряд) Или я чегото спутал?


Пётр спасибо за ответ что ниже. А я то думаю, что за танци с бубном вокруг @Array(), и почему нет номера (*p = @v$() )
Dim Array.Point(1); Array of points
*Pointer.Point = @Array() ; Store the array address

_________________
искатель истины


Последний раз редактировалось balex1978 Чт июн 21, 2018 1:12 pm, всего редактировалось 1 раз.

Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Чт июн 21, 2018 12:59 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11206
Благодарил (а): 4 раз.
Поблагодарили: 421 раз.
Код:
1
2
3
4
5
6
7
8
9
10
Dim v$(50)
 
v$(0) = "1234"
v$(1) = "5678"
*p = @v$()
 
For i=0 To 1
  Debug PeekS(PeekI(*p))
  *p+SizeOf(Integer)
Next i


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Чт июн 21, 2018 8:43 pm 
Не в сети
док

Зарегистрирован: Чт фев 09, 2017 10:37 am
Сообщений: 183
Благодарил (а): 19 раз.
Поблагодарили: 32 раз.
Пункты репутации: 0
Пётр писал(а):
ANSI содержит только английские буквы и знаки препинания (7-ми битная кодировка). Кириллица и другие национальные алфавиты не поддерживаются.
Несколько лет назад я так и описывал в справке AutoIt3, но мне показалось странным использование ASCII то есть без национального языка, и я снова вбил в гугл, и так кто о чём спорит и представили даже таблицы, и я как то засомневался.

Пётр писал(а):
в UTF-8, а не в юникоде (UCS2).
Это тоже странно писать в справке оба (UTF-8 и юникод) как отличающееся, хотя последнее является обобщающим. UTF-8, как и другие (UTF-16, UTF-32) они все юникод. Тогда то что называется под грифом "юникод", должно конкретно называться UCS2 (или UCS4). Интересно что в виндовом блокноте (на Win10) при сохранении пишет форматы UTF-8 и Юникод, но не использует UCS2, хотя в Notepad++ используется аббревиатура UCS2.

Код:
1
UTF8(regex1$)

такой функции у себя не нашёл но компилятор не пикнул. В общем не заработало, с ANSI поиск не работает. Попробовал с "MakeUTF8Text" ,тоже отрицательный результат.

Пётр писал(а):
Кодировка выходного параметра неуказанна
ну там указано что она будет такой как в документе, чтобы функция поиска с текстом в этой кодировке сработала, то есть по сути нам и не важно, в какой она кодировке, главное результат скормить функции поиска. Я проверю длину возвращаемой строки, может она 5000 символов берёт.
Код:
1
MessageRequester("Сообщение", Str(Len(regex1$)))

Добавил вывод длины строки, ищу текст 11 символов, мессага выдаёт длину 6. :lol: а в попугаях гораздо длиннее.

Один человек пишет что на Windows 8 x64 у него не работает плагин в версии x64, а на 7-ке работает. Это странно, я использую x86 на Windows 10 x64, у меня работает.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: плагин подсветки для Notepad++
СообщениеДобавлено: Чт июн 21, 2018 9:31 pm 
Не в сети
МОДЕРАТОР
Аватар пользователя

Зарегистрирован: Пн апр 09, 2007 4:53 pm
Сообщений: 11206
Благодарил (а): 4 раз.
Поблагодарили: 421 раз.
AZJIO писал(а):
Тогда то что называется под грифом "юникод", должно конкретно называться UCS2
Оно конкретно так и называется. https://www.purebasic.com/documentation ... icode.html
Цитата:
On Windows, PureBasic internally uses the UCS2 encoding which is the format used by the Windows unicode API, so no conversions are needed at runtime when calling an OS function.
В винде юникодные функции (заканчивающиеся на W) работают с кодировкой UCS2 https://ru.wikipedia.org/wiki/Юникод_в_операционных_системах_семейства_Microsoft_Windows
Цитата:
Одной из первых компаний, последовательно внедрявших Юникод, была Майкрософт — Windows NT была первой операционной системой, использовавшей Юникод в системных вызовах. Было выбрано двухбайтное представление символов (UCS-2); начиная с Windows 2000, возможно представление символов дополнительных плоскостей с помощью суррогатных пар UTF-16.


AZJIO писал(а):
такой функции у себя не нашёл но компилятор не пикнул.
Справка от 5.44? Пора бы ее обновить до 5.62. На подходе 5.70.
AZJIO писал(а):
Один человек пишет что на Windows 8 x64 у него не работает плагин в версии x64, а на 7-ке работает.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
ProcedureCDLL setInfo(*NppHandle, *ScintillaMainHandle, *ScintillaSecondHandle)
        NppData\_nppHandle=*NppHandle
        NppData\_scintillaMainHandle=*ScintillaMainHandle
        NppData\_scintillaSecondHandle=*ScintillaSecondHandle
        ;
        ;<< Когда инфа Notepad++ изменилась >>
        ; Ваш код здесь
        ;
        ; мессага на запуске
        MessageRequester("PB Plugin for notepad++", ""+NppData\_nppHandle+#CR$+
                                                    NppData\_scintillaMainHandle+#CR$+
                                                    NppData\_scintillaSecondHandle)
EndProcedure

С notepad++ x64 в окне отображается.
Цитата:
741264
0
3

Дизассемблировал один из плагонов и посмотрел как устроена функция setInfo.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public setInfo
setInfo proc near
 
arg_0= qword ptr  8
 
sub     rsp, 28h
movups  xmm0, xmmword ptr [rcx]
movsd   xmm1, qword ptr [rcx+10h]
movups  cs:hWnd, xmm0
movsd   cs:qword_180025320, xmm1
call   sub_1800034C0
add     rsp, 28h
jmp     sub_180003270
setInfo endp
 

Похоже что вместо передачи трех аргументов передается только один - указатель на структуру, т. е. что-то типа.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  Structure x64_Handle Align #PB_Structure_AlignC
    *NppHandle
    *ScintillaMainHandle
    *ScintillaSecondHandle
  EndStructure
 
  ProcedureCDLL setInfo(*Handle.x64_Handle)
    NppData\_nppHandle=*Handle\NppHandle
    NppData\_scintillaMainHandle=*Handle\ScintillaMainHandle
    NppData\_scintillaSecondHandle=*Handle\ScintillaSecondHandle
    ;
    ;<< Когда инфа Notepad++ изменилась >>
    ; Ваш код здесь
    ;
    ; мессага на запуске
        MessageRequester("PB Plugin for notepad++", ""+NppData\_nppHandle+#CR$+
                                                    NppData\_scintillaMainHandle+#CR$+
                                                    NppData\_scintillaSecondHandle)
  EndProcedure

В этом случае работает.

Посмотрел исходник плагина. В нем такой код.
Код:
1
2
3
4
5
extern "C" __declspec(dllexport) void setInfo(NppData notpadPlusData)
{
        nppData = notpadPlusData;
        commandMenuInit();
}

Т. е. должно быть.
Код:
1
2
3
4
5
6
7
8
9
10
11
12
ProcedureCDLL setInfo(*Npp.NppData)
 
  CopyStructure(*Npp, NppData, NppData)
  ;
  ;<< Когда инфа Notepad++ изменилась >>
  ; Ваш код здесь
  ;
  ; мессага на запуске
  ;     MessageRequester("PB Plugin for notepad++", ""+NppData\_nppHandle+#CR$+
  ;                                                 NppData\_scintillaMainHandle+#CR$+
  ;                                                 NppData\_scintillaSecondHandle)
EndProcedure


_________________
Компьютер позволяет решать все те проблемы, которые до его изобретения не существовали. :) :)


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 50 ]  На страницу Пред.  1, 2, 3, 4  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: Bing [Bot] и гости: 8


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB