Вы здесь

bBrowser: Охота на дроздов

Мерлезонский балет
У людей – Зима, а у меня за окном тарабанит серый однотонный дождь. День короткий и в четыре – уже темно. Незаметно подползает скука и, зевая, заглядывает в глаза. Стоп, надо переключиться и заняться чем-то полезным. Самое время подвести черту под старой темой, написать документацию, составить список дел или, как сейчас – сделать маленькую заметку в дневнике.
 
В начале года в разделе проектов я выложил свой класс msArrayServer. Потом, совершенно неожиданно один из читателей решил поискать и нашёл на нашем сайте класс msMySQL. Видимо, что-то почитал о нём через Гугл-переводчик и пару раз довольно прямо спросил, что я считаю проблемным в классе bBrowser при работе с AdoRecordSet.
 
Потому, счёл нужным ещё раз вернуться к теме использования bBrowser-а и недоразумений, связанных с этим. Собственно, наверное, в ближайшее время это будет моя последняя заметка о bBrowser. Есть много других интересных тем. А пока позволю себе продолжить.
 
Я очень уважаю создателя и автора bBrowser. Это настоящий художник. Но, нет пределу совершенству. Поэтому, я могу видеть его произведение в другом свете, в другом измерении. Как говориться, «что русскому – хорошо, то немцу – смерть». И мне кажется, что я ощущаю, в каком направлении он думает. Но мне хочется иного. Потому, я написал свой класс msArrayServer, как альтернативу bArrayServer. Будет ли альтернатива браузеру – не знаю, но я знаю, какая мне нужна.
 
По поводу высказанных в переписке с читателями замечаний, что неплохо бы мне «вывалить» все ошибки и недоработки, которые я нашёл – я уже отвечал. И позволю себе ответить ещё раз: я не нанимался находить и исправлять ошибки, мне за это не платят. Я делаю свою работу, что-то нахожу, что-то исправляю, чем-то считаю возможным поделиться. Кое-что расскажу и сейчас (только ниже).
 
Ещё раз хочу подчеркнуть, что «свинья лужу найдёт». Они всегда были, есть и будут. Они есть у меня, они есть у других. Не ошибается только тот, кто ничего не делает. И особенно тяжело тому, кто идёт впереди. Поэтому, со всей искренностью – ещё раз снимаю шляпу и низко кланяюсь перед Joachim Bieler.
 
Пожалуй, начну со своей ошибки. В начале прошлого года я посоветовал автору добавить (в режиме правки данных) обработку события выбора «мышкой» в списке ComboBox-а нужной позиции. Прислал пример. Достаточно простой. Автор пошёл навстречу. Я вскользь проверил обновление, но глубоко тестировать не стал. А через время, меня стали тревожить пользователи с жалобой, что раньше можно было при редактировании (в ячейках, где выбор данных делается из ComboBox) с помощью клавиатуры, простым набором первых символов текста перемещаясь по списку значений. А теперь, приходится список всегда раскрывать (F4), а иначе – никак. Короче, ай-яй-яй, потеря времени…
 
Ясное дело, что обработку события выбора «мышкой» нужно делать только тогда, когда список открыт. А когда список закрыт – пропускать. Иначе, это будет перебивать работу клавиатуры. И я изменил метод EventHandler():
 
 
METHOD EventHandler( oEvent ) CLASS msBrowser
 
      LOCAL iMessage AS DWORD
      LOCAL oObj AS OBJECT
 
 
      iMessage := oEvent:uMsg
 
      IF iMessage = WM_COMMAND .AND. oEvent:LParam <> 0
 
      // CBN_SELENDOK - Указывает, что выбор, сделанный в выпадающем списке,
      //                в то время как он был раскрыт, должен быть принят.
 
            // Проверяем объект: КомбоБох ли это?
            oObj := SELF:oEditSpec:Edit
            IF .NOT. oObj == NULL_OBJECT .AND. IsInstanceOf( oObj, #ComboBox ) .AND. HiWord( oEvent:WParam ) == CBN_SELENDOK
 
                  SELF:oCommandOwner:Dispatch( oEvent )
 
                  // Еслиредактируем
                  IF SELF:InEdit()
 
                        // Если список открыт
                        IF SendMessage( oObj:Handle(), CB_GETDROPPEDSTATE, 0, 0L ) <> 0
 
                             IF !SELF:EditClose() // Заканчиваем
 
                                   SELF:EditCancel() // Иначе - прерываем ...
                             ENDIF
                        ENDIF
                  ENDIF
 
                  RETURN SELF:oCommandOwner:EventReturnValue
            ENDIF
***
***
 
Из прочих претензий к автору, могу продолжить, что мне не нравится, как он делает ComboBox в методе EditCreate(). Я понимаю, что люди спешат, но остаюсь при своём. В его варианте не хватает возможности управлять длиной и шириной списка, возможностью задать стиль. Примеры не даю. Хочется увидеть-почитать, как это делают другие.
 
А взамен, могу похвастаться, как прошлым летом на досуге «победил» глюк с перемещением фокуса в окне с bBrowser-ом при помощи клавиши TAB. В чём суть проблемы? Она несколько экзотическая. Если на основное окно типа DialogWindow поместить «закладки» (TabControl), а на закладку положить подокно с bBrowser-ом, то фокус по основному окну будет прыгать правильно. Если же, в качестве основного окна применить DataWindow (а это очень частое явление), то при попадании фокуса в закладку, где лежит bBrowser – он уже не выходит. Чудеса!
 
А суть оказалась в обработке событий bBrowser-ом. Именно здесь причина загадочного поведения. :))   И это дело я решил кардинально: с помощью обработки события нажатия клавиши TAB в методе EventHandler() и полного переписывания метода Move2Control(). Так что теперь, как говорил Винни Пух: «и входит… и выходит!»
 
