Форум » [x]Harbour » Как закрыть (дополнительное) окно крестиком. » Ответить

Как закрыть (дополнительное) окно крестиком.

Sergy: Добрый день. Для удобства юзеров добавил (отключаемое) окно, в котором параллельно выводится статистика продаж по товару, который просматривается в текущем DBEDIT(). Код такой:[more][pre2]* -------------------- * FUNC DWindowNew(aParams) // отдельное окно LOCAL pGT,tmp,aDim,dw,dh,fw,fh IF IsARRAY(aParams) .AND. LEN(aParams) == 9 aDim := aParams // just link ELSE dw := hb_gtInfo(HB_GTI_DESKTOPWIDTH) dh := hb_gtInfo(HB_GTI_DESKTOPHEIGHT) fw := hb_gtInfo(HB_GTI_FONTWIDTH) fh := hb_gtInfo(HB_GTI_FONTSIZE) aDim := ACLONE(aParams) // clone and modify ASIZE(aDim,9) DEFAULT aDim[1] TO INT(MAXROW()/2) DEFAULT aDim[2] TO INT(MAXCOL()/2) DEFAULT aDim[3] TO fw * (INT( dw/fw ) - aDim[2]) // в правый верхний DEFAULT aDim[4] TO 1 // fh * (INT( dh/fh ) - aDim[1]) // угол экрана DEFAULT aDim[5] TO hb_gtInfo(HB_GTI_WINTITLE) DEFAULT aDim[6] TO SETCOLOR() DEFAULT aDim[7] TO hb_gtInfo(HB_GTI_FONTNAME) DEFAULT aDim[8] TO hb_gtInfo(HB_GTI_FONTWIDTH) DEFAULT aDim[9] TO hb_gtInfo(HB_GTI_FONTSIZE) ENDIF // pGT := hb_gtCreate("WVT") // создаем окно tmp := hb_gtSelect(pGT) // переключаемся на него // SETCURSOR(SC_NONE) SETMODE(aDim[1],aDim[2]) // размеры в символах SETCOLOR(aDim[6]) // hb_gtInfo(HB_GTI_CLOSABLE ,FALSE) // disable close hb_gtInfo(HB_GTI_ALTENTER ,FALSE) // disable Alt+Enter hb_gtInfo(HB_GTI_SETPOS_XY,{aDim[3],aDim[4]}) // положение верхнего левого угла окна hb_gtInfo(HB_GTI_WINTITLE ,aDim[5]) hb_gtInfo(HB_GTI_FONTNAME ,aDim[7]) hb_gtInfo(HB_GTI_FONTWIDTH,aDim[8]) hb_gtInfo(HB_GTI_FONTSIZE ,aDim[9]) hb_gtInfo(HB_GTI_ICONRES, "ICON_03" ) // доп.иконка из ресурсов CLS // включаем отображение окна DWindowSelect(tmp) // переключаемся на основное окно // RETURN pGT // возвращаем указатель на вновь созданное окно для дальнейшей работы[/pre2][/more] Все-бы хорошо, но, блин, "не-идеально": Если НЕ ЗАДАТЬ в свойствах вновь создаваемого окна hb_gtInfo(HB_GTI_CLOSABLE ,FALSE), то нажатие на крестик "дополнительного" (detached) окна приводит к вырубанию всей программы, несмотря на то, что ее "основное" окно, разумеется, нельзя закрыть "крестиком". Если задать (как в примере) - то закрыть окно или "срубить" программу нельзя. Поэтому отдельное окно включается/выключается комбинацией, допустим, Ctrl+F7. Коряга вышла какая-то, если честно... Конечно, можно повесить на виртуальную кнопку HB_K_CLOSE переназначение на K_CTRL_F7 и точно так-же ловить ее в программе - но как тогда отличить - какой именно "крестик" был нажат - на основном окне или на дополнительном? А если дополнительных окон будет несколько? ... Идея с доп. окнами подошла и мне (несложно), и юзерам (удобно и информативно) - но вот "костыль" с Ctrl+F7 мне не нравится... Буду признателен за идеи. Спасибо.

Ответов - 14

Dima: Sergy пишет: Отправлено: Сегодня 22:25. Заголовок: Как закрыть (дополнительное) окно крестиком. - новое! Добрый день. Доброй ночи скорее всего Подумаем.

Dima: А зачем доп инфу выводить в окне ? Рисуй ее где то рядом , в том же окне. Как варик можно пробнуть окна из CT , но это снова окно. PS Покажи скрин. Я имею в виду типа так При движении по бровсу инфа вверху меняется

Dima: Dima пишет: Как варик можно пробнуть окна из CT , но это снова окно. Окно но не WIN , так что вариант Пример: core-master\contrib\hbct\tests\ctwtest.prg


Sergy: Вот такая петрушка - быстро и наглядно выводится сезонность товара. Окно со статистикой можно двигать по экрану куда угодно, менять размер и тп. Положение/размер для каждого юзера сохраняется отдельно в его личных настройках - кому как больше нравится.

Петр: Sergy пишет: Если НЕ ЗАДАТЬ в свойствах вновь создаваемого окна hb_gtInfo(HB_GTI_CLOSABLE ,FALSE), то нажатие на крестик "дополнительного" (detached) окна приводит к вырубанию всей программы, несмотря на то, что ее "основное" окно, разумеется, нельзя закрыть "крестиком". А вы не пробовали использовать связку HB_GTI_CLOSEMODE и HB_GTI_WINHANDLE? #define HB_GTI_CLOSEMODE 74 /* Close event: 0 terminate application, >=1 generate HB_K_CLOSE, 2 disable close button */ pGT := hb_gtCreate("WVT") hwndA := hb_gtInfo( HB_GTI_WINHANDLE ) hb_gtInfo(HB_GTI_CLOSABLE , TRUE) hb_gtInfo(HB_GTI_CLOSEMODE, 1 ) и там уже в обработчике HB_K_CLOSE hwndB := hb_gtInfo( HB_GTI_WINHANDLE ) if( hwndB == hwndA ); pGT := NIL endif

Sergy: Петр пишет: А вы не пробовали использовать связку HB_GTI_CLOSEMODE и HB_GTI_WINHANDLE? Не пробовал. Поковыряюсь в данном направлении. Спасибо.

Dima: Sergy пишет: Поковыряюсь в данном направлении Отпиши если получилось.

Sergy: Не работает. Когда фокус переключается на "дополнительное" окно, любые нажатия на любые кнопки не "доходят" до главного окна, в том числе HB_K_CLOSE.

Dima: Sergy Если есть желание , накидай простой пример , затестим и подумаем.

Петр: Sergy пишет: Не работает. В harbour/tests есть хороший пример wvtext.prg, можете посмотреть. Вот его урезанная версия [pre2] #include "hbgtinfo.ch" #include "inkey.ch" REQUEST HB_GT_WVT_DEFAULT procedure main() local pGT local kX, k Set( _SET_EVENTMASK, HB_INKEY_ALL + HB_INKEY_EXT ) pGT := hb_gtCreate( 'GTWVT' ) hb_gtSelect( pGT ) hb_gtInfo( HB_GTI_CLOSEMODE, 1 ) ? "Main window, press F10" do while .T. kX := Inkey( 0 ) ; k := hb_keyStd( kX ) if k == HB_K_CLOSE if Alert( "Close Application", { "Yes", "No" } ) == 1 quit endif elseif k == K_F10 if hb_mtvm() hb_threadStart( @thFunc() ) else Alert( "MT mode not available. Rebuild this program with -mt switch and try again." ) endif endif enddo return static procedure thFunc() hb_gtReload( hb_gtVersion() ) hb_gtInfo( HB_GTI_CLOSEMODE, 1 ) ? "Second window" do while .T. kX := Inkey( 0 ) ; k := hb_keyStd( kX ) if k == HB_K_CLOSE if Alert( "Close Window", { "Yes", "No" } ) == 1 exit endif endif enddo return [/pre2]

Sergy: Да. Хороший пример. Вот на его основе - примерно то, что происходит в моей программе: [pre2]#include "hbgtinfo.ch" #include "inkey.ch" REQUEST HB_GT_WVT_DEFAULT PROCEDURE main() LOCAL pGT,pMain,k SET( _SET_EVENTMASK, HB_INKEY_ALL + HB_INKEY_EXT ) // pGT := hb_gtCreate( 'GTWVT' ) pMain := hb_gtSelect( pGT ) hb_gtInfo( HB_GTI_CLOSEMODE, 1 ) hb_gtInfo(HB_GTI_WINTITLE ,"Second window") hb_gtInfo(HB_GTI_SETPOS_XY,{600,300}) SETMODE(15,50) // hb_gtSelect( pMain ) hb_gtInfo( HB_GTI_CLOSEMODE, 1 ) hb_gtInfo(HB_GTI_WINTITLE ,"Main window") hb_gtInfo(HB_GTI_SETPOS_XY,{1,1}) // ? "Main window, press any key to show it in second window" // DO WHILE .T. k := hb_keyStd( Inkey( 0 ) ) // IF k == HB_K_CLOSE IF Alert( "Close Application", { "Yes", "No" } ) == 1 QUIT ENDIF ELSE IF k > 256 // ignore mouse moving ELSE ? "Key pressed: ("+CHR(k)+")" ShowInfo(pGT,k) ENDIF ENDIF ENDDO // RETURN * --------------------------- * STATIC FUNC ShowInfo(pGt,nKey) STATIC nCnt := 0 LOCAL pPrev := hb_gtSelect( pGT ) // ? hb_NTOS(++nCnt)+". Key pressed: "+ALLTRIM(STR(nKey)) hb_gtSelect( pPrev ) // RETURN NIL [/pre2] Есть непонятка с местонахождением курсора (почему-то виден в дополнительном окне, а не главном) и потерей фокуса при старте - но это не принципиально в данном случае. Можно сделать hb_gtInfo(HB_GTI_SETFOCUS,pGT), где это необходимо (для WVG).

Петр: Sergy пишет: примерно то, что происходит в моей программе Это больше на клавиатурного шпиона похоже, чем окно статистики попытка №2 поток + мьютекс [pre2] #include "hbgtinfo.ch" #include "inkey.ch" REQUEST HB_GT_WVT_DEFAULT static s_mtxBuffer procedure main() local pMain local key Set( _SET_EVENTMASK, HB_INKEY_ALL + HB_INKEY_EXT ) s_mtxBuffer := hb_mutexCreate() pMain := hb_gtCreate( 'GTWVT' ) hb_gtSelect( pMain ) hb_gtInfo( HB_GTI_CLOSEMODE, 1 ) hb_gtInfo( HB_GTI_WINTITLE, "Main window" ) ? ">" do while .T. key := hb_keyStd( Inkey( 0 ) ) if key == HB_K_CLOSE if Alert( "Close Application", { "Yes", "No" } ) == 1 quit endif elseif key == K_F10 if hb_mtvm() hb_threadStart( @thFunc() ) else hb_gtAlert( "MT mode not available. Rebuild this program with -mt switch and try again." ) endif else if key <= 256 ? "Key pressed: (" + Chr( key ) + ")" hb_mutexNotify( s_mtxBuffer, key ) endif endif enddo return static procedure thFunc() thread static nCount := 0 local nKey, key hb_gtReload( hb_gtVersion() ) hb_gtInfo( HB_GTI_WINTITLE, "Second window" ) hb_gtInfo( HB_GTI_SETPOS_XY, {600, 300} ) hb_gtInfo( HB_GTI_CLOSEMODE, 1 ) ? ">" do while .T. hb_mutexSubscribe( s_mtxBuffer, 0.1, @nKey ) if nKey != Nil hb_keyPut( nKey ) endif key := hb_keyStd( Inkey( 0.1 ) ) if key == HB_K_CLOSE if hb_gtAlert( "Close Window", { "Yes", "No" } ) == 1 exit endif else if key == nKey ? hb_NtoS( ++nCount ) + ". Key pressed: " + AllTrim( Str( key ) ) nKey := Nil endif endif enddo return [/pre2]

Sergy: Спасибо за наводку, но чет как-то получается "из пушки по воробьям". Программа у меня не МТ-шная, поскольку пока не понимаю, где с умом применить многопоточность для складской программы... Но уж точно не для того, чтобы вместо Ctrl+Fx юзер мог нажать крестик...

Sergy: Петр пишет: попытка №2 поток + мьютекс В связи с началом использования LetoDBf, программа "как то сама" вдруг "неожиданно" стала многопоточной. Попытаюсь осознать и применить "попытку N2".



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