// описываем направления движения enum Direction { dirNone = -1, dirLt, dirRg, dirUp, dirDn }; // Собственно, класс потока class TMyThread : public TThread { private: TButton *btn; Direction FState; protected: void __fastcall Execute(); public: __fastcall bool SetState(Direction state) { FState = state; if(state == dirNone) { Suspend(); } else { Resume(); } return true; } __fastcall TMyThread(TButton *button, bool CreateSuspended): TThread(CreateSuspended) { btn = button; } }; // Выделяем место под указатели на потоки const int num_threads = 2; TMyThread *thr[num_threads]; // Реализация метода Execute void __fastcall TMyThread::Execute() { const int nStep = 1; do { int dx = 0, dy = 0; switch(FState) { case dirLt: dx = -nStep; break; case dirRg: dx = +nStep; break; case dirUp: dy = -nStep; break; case dirDn: dy = +nStep; break; } btn->Left += dx; btn->Top += dy; Sleep(100); } while(!Suspended); } void __fastcall TForm1::FormCreate(TObject *Sender) { // При инициализации формы - запускаем потоки для двух кнопок thr[0] = new TMyThread(Button1, true); thr[1] = new TMyThread(Button2, true); } // Эта функция просто очень сильно "разгрузит" обработчик сообщений int key_pressed(unsigned int key, Direction& dir) { unsigned codes[num_threads][4] = { // коды должны следовать в порядке dirLt, dirRg, dirUp, dirDn {37, 39, 38, 40}, {65, 68, 87, 83} }; for(int i = 0; i < num_threads; i++) { for(int j = 0; j < 4; j++) { if(codes[i][j] == key) { dir = static_cast(j); return i; } } } return -1; } void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg, bool &Handled) { int thread_n; Direction dir; switch(Msg.message) { case WM_KEYDOWN: if((thread_n = key_pressed(Msg.wParam, dir)) >= 0) { Handled = thr[thread_n]->SetState(dir); } break; case WM_KEYUP: if((thread_n = key_pressed(Msg.wParam, dir)) >= 0) { Handled = thr[thread_n]->SetState(dirNone); } break; } }