Наверное, некоторые смотрели мою демонстрационную версию программы для СТО и магазина запчастей. Практически везде в браузерах сделано переключение и изменение сортировки данных щелчком «мышкой» на нужном заголовке колонки. Хорошее это дело. Пользователям нравится, но тоже – пришлось «попотеть». Как и многие, я смотрел примеры, которые шли вместе с bBrowser-ом. Хорошее подспорье. Но, пришлось кое-что переделать. Например, учесть скрытую ошибку, содержащуюся в этой строке (см. bSample - SortMarker):
 
// create bCompoundValue for column caption
ocvCaption := bCompoundValue{}
IF aoColumn[iPos]:ValType="N"
 
      // fieldname on the right side, sort direction on the left side
      ocvCaption:AddValue(bCompoundValue{aoColumn[iPos]:Caption, Point{20, 0}, Dimension{aoColumn[iPos]:Width-6, -1}})
      ocvCaption:AddValue(bCompoundValue{"", Point{2, -1}, Dimension{13, -1},,,, oFont})
ELSE
      // fieldname on the left side, sort direction on the right side
                        ocvCaption:AddValue(bCompoundValue{aoColumn[iPos]:Caption, Point{0, 0}, Dimension{aoColumn[iPos]:Width-6, -1}})
      ocvCaption:AddValue(bCompoundValue{"", Point{aoColumn[iPos]:Width, -1}, Dimension{13, -1},,,, oFont})
ENDIF
 
А если начальная ширина колонки окажется меньше 6-и? Или такого не бывает?
 
Но, больше всего проблем у меня вызвало то, что для колонок с числовыми данными по умолчанию сделано выравнивание справа. Это удобно. Только, такое «равнение» и для заголовка. А что это значит? А это значит, что если пользователь сузит столбец, то знак сортировки визуально исчезнет. Неудобно. Но, можно поменять местами текст заголовка и сам значок. Тогда испортиться выравнивание текста. Ага, ну можно задать выравнивание текста заголовка принудительно. Можно, но мне это надоело. Я взял и закомментировал пару строк в методе DrawCaption():
 
IF iCaptionAlignmentH=BALIGN_AUTO
      IF IsInstanceOf(oColumn, #bGroupColumn)
            iCaptionAlignmentH := BALIGN_CENTER
 
// Не надо мне выравнивание справа! (только слева!!!)
//    ELSEIF IVarGet(oColumn, #ValType) == "N"
//          iCaptionAlignmentH := BALIGN_RIGHT
      ELSE
            iCaptionAlignmentH := BALIGN_LEFT
      ENDIF
ENDIF
 
 
У каждого поэта свои стихи, а у художника – краски.
 
 
По просьбе Joachim Bieler-а тексты из SDK стараюсь сокращать. Так что – не обессудьте. Некоторые вещи специально не описал – пусть это станет заданием для «знаек». Вообще, приятно пообщаться с умными людьми. Хотелось бы, чтобы они заходили почаще. :))
 
 
 
Просто интересная информация.
 
Мерлезо́нский балет (часто также Марлезо́нский балет, от фр. Le ballet de la Merlaison, букв. «Балет дроздования», то есть «Балет об охоте на дроздов») — балет в 16 актах, поставленный королём Франции Людовиком XIII. Традиция проведения подобных придворных балетов (франц.) появилась во Франции во время правления Генриха III и переживала расцвет в эпоху Людовика XIII. Эти балеты исполнялись членами королевской семьи, придворными, профессиональными танцорами, и были красочными представлениями, часто сочетавшими хореографию, вокальную и инструментальную музыку, поэзию и театр.
 
Мерлезонский балет был исполнен 15 марта 1635 года в замке Шантийи и 17 марта в аббатстве Ройомон. Людовик XIII, с детства увлекавшийся музыкой и танцами и получивший прекрасное музыкальное образование, выступил автором всех составляющих Мерлезонского балета (сюжет, музыка, хореография, эскизы декораций и костюмов). За сюжетную основу балета была взята охота на дроздов — одно из любимых развлечений короля. Сам Людовик исполнил в балете две небольшие роли: торговки приманками (в 3 акте) и крестьянина (в 13 акте).
 
 

Комментарии

i love your website and i think you did a fantastic job so please keep it up.

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer