ComboBox+Дерево
Да, в OnClose родительской формы я вызываю также delete для своей формы-комбобокса. Все равно, он все время торчит на экране :(
Для этих целей специально существует TFrame, Сomboboxs втч с деревьями именно так сделаны
Для этих целей специально существует TFrame, Сomboboxs втч с деревьями именно так сделаны
Спасибо за ответ! Представь, что ComboBox сидит на узкой панельке. При раскрытии его, выпадающий список все равно выходит за пределы панельки. Я смог добиться такого только сделав контрол формой, предком этой формы сделав другую форму, а не панель, и поставив FormStyle=fsStayOnTop, но получается не очень красиво(см. выше). С фреймом такого не получается. Пробовал использовать SetWindowPos - не помогает. Подскажите, пожалуйста.
Блин, пишу путанно ужасно. Задача такая: сделать нечто имитирующее ComboBox. Проблема: если это нечто "посадить" на панель, то при раскрытии его (увеличении размера) оно обрезается по размеру родительской панели.
Так Ты установи стиль у TreeView в WS_POPUP и все будет ОК (SetWindowLond(), GetWindowLong...). Можно вооще посадить TreeView и на DesktopWindow -
::SetParent(Handle, GetDesktopWindow());
так в IDE BCB у ObjectInspector сделано.
Я вышел из этого положения, задав FormStyle=fsStayOnTop.
А вот это неудачный ход.
Что делать?
Лучше конечно создать отдельную форму без заголовка, бордюра и конечно с WS_POPUP
Это базовая POPUP-форма для любого контрола.
: TForm(Owner)
{
}
void __fastcall TPopupForm::CreateParams(TCreateParams& Params)
{
TForm::CreateParams(Params);
Params.Style &= ~(WS_CAPTION | WS_SIZEBOX | WS_POPUP);
Params.Style |= WS_CHILD | WS_BORDER;
Params.ExStyle |= WS_EX_PALETTEWINDOW;
Params.WindowClass.style |= CS_SAVEBITS;
}
void __fastcall TPopupForm::CreateWnd()
{
TForm::CreateWnd();
::SetParent(Handle, GetDesktopWindow());
}
void __fastcall TPopupForm::VisibleChanging()
{
TForm::VisibleChanging();
if (Visible)
{
ReleaseCapture();
}
else
{
if (ActiveControl)
{
SetCapture(ActiveControl->Handle);
SNDMSG(ActiveControl->Handle, WM_SETFOCUS, 0, 0);
}
else SetCapture(Handle);
}
}
void __fastcall TPopupForm::CMMouseEnter(TMessage& AMsg)
{
ReleaseCapture();
}
void __fastcall TPopupForm::CMMouseLeave(TMessage& AMsg)
{
if (Visible)
{
if (ActiveControl)
{
SetCapture(ActiveControl->Handle);
}
else SetCapture(Handle);
}
}
void __fastcall TPopupForm::WMActivateApp(TMessage& AMsg)
{
if (!AMsg.WParam)
{
Close();
}
}
void __fastcall TPopupForm::FormMouseDown(TObject *Sender,
TMouseButton Button, TShiftState Shift, int X, int Y)
{
if (X < 0 || X >= Width || Y < 0 || Y >= Height)
{
// close the form
Close();
}
}
На нее сади TreeView.
Надо будет обработать кое-какие события...
TMouseButton Button, TShiftState Shift, int X, int Y)
{
//ну конечно можно сделать через методы TTreeView
TV_HITTESTINFO tvhti = {X, Y};
SNDMSG(TreeView1->Handle, TVM_HITTEST, 0,
reinterpret_cast<LPARAM>(&tvhti));
if (tvhti.flags & TVHT_ONITEM)
{
Close();
}
}
Теперь с ней можно работать...
: TForm(Owner)
{
TreeViewPopupForm_ = new TTreeViewPopupForm(this);
TreeViewPopupForm_->OnClose = TreeViewPopupFormClose;
}
void __fastcall TForm1::TreeViewSpeedButtonClick(TObject *Sender)
{
RECT RPopup;
if (GetWindowRect(TreeViewPanel->Handle, &RPopup))
{
TreeViewEdit->SetFocus();
TreeViewEdit->SelectAll();
TreeViewPopupForm_->Left = RPopup.left;
TreeViewPopupForm_->Top = RPopup.bottom;
TreeViewPopupForm_->Show();
}
}
void __fastcall TForm1::TreeViewPopupFormClose(TObject* Sender,
TCloseAction &Action)
{
TTreeNode* Node = TreeViewPopupForm_->TreeView1->Selected;
if (Node)
{
TreeViewEdit->Text = Node->Text;
TreeViewEdit->SelectAll();
TreeViewImage->Picture = NULL;
TreeViewPopupForm_->ImageList1->GetBitmap(
Node->ImageIndex, TreeViewImage->Picture->Bitmap
);
}
}
void __fastcall TForm1::TreeViewEditKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if (TreeViewPopupForm_->Visible)
{
SNDMSG(
TreeViewPopupForm_->ActiveControl->Handle,
WM_KEYDOWN, Key, 0
);
Key = 0;
}
}
void __fastcall TForm1::TreeViewEditKeyUp(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if (TreeViewPopupForm_->Visible)
{
SNDMSG(
TreeViewPopupForm_->ActiveControl->Handle,
WM_KEYUP, Key, 0
);
Key = 0;
}
}
void __fastcall TForm1::TreeViewEditKeyPress(TObject *Sender, char &Key)
{
if (Key == '\r' && TreeViewPopupForm_->Visible)
{
TreeViewPopupForm_->Close();
Key = 0;
}
}
Ну, что здесь TreeViewEdit и TreeViewSpeedButton понятно.
Все.
Блин, дружище, спасибо большое! Я уже сделал как-то, но все равно не совсем удовлетворительно. Буду переделывать по твоему образцу. Возился со вчерашнего дня. Очень выручил!
выложи посмотреть свое творение жутко интересно
выложи посмотреть свое творение жутко интересно
Обязательно. Сегодня-завтра уберу одну шероховатость и выложу.
Обязательно. Сегодня-завтра уберу одну шероховатость и выложу.
если что могу в приват скинуть свой e-mail
если что могу в приват скинуть свой e-mail
Кидай, мой e-mail, кстати: [email]chert_poberi77@mail.ru[/email]
А то сейчас зафлеймим здесь все...
Кидай, мой e-mail, кстати: [email]chert_poberi77@mail.ru[/email]
А то сейчас зафлеймим здесь все...
А может всеже выложить в " Исходники" пусть Все пользуются? Я не о себе беспокоюсь, сам и так знаю как сделать.
А может всеже выложить в " Исходники" пусть Все пользуются? Я не о себе беспокоюсь, сам и так знаю как сделать.
Уфф, долго я мучился. Мне почему-то не нравилась идея класть окошко на Desktop, и я даже почти написал комбобокс в виде POPUPWINDOW, но оставалась неразрешимая проблема с фокусом.
Вчера с помощью WinSight32 посмотрел как устроен настоящий ComboBox и понял что ты прав. Окошко у них Child и спрятано на Desktop. В итоге еще раз посмотрел твой код и наконец-то покончил с этим комбобоксом.
Еще раз огромное тебе спасибо!
Всем кто заинтересуется, я выложил свой компонент в исходниках: http://sources.codenet.ru/download.php?id=472&cid=24&o=2&my=0
он разрабатывался для своих нужд и поэтому малофункционален, но код там маленький, в нем легко разобраться и приспособить под себя.