//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]);*/}//---------------------------------------------------------------------------
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 // дальше пошла форма, без изменений...
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...}
void __fastcall TForm1::FormCreate(TObject *Sender){ ComboBox1->Style = csOwnerDrawVariable; // } // Добавляем обработчик OnMeasureItemvoid __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, а можно ли сделать чтобы при таком коде вместо пустого поля была строка из выбранных пунктов на которых стоит галочка?
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;}
__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;}
void __fastcall TForm1::ComboBox1Select(TObject *Sender){ // тут все необходимые действия по отметке чекбокса cbx->DroppedDown = true;}
// добавить вот эти 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]);