Основано на ответе Космина (что является хорошей отправной точкой, но не работает в реальной жизни).
Мой код написан на C ++, но, поскольку он является «клоном» ответа Consmin, пользователи Delphi могут легко его понять (и посмотреть, что изменилось).
PS: обратите внимание, что я перетаскиваю TPanels вместо TButtons (очень незначительное изменение).
void __fastcall TfrmVCL::ButtonDragDrop(TObject *Sender, TObject *Source, int X, int Y)
{
TRect CurCellRect;
TRect DestCellRect;
int Col;
int Row;
int srcCol; int srcRow;
int destCol; int destRow;
int srcIndex; int destIndex;
TPanel *SrcBtn;
TPanel *DestBtn;
SrcBtn = dynamic_cast<TPanel *>(Source);
if (SrcBtn)
{
int ColCount = GridPnl->ColumnCollection->Count ;
int RowCount = GridPnl->RowCollection->Count ;
// SOURCE
srcIndex = GridPnl->ControlCollection->IndexOf( SrcBtn );
srcCol = GridPnl->ControlCollection->Items[ srcIndex ]->Column; // the column for the dragged button
srcRow = GridPnl->ControlCollection->Items[ srcIndex ]->Row;
// DESTINATION
// we get coordinates of the button I drag onto
DestBtn= dynamic_cast<TPanel *>(Sender);
if (!DestBtn) return;
destIndex = GridPnl->ControlCollection->IndexOf( DestBtn );
destCol = GridPnl->ControlCollection->Items[ destIndex ]->Column; // the column for the dragged button
destRow = GridPnl->ControlCollection->Items[ destIndex ]->Row;
DestCellRect = GridPnl->CellRect[ destCol ][ destRow ];
// Check all cells
for ( Col = 0 ; Col < ColCount ; Col++ )
{
for ( Row = 0 ; Row < RowCount ; Row++ )
{
// Get the bounding rect for this cell
CurCellRect = GridPnl->CellRect[ Col ][ Row ];
if (IntersectRect_ForReal(DestCellRect, CurCellRect))
{
GridPnl->ControlCollection->Items[srcIndex]->SetLocation(Col, Row, false);
return;
}
else
lblCurCellRect->Caption= "NO HIT";
}
}
}
}