Форум » [x]Harbour » Пара простых вопросов ;) » Ответить

Пара простых вопросов ;)

Dima: 1. Как узнать что путь к папке из которой запускается программа имеет символы кирилицы ? На ум приходит такой способ [pre2] proc main() local a REQUEST HB_LANG_RU866 HB_LANGSELECT("RU866") REQUEST HB_CODEPAGE_RU866 hb_cdpSelect( "RU866" ) a:=curdir() ? a if hb_oemtoansi(a)#a ? "Есть кирилица" endif wait RETURN NIL [/pre2] Есть еще метода ? 2. Как узнать что путь к папке из которой запускается программа имеет длинные имена ? На вскидку приходит вариант разбить на токены с разделителем "\" и затем чекать длины всех токенов. Есть еще метода ?

Ответов - 85, стр: 1 2 3 4 5 All

Dima: Haz Спасибо мастеру по регулярным выражениям ! ;) Да так подойдет. Описания что то не нашел я на hb_RegExSplit , интересная функция.

Dima: Haz пишет: |\ Игорь извини что дергаю в выходной. Что означает эта пара символов ?

Haz: Dima пишет: Что означает эта пара символов | - это знак или \ - это модификатор который говорит что . ( точка ) не любой один символ а именно точка на счет мастера ты погорячился я сам их редко применяю и все время со шпаргалками hb_RegExSplit у Александра на сайте есть http://www.kresin.ru/hrbfaq_3.html#Doc9


Dima: OK. Спасибо

Dima: В функции работающей(добавленной) через HB_IDLEADD() можно завершить работу основной программы через QUIT он же __Quit() . Попробовал тоже самое сделать в функции запущенной в отдельном потоке. Не получилось и QUIT просто заканчивает работу данного потока. Что логично. Вопрос: возможно ли из отдельного потока завершить работу основной программы ?

alkresin: Dima пишет: Вопрос: возможно ли из отдельного потока завершить работу основной программы ? По-видимому, нельзя. Надо при необходимости отправить сообщение основному потоку ( через общую переменную, например ), ну а он и завершит.

Dima: alkresin пишет: ( через общую переменную, например ), ну а он и завершит Как тогда отслеживать эту переменную в основном потоке ? Повесить функцию через Hb_idleadd() или как то иначе ...

Sergy: Как вариант - отслеживать наличие "нужного" потока (который посылает команду на завершение приложения). Как только он "кончился" - завершать основную программу.

alkresin: Dima пишет: Повесить функцию через Hb_idleadd() В консоли - наверное, так. В GUI - таймеры есть.

Dima: alkresin пишет: В GUI - таймеры есть. Как в Минигуи например C:\MiniGUI\SOURCE\c_timer.c ? А его можно использовать в консоли ?

alkresin: А его можно использовать в консоли ? Вопрос интересный. Не знаю, как именно это сделано в Minigui и можно ли использовать тот код напрямую, но что-то свое на его основе написать можно.

alkresin: Попробовал сейчас, получилось: [pre] function main() local s := " " ANNOUNCE HB_GTSYS request HB_GT_WVT REQUEST HB_GT_WVT_DEFAULT #include "hbgtinfo.ch" hb_gtinfo( HB_GTI_FONTWIDTH, Int( hb_gtinfo( HB_GTI_DESKTOPWIDTH ) / 80 ) ) hb_gtinfo( HB_GTI_FONTSIZE, Int( ( hb_gtinfo( HB_GTI_DESKTOPHEIGHT ) - 64 ) / 25 ) ) hb_gtinfo( HB_GTI_CLOSABLE, .F. ) clear screen xxx_settimer( 1000 ) @ 1,1 GET s READ xxx_killtimer() return nil Function xxx_timerproc() static nn := 0 nn ++ @ 1,20 say str(nn) Return Nil #pragma BEGINDUMP #include <windows.h> #include "hbapi.h" HWND handle; void wrlog( const char * sFile, const char * sTraceMsg, ... ) { FILE *hFile; if( sFile == NULL ) { hFile = hb_fopen( "ac.log", "a" ); } else { hFile = hb_fopen( sFile, "a" ); } if( hFile ) { va_list ap; va_start( ap, sTraceMsg ); vfprintf( hFile, sTraceMsg, ap ); va_end( ap ); fclose( hFile ); } } static void CALLBACK s_timerProc( HWND hWnd, UINT message, UINT idTimer, DWORD dwTime ) { static PHB_DYNS s_pSymTest = NULL; HB_SYMBOL_UNUSED( message ); if( s_pSymTest == NULL ) s_pSymTest = hb_dynsymGetCase( "XXX_TIMERPROC" ); wrlog( NULL,"proc-1" ); if( hb_dynsymIsFunction( s_pSymTest ) ) { wrlog( NULL,"proc-2" ); hb_vmPushDynSym( s_pSymTest ); hb_vmPushNil(); hb_vmPushLong( ( LONG ) idTimer ); hb_vmPushLong( ( LONG ) dwTime ); hb_vmDo( 2 ); } } HB_FUNC( XXX_SETTIMER ) { handle = GetActiveWindow(); SetTimer( handle, 1001, ( UINT ) hb_parni( 1 ), s_timerProc ); } HB_FUNC( XXX_KILLTIMER ) { KillTimer( handle, 1001 ); } #pragma ENDDUMP [/pre] Но это не работает с gtwin, т.к. там нет окна. Нужен gtwvt или что-то вроде этого.

