Форум » GUI » MiniGUI-Browse- поиск по букве » Ответить

MiniGUI-Browse- поиск по букве

valery2: Извините меня, но очень нужна помощь. С Clipperr-ом работаю давно, в Mini - нет и года. Начальству ну очень нужно поиск в прайс-листе по протому нажатию любой русской буквы. Не долго мудрствуя, определил все клавиши и, в частности русские _DefineHotKey ( , 0 , 192 , {|| poisk(chr(192))} ) // буква "А" и т.д. В Browse все цифры и латинские буквы проходят, а русские - никакой реакции. А начальству вынь да полож.

Ответов - 43, стр: 1 2 3 All

gfilatov: valery2 пишет: определил все клавиши Решение простое, но неэффективное Посмотрите, как это сделать грамотнее в примере из папки samples\Basic\DualBrowse (функция IncrementalSearch()).

valery2: Большое спасибо, попробую.

valery2: Посмотрел, попробовал - ну и наворочено. А мне-то всего и надо - в Browse по нажатию любой клавиши ( особенно русские буквы) не просто стать на запись, где есть эта буква, а вызвать мою функцию Poisk(rr), загнав туда, через параметр, эту самую букву, адальше эта самая функция сама уже будет формировать слова, фразы и осуществлять поиск.


Петр: valery2 пишет: Посмотрел, попробовал - ну и наворочено. Joe написал как смог Найдете более простое и эффективное решение - напишите Григорию, он с удовольствием опубликует.

valery2: Неужели ни у кого не вставала подобная проблема? В Clippere в Dbedit все это элементарно, в одну строчку. А сдесь ... Еслиб было время, да побольше опыта. Потому и прошу помощи.

MMK: valery2 пишет: Еслиб было время В GUI вроде есть TsBrows ,так там по одной букве поиск встроенный должен быть. Ну , а если сам ( в нем же ) то так: obi:bKeyChar={ |nKey| Poisk(nKey,oBi,oWn,oFld ) }

valery2: Спасибо за подсказку! Надо обжевать.

valery2: Еще раз спасибо, но всеэто не то. TsBrowse тянет за собой кучу переделок в уже существующей проге. А у меня в окне еще 2 Browse и им абсолютно не нужны эти навороты. В результате начинаю путаться с управлением и т.д. Не уверен, что переход полностью на TsBrowse по времени переделки программы целесообразней какого-нибудь собственного "изобретения".

КСС: Сейчас не могу предложить ничего конкретного, но несколько лет назад, когда ещё был только MiniGUI, я его тестил и озадачился тем же. И тогда я пошел по пути DBEDIT - нашел в исходнике с определением окон участок кода перехватывающий клавиши в BROWSE и просто добавил в конец (там кажется DO CASE) вызов своей функции. Это был просто эксперимент, но всё получилось. Как это лучше оформить для использования пока не знаю, но планирую вернуться к этому в ближайшие две недели.

valery2: КСС пишет:я пошел по пути DBEDIT - нашел в исходнике с определением окон участок кода перехватывающий клавиши в BROWSE и просто добавил в конец (там кажется DO CASE) вызов своей функции. Это чень интересно. Нельзя-ли ссылочку на исходник DBEDIT, или сам текст исходника на moongo@mail.ru ?!! Весьма презнателен заранее !

valery2: КСС Прошу прощения - Весьма прИзнателен .

Петр: valery2, КСС в принципе предложил тот же путь решения (в общем правильный), что и Joe, только в худшем исполнении. В лучшем случае вы можете получить клон MiniGUI, который не сможете поддерживать. Ну, а в в худшем.. Григорий - пример Joe нужно убирать, пусть пользователи учатся использовать SET EVENTS FUNCTION TO MYEVENTS И пожалуйста исправьте этот фрагмент: Case GetGridvKey(lParam) == 46 // DEL If _HMG_aControlPicture == .t.

КСС: Эта обработка кнопок описана, кажется, в файле исходников h_windows.prg. Как я уже писал, дело было давно и это был эксперимент. Написал это здесь в качестве зацепки для других программистов. Планирую в ближайшее время повторить изыскания, потому что пишу программу на MiniGUI-Ext. Если что-то вразумительное получится - выложу.

valery2: Петр пишет: КСС в принципе предложил тот же путь решения (в общем правильный), что и Joe, только в худшем исполнении. Ваши намерения понятны, но : 1. Используя пример JOE , сразу исчезает MENU в ext форме 2. В h_windows.prg огромное количество переопределенных функций и переменных, существующих в библиотеках, а расследование, что - не нужно и что за собой тянет их удаление занимает много времени. 3. Вы пишите:пусть пользователи учатся использовать SET EVENTS FUNCTION TO MYEVENTS Но по EVENTS практически ничего нет в документации, а примеров - кот наплакал. Теперь Вы вообще хотите убрать пример JOE. А на чем учиться?

