Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

ComboBox+Дерево

621
24 августа 2004 года
Бешеный кролик
151 / / 23.03.2004
Мне нужно было создать комбобокс с выпадающим TTreeView. Нужно было срочно, поэтому я решил не писать новый компонент (на мой взгляд сложная задача), а сделать окошко с Edit'ом, кнопочкой и TTreeView, которое появляется и исчезает. Получилось все удовлетворительно, сходство с ComboBox почти 100%, что мне и надо было. Теперь проблема: я это окошко создаю в OnShow некой формы, и делаю ее Child'ом. При этом мой контрол должен располагаться на определенной панели (Но сделать его Child'ом панели нельзя, т.к. панель узкая и тогда дерево просто не будет выпадать, а если контрол сидит не на панели, то он, естественно, исчезает теряя фокус). Я вышел из этого положения, задав FormStyle=fsStayOnTop. В этот раз совсем все хорошо, но во время закрытия окна-родителя (а оно закрывается долго) на экране все время остается мой контрол. Некрасиво. Пробовал делать в OnClose FormStyle=fsNormal или Hide, выдает Access violation. Что делать?
621
24 августа 2004 года
Бешеный кролик
151 / / 23.03.2004
Да, в OnClose родительской формы я вызываю также delete для своей формы-комбобокса. Все равно, он все время торчит на экране :(
5.7K
24 августа 2004 года
forw
47 / / 24.08.2004
Цитата:
Originally posted by Бешеный кролик
Да, в OnClose родительской формы я вызываю также delete для своей формы-комбобокса. Все равно, он все время торчит на экране :(


Для этих целей специально существует TFrame, Сomboboxs втч с деревьями именно так сделаны

621
24 августа 2004 года
Бешеный кролик
151 / / 23.03.2004
Цитата:
Originally posted by forw

Для этих целей специально существует TFrame, Сomboboxs втч с деревьями именно так сделаны



Спасибо за ответ! Представь, что ComboBox сидит на узкой панельке. При раскрытии его, выпадающий список все равно выходит за пределы панельки. Я смог добиться такого только сделав контрол формой, предком этой формы сделав другую форму, а не панель, и поставив FormStyle=fsStayOnTop, но получается не очень красиво(см. выше). С фреймом такого не получается. Пробовал использовать SetWindowPos - не помогает. Подскажите, пожалуйста.

621
24 августа 2004 года
Бешеный кролик
151 / / 23.03.2004
Блин, пишу путанно ужасно. Задача такая: сделать нечто имитирующее ComboBox. Проблема: если это нечто "посадить" на панель, то при раскрытии его (увеличении размера) оно обрезается по размеру родительской панели.
621
24 августа 2004 года
Бешеный кролик
151 / / 23.03.2004
Вопрос снят.
246
24 августа 2004 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by Бешеный кролик
Блин, пишу путанно ужасно. Задача такая: сделать нечто имитирующее ComboBox. Проблема: если это нечто "посадить" на панель, то при раскрытии его (увеличении размера) оно обрезается по размеру родительской панели.


Так Ты установи стиль у TreeView в WS_POPUP и все будет ОК (SetWindowLond(), GetWindowLong...). Можно вооще посадить TreeView и на DesktopWindow -
::SetParent(Handle, GetDesktopWindow());
так в IDE BCB у ObjectInspector сделано.

Цитата:
Originally posted by Бешеный кролик

Я вышел из этого положения, задав FormStyle=fsStayOnTop.


А вот это неудачный ход.

Цитата:
Originally posted by Бешеный кролик

Что делать?


Лучше конечно создать отдельную форму без заголовка, бордюра и конечно с WS_POPUP
Это базовая POPUP-форма для любого контрола.

Код:
__fastcall TPopupForm::TPopupForm(TComponent* Owner)
   : 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.
Надо будет обработать кое-какие события...
Код:
void __fastcall TTreeViewPopupForm::TreeView1MouseUp(TObject *Sender,
   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();
   }
}

Теперь с ней можно работать...
Код:
__fastcall TForm1::TForm1(TComponent* Owner)
   : 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 понятно.
Все.
621
24 августа 2004 года
Бешеный кролик
151 / / 23.03.2004
Блин, дружище, спасибо большое! Я уже сделал как-то, но все равно не совсем удовлетворительно. Буду переделывать по твоему образцу. Возился со вчерашнего дня. Очень выручил!
272
25 августа 2004 года
vladsoft
512 / / 20.08.2000
Цитата:
Originally posted by Бешеный кролик
Блин, дружище, спасибо большое! Я уже сделал как-то, но все равно не совсем удовлетворительно. Буду переделывать по твоему образцу. Возился со вчерашнего дня. Очень выручил!


выложи посмотреть свое творение жутко интересно

621
26 августа 2004 года
Бешеный кролик
151 / / 23.03.2004
Цитата:
Originally posted by vladsoft

выложи посмотреть свое творение жутко интересно



Обязательно. Сегодня-завтра уберу одну шероховатость и выложу.

272
26 августа 2004 года
vladsoft
512 / / 20.08.2000
Цитата:
Originally posted by Бешеный кролик


Обязательно. Сегодня-завтра уберу одну шероховатость и выложу.


если что могу в приват скинуть свой e-mail

621
26 августа 2004 года
Бешеный кролик
151 / / 23.03.2004
Цитата:
Originally posted by vladsoft

если что могу в приват скинуть свой e-mail



Кидай, мой e-mail, кстати: [email]chert_poberi77@mail.ru[/email]
А то сейчас зафлеймим здесь все...

246
27 августа 2004 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by Бешеный кролик


Кидай, мой e-mail, кстати: [email]chert_poberi77@mail.ru[/email]
А то сейчас зафлеймим здесь все...



А может всеже выложить в " Исходники" пусть Все пользуются? Я не о себе беспокоюсь, сам и так знаю как сделать.

621
28 августа 2004 года
Бешеный кролик
151 / / 23.03.2004
Цитата:
Originally posted by GIZMO


А может всеже выложить в " Исходники" пусть Все пользуются? Я не о себе беспокоюсь, сам и так знаю как сделать.



Уфф, долго я мучился. Мне почему-то не нравилась идея класть окошко на Desktop, и я даже почти написал комбобокс в виде POPUPWINDOW, но оставалась неразрешимая проблема с фокусом.
Вчера с помощью WinSight32 посмотрел как устроен настоящий ComboBox и понял что ты прав. Окошко у них Child и спрятано на Desktop. В итоге еще раз посмотрел твой код и наконец-то покончил с этим комбобоксом.

Еще раз огромное тебе спасибо!

Всем кто заинтересуется, я выложил свой компонент в исходниках: http://sources.codenet.ru/download.php?id=472&cid=24&o=2&my=0

он разрабатывался для своих нужд и поэтому малофункционален, но код там маленький, в нем легко разобраться и приспособить под себя.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог