Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > TListBox MultiSelect Help


Автор: StrikeTheCore 25.5.2006, 00:05
Hello,

These forums were recommended to me due to a lack of Borland C++ forums in English, so I was hoping I could get an answer here.

I have created a TListBox and need to select multiple items for a project. Both MultiSelect and ExtendedSelect are set to true, yet when the program runs only one item can be selected at a time. When dragging mutliple items are selected but on MouseButtonUp all are lost. 

If you have any insight into why this is happening please let me know.

Thanks,

Brian 

Автор: chwind 25.5.2006, 10:42
What events assigned to ListBox. Show your code please 

Автор: StrikeTheCore 26.5.2006, 16:21
I am using OnMouseDown, OnMouseUp, and OnMouseMove. To clarify, what I want is to be able to select multiple items and be able to drag them all in a block to a different position in the list. My code is as follows:


void __fastcall TForm1::MsgTypesMouseUp(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
        AnsiString str;
        int i = 0;
        if(dragItem == -1)
                return;
        if(Button == mbLeft)
        {
                if(dragItem >= MsgTypes->Items->Count)
                        dragItem = MsgTypes->Items->Count-1;
                MsgTypes->Items->Move(startDragItem, dragItem);
                for(int count=(startDragItem<dragItem?startDragItem:dragItem); count<=(startDragItem>dragItem?startDragItem:dragItem);count++)
                {
                        i = 0;
                        str = MsgTypes->Items->Strings[count];
                        MsgTypes->Items->Strings[count] = AnsiString().sprintf("%03d",msgEnumValues[count])+str.Delete(1,3);
                        str.Delete(1,1);
                        for (i = 0; i < 256; i++)
                                if (mappings[i].AnsiCompare(str))
                                        break;
                        mappings[count] = str;
                        mappings[i] = NULL;
                }
                dragItem = -1;
                startDragItem = -1;
        }
}



void __fastcall TForm1::MsgTypesMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
        TPoint point;
        point.x = X;
        point.y = Y;
        if(Button == mbLeft)
        {
                dragItem = MsgTypes->ItemAtPos(point, true);
                if(dragItem == -1 || dragItem < 2)
                {
                        dragItem = -1;
                        return;
                }
                startDragItem = dragItem;
        }
}


void __fastcall TForm1::MsgTypesMouseMove(TObject *Sender,
      TShiftState Shift, int X, int Y)
{
        TPoint point;
        if(dragItem == -1)
                return;
        point.x = X;
        point.y = Y;
        if(Shift.Contains(ssLeft)){
                dragItem = MsgTypes->ItemAtPos(point, false);
                if(dragItem > MsgTypes->Items->Count)
                        return;
                if(dragItem < 2)
                        dragItem = 2;
        }
}


The dragItem and startDragItem are both global ints. Also I want to prevent moving the first 2 items, and that is the reason for the addition if statements. Any help with why this is not working is greatly appreciated.

Добавлено @ 16:34 
I should also say that the actual problem I am having is that when MultiSelect is set to true you can drag the mouse to select multiple items but when the mouse button is released all selections are lost and the first selected item moves to the last selected item (which is correct behavior without multiselect). What I need to do is allow for the user to select a large block, then be able to drag that entire block to a different position. 

Автор: chwind 27.5.2006, 16:06
It is a working code. I have checked up  smile 

cpp file
Код


//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::MsgTypesMouseDown(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
  TListBox * ListBox = (TListBox *)Sender;
  Caption = IntToStr(ListBox->SelCount);
  if (Button == mbRight)
  {
    TPoint point;
    point.x = X;
    point.y = Y;
    startDragItem = ListBox->ItemAtPos(point, true);
  }else
    startDragItem = -1;
}
//---------------------------------------------------------------------
void __fastcall TForm1::MsgTypesMouseUp(TObject *Sender,
      TMouseButton Button, TShiftState Shift, int X, int Y)
{
  TListBox * ListBox = (TListBox *)Sender;
  if (Button == mbRight)
  {
    TPoint point;
    point.x = X;
    point.y = Y;
    stopDragItem = ListBox->ItemAtPos(point, true);
    MoveBlockItem(ListBox, stopDragItem - startDragItem);
    startDragItem = -1;
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::MsgTypesMouseMove(TObject *Sender,
      TShiftState Shift, int X, int Y)
{
  TListBox * ListBox = (TListBox *)Sender;
  if (startDragItem>0)
  {
    TPoint point;
    point.x = X;
    point.y = Y;
    int CurDragItem = ListBox->ItemAtPos(point, true);
    MoveBlockItem(ListBox, CurDragItem - startDragItem);
    startDragItem = CurDragItem;
  }
}
//---------------------------------------------------------------------------
void TForm1::MoveBlockItem(TListBox * _ListBox, int _dDrag)
{
    if (_dDrag>0)
    {
      for (int i = _ListBox->Count-1; i >=0; --i)
      {
        if (_ListBox->Selected[i])
        {
          if (i+_dDrag >= _ListBox->Count)_dDrag = _ListBox->Count-i-1;
          _ListBox->Items->Move(i,i+_dDrag);
          _ListBox->Selected[i+_dDrag] = true;
        }
      }
    }else
    if (_dDrag<0)
    {
      for (int i = 0; i <_ListBox->Count; ++i)
      {
          if (_ListBox->Selected[i])
          {
            if (i+_dDrag < 0)_dDrag = -i;
            _ListBox->Items->Move(i,i+_dDrag);
            _ListBox->Selected[i+_dDrag] = true;
          }
      }
    }
}


h file
Код

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
  TListBox *MsgTypes;
  void __fastcall MsgTypesMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
  void __fastcall MsgTypesMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
  void __fastcall MsgTypesMouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y);
private:    // User declarations
public:        // User declarations
  __fastcall TForm1(TComponent* Owner);
  int dragItem,startDragItem,stopDragItem;
  void MoveBlockItem(TListBox * _ListBox, int _dDrag);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

 
Only you should finish a code to forbid to move the first 2 elements 
Has forgotten to tell, elements move the right mouse button. 

Автор: StrikeTheCore 30.5.2006, 15:44
That worked great and did exactly what I needed.

Thanks a lot.

-Brian 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)