gfilatov: Петр пишет: исправьте этот фрагмент: Case GetGridvKey(lParam) == 46 // DEL If _HMG_aControlPicture == .t. Петр Спасибо! Я уже поправил этот свой ляп в новом релизе Может, есть еще какие-либо дополнения для нового релиза?

Петр: "В общем правильный" путь - это переопределение реакции окна BROWSE на событие LVN_KEYDOWN. MiniGUI позволяет делать это в два способа - или переопределять функцию Events или через SET EVENTS FUNCTION TO определить пользовательскую функцию, которая будет делать какие-то специфические для программы вещи и потом уже вызывать глобальную Events() В не зависимости то того, как вы будете переопределять Events(), вы можете столкнуться с проблемой клонов и дальшей несовместимости с сл.версиями MiniGUI (если такие будут) - это и в случае изменения исходников самой библиотеки и в варианте Joe (включении в исходники программы модифицированной Events). Вы это сами подтвердили, приведя пример с MENU ext. Раз так, то нечего пропагандировать плохой стиль программирования. Да - это допустимо, но вы должны делать это осознанно и только в случае если нет других возможностей или вы решили сделать свой клон библиотеки. Теперь о h_windows.prg - я предлагал Григорию вынести Events в отдельный файл, к сожалению это предложение было проигнорировано. Вопрос о документации всплывает не первый раз, и опять же к сожалению я должен констатировать, что у MiniGUI Ext нет сообщества. Желающих работать над совершенствованием библиотеки (исходники, документация) - фактически нет. И количеством примеров это компенсировать нельзя.

gfilatov: Петр пишет: Желающих работать над совершенствованием библиотеки (исходники, документация) - фактически нет. Подтверждением этого может служить обсуждение библиотеки на этом форуме (иногда создается впечатление, что я беседую сам с собой ) Петр пишет: количеством примеров это компенсировать нельзя. Снова согласен, особенно, если эти примеры обычно никто не изучает... Петр пишет: я предлагал Григорию вынести Events в отдельный файл Это не проблема! Если можно, повторите снова свою аргументацию по этому вопросу

valery2: Простите, Петр, но никто здесь не пытается "пропагандировать плохой стиль программирования". Происходит только взаимный обмен опытом и обучение, как на своих так и на чужых положительных и ошибочных примерах. Или это Вы решили нас отшлёпать по попке (настроение такое)? А если серьезно, Вы могли обратить внимание, что в MiniGUI я недавно, и многое для меня еще неясно. Поэтому приму ЛЮБУЮ, но достаточно внятную, помощь.

valery2: В догонку. Вставил следующее: Function MyEvents ( hWnd, nMsg, wParam, lParam ) *------------------------------------------------------------------------------* Local i, x if nMsg == WM_NOTIFY IF GetNotifyCode ( lParam ) == LVN_KEYDOWN ppp(lParam) endif else Events ( hWnd, nMsg, wParam, lParam ) endif Return (0) procedure ppp(lparam) if chr(GetGridvKey( lParam )) $ '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNMйцукенгшщзхъфывапролджэячсмитьбюёЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ' msginfo(chr(GetGridvKey( lParam ))) endif return Прекрасно реагирует, но только на цифры и латинские бувы (причем, почему-то shr() выдает на экран латинские буквы только в верхнем регистре, хотя жму и так и этак), на кирилицу-ноль внимания!

gfilatov: Петр пишет: Теперь о h_windows.prg - я предлагал Григорию вынести Events в отдельный файл, к сожалению это предложение было проигнорировано. Выделил функцию Events() вместе со связанными с ней функциями _OnGetMinMaxInfo(), _SetNextFocus(), _PushEventInfo() и _PopEventInfo() в отдельный h_events.prg

valery2: Еще одна неприятность - перестал работать ON CHANGE . Точнее, срабатывает, если только кликнуть непосредсвенно на строку, а скрул не реагирует.

Петр: valery2 пишет: Поэтому приму ЛЮБУЮ, но достаточно внятную, помощь. Еще раз пересмотрите примеры - в вашем коде заложена возможность достаточно серьезной ошибки. И еще, GetGridvKey возвращает т.н. virtual-key code, для того "правильно" использовать их нужно использовать WinAPI. Но в вашем простом случае можно использовать таблицу перекодировки. Замените процедуру ppp сл.кодом procedure ppp(lparam) Form_1.Title := str(GetGridvKey( lParam )) + str( GetKeyboardMode() ) return и поймете к чему я клоню. GetKeyboardMode() найдете в исходниках MiniGUI. Надеюсь, внятно написал

valery2: Уважаемый Петр. Благодарю Вас за ваше внимание и участие. Применил вашу рекомендацию: Form_1.Title := str(GetGridvKey( lParam )) + str( GetKeyboardMode() ) Даже начал некую перекодировку, но как Вы верно заметили, GetGridvKey возвращает т.н. virtual-key code, причем только в ограниченном диапазоне, т.е. клавиши ",<", ".>", "[{" и т.д. ему, судя по всему, невидимы. Перекодировочка получается неполная.

Петр: valery2 пишет: т.е. клавиши ",<", ".>", "[{" и т.д. ему, судя по всему, невидимы. А зачем Вам это нужно? Я думал, что Вам нужно что-то вроде: /*----------------------*/ Function MyEvents( hWnd, nMsg, wParam, lParam ) Local result := 0 if nMsg == 78 //WM_NOTIFY if GetNotifyCode ( lParam ) == (-155) //LVN_KEYDOWN // if GetKeyboardMode() == 1049 //RU test( GetGridvKey( lparam ) ) // endif else result := Events ( hWnd, nMsg, wParam, lParam ) endif else result := Events ( hWnd, nMsg, wParam, lParam ) endif Return result Procedure test( lparam ) local ch := chr( ToAsciiEx(lparam) ) if ch $ "тестТЕСТ" Form_1.Title := Form_1.Title + " " + ch endif return #pragma BEGINDUMP #include <windows.h> #include "hbapi.h" #include "hbapiitm.h" HB_FUNC( TOASCIIEX ) { HKL hkl = GetKeyboardLayout( 0 ); BYTE KeyState[256]; WORD lpChar; GetKeyboardState( KeyState ); ToAsciiEx( hb_parnl(1), 0, KeyState, &lpChar, 0, hkl ); hb_retnl( LOBYTE( lpChar )); } #pragma ENDDUMP

PSP: gfilatov пишет: Подтверждением этого может служить обсуждение библиотеки на этом форуме (иногда создается впечатление, что я беседую сам с собой Да, такое впечатление есть. Но, имхо, это не потому, что всем пох... Просто люди привыкли к Клипперу, консоль им ближе, чем GUI (тут я сужу по себе). Некоторые пробуют, задают вопросы. И, я думаю, есть уже довольно серьезные приложения. И хочу сказать: БОЛЬШОЕ СПАСИБО за Вашу работу!!!

КСС: Всем доброго утра! Горячие дебаты прошли пока меня не было. За субботу подготовил готовый пример обработки нажатия клавиш и поиска по ним для BROWSE и GRID. С использованием SET EVENTS FUNCTION TO получилось всё очень просто, надёжно, совместимо и наглядно. Может служить примером, которых, как пишут, не хватает. Но я также не решил проблему получения русских букв из виртуального кода. Так что пример работает, но пока только с английскими буковками. Вот сейчас воспользуюсь подсказками Петра и через пару часиков выложу.

КСС: Изменения внёс - всё работает, но вот остался маленький недостаток: виртуальный код возвращают и все функциональные клавиши, и даже после обработки в функии TOASCIIEX() их код попадает в рабочий диапазон клавиш. Например, левый Shift - буква Д, правый - L. Требуется помощь Петра, Григория или Александра. Спасибо.

valery2: Все получилось!!! Я тоже поработал вчера. Спешу принести свою благодарность всем, кто принял живое участие в этой проблемме. Прошу принять особую плагодарность Петра, за указание верного пути и, особенно, за функцию ToAsciiEx. Вот результат: Function MyEvents ( hWnd, nMsg, wParam, lParam ) Local i, x if nMsg == WM_NOTIFY IF GetNotifyCode ( lParam ) == LVN_KEYDOWN ppp( GetGridvKey( lparam ),hWnd, nMsg, wParam, lParam ) else Events ( hWnd, nMsg, wParam, lParam ) endif else Events ( hWnd, nMsg, wParam, lParam ) endif Return (0) procedure ppp(vparam,hWnd, nMsg, wParam, lParam) local ch := '', ch1:=0 if GetKeyboardMode() == 1033 if chr(vparam) $ "1234567890QWERTYUIOPASDFGHJKLZXCVBNM" //** msginfo(chr(vparam )) MyPoisk(chr(vparam)) else Events ( hWnd, nMsg, wParam, lParam ) endif elseif GetKeyboardMode() == 1049 ch := chr( ToAsciiEx(vparam) ) ch1:=ToAsciiEx(vparam) if ch $ "1234567890йцукенгшщзхъфывапролджэчсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ" .or.ch1=255.and.vparam=90 //* MyPoisk(ch) else Events ( hWnd, nMsg, wParam, lParam ) endif endif // * ch1=255.and.vparam=90 - это маленькая буква "я". С остальными значениями vparam это горячие клавиши. //** по аналогичной причине в английской раскладке исключил маленькие буквы. Просто в MyPoisk строку поиска обрабатываю через UPPER(). return #pragma BEGINDUMP #include <windows.h> #include "hbapi.h" #include "hbapiitm.h" HB_FUNC( GETKEYBOARDMODE ) { HKL kbl; HWND CurApp; DWORD idthd; int newmode; CurApp=GetForegroundWindow(); idthd=GetWindowThreadProcessId(CurApp,NULL); kbl=GetKeyboardLayout(idthd); newmode=(int)LOWORD(kbl); hb_retnl(newmode); } HB_FUNC( TOASCIIEX ) { HKL hkl = GetKeyboardLayout( 0 ); BYTE KeyState[256]; WORD lpChar; GetKeyboardState( KeyState ); ToAsciiEx( hb_parnl(1), 0, KeyState, &lpChar, 0, hkl ); hb_retnl( LOBYTE( lpChar )); } #pragma ENDDUMP

КСС: Рад за Valery2, только хочу предостеречь от ошибки - в его процедуре MyEvents события LVN_KEYDOWN перехватываются для всех форм и контролов программы, что чревато последствиями. Обратите внимание, как у меня сделано многократное вложение IF - это как раз для того, чтобы "вырезать" из стандартного обработчика событий только определённые для определённых форм и контролов. Григорий Филатов пишет: Подтверждением этого может служить обсуждение библиотеки на этом форуме (иногда создается впечатление, что я беседую сам с собой Думаю он не прав, многие из нас заинтересованы в проекте. Я лично, не надоедаю ему с указанием обнаруженных ошибок только из уважения к его работе для нас Вот например: 1) Событие ONSIZE окна при активном XP стиле не срабатывает при открытии окна, а в классическом стиле срабатывает сразу при открытии, до каких-либо интерактивных изменений размеров. Событие окна ON RESTORE не работает при восстановлении из свернутого состояния; 2) При изменении заголовка BROWSE после активации окна выравнивание прыгает как ему заблагорассудится. Ещё раз спасибо всем разработчикам - MiniGUI-Ext на удивление получается простым и очень гибким продуктом.

КСС: Выкладываю пример автопоиска для BROWSE и GRID. Всё оптимизировано на многократное использование в большом проекте. Осталась проблема с функциональными клавишами. Но на готовом примере проще будет найти красивае решение. Вот первый файл: //#include "MiniGui.ch" #define WM_NOTIFY 78 #define LVN_KEYDOWN ( - 155 ) //------------------------------------------------------------------------------ FUNCTION MyEvents( hWnd, nMsg, wParam, lParam ) //------------------------------------------------------------------------------ LOCAL i, Result := 0, cFormName := "", cControlName := "" if nMsg = WM_NOTIFY if GetNotifyCode( lParam ) = LVN_KEYDOWN i := Ascan( _HMG_aFormHandles , hWnd ) cFormName := if( i > 0, _HMG_aFormNames[ i ], "" ) i := Ascan( _HMG_aControlHandles, GetHwndFrom( lParam ) ) cControlName := if( i > 0, _HMG_aControlNames[ i ], "" ) if cFormName == "Form_1" .and. cControlName == "Browse_1" Result := Form1Event1( i, lParam ) elseif cFormName == "Form_1" .and. cControlName == "Grid_1" Result := Form1Event2( i, lParam ) elseif cFormName == "Form2" .and. cControlName == "Browse_1" // elseif cFormName == "winPreparChild" .and. cControlName == "Browse_1" // elseif cFormName == "winUsersRights" .and. cControlName == "Grid_1" // else Result := Events( hWnd, nMsg, wParam, lParam ) endif else Result := Events( hWnd, nMsg, wParam, lParam ) endif else Result := Events( hWnd, nMsg, wParam, lParam ) endif RETURN Result //------------------------------------------------------------------------------ #pragma BEGINDUMP #include <windows.h> #include "hbapi.h" #include "hbapiitm.h" HB_FUNC( TOASCIIEX ) { HKL hkl = GetKeyboardLayout( 0 ); BYTE KeyState[256]; WORD lpChar; GetKeyboardState( KeyState ); ToAsciiEx( hb_parnl(1), 0, KeyState, &lpChar, 0, hkl ); hb_retnl( LOBYTE( lpChar )); } #pragma ENDDUMP //------------------------------------------------------------------------------

valery2: КСС Спасибо за замечание, только я это уже заметил, внес у себя ранее. Все отрабатывает без сбоев. Только реализовано это у меня как-то горбато и не краиво. Поэтому пока убрал из примера. А где можно посмотреть Ваш пример?

КСС: А вот и второй. /* * MINIGUI - Harbour Win32 GUI library Demo * * Copyright 2002 Roberto Lopez <harbourminigui@gmail.com> * http://harbourminigui.googlepages.com/ */ #include "minigui.ch" #include "Dbstruct.ch" Function Main Private aRows [20] [3] Private nSortColBrowse := 1, nSortColGrid := 1, cSearchText := "", cPressedKeys := "" REQUEST DBFCDX , DBFFPT SET CENTURY ON SET DELETED ON //------------------------------------------------------------------------------ SET CODEPAGE TO RUSSIAN // Very important for UPPER() SET EVENTS FUNCTION TO MYEVENTS //------------------------------------------------------------------------------ DEFINE WINDOW Form_1 ; AT 0,0 ; WIDTH 640 HEIGHT 480 ; TITLE "MiniGUI Browse/Grid ColumnSearch Demo" ; MAIN NOMAXIMIZE ; ON INIT OpenTables() ; ON RELEASE CloseTables() DEFINE MAIN MENU POPUP 'File' ITEM 'Exit' ACTION Form_1.Release END POPUP POPUP 'Help' ITEM 'About' ACTION MsgInfo ("MiniGUI Browse/Grid ColumnSearch Demo") END POPUP END MENU DEFINE STATUSBAR STATUSITEM 'HMG Power Ready' END STATUSBAR @ 10,10 BROWSE Browse_1 ; WIDTH 610 ; HEIGHT 200 ; HEADERS { 'Code' , 'First Name' , 'Last Name', 'Birth Date', 'Married' , 'Biography' } ; WIDTHS { 100 , 150 , 150 , 150 , 150 } ; WORKAREA Test ; FIELDS { 'Test->Code' , 'Test->First' , 'Test->Last' , 'Test->Birth' , 'Test->Married' } ; VALUE 1 ; JUSTIFY { BROWSE_JTFY_RIGHT, BROWSE_JTFY_CENTER, BROWSE_JTFY_CENTER, ; BROWSE_JTFY_CENTER, BROWSE_JTFY_CENTER } ; ON HEADCLICK { {|| BrowseHeadClick(1)}, {|| BrowseHeadClick(2)}, , , } ; ON GOTFOCUS {|| BrowseHeadClick( nSortColBrowse ) } aRows [1] := {'Simpson','Homer','555-5555'} aRows [2] := {'Петров','Иван','324-6432'} aRows [3] := {'Smart','Max','432-5892'} aRows [4] := {'Иванов','Андрей','894-2332'} aRows [5] := {'Русский','James','346-9873'} aRows [6] := {'Сидоров','Сергей','394-9654'} aRows [7] := {'Flanders','Ned','435-3211'} aRows [8] := {'Калугина','Анна','123-1234'} aRows [9] := {'Pedemonti','Flavio','000-0000'} aRows [10] := {'Gomez','Juan','583-4832'} aRows [11] := {'Попова','Ирина','321-4332'} aRows [12] := {'Borges','Javier','326-9430'} aRows [13] := {'Альварес','Alberto','543-7898'} aRows [14] := {'Гонсалес','Ольга','437-8473'} aRows [15] := {'Batistuta','Gol','485-2843'} aRows [16] := {'Vinazzi','Amigo','394-5983'} aRows [17] := {'Котлов','Flavio','534-7984'} aRows [18] := {'Ладыко','Геннадий','854-7873'} aRows [19] := {'Теплицын','Alejandra','???-????'} aRows [20] := {'Reyes','Monica','432-5836'} @ 220,10 GRID Grid_1 ; WIDTH 610 ; HEIGHT 170 ; HEADERS {'Column 1','Column 2','Column 3'} ; WIDTHS {140,140,140} ; ITEMS aRows ; ON HEADCLICK { {|| GridHeadClick(1)}, {|| GridHeadClick(2)}, } ; ON GOTFOCUS {|| GridHeadClick( nSortColGrid ) } END WINDOW CENTER WINDOW Form_1 ACTIVATE WINDOW Form_1 Return Nil Function BrowseHeadClick( nCol ) if nCol = 1 set order to tag "Code" nSortColBrowse := 1 cPressedKeys := "" cSearchText := "Sort&Search by < " + "Code" + " >: " Form_1.Browse_1.Header( 1 ) := 'Code ' +chr(94) Form_1.Browse_1.Header( 2 ) := 'First Name ' +chr(45) elseif nCol = 2 set order to tag "First" nSortColBrowse := 2 cPressedKeys := "" cSearchText := "Sort&Search by < " + "First Name" + " >: " Form_1.Browse_1.Header( 1 ) := 'Code ' +chr(45) Form_1.Browse_1.Header( 2 ) := 'First Name ' +chr(94) endif Form_1.Browse_1.Refresh Form_1.StatusBar.Item(1) := cSearchText Return Nil Function GridHeadClick( nCol ) Local i if nCol = 1 aRows := asort( aRows,,, { |x, y| x[1] < y[1] } ) // Must be Refresh for i = 1 to len( aRows ) Form_1.Grid_1.Item( i ) := aRows[ i ] next nSortColGrid := 1 cPressedKeys := "" cSearchText := "Sort&Search by < " + "Column 1" + " >: " Form_1.Grid_1.Header( 1 ) := 'Column 1 ' +chr(94) Form_1.Grid_1.Header( 2 ) := 'Column 2 ' +chr(45) elseif nCol = 2 aRows := asort( aRows,,, { |x, y| x[2] < y[2] } ) // Must be Refresh for i = 1 to len( aRows ) Form_1.Grid_1.Item( i ) := aRows[ i ] next nSortColGrid := 2 cPressedKeys := "" cSearchText := "Sort&Search by < " + "Column 2" + " >: " Form_1.Grid_1.Header( 1 ) := 'Column 1 ' +chr(45) Form_1.Grid_1.Header( 2 ) := 'Column 2 ' +chr(94) endif Form_1.Grid_1.Value := if( Form_1.Grid_1.Value = 0, 1, Form_1.Grid_1.Value ) Form_1.StatusBar.Item(1) := cSearchText Return Nil Procedure OpenTables() if !file("test.dbf") CreateTable() endif Use Test index Test Via "DBFCDX" set order to tag "Code" Go Top Form_1.Browse_1.Value := RecNo() BrowseHeadClick( 1 ) Return Procedure CloseTables() Use Return Procedure CreateTable LOCAL aDbf[5][4] aDbf[1][ DBS_NAME ] := "Code" aDbf[1][ DBS_TYPE ] := "Numeric" aDbf[1][ DBS_LEN ] := 10 aDbf[1][ DBS_DEC ] := 0 // aDbf[2][ DBS_NAME ] := "First" aDbf[2][ DBS_TYPE ] := "Character" aDbf[2][ DBS_LEN ] := 25 aDbf[2][ DBS_DEC ] := 0 // aDbf[3][ DBS_NAME ] := "Last" aDbf[3][ DBS_TYPE ] := "Character" aDbf[3][ DBS_LEN ] := 25 aDbf[3][ DBS_DEC ] := 0 // aDbf[4][ DBS_NAME ] := "Married" aDbf[4][ DBS_TYPE ] := "Logical" aDbf[4][ DBS_LEN ] := 1 aDbf[4][ DBS_DEC ] := 0 // aDbf[5][ DBS_NAME ] := "Birth" aDbf[5][ DBS_TYPE ] := "Date" aDbf[5][ DBS_LEN ] := 8 aDbf[5][ DBS_DEC ] := 0 // DBCREATE("Test", aDbf, "DBFCDX") Use test Via "DBFCDX" zap For i:= 1 To 100 append blank Replace code with i Replace First With aRows[Random(20)][1] Replace Last With 'Last Name '+ Str(i) Replace Married With .t. replace birth with date()+i-10000 Next i Index on str(Code,10) Tag "Code" To "Test" Index on upper(First) Tag "First" To "Test" Use Return //------------------------------------------------------------------------------ #DEFINE NATION_CHARS ; "`1234567890-=\~!@#$%^&*()_+/.,|QWERTYUIOPASDFGHJKLZXCVBNMЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ" //------------------------------------------------------------------------------ Function Form1Event1( i, lParam ) //------------------------------------------------------------------------------ Local nLastRec := 1 Local nVirtKey := GetGridvKey( lParam ) Do Case /* Case nVirtKey == 65 // A if GetAltState() == -127 .or. GetAltState() == -128 // ALT if _HMG_acontrolmiscdata1 [2] == .T. _BrowseEdit ( _hmg_acontrolhandles , _HMG_acontrolmiscdata1 [4] ,; _HMG_acontrolmiscdata1 [5] , _HMG_acontrolmiscdata1 [3] ,; _HMG_aControlInputMask , .t. , _HMG_aControlFontColor ) EndIf EndIf */ Case nVirtKey == 46 // DEL *If _HMG_aControlPicture == .t. If MsgYesNo( _HMG_BRWLangMessage [1] , _HMG_BRWLangMessage [2] ) == .t. _BrowseDelete('','',i) EndIf *EndIf Case nVirtKey == 36 // HOME _BrowseHome('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 35 // END _BrowseEnd('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 33 // PGUP _BrowsePrior('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 34 // PGDN _BrowseNext('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 38 // UP _BrowseUp('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 40 // DOWN _BrowseDown('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case ( Upper( chr( ToAsciiEx(nVirtKey) ) ) $ NATION_CHARS ) .or. nVirtKey = 8 if nVirtKey = 8 // BackSpace cPressedKeys := left( cPressedKeys, len(cPressedKeys)-1 ) else cPressedKeys := cPressedKeys + Upper( chr( ToAsciiEx(nVirtKey) ) ) endif Form_1.StatusBar.Item(1) := cSearchText + cPressedKeys nLastRec := recno() *if lSearchFromTop go top *endif if nSortColBrowse = 1 if ! dbseek( str(val(cPressedKeys), 10) ) go nLastRec endif elseif nSortColBrowse = 2 if ! dbseek( cPressedKeys ) go nLastRec endif endif Form_1.Browse_1.Value := recno() Return 1 Otherwise cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText EndCase RETURN 0 //------------------------------------------------------------------------------ Function Form1Event2( i, lParam ) //------------------------------------------------------------------------------ Local nLastRec := 1, nFindElem := 0 Local nVirtKey := GetGridvKey( lParam ) Do Case Case nVirtKey == 36 // HOME _GridHome('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 35 // END _GridEnd('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 33 // PGUP _GridPgUp('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 34 // PGDN _GridPgDn('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 38 // UP _GridPrior('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case nVirtKey == 40 // DOWN _GridNext('','',i) cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText Return 1 Case ( Upper( chr( ToAsciiEx(nVirtKey) ) ) $ NATION_CHARS ) .or. nVirtKey = 8 if nVirtKey = 8 // BackSpace cPressedKeys := left( cPressedKeys, len(cPressedKeys)-1 ) else cPressedKeys := cPressedKeys + Upper( chr( ToAsciiEx(nVirtKey) ) ) endif Form_1.StatusBar.Item(1) := cSearchText + cPressedKeys nLastRec := Form_1.Grid_1.Value nFindElem := ascan( aRows, { | x | left( upper( x[nSortColGrid] ), len(cPressedKeys) ) == cPressedKeys } ) if nFindElem > 0 Form_1.Grid_1.Value := nFindElem else Form_1.Grid_1.Value := nLastRec endif Return 1 // Must be 1 to disable standard search procedure Otherwise cPressedKeys := "" Form_1.StatusBar.Item(1) := cSearchText EndCase RETURN 0 //------------------------------------------------------------------------------ #include "MyEvents.prg" //------------------------------------------------------------------------------

valery2: КСС Спасибо за замечание, только я это уже заметил, внес у себя ранее. Все отрабатывает без сбоев. Только реализовано это у меня как-то горбато и некрасиво. Поэтому пока убрал из примера. А где можно посмотреть Ваш пример?

valery2: Извините, нечаянно кликнул дважды.

КСС: На всякий случай, для новичков: первый файл обзываем MyEvents.prg, второй - как хотите. Копируете оба файла в новый каталог каталога SAMPLES\BASIC. Берём любой файл Compile.bat из примеров, копируем себе и меняем там имя файла на своё, которое вы дали второму модулю.

Andrey: Спасибо КСС за пример, их всегда нехватает !

_sergey: добрый день. Решил попробовать пример KCC, скачал minigui+harbour с http://harbourminigui.googlepages.com/, сохранил файлы КСС, запустил компиляцию, получил ошибку: [pre]Harbour Beta build 0.99-3 Intl. Copyright 1999-2007, http://www.harbour-project.org/ HMG build 2.0.031 - http://harbourminigui.googlepages.com/ Compiling 'main2.prg'... main2.prg(20) Error E0030 Syntax error: "syntax error at 'EVENTS'" 1 error[/pre] что я сделал не так? может вы используете xharbour?

КСС: Мы используем (большинство) MiniGUI-Ext [url=http://hmgextended.com/files/CONTRIB/hmg-1.4-48-setup.zip ]click here[/url]

КСС: Чё-то не так показывает http://hmgextended.com/files/CONTRIB/hmg-1.4-48-setup.zip

_sergey: однако, сколько версий minigui в интернете! 1) Roberto Lopez http://harbourminigui.googlepages.com 2) Григорий Филатов http://minigui.mylivepage.ru 3) ещё и http://hmgextended.com !

