1. Пользуйтесь тегами кода. - [code] ... [/code] 2. Точно указывайте язык, название и версию компилятора (интерпретатора). 3. Название темы должно быть информативным. В описании темы указываем язык!!!
Хочу сделать следуюшее...чтобы по определенным клавишам двигалася напиример Button1, а по другим Button2...написал примерно так
void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg, bool &Handled) { // Memo1->Lines->Add(Msg.wParam); const nStep = 1; switch(Msg.wParam) { case 40: Button1->Top += nStep; break; case 38: Button1->Top -= nStep; break; case 37: Button1->Left -= nStep; break; case 39: Button1->Left += nStep; break;
case 83: Button2->Top += nStep; break; case 87: Button2->Top -= nStep; break; case 65: Button2->Left -= nStep; break; case 68: Button2->Left += nStep; break;
}
Но теперь пока одна кнопка движеться вторая не будет...как реализовать независимое движение?.. может как то через много поточность?..можно для каждой кнопки писать свой поток и в нём ждать нажатия определённой кнопки и его уже орабатывать...но как ето сделать?..
break; case WM_KEYUP: switch(Msg.wParam) { case 40: case 38: case 37: case 39: { Handled = true; moving[0].b = false; break; } case 83: case 87: case 65: case 68: { Handled = true; moving[1].b = false; break; } }
Хотелось бы всё таки узнать как сделать через потоки... мне непонятно к в потоке узнать что нажата клавиша?..
А зачем Handled ( - признак обработки события) выставлять в true?..
Цитата
// Ну, ты же понимаешь, что все это можно записать и намного короче, // добавив одну-единственную функцию, правда? Это - просто пример...
Я как то об этом не задумывался даже... Я так понимаю эта функция просто внутри себя будет проверять клавиши, да и кнопку которую двигать ей тоже отправлять надо...и она уже будет двигать ету кнопку...
А зачем Handled ( - признак обработки события) выставлять в true?..
Затем, что если ты этого не сделаешь, и у тебя на форме будет, например, Edit, и фокус будет на нем, то этот Edit будет заполняться символами, которые ты вводишь (нажимая клавишу). А если ничего из текстовых контролов не будет - то программа будет пищать. А установкой Handled = true ты говоришь обработчику ApplicationMessage, что это событие уже обработано, дальше по цепочке его передавать не надо...
Затем, что если ты этого не сделаешь, и у тебя на форме будет, например, Edit, и фокус будет на нем, то этот Edit будет заполняться символами, которые ты вводишь (нажимая клавишу). А если ничего из текстовых контролов не будет - то программа будет пищать. А установкой Handled = true ты говоришь обработчику ApplicationMessage, что это событие уже обработано, дальше по цепочке его передавать не надо...
Да...интересно..я вроде во всём разобрался...
И я так понимаю Sleep(100); чтобы мы успели нажать какую либо кнопку...но при етом слишком скорость маленькая...а при Sleep(10) у меня в конце концов всё таки зависало =(... А вообще при отключения Sleep кнопки почему то движуться с разными скоростями и зависает быстро..=( Не мог бы ты привести пример ещё какого либо способа...
(не обязательно на счёт данной задачи...я могу разобраться и сам попрбовать сделать..=)...в общем как тебе удобней...)
а при Sleep(10) у меня в конце концов всё таки зависало =(...
Поменял в Execute() условие выхода на
... } while(!Terminated);
(как я мог написать там Suspended - не понимаю ), гонял программу минут 20 со Sleep(5) и nStep = 2: скорости движения одинаковые, зависаний никаких не обнаружено. Я надеюсь, ты в OnDestroy формы прописал завершение потоков?
(как я мог написать там Suspended - не понимаю ), гонял программу минут 20 со Sleep(5) и nStep = 2: скорости движения одинаковые, зависаний никаких не обнаружено. Я надеюсь, ты в OnDestroy формы прописал завершение потоков?
Да..так лучше... Теперь написал...они же и так сами должны завершаться при завершении приложения?..
Должны... Но их должна завершить система, а это требует дополнительного времени, будет подвисать при выходе. А если ты напишешь
for(int i = num_threads - 1; i >= 0; i--) { thr[i] -> Terminate(); }
, то дело пойдет быстрее...
Понятно...А как отловить нажатие двух кнопок сразу?..хочу добавить движение по диагоналям... А какой компонент лучше использовать для движения?...хочу написать что то вроде Ice hockey, так что это могут быть и TPanel и просто прямоугольник нарисованый...
const int num_threads = 2; TMyThread *thr[num_threads];
void __fastcall TMyThread::Execute() { const int nStep = 2;
do {
int dx = 0, dy = 0; for(int dir = dirLt; dir <= dirDn; dir++) { // если текущее направление присутствует во множестве if(FState.Contains(dir)) { // то высчитываем, куда двигаться... switch(dir) { case dirLt: dx = -nStep; break; case dirRg: dx = +nStep; break; case dirUp: dy = -nStep; break; case dirDn: dy = +nStep; break; }
Угу... Именно свойства. А что непонятно? Описываешь свойство (имя и тип), и указываешь что для чтения обращение к свойству аналогично обращению к FState. Поскольку нет write=, то это свойство только для чтения. И не является свойством "по умолчанию".
Цитата
<< это что значит?..
для типа Set перегружены операторы << (через него реализовано добавление элемента в множество) и >> (извлечение элемента из множества, если он там присутствует)
Угу... Именно свойства. А что непонятно? Описываешь свойство (имя и тип), и указываешь что для чтения обращение к свойству аналогично обращению к FState. Поскольку нет write=, то это свойство только для чтения. И не является свойством "по умолчанию".
Вроде разобрался...а почему используется свойство?...можно так
TDir GetState() {return FState;};
Через свойство лучше чем то?..
Цитата
для типа Set перегружены операторы << (через него реализовано добавление элемента в множество) и >> (извлечение элемента из множества, если он там присутствует)
Handled = thr[thread_n]->SetState( thr[thread_n]->GetState() >> dir // <--- вызов функции GetState );
, правда? А не боишься, что у тебя будет постоянно создаваться новая копия множества, и ты потом получишь тормоза при выходе из программы? А при работе с __property ты работаешь с одной и той же переменной...
Handled = thr[thread_n]->SetState( thr[thread_n]->GetState() >> dir // <--- вызов функции GetState );
, правда?
Ну это понятно...
Цитата
А не боишься, что у тебя будет постоянно создаваться новая копия множества, и ты потом получишь тормоза при выходе из программы? А при работе с __property ты работаешь с одной и той же переменной...
Я так понимаю что они создаються при возвращении значения...но разве эта копия будет существовать до самого выхода из программы?..они не будут удаляться при выходе за '}' ?.. Согласен, что твой вариант работать все равно будет лучше...