C++Builder
  Начало   Форум   Помощь Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Совмещение TComboBox и TCheckBox  (Прочитано 5121 раз)
Sasha
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 413


Совмещение TComboBox и TCheckBox
« : 16 Апрель 2014, 17:22:00 »

Здравствуйте!!!

Ребята, делаю компонент из 2-х компонентов (ComboBox и CheckListBox). Посоветовали код правда он написан на Delphi

Вот он

Код
//Set ComboBox.Style:=csOwnerDrawFixed
//tested with D6 and WinXP...
 
  //.....
  private
    Selected: array of Boolean;
  //.....
 
 
procedure TTForm1.ComboBox1DrawItem(Control: TWinControl;
     Index: Integer; Rect: TRect; State: TOwnerDrawState);
begin
  SetLength(Selected, TComboBox(Control).Items.Count);
  with TComboBox(Control).Canvas do
  begin
    FillRect(rect);
 
    Rect.Left := Rect.Left + 1;
    Rect.Right := Rect.Left + 13;
    Rect.Bottom := Rect.Bottom;
    Rect.Top := Rect.Top;
 
    if not (odSelected in State) and (Selected[Index]) then
      DrawFrameControl(Handle, Rect, DFC_BUTTON,
        DFCS_BUTTONCHECK or DFCS_CHECKED or DFCS_FLAT)
    else if (odFocused in State) and (Selected[Index]) then
      DrawFrameControl(Handle, Rect, DFC_BUTTON,
        DFCS_BUTTONCHECK or DFCS_CHECKED or DFCS_FLAT)
    else if (Selected[Index]) then
      DrawFrameControl(Handle, Rect, DFC_BUTTON,
        DFCS_BUTTONCHECK or DFCS_CHECKED or DFCS_FLAT)
    else if not (Selected[Index]) then
      DrawFrameControl(Handle, Rect, DFC_BUTTON, DFCS_BUTTONCHECK or DFCS_FLAT);
 
    TextOut(Rect.Left + 15, Rect.Top, TComboBox(Control).Items[Index]);
  end;
end;
 
procedure TForm1.ComboBox1Select(Sender: TObject);
var
  i: Integer;
  Sel: string;
begin
  Sel := EmptyStr;
  Selected[TComboBox(Sender).ItemIndex] := not Selected[TComboBox(Sender).ItemIndex];
  for i := 0 to TComboBox(Sender).Items.Count - 1 do
    if Selected[i] then
      Sel := Sel + TComboBox(Sender).Items[i] + ' ';
  ShowMessage(Sel);  //Just for test...
end;
 

Часть кода я переделал сам вот она


Код
private:
bool Selected[];
 
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
 