Dima: Сейчас попробую. Да работает примерчик. Спасибо. GTWIN не использую. А я пробовал так. Срабатывает , но почему то однократно. Почему ? [pre2] REQUEST HB_GT_WVT REQUEST HB_GT_WVG Proc main local hwnd cls hwnd:=GetForegroundWindow() INITTIMER(hwnd,"TEST",100,My_test()) wait KILLTIMER(hwnd,"TEST") return ****************** Func My_test() @ 3,2 say seconds() return nil ****************** #pragma BEGINDUMP #include <windows.h> #include <hbapi.h> HB_FUNC (GETFOREGROUNDWINDOW) { HWND hWnd = GetForegroundWindow(); hb_retnl ((LONG) hWnd); } HB_FUNC( INITTIMER ) { hb_retl( SetTimer( ( HWND ) hb_parnl( 1 ), ( UINT ) hb_parni( 2 ), ( UINT ) hb_parni( 3 ), ( TIMERPROC ) NULL ) ); } HB_FUNC( KILLTIMER ) { KillTimer( ( HWND ) hb_parnl( 1 ), // handle of main window ( UINT ) hb_parni( 2 ) ); // timer identifier } #pragma ENDDUMP [/pre2]

alkresin: Таймер в в вашем примере не срабатывает ни разу, т.к. в inittimer() не определена callback процедура, NULL стоит. А один раз срабатывает my_test() при вызове initimer() - ему передается значение, возвращаемое my_test()

Dima: Вот так правильно будет ? HB_FUNC( INITTIMER ) { hb_retl( SetTimer( ( HWND ) hb_parnl( 1 ), ( UINT ) hb_parni( 2 ), ( UINT ) hb_parni( 3 ), ( TIMERPROC ) hb_parni( 4 ) ) ); } В Си я конечно валенок ;)

alkresin: Dima пишет: Вот так правильно будет ? Нет, конечно. Inittimer должен быть такой, как в моем примере. А если вы хотите передать процедуру обработки прерывания от таймера, то надо это делать на Harbour уровне - как в Hwgui, да и в Minigui, наверное, так же. Вам надо привязать эту процедуру, например, к id ( 2-й параметр в вызове settimer() ) - поместить в массив, например, соответсвующие id и кодоблок процедуры - а затем из callback-функции найти этот кодоблок по id и выполнить.

Dima: Has подсказал. Сваял примерчик , работает. [pre2] Proc main REQUEST HB_GT_WVT cls Wvt_SetTimer( 2, 200) wait Wvt_KillTimer(2) return ************* Func WVT_TIMER() @ 10,0 say time() return .t. [/pre2]

Dima: alkresin Александр у меня вопрос. Функции xxx_settimer() , xxx_killtimer() , xxx_timerproc() или Wvt_SetTimer() , Wvt_KillTimer() , WVT_TIMER() это из той же оперы что и HB_IDLEADD() или это "родственники" потоков или что то еще ? Почему спрашиваю. Допустим есть функция которая была добавлена в HB_IDLEADD() и срабатывает каждые 200 мск да еще что то выводит на экран ("для крутости") , так вот в основной программе я получу тормоза. Если тоже самое сделать через поток , тормозов нет.

alkresin: Dima пишет: это из той же оперы что и HB_IDLEADD() или это "родственники" потоков или что то еще ? Что-то еще. Насколько я понимаю, считает время и организует прерывание отдельный системный процесс, а обрабатывается это прерывание во время idle state. Допустим есть функция которая была добавлена в HB_IDLEADD() и срабатывает каждые 200 мск да еще что то выводит на экран ("для крутости") , так вот в основной программе я получу тормоза. Возможно, проблема в реализации этой функции, может, ее надо реже вызывать.

Dima: alkresin пишет: Возможно, проблема в реализации этой функции Так и есть , мой косяк. Спасибо за подсказку



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