• AndreyMst (19.01.11 17:51) [0]
    Здравствуйте!

    Пытаюсь реализовать нечто похожее на КомбоБокс. Интересен один механизм который используется в оригинальном КомбоБоксе, а именно закрытие его Popup списка Item-ов при выделении другого контрола, активации и деактивации окна, при том что само Popup окно создается и показывается неактивным т.к. окно содержащее КомбоБокс не теряет своей активности при его открытии, соответственно Popup не получает фокус (Иначе бы он стал активным). Также для того чтобы окно не активировалось по клику на нем я обрабатываю сообщение WM_MOUSEACTIVATE, где возвращаю в результат MA_NOACTIVATE.
    Следовательно, что я сейчас имею:
    1) Невозможно обрабатывать сообщение WM_ACTIVATE (Из за того что Popup изначально не активен).
    2) Невозможно обработать сообщения WM_SETFOCUS и WM_KILLFOCUS (Из за того что Popup не получает фокус).

    Все что сумел сделать, это обработать WM_ACTIVATEAPP при потере фокуса окном процесса и WM_WINDOWPOSCHANGING при смене Z ордера на окне.

    Само окошко реализовано на основе класса TWinControl. Привожу некоторые фрагменты кода:

    //Инициализация стиля окна, для перевода его в POPUP
     procedure TAMCheckComboBoxDropDownList.CreateParams(
     var Params: TCreateParams);
     begin
       inherited CreateParams(Params);
       with Params do
         begin
           Style := WS_POPUP;
           if NewStyleControls then
             ExStyle := WS_EX_TOOLWINDOW;
         end;
     end;



    //Процедура скрытия Popup окна
    procedure TAMCheckComboBoxDropDownList.HideList;
     begin
       if fActive then
         begin
           ShowWindow(Handle, SW_HIDE);
           fActive := false;
         end;
     end;



    //Процедура показа Popup окна
    procedure TAMCheckComboBoxDropDownList.ShowList;
     var
       Rct : TRect;
     begin
       //Получаю область КомбоБокса (Экземпляр его класса fOwner, тоже наследованный от TWinControl)
       GetWindowRect(fOwner.Handle, Rct);
       //Устанавливаю размер Popup окна равный ширине КомбоБокса и располагаю Popup под ним
       SetWindowPos(Handle, HWND_TOP, Rct.Left, Rct.Bottom, Rct.Right - Rct.Left, 100, SWP_NOACTIVATE);
       ParentWindow := fOwner.Handle;
       //Показываю его неактивным
       ShowWindow(Handle, SW_SHOWNOACTIVATE);
       fActive := true;
     end;



    //Обработка сообщения WM_MOUSEACTIVATE
    procedure TAMCheckComboBoxDropDownList.WMMouseActivate(
     var Msg: TWMMouseActivate);
     begin
       Msg.Result := MA_NOACTIVATE;
     end;



    Собственно остался вопрос, как прятать Popup, так как это делает стандартный ComboBox?
  • DimaBr © (20.01.11 11:45) [1]
    1. От кого наследован TAMCheckComboBoxDropDownList ?
  • AndreyMst (20.01.11 14:42) [2]
    От TWinControl
  • DimaBr © (20.01.11 15:47) [3]
    Проще сделать выпадающее окно отдельным контролом, которым и управлять, а не использовать параметры стилей
  • AndreyMst (20.01.11 15:57) [4]

    > DimaBr ©   (20.01.11 15:47) [3]
    > Проще сделать выпадающее окно отдельным контролом, которым
    > и управлять, а не использовать параметры стилей


    А что по твоему я делаю??? Как еще можно сделать выпадающее окно (Разве что на Win API) не используя оконный контрол (TWinControl)? И что ты имеешь ввиду под использованием параметров стилей? Если процедуру CreateParams, то это необходимо для создания Popup окна, стиль WS_EX_TOOLWINDOW отключает появление кнопки в TaskBar'е. Если есть какие-нибудь предложения, прошу дать ответ в развернутом виде.
  • KilkennyCat © (20.01.11 23:38) [5]

    > Как еще можно сделать выпадающее окно (Разве что на Win API) не используя оконный контрол (TWinControl)?

    да хотя бы используя TGraphicControl
  • DimaBr © (21.01.11 09:01) [6]
    Не понятно, когда нужно прятать ваше окно. Попробуйте прятать на CM_CancelMode

    procedure TMyPopupEdit.CMCancelMode(var Message: TCMCancelMode);
    begin
     if (Message.Sender <> Self) and (Message.Sender <> FPopup) and
       (Message.Sender <> FButton) and ((FPopup <> nil) and
       not FPopup.ContainsControl(Message.Sender)) then
       PopupCloseUp(FPopup, False);
    end;

Есть новые Нет новых   [134466   +3][b:0][p:0.002]