ComboBox1->Items->Add("Item1");
ComboBox1->Items->Add("Item2");
ComboBox1->Items->Add("Item3");
ComboBox1->Style = csOwnerDrawFixed;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox1Select(TObject *Sender)
{
 
 
int i;
String Sel = "";
Selected[ComboBox1->ItemIndex]!=Selected[ComboBox1->ItemIndex];
for(int i = 0; i ComboBox1->Items->Count;i++)
{
 if (Selected[i])
 {
  Sel+=ComboBox1->Items->Strings[i] + " ";
 }
}
ShowMessage(Sel);
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
     TRect &Rect, TOwnerDrawState State)
{
/*begin
  SetLength(Selected, TComboBox(Control).Items.Count);
  with TComboBox(Control).Canvas do
  begin
    FillRect(rect);*/

 
    Rect->Left = Rect->Left + 1;
    Rect->Right = Rect->Left + 13;
    Rect->Bottom = Rect->Bottom;
    Rect->Top = Rect->Top;
 
    /*Rect.Left := Rect.Left + 1;
    Rect.Right := Rect.Left + 13;
    Rect.Bottom := Rect.Bottom;
    Rect.Top := Rect.Top;*/

 
    if not (odSelected in State) and (Selected[Index])
    {
      DrawFrameControl(Handle, Rect, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
    }
    else if (odFocused in State) and (Selected[Index])
    {
      DrawFrameControl(Handle, Rect, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
    }
    else if (Selected[Index])
    {
      DrawFrameControl(Handle, Rect, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
    }
    else if  (!Selected[Index])
    {
      DrawFrameControl(Handle, Rect, DFC_BUTTON, DFCS_BUTTONCHECK | DFCS_FLAT);
    }
    TextOut(Rect->Left + 15, Rect->Top, ComboBox1->Items->Strings[Index]);
 
     /*if not (odSelected in State) and (Selected[Index]) then
      DrawFrameControl(Handle, Rect, DFC_BUTTON,
        DFCS_BUTTONCHECK or DFCS_CHECKED or DFCS_FLAT)
    else if (odFocused in State) and (Selected[Index]) then
      DrawFrameControl(Handle, Rect, DFC_BUTTON,
        DFCS_BUTTONCHECK or DFCS_CHECKED or DFCS_FLAT)
    else if (Selected[Index]) then
      DrawFrameControl(Handle, Rect, DFC_BUTTON,
        DFCS_BUTTONCHECK or DFCS_CHECKED or DFCS_FLAT)
    else if not (Selected[Index]) then
      DrawFrameControl(Handle, Rect, DFC_BUTTON, DFCS_BUTTONCHECK or DFCS_FLAT);
 
    TextOut(Rect.Left + 15, Rect.Top, TComboBox(Control).Items[Index]);*/

}
//---------------------------------------------------------------------------
 
 

Остальную часть не могу осилить. Помогите, пожалуйста. Заранее благодарен за помощь

« Последнее редактирование: 17 Апрель 2014, 15:44:20 от volvo877 » Записан
volvo877
Глобальный модератор


Сказали спасибо: +736/-1
Offline

Сообщений: 891


Re: переделать код из Delphi в С++Builder
« Ответ #1 : 16 Апрель 2014, 18:15:28 »

Sasha, ты же знаешь, что я предпочитаю Interceptor classes, правда? Вот моя версия:
header-файл, перед объявлением класса формы:
Код
namespace MyComboBox
{
   class TComboBox : public Stdctrls::TComboBox
   {
   protected:
       virtual void __fastcall DrawItem(int Index, const TRect &Rect,
           TOwnerDrawState State)
       {
           Canvas->FillRect(Rect);
           TRect R = Classes::Rect(Rect.Left + 1, Rect.Top, Rect.Left + 13, Rect.Bottom);
           int isSelected = (int)(Items->Objects[Index]);
 
           if (!State.Contains(odSelected) && isSelected)
           {
               DrawFrameControl(Canvas->Handle, &R, DFC_BUTTON,
                   DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
           }
           else if (State.Contains(odFocused) && isSelected)
           {
               DrawFrameControl(Canvas->Handle, &R, DFC_BUTTON,
                   DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
           }
           else if (isSelected)
           {
               DrawFrameControl(Canvas->Handle, &R, DFC_BUTTON,
                   DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
           }
           else if (!isSelected)
           {
               DrawFrameControl(Canvas->Handle, &R, DFC_BUTTON,
                   DFCS_BUTTONCHECK | DFCS_FLAT);
           }
           Canvas->TextOut(Rect.Left + 15, Rect.Top, Items->Strings[Index]);
       }
 
       DYNAMIC void __fastcall Select(void)
       {
           String Sel = "";
           int isSelected = (int)(Items->Objects[ItemIndex]);
           Items->Objects[ItemIndex] = (TObject*)(isSelected ? 0 : 1);
           for (int i = 0; i Items->Count; i++)
           {
               if ((int)(Items->Objects[i]))
                   Sel += Items->Strings[i] + " ";
           }
           ShowMessage(Sel); // Just for test...
       }
 
       __fastcall virtual TComboBox(Classes::TComponent* AOwner)
           : Stdctrls::TComboBox(AOwner)
       {
           for (int i = 0; i Items->Count; i++)
               Items->Objects[i] = (TObject*)0; // насколько я помню, это и так делается по умолчанию, но...
       }
   };
}
#define TComboBox MyComboBox::TComboBox
 
class TForm1 : public TForm // дальше пошла форма, без изменений...
,и все комбобоксы на форме превратились в комбобоксы с чекбоксами...
Записан
Sasha
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 413


Re: переделать код из Delphi в С++Builder
« Ответ #2 : 16 Апрель 2014, 18:37:51 »

Цитата: volvo877 от 16 Апрель 2014, 18:15:28
Sasha, ты же знаешь, что я предпочитаю Interceptor classes, правда? Вот моя версия:
header-файл, перед объявлением класса формы:
Код
namespace MyComboBox
{
   class TComboBox : public Stdctrls::TComboBox
   {
   protected:
       virtual void __fastcall DrawItem(int Index, const TRect &Rect,
           TOwnerDrawState State)
       {
           Canvas->FillRect(Rect);
           TRect R = Classes::Rect(Rect.Left + 1, Rect.Top, Rect.Left + 13, Rect.Bottom);
           int isSelected = (int)(Items->Objects[Index]);
 
           if (!State.Contains(odSelected) && isSelected)
           {
               DrawFrameControl(Canvas->Handle, &R, DFC_BUTTON,
                   DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
           }
           else if (State.Contains(odFocused) && isSelected)
           {
               DrawFrameControl(Canvas->Handle, &R, DFC_BUTTON,
                   DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
           }
           else if (isSelected)
           {
               DrawFrameControl(Canvas->Handle, &R, DFC_BUTTON,
                   DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
           }
           else if (!isSelected)
           {
               DrawFrameControl(Canvas->Handle, &R, DFC_BUTTON,
                   DFCS_BUTTONCHECK | DFCS_FLAT);
           }
           Canvas->TextOut(Rect.Left + 15, Rect.Top, Items->Strings[Index]);
       }
 
       DYNAMIC void __fastcall Select(void)
       {
           String Sel = "";
           int isSelected = (int)(Items->Objects[ItemIndex]);
           Items->Objects[ItemIndex] = (TObject*)(isSelected ? 0 : 1);
           for (int i = 0; i Items->Count; i++)
           {
               if ((int)(Items->Objects[i]))
                   Sel += Items->Strings[i] + " ";
           }
           ShowMessage(Sel); // Just for test...
       }
 
       __fastcall virtual TComboBox(Classes::TComponent* AOwner)
           : Stdctrls::TComboBox(AOwner)
       {
           for (int i = 0; i Items->Count; i++)
               Items->Objects[i] = (TObject*)0; // насколько я помню, это и так делается по умолчанию, но...
       }
   };
}
#define TComboBox MyComboBox::TComboBox
 
class TForm1 : public TForm // дальше пошла форма, без изменений...
,и все комбобоксы на форме превратились в комбобоксы с чекбоксами...
Знаю!!!!!!!!!!!!Спасибо. Если б я так мог..................Буду пробывать твой код
Записан
Sasha
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 413


Re: переделать код из Delphi в С++Builder
« Ответ #3 : 16 Апрель 2014, 18:48:02 »

>>
А если к примеру мне надо один конкретный ComboBox, а не все?
Записан
volvo877
Глобальный модератор


Сказали спасибо: +736/-1
Offline

Сообщений: 891


Re: переделать код из Delphi в С++Builder
« Ответ #4 : 16 Апрель 2014, 19:00:09 »

Значит, прописывай эти же действия в обработчиках этого конкретного комбобокса:
Код
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   ComboBox1->Style = csOwnerDrawFixed;
}
 
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
   TRect &Rect, TOwnerDrawState State)
{
   TComboBox *cbx = static_castTComboBox*>(Control);
 
   cbx->Canvas->FillRect(Rect);
   TRect R = Classes::Rect(Rect.Left + 1, Rect.Top, Rect.Left + 13,
       Rect.Bottom);
   int isSelected = (int)(cbx->Items->Objects[Index]);
 
   if (!State.Contains(odSelected) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (State.Contains(odFocused) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (!isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_FLAT);
   }
   cbx->Canvas->TextOut(Rect.Left + 15, Rect.Top, cbx->Items->Strings[Index]);
 
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::ComboBox1Select(TObject *Sender)
{
   TComboBox *cbx = static_castTComboBox*>(Sender);
   String Sel = "";
   int isSelected = (int)(cbx->Items->Objects[cbx->ItemIndex]);
   cbx->Items->Objects[cbx->ItemIndex] = (TObject*)(isSelected ? 0 : 1);
   for (int i = 0; i cbx->Items->Count; i++)
   {
       if ((int)(cbx->Items->Objects[i]))
           Sel += cbx->Items->Strings[i] + " ";
   }
   ShowMessage(Sel); // Just for test...
}
, namespace MyComboBox в таком случае не нужен...
Записан
Sasha
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 413


Re: переделать код из Delphi в С++Builder
« Ответ #5 : 16 Апрель 2014, 23:53:38 »

Цитата: volvo877 от 16 Апрель 2014, 19:00:09
Значит, прописывай эти же действия в обработчиках этого конкретного комбобокса:
Код
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   ComboBox1->Style = csOwnerDrawFixed;
}
 
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
   TRect &Rect, TOwnerDrawState State)
{
   TComboBox *cbx = static_castTComboBox*>(Control);
 
   cbx->Canvas->FillRect(Rect);
   TRect R = Classes::Rect(Rect.Left + 1, Rect.Top, Rect.Left + 13,
       Rect.Bottom);
   int isSelected = (int)(cbx->Items->Objects[Index]);
 
   if (!State.Contains(odSelected) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (State.Contains(odFocused) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (!isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_FLAT);
   }
   cbx->Canvas->TextOut(Rect.Left + 15, Rect.Top, cbx->Items->Strings[Index]);
 
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::ComboBox1Select(TObject *Sender)
{
   TComboBox *cbx = static_castTComboBox*>(Sender);
   String Sel = "";
   int isSelected = (int)(cbx->Items->Objects[cbx->ItemIndex]);
   cbx->Items->Objects[cbx->ItemIndex] = (TObject*)(isSelected ? 0 : 1);
   for (int i = 0; i cbx->Items->Count; i++)
   {
       if ((int)(cbx->Items->Objects[i]))
           Sel += cbx->Items->Strings[i] + " ";
   }
   ShowMessage(Sel); // Just for test...
}
, namespace MyComboBox в таком случае не нужен...

Спасибо, код работает супер!!!! Хотелось бы ещё спросить, а можно ли сделать квадратики чуть больше, а также галочки в них? А то немного маловаты!!!!!!!!!!!!!!!1
Записан
volvo877
Глобальный модератор


Сказали спасибо: +736/-1
Offline

Сообщений: 891


Re: переделать код из Delphi в С++Builder
« Ответ #6 : 17 Апрель 2014, 00:53:22 »

Используй стандартные системные размеры:

Код
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   ComboBox1->Style = csOwnerDrawVariable; //
}
 
// Добавляем обработчик OnMeasureItem
void __fastcall TForm1::ComboBox1MeasureItem(TWinControl *Control, int Index, int &Height)
{
   Height = ::GetSystemMetrics(SM_CYMENUCHECK) + 2;
}
 
// и чуть-чуть исправляем отрисовку (везде вместо прибитых гвоздями
// значений используем системные настройки):
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
   TRect &Rect, TOwnerDrawState State)
{
   TComboBox *cbx = static_castTComboBox*>(Control);
 
   cbx->Canvas->FillRect(Rect);
   TRect R = Classes::Rect(Rect.Left + 1, Rect.Top, Rect.Left + 2 + ::GetSystemMetrics(SM_CXMENUCHECK),
       Rect.Bottom);
   int isSelected = (int)(cbx->Items->Objects[Index]);
 
   if (!State.Contains(odSelected) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (State.Contains(odFocused) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (!isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_FLAT);
   }
   cbx->Canvas->TextOut(Rect.Left + 4 + ::GetSystemMetrics(SM_CXMENUCHECK), Rect.Top, cbx->Items->Strings[Index]);
}
По-моему - как стандартный выглядит:
Записан
Sasha
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 413


Re: переделать код из Delphi в С++Builder
« Ответ #7 : 17 Апрель 2014, 01:15:18 »

Цитата: volvo877 от 17 Апрель 2014, 00:53:22
Используй стандартные системные размеры:

Код
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   ComboBox1->Style = csOwnerDrawVariable; //
}
 
// Добавляем обработчик OnMeasureItem
void __fastcall TForm1::ComboBox1MeasureItem(TWinControl *Control, int Index, int &Height)
{
   Height = ::GetSystemMetrics(SM_CYMENUCHECK) + 2;
}
 
// и чуть-чуть исправляем отрисовку (везде вместо прибитых гвоздями
// значений используем системные настройки):
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
   TRect &Rect, TOwnerDrawState State)
{
   TComboBox *cbx = static_castTComboBox*>(Control);
 
   cbx->Canvas->FillRect(Rect);
   TRect R = Classes::Rect(Rect.Left + 1, Rect.Top, Rect.Left + 2 + ::GetSystemMetrics(SM_CXMENUCHECK),
       Rect.Bottom);
   int isSelected = (int)(cbx->Items->Objects[Index]);
 
   if (!State.Contains(odSelected) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (State.Contains(odFocused) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (!isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_FLAT);
   }
   cbx->Canvas->TextOut(Rect.Left + 4 + ::GetSystemMetrics(SM_CXMENUCHECK), Rect.Top, cbx->Items->Strings[Index]);
}
По-моему - как стандартный выглядит:

Спасибо большое!! И чтобы добить окончательно эту тему хочу спросить тебя ещё....

Есть такая вот строка

Код
ComboBox1->ItemIndex = -1;//при таком индексе поле у коmboboxa пустое т.е по defaultu, а можно ли сделать чтобы при таком коде вместо пустого поля была строка из выбранных пунктов на которых стоит галочка?
 
Записан
volvo877
Глобальный модератор


Сказали спасибо: +736/-1
Offline

Сообщений: 891


Re: переделать код из Delphi в С++Builder
« Ответ #8 : 17 Апрель 2014, 01:40:23 »

Нет, с OwnerDraw комбобоксом такие вещи не проходят.
Записан
volvo877
Глобальный модератор


Сказали спасибо: +736/-1
Offline

Сообщений: 891


Re: переделать код из Delphi в С++Builder
« Ответ #9 : 17 Апрель 2014, 01:52:28 »

Зато никто не мешает сделать так:
Код
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
   TRect &Rect, TOwnerDrawState State)
{
   TComboBox *cbx = static_castTComboBox*>(Control);
 
   cbx->Canvas->FillRect(Rect);
 
   if (!Index)
   {
       String Sel = "";
       for (int i = 1; i cbx->Items->Count; i++)
       {
           if ((int)(cbx->Items->Objects[i]))
               Sel += cbx->Items->Strings[i] + " ";
       }
       cbx->Canvas->Font->Color = clGray;
       cbx->Canvas->TextOut(Rect.Left + 2, Rect.Top, Sel);
       return;
 
   }
   TRect R = Classes::Rect(Rect.Left + 1, Rect.Top,
       Rect.Left + 2 + ::GetSystemMetrics(SM_CXMENUCHECK), Rect.Bottom);
   int isSelected = (int)(cbx->Items->Objects[Index]);
 
   if (!State.Contains(odSelected) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (State.Contains(odFocused) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (!isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_FLAT);
   }
   cbx->Canvas->TextOut(Rect.Left + 4 + ::GetSystemMetrics(SM_CXMENUCHECK),
       Rect.Top, cbx->Items->Strings[Index]);
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::ComboBox1Select(TObject *Sender)
{
   TComboBox *cbx = static_castTComboBox*>(Sender);
   if (cbx->ItemIndex == 0)
       return;
 
   int isSelected = (int)(cbx->Items->Objects[cbx->ItemIndex]);
   cbx->Items->Objects[cbx->ItemIndex] = (TObject*)(isSelected ? 0 : 1);
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox1MeasureItem(TWinControl *Control, int Index,
   int &Height)
 
{
   Height = ::GetSystemMetrics(SM_CYMENUCHECK) + 2;
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   ComboBox1->ItemIndex = 0;
}
, то есть, оставить нулевую строку для хранения списка выбранных элементов, и запретить рисование в ней чекбокса и выбор этого пункта... А при необходимости отобразить список - просто отображать не (-1)-ю, а нулевую строку...
Записан
Sasha
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 413


Re: переделать код из Delphi в С++Builder
« Ответ #10 : 17 Апрель 2014, 11:28:23 »

Цитата: volvo877 от 17 Апрель 2014, 01:52:28
Зато никто не мешает сделать так:
Код
void __fastcall TForm1::ComboBox1DrawItem(TWinControl *Control, int Index,
   TRect &Rect, TOwnerDrawState State)
{
   TComboBox *cbx = static_castTComboBox*>(Control);
 
   cbx->Canvas->FillRect(Rect);
 
   if (!Index)
   {
       String Sel = "";
       for (int i = 1; i cbx->Items->Count; i++)
       {
           if ((int)(cbx->Items->Objects[i]))
               Sel += cbx->Items->Strings[i] + " ";
       }
       cbx->Canvas->Font->Color = clGray;
       cbx->Canvas->TextOut(Rect.Left + 2, Rect.Top, Sel);
       return;
 
   }
   TRect R = Classes::Rect(Rect.Left + 1, Rect.Top,
       Rect.Left + 2 + ::GetSystemMetrics(SM_CXMENUCHECK), Rect.Bottom);
   int isSelected = (int)(cbx->Items->Objects[Index]);
 
   if (!State.Contains(odSelected) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (State.Contains(odFocused) && isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_CHECKED | DFCS_FLAT);
   }
   else if (!isSelected)
   {
       DrawFrameControl(cbx->Canvas->Handle, &R, DFC_BUTTON,
           DFCS_BUTTONCHECK | DFCS_FLAT);
   }
   cbx->Canvas->TextOut(Rect.Left + 4 + ::GetSystemMetrics(SM_CXMENUCHECK),
       Rect.Top, cbx->Items->Strings[Index]);
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::ComboBox1Select(TObject *Sender)
{
   TComboBox *cbx = static_castTComboBox*>(Sender);
   if (cbx->ItemIndex == 0)
       return;
 
   int isSelected = (int)(cbx->Items->Objects[cbx->ItemIndex]);
   cbx->Items->Objects[cbx->ItemIndex] = (TObject*)(isSelected ? 0 : 1);
}
 
// ---------------------------------------------------------------------------
void __fastcall TForm1::ComboBox1MeasureItem(TWinControl *Control, int Index,
   int &Height)
 
{
   Height = ::GetSystemMetrics(SM_CYMENUCHECK) + 2;
}
// ---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   ComboBox1->ItemIndex = 0;
}
, то есть, оставить нулевую строку для хранения списка выбранных элементов, и запретить рисование в ней чекбокса и выбор этого пункта... А при необходимости отобразить список - просто отображать не (-1)-ю, а нулевую строку...

Ещё раз спасибо за код пришлось добавлять ещё одну пустую строку сверху, чтобы писало все строки, а то у меня 3 строки, а с этим кодому меня первая строка пустая, а остальные 2 заполнены. Вообщем сделал так:

Код
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
 
 
ComboBox1->Items->Add("");
ComboBox1->Items->Add("1");
ComboBox1->Items->Add("2");
ComboBox1->Items->Add("3");
ComboBox1->Style = csOwnerDrawFixed;
}

И ещё хотелось бы немного узнать, я не нашёл в твоём коде, где можно уменьшить толщину квадратиков в которых стоит галочка, а то они очень жирные. И ещё возможно ли сделать так, чтобы ComboBox не закрывался пока я не выберу мне нужные строки, а потом я сам нажму на кнопку в ComboBoxe чтобы убрать выпадающий список?
Записан
volvo877
Глобальный модератор


Сказали спасибо: +736/-1
Offline

Сообщений: 891


Re: переделать код из Delphi в С++Builder
« Ответ #11 : 17 Апрель 2014, 11:48:41 »

Цитата: Sasha от 17 Апрель 2014, 11:28:23
где можно уменьшить толщину квадратиков в которых стоит галочка, а то они очень жирные.
Нигде. Это стандартная функция отрисовки чекбокса, как настроено в системе, так она и рисует. Если нужна другая отрисовка - рисуй вручную. Это без меня, я этим извратом заниматься не буду.

Цитата: Sasha от 17 Апрель 2014, 11:28:23
И ещё возможно ли сделать так, чтобы ComboBox не закрывался пока я не выберу мне нужные строки, а потом я сам нажму на кнопку в ComboBoxe чтобы убрать выпадающий список?
Можно попробовать вот так:
Код
void __fastcall TForm1::ComboBox1Select(TObject *Sender)
{
   // тут все необходимые действия по отметке чекбокса
   cbx->DroppedDown = true;
}
, тогда сразу после закрытия комбобокс снова переоткроется.
Записан
Sasha
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 413


Re: переделать код из Delphi в С++Builder
« Ответ #12 : 17 Апрель 2014, 11:56:51 »

Спасибо
Записан
volvo877
Глобальный модератор


Сказали спасибо: +736/-1
Offline

Сообщений: 891


Re: переделать код из Delphi в С++Builder
« Ответ #13 : 17 Апрель 2014, 12:29:37 »

Ну вот что у меня за привычка дурацкая, доводить все до конца? Чтобы
Цитата: Sasha от 17 Апрель 2014, 11:28:23
уменьшить толщину квадратиков в которых стоит галочка, а то они очень жирные.
, достаточно:

Код
    // добавить вот эти 4 строки перед выводом текста в обработчике OnDrawItem
   cbx->Canvas->Pen->Color = clWhite;
   cbx->Canvas->Brush->Style = bsClear;
   cbx->Canvas->Rectangle(R.Left + 1, R.Top + 1, R.Right - 2, R.Bottom - 2);
   cbx->Canvas->Rectangle(R.Right - 2, R.Top + 1, R.Right - 1, R.Bottom - 2);
 
   cbx->Canvas->TextOut(Rect.Left + 4 + ::GetSystemMetrics(SM_CXMENUCHECK),
       Rect.Top, cbx->Items->Strings[Index]);
, и будет так:
Записан
Sasha
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 413


Re: переделать код из Delphi в С++Builder
« Ответ #14 : 17 Апрель 2014, 12:51:22 »

У меня так
Записан
volvo877
Глобальный модератор


Сказали спасибо: +736/-1
Offline

Сообщений: 891


Re: переделать код из Delphi в С++Builder
« Ответ #15 : 17 Апрель 2014, 13:00:52 »

Очень странно, проверил и со скинами, и без них, везде рисуется корректно. Значит, меняй цвет линии на красный, и смотри, где и как надо изменить координаты отрисовываемых прямоугольников, чтобы они закрыли одну из двух черных линии окантовки, которую рисует DrawFrameControl. Потом изменишь цвет обратно на белый - и получишь тонкие CheckBox-ы
Записан
Sasha
Участник


Сказали спасибо: +13/-0
Offline

Сообщений: 413


« Ответ #16 : 17 Апрель 2014, 14:00:42 »

Цитата: volvo877 от 17 Апрель 2014, 13:00:52
Очень странно, проверил и со скинами, и без них, везде рисуется корректно. Значит, меняй цвет линии на красный, и смотри, где и как надо изменить координаты отрисовываемых прямоугольников, чтобы они закрыли одну из двух черных линии окантовки, которую рисует DrawFrameControl. Потом изменишь цвет обратно на белый - и получишь тонкие CheckBox-ы
спасибо, буду пробывать
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  




....

Powered by SMF 1.1.21 | SMF © 2025, Simple Machines
Страница сгенерирована за 0.219 секунд. Запросов: 21.