_sergey: спасибо, КСС, запустился пример! маленькое замечание: переключение на другую раскладку ([ctrl]+[shift]) добавляется в строку поиска примером интересуюсь просто так, посмотреть на minigui

valery2: В общем, решил все-таки выложить свой, хоть и корявый, но более компактный и абсолютно без глюков: Function MyEvents ( hWnd, nMsg, wParam, lParam ) Local i, x, cFormName := "", cControlName := "" if nMsg == WM_NOTIFY IF GetNotifyCode ( lParam ) == LVN_KEYDOWN i := Ascan( _HMG_aFormHandles , hWnd ) cFormName := if( i > 0, _HMG_aFormNames[ i ], "" ) i := Ascan( _HMG_aControlHandles, GetHwndFrom( lParam ) ) cControlName := if( i > 0, _HMG_aControlNames[ i ], "" ) if cFormName == "Window_1" .and. cControlName == "Browse_1" ppp( GetGridvKey( lparam ),hWnd, nMsg, wParam, lParam ) else Events ( hWnd, nMsg, wParam, lParam ) endif else Events ( hWnd, nMsg, wParam, lParam ) endif else Events ( hWnd, nMsg, wParam, lParam ) endif Return (0) procedure ppp(vparam,hWnd, nMsg, wParam, lParam) local ch := '', ch1:=0 local i local perkod1[74] // массив кодов русских букв local perkod2[74] // массмв кодов клавиш perkod1[1]:=48 perkod1[2]:=49 // а дальше просто топором и кувалдой perkod1[3]:=50 perkod1[4]:=51 // первые 10 - цифры perkod1[5]:=52 perkod1[6]:=53 perkod1[7]:=54 perkod1[8]:=55 perkod1[9]:=56 perkod1[10]:=57 perkod1[11]:=233 // далее идут русские буквы, сначала маленькие, потом заглавные, но не по алфавиту, по клавиатуре - perkod1[12]:=246 // слева->направо, сверху-> вниз perkod1[13]:=243 perkod1[14]:=234 perkod1[15]:=229 perkod1[16]:=237 perkod1[17]:=227 perkod1[18]:=248 perkod1[19]:=249 perkod1[20]:=231 perkod1[21]:=245 perkod1[22]:=250 perkod1[23]:=244 perkod1[24]:=251 perkod1[25]:=226 perkod1[26]:=224 perkod1[27]:=239 perkod1[28]:=240 perkod1[29]:=238 perkod1[30]:=235 perkod1[31]:=228 perkod1[32]:=230 perkod1[33]:=253 perkod1[34]:=255 perkod1[35]:=247 perkod1[36]:=241 perkod1[37]:=236 perkod1[38]:=232 perkod1[39]:=242 perkod1[40]:=252 perkod1[41]:=225 perkod1[42]:=254 perkod1[43]:=201 perkod1[44]:=214 perkod1[45]:=211 perkod1[46]:=202 perkod1[47]:=197 perkod1[48]:=205 perkod1[49]:=195 perkod1[50]:=216 perkod1[51]:=217 perkod1[52]:=199 perkod1[53]:=213 perkod1[54]:=216 perkod1[55]:=212 perkod1[56]:=219 perkod1[57]:=194 perkod1[58]:=192 perkod1[59]:=207 perkod1[60]:=208 perkod1[61]:=206 perkod1[62]:=203 perkod1[63]:=176 perkod1[64]:=198 perkod1[65]:=221 perkod1[66]:=223 perkod1[67]:=215 perkod1[68]:=209 perkod1[69]:=204 perkod1[70]:=200 perkod1[71]:=210 perkod1[72]:=220 perkod1[73]:=193 perkod1[74]:=222 perkod2[1]:=48 perkod2[2]:=49 perkod2[3]:=50 perkod2[4]:=51 perkod2[5]:=52 perkod2[6]:=53 perkod2[7]:=54 perkod2[8]:=55 perkod2[9]:=56 perkod2[10]:=57 perkod2[11]:=81 perkod2[12]:=87 perkod2[13]:=69 perkod2[14]:=82 perkod2[15]:=84 perkod2[16]:=89 perkod2[17]:=85 perkod2[18]:=73 perkod2[19]:=79 perkod2[20]:=80 perkod2[21]:=219 perkod2[22]:=221 perkod2[23]:=65 perkod2[24]:=83 perkod2[25]:=68 perkod2[26]:=70 perkod2[27]:=71 perkod2[28]:=72 perkod2[29]:=74 perkod2[30]:=75 perkod2[31]:=76 perkod2[32]:=186 perkod2[33]:=222 perkod2[34]:=90 perkod2[35]:=88 perkod2[36]:=67 perkod2[37]:=86 perkod2[38]:=66 perkod2[39]:=78 perkod2[40]:=77 perkod2[41]:=188 perkod2[42]:=190 perkod2[43]:=81 perkod2[44]:=87 perkod2[45]:=69 perkod2[46]:=82 perkod2[47]:=84 perkod2[48]:=89 perkod2[49]:=85 perkod2[50]:=73 perkod2[51]:=79 perkod2[52]:=80 perkod2[53]:=219 perkod2[54]:=221 perkod2[55]:=65 perkod2[56]:=83 perkod2[57]:=68 perkod2[58]:=70 perkod2[59]:=71 perkod2[60]:=72 perkod2[61]:=74 perkod2[62]:=75 perkod2[63]:=76 perkod2[64]:=86 perkod2[65]:=222 perkod2[66]:=90 perkod2[67]:=88 perkod2[68]:=67 perkod2[69]:=86 perkod2[70]:=66 perkod2[71]:=78 perkod2[72]:=77 perkod2[73]:=188 perkod2[74]:=190 if GetKeyboardMode() == 1033 if chr(vparam) $ "1234567890QWERTYUIOPASDFGHJKLZXCVBNM" MyPoisk(chr(vparam )) else Events ( hWnd, nMsg, wParam, lParam ) endif elseif GetKeyboardMode() == 1049 ch := chr( ToAsciiEx(vparam) ) ch1:=ToAsciiEx(vparam) if ch $ "1234567890йцукенгшщзхъывапролджэяфчсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ" if ascan(perkod2,vparam)>0 if ascan(perkod1,ch1)=ascan(perkod2,vparam) // вот тут и исчезают глюки MyPoisk(ch) else Events ( hWnd, nMsg, wParam, lParam ) endif else Events ( hWnd, nMsg, wParam, lParam ) endif else Events ( hWnd, nMsg, wParam, lParam ) endif endif return

КСС: _Sergey пишет: однако, сколько версий minigui в интернете! Только две версии - MiniGUI Роберто Лопеса (и команды) и MiniGUI-Ext - это в определённый момент ответвившийся проект, который сопровождает, на сколько я знаю, Григорий Филатов (и команда), который здесь часто бывает А то, что функциональные клавиши порождают код совпадающий с кодом алфавита и заголовки колонок BROWSE прыгают при смене их заголовков я писал в начале, как о имеющемся недостатке. Вот Valery2 вроде бы нашел решение, но оно не очень красивое Я надеялся, что разработчики помогут нам красиво "расковырять" этот виртуальный код нажатой клавиши. Если нет - будем сами, кто как сможет Прыгающие заголовки колонок BROWSE надеюсь разработчики поправят.



полная версия страницы