Форум » [x]Harbour » Выделение текста мышью в GTWVT на Harbour » Ответить

Выделение текста мышью в GTWVT на Harbour

NickSam: Добрый день, коллеги! После прочтения этого форума заинтересовался терминалом GTWVT, стал на него переводить консольную программу на Harbour но в процессе столкнулся с тем, что как то странно работает выделение мышью текста. Оно начинает работать только если в верхнем левом углу консольного окна нажать "Mark and Copy", начинаю выделение мышью но оно сразу заканчивается не успевая нажать Ctrl-C. Можно ли как то сделать нормальное выделение текста мышью как это сделано в GTWIN терминале?

Ответов - 14

Dima: Это работает чуть не так. Выделяем мышкой и педаль мышки отпускаем. Всё , текст уже в буфере.

NickSam: Dima, спасибо большое. Никогда бы не догадался. А можно как то сделать чтобы каждый раз "Mark and Copy" для очередного выделения не нажимать?

Dima: NickSam пишет: А можно как то сделать чтобы каждый раз "Mark and Copy" для очередного выделения не нажимать? А как часто это нужно ? У "моих" таких потребностей вообще не возникает...


NickSam: Dima пишет: А как часто это нужно ? Dima пишет: "Мои" достаточно часто этим пользуются и, к сожалению, это единственный момент, который мешает переходу на GTWVT.

Sergy: Можно что угодно делать с буфером обмена при помощи нескольких вызовов: xValue := hb_GtInfo( HB_GTI_CLIPBOARDDATA ) - прочитать содержимое буфера обмена hb_GtInfo( HB_GTI_CLIPBOARDDATA, xValue ) - поместить xValue в буфер обмена hb_GtInfo( HB_GTI_CLIPBOARDPASTE ) - вставить содержимое буфера обмена в буфер клавиатуры Остается организовать вызов этих функций наиболее привычным для Ваших юзеров способом: стрелки с шифтом, Ctrl-C/Ctrl-V или ещё как...

NickSam: Sergy пишет: hb_GtInfo( HB_GTI_CLIPBOARDDATA, xValue ) - поместить xValue в буфер обмена У меня все равно остается вопрос: как сформировать этот xValue с помощью выделения мышью не обращаясь каждый раз к "Mark and Copy".

SergKis: NickSam пишет У меня все равно остается вопрос: как сформировать этот xValue с помощью выделения мышью не обращаясь каждый раз к "Mark and Copy". Ловите #define K_LBUTTONDOWN 1002 запоминаете координаты, ловите #define K_MOUSEMOVE 1001 до момента поимки #define K_LBUTTONUP 1003 разница между координатами даст значение xValue (читаете с экрана или еще как ...)

Sergy: NickSam пишет: как сформировать этот xValue с помощью выделения мышью не обращаясь каждый раз к "Mark and Copy". Другого встроенного и универсального решения нет. Если речь идет о редактировании текста - можно посмотреть в соседней ветке, как реализован класс Tedit() и в аналогичных примерах: обычно юзер "привык" к комбинации SHIFT+стрелки. Если речь об "общем" решении в пределах всего приложения, я-бы пошел таким путем: определил через SETKEY() процедуру, которая будет обрабатывать ситуацию "выделить и скопировать" в любом месте программы. После вызова данная процедура через SAVESCREEN() получает текущее содержимое экрана. Его формат - простая строка, в которой чередуется 1 байт с кодом символа и 1 байт цветовыми атрибуами этого символа. Далее, анализируя работу юзера с мышью (см. коды в сообщении выше или inkey.ch) и зная размер экрана (MAXROW(), MAXCOL()), получаете нужный фрагмент строки из SAVESCREEN(), выкидываете из него цветовые атрибуты и вставляете итог в буфер обмена.

SergKis: Sergy пишет определил через SETKEY() процедуру, которая будет обрабатывать ситуацию "выделить и скопировать" в любом месте программы. ... Далее, анализируя работу юзера с мышью ... Давно не работал с wvt терминалом ..., большого анализа и не надо, вроде (или подзабыл уже)[pre2] SET EVENTMASK TO INKEY_ALL ... обработчики SetKey(K_LBUTTONDOWN, {|| ... }) SetKey(K_MOUSEMOVE , {|| ... }) SetKey(K_LBUTTONUP , {|| ... }) SetKey(K_CTRL_C , {|| ... }) ... и т.д. на текстах и др. местах с k := INKEY(0) If ! empty( b := SetKey(k) ) EVal(b, ...) EndIf [/pre2] А тексты с экрана брать SaveScreen, как и было сказано выше

NickSam: Sergy, SergKis спасибо большое за идею. Сделал все так Вы расписали, все получилось, ниже приведен код. Единственно, не получается подкрасить область выделения экрана где находится курсор в Tbrowse и активный Get в Read. То есть это строка экрана попадает в буфер, но визуально другим цветом не выделяется. FUNCTION Main() PUBLIC y1_mouse := 0, x1_mouse := 0, y2_mouse := 0, x2_mouse := 0 PUBLIC lMark := .F., scr_origin := '' SET EVENTMASK TO INKEY_ALL SetKey(K_LBUTTONDOWN, {|| MarkAndCopy() }) SetKey(K_MOUSEMOVE , {|| MarkAndCopy() }) SetKey(K_LBUTTONUP , {|| MarkAndCopy() }) .......... .......... RETURN FUNCTION MarkAndCopy() LOCAL scr := '' LOCAL i := 0, n := 0, cStr := '', len_str := 0 if lastkey () == K_LBUTTONDOWN // Начинаем выделение scr_origin = savescreen() y1_mouse = mrow() x1_mouse = mcol() lMark = .T. elseif lastkey () == K_MOUSEMOVE .and. lMark // Закрашиваем выделенную область экрана y2_mouse = mrow() x2_mouse = mcol() scr = savescreen(y1_mouse,x1_mouse,y2_mouse,x2_mouse) for i = 1 to len(scr) n = i/2 if int(n) == n cStr += chr(224) // Меняем атрибут на цвет выделения else cStr += substr(scr,i,1) endif next restscreen(,,,,scr_origin) restscreen(y1_mouse,x1_mouse,y2_mouse,x2_mouse,cStr) elseif lastkey () == K_LBUTTONUP // Сохраняем в буфер содержимое выделенной области экрана y2_mouse = mrow() x2_mouse = mcol() if y1_mouse <> y2_mouse .or. x1_mouse <> x2_mouse scr = savescreen(y1_mouse,x1_mouse,y2_mouse,x2_mouse) scr = CharOdd(scr) // Отбрасываем атрибуты // Вставляем символ переноса строки между строками экрана len_str = abs(x2_mouse - x1_mouse) + 1 for i = 1 to len(scr) cStr += substr(scr,i,1) n = i/len_str if int(n) == n cStr += chr(10) endif next hb_GtInfo( HB_GTI_CLIPBOARDDATA, cStr ) restscreen(,,,,scr_origin) endif lMark = .F. endif RETURN

SergKis: NickSam пишет не получается подкрасить область выделения экрана где находится курсор в Tbrowse и активный Get в Read. Для покраски, наверно, надо лезть в обработчик Tbrowse ( Userfunc после внутреннего inkey получает работу ), а для GET\READ в класс лезть, как это делать не помню, забыл уже, где то в темах поднимали этот вопрос. А с Tbrowse не работал (только щупал), т.к. еще с Summer 87 с dbf была работа своей таблицы, примерно как в hbedit FMenu сделана. Может кто подскажет как красить, кто в теме. А в тексте выше, не увидел, учет движения мыши справа налево

SergKis: NickSam Попробуйте на K_LBUTTONDOWN организовать свой цикл с iney(0) поимки перемещения мыши и закраски до нажатия K_LBUTTONUP остановки закраски и ожидания K_CTRL_C. Любые другие коды разрывают цикл

NickSam: SergKis, еще раз огромное спасибо за помощь. В таком варианте все получилось. Ниже код, может кому пригодится. FUNCTION Main() SET EVENTMASK TO INKEY_ALL SetKey(K_LBUTTONDOWN, {|| MarkAndCopy() }) .......... .......... RETURN FUNCTION MarkAndCopy() LOCAL y1_mouse := 0, x1_mouse := 0, y2_mouse := 0, x2_mouse := 0 LOCAL scr := '', scr_origin := '' LOCAL i := 0, n := 0, cStr := '', len_str := 0 scr_origin = savescreen() y1_mouse = mrow() x1_mouse = mcol() do while .T. inkey(0) if lastkey () == K_MOUSEMOVE // Закрашиваем выделенную область экрана y2_mouse = mrow() x2_mouse = mcol() scr = savescreen(y1_mouse,x1_mouse,y2_mouse,x2_mouse) cStr = '' for i = 1 to len(scr) n = i/2 if int(n) == n cStr += chr(224) // Меняем атрибут на цвет выделения else cStr += substr(scr,i,1) endif next restscreen(,,,,scr_origin) restscreen(y1_mouse,x1_mouse,y2_mouse,x2_mouse,cStr) elseif lastkey () == K_LBUTTONUP // Сохраняем в буфер содержимое выделенной области экрана y2_mouse = mrow() x2_mouse = mcol() if y1_mouse <> y2_mouse .or. x1_mouse <> x2_mouse scr = savescreen(y1_mouse,x1_mouse,y2_mouse,x2_mouse) scr = CharOdd(scr) // Отбрасываем атрибуты // Вставляем символ переноса строки между строками экрана cStr = '' len_str = abs(x2_mouse - x1_mouse) + 1 for i = 1 to len(scr) cStr += substr(scr,i,1) n = i/len_str if int(n) == n cStr += chr(10) endif next hb_GtInfo( HB_GTI_CLIPBOARDDATA, cStr ) restscreen(,,,,scr_origin) endif exit elseif .T. exit endif enddo RETURN

NickSam: SergKis пишет: А в тексте выше, не увидел, учет движения мыши справа налево Как ни странно, так все нормально работает. Видимо savescreen() сам распознает min-max значения координат.



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