Конференция "Компоненты" » Мышиный Перехват в дизайн-тайм
 
  • DevilDevil © (26.07.06 10:17) [0]
    Мой TCustomControl компонент должен перехватывать мышиные движения и клики. Реализую перекрытием MouseDown и MouseMove. В ран тайм всё работает нормально. Как сделать, чтобы и в дизайн-тайм всё работало?
  • DimaBr (26.07.06 12:28) [1]
    Приблизительно так

    procedure WMNCHITTEST(var M: TWMNCHITTEST); message WM_NCHITTEST;
    ......
    procedure TMyCustomControl.WMNCHITTEST(var M: TWMNCHITTEST);
     var R: TRect;
         P: TPoint;
    begin
       R:=GetClientRect;
       P:=ScreenToClient(Point(M.XPos, M.YPos));
       if (P.x<R.Left)and(P.y<R.Left) then M.Result:=HTTOPLEFT else
       if (P.x<R.Left)and(P.y>R.Bottom) then M.Result:=HTBOTTOMLEFT else
       if (P.x>R.Right)and(P.y<R.Left) then M.Result:=HTTOPRIGHT else
       if (P.x>R.Right)and(P.y>R.Bottom) then M.Result:=HTBOTTOMRIGHT else
       if P.x<R.Left then M.Result:=HTLEFT else
       if P.x>R.Right then M.Result:=HTRIGHT else
       if P.y<R.Left then M.Result:=HTTOP else
       if P.y>R.Bottom then M.Result:=HTBOTTOM else
       if P.y<R.Top then M.Result:=HTCAPTION else M.Result:=HTCLIENT;
       if (csDesigning in ComponentState) and (M.Result=HTCAPTION) then inherited
     end;
    end;

  • DevilDevil © (26.07.06 12:43) [2]
    > DimaBr   (26.07.06 12:28) [1]
    Cool, а что за сообщение такое
    WMNCHITTEST

    ?  За что оно отвечает, только за мышиные или за все сообщения в DesignTime?
    csDesigning

    стало быть автоматически выставляется в DesignTime?
  • Сергей М. © (26.07.06 13:14) [3]

    > что за сообщение такое WMNCHITTEST?


    The WM_NCHITTEST message is sent to a window when the cursor moves, or when a mouse button is pressed or released. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is posted to the window that has captured the mouse.
  • DimaBr (26.07.06 13:31) [4]

    >  csDesigning стало быть автоматически выставляется в DesignTime?

    Да, и это то прекрасно, если нужно отличить от Run Time.
  • DevilDevil © (26.07.06 14:45) [5]
    А кто-нить знает, как в C++ вызвать типа inherited. Делаю:
    TCustomControl::WMNCHitTest(M)

    , говорит, недоступен
  • DevilDevil © (26.07.06 16:05) [6]
    А вообще последняя строка критична?
    Если нет, то без неё у меня всё по прежнему; как быть?
  • DimaBr (27.07.06 10:19) [7]
    Прошу прощения, код просто вырезал из компонента, а в нём переопределён
    GetClientRect, поэтому замените строчку
    R:=GetClientRect;


    на:
    with ClientRect do R := Rect(Left+1,Top+1,Right-2,Bottom-2);

  • DevilDevil © (27.07.06 14:09) [8]
    Один Фиг реакции нет.

    DimaBr, пожалуйста, если есть такая возможность, протестите свой компонент без последней строчки. Если у Вас не будет работать, значит всё дело в ней
  • DimaBr (27.07.06 14:24) [9]
    Вот, работает даже без фокусировки на компоненте.
    unit Test;

    interface

    uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, ExtCtrls;

    type
     TForm1 = class(TForm)
       Panel1: TPanel;
       MyPanel1: TMyPanel;
       procedure FormCreate(Sender: TObject);
     private
       { Private declarations }
     public
       { Public declarations }
     end;

    TMyPanel = class(TPanel)
     private
       procedure WMNCHITTEST(var M: TWMNCHITTEST);message WM_NCHITTEST;
    end;

    var
     Form1: TForm1;
     APanel: TMyPanel;
    procedure Register;
    implementation

    {$R *.dfm}

    procedure Register;
    begin
     RegisterComponents('Standard',[TMyPanel]);
    end;

    procedure TMyPanel.WMNCHITTEST(var M: TWMNCHITTEST);
    var R: TRect;
        P: TPoint;
    begin
      with ClientRect do R := Rect(Left+1,Top+1,Right-2,Bottom-2);
      P:=ScreenToClient(Point(M.XPos, M.YPos));
      if (P.x<R.Left)and(P.y<R.Left) then M.Result:=HTTOPLEFT else
      if (P.x<R.Left)and(P.y>R.Bottom) then M.Result:=HTBOTTOMLEFT else
      if (P.x>R.Right)and(P.y<R.Left) then M.Result:=HTTOPRIGHT else
      if (P.x>R.Right)and(P.y>R.Bottom) then M.Result:=HTBOTTOMRIGHT else
      if P.x<R.Left then M.Result:=HTLEFT else
      if P.x>R.Right then M.Result:=HTRIGHT else
      if P.y<R.Left then M.Result:=HTTOP else
      if P.y>R.Bottom then M.Result:=HTBOTTOM else
      if P.y<R.Top then M.Result:=HTCAPTION else M.Result:=HTCLIENT;
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
     APanel:= TMyPanel.Create(self);
     APanel.Parent := form1;
    end;

    end.

  • DevilDevil © (27.07.06 15:14) [10]
    Если я всё правильно понял, то мне нужно отследить, находится ли курсор в клиентской области (HTCLIENT). Вообщем я делаю табличку, сверху названия столбцов, высота которых равна TitleHeight [17 пикселей]. И всё равно блин чё та не хочет. А HTCAPTION - это что такое? Делаю так:

    void __fastcall TInfoTable::WMNCHitTest(Messages::TWMNCHitTest &Message)
    {  
    //TRect R = GetClientRect();


      TRect R, CL = ClientRect;
      R = Rect(CL.Left+1,CL.Top+1+TitleHeight,CL.Right-2,CL.Bottom-2);
      TPoint P = ScreenToClient(Point(Message.XPos, Message.YPos));

      Message.Result = 0;
    if (ComponentState.Contains(csDesigning))
    {
      if (P.x<R.Left && P.y<R.Left) Message.Result=HTTOPLEFT; else
      if (P.x<R.Left && P.y>R.Bottom) Message.Result=HTBOTTOMLEFT; else
      if (P.x>R.Right && P.y<R.Left) Message.Result=HTTOPRIGHT; else
      if (P.x>R.Right && P.y>R.Bottom) Message.Result=HTBOTTOMRIGHT; else
      if (P.x<R.Left) Message.Result=HTLEFT; else
      if (P.x>R.Right) Message.Result=HTRIGHT; else
      if (P.y<R.Left) Message.Result=HTTOP; else
      if (P.y>R.Bottom) Message.Result=HTBOTTOM; else
      if (P.y<R.Top) Message.Result=HTCLIENT;
    //  if (P.y<R.Top) Message.Result=HTCAPTION; //else Message.

    Result=HTCLIENT;
    }
    if (!Message.Result) Message.Result=HTCLIENT;
    //  if (ComponentState.Contains(csDesigning) && Message.Result==HTCAPTION) TCustomControl::WMNCHitTest();//(Message);



    }
  • DimaBr (27.07.06 15:51) [11]
    К сожалению, я не силён в Си, но идея этого события такова чтобы вернуть результат системе, где находится курсор мыши, как системе отобразить курсор и как реагировать. Для этого и передаётся параметр var M: TWMNCHITTEST. который мы и заполняем. Данный код отслеживает положение курсора и если это положение у самого края компонента - то возвращается значение у какого собственно говоря края. В зависимости от вернувшегося значения система реагирует на поведение курсора. То есть, если мы находимся у правого края, отрабатывается условие
    if P.x>R.Right then M.Result:=HTRIGHT


    и возвращается значение HTRIGHT. Система отображает курсор в виде <-> и при нажатии на левую кнопку мыши и её перемещение происходит изменение ширины компонента по правому краю.
  • DevilDevil © (27.07.06 16:31) [12]
    Ну это более менее понятно. А
    HTCAPTION

    ?
  • DimaBr (27.07.06 16:34) [13]
    Курсор находится в районе заголовка окна.
  • DevilDevil © (27.07.06 16:41) [14]
    Не катит! Вообще одну строчку оставил:
    Message.Result=HTCLIENT;



    Естественно, перекомпилировал и даже переустановил.
    По идее в ДизайнТайм вообще не должен реагировать... А он реагирует :( [всмысле компонент можно перемещать, изменять размеры]
  • DimaBr (27.07.06 16:58) [15]
    Я не понимаю чего вы хотите добиться.

    > По идее в ДизайнТайм вообще не должен реагировать

    Всё с точностью до наоборот. Вы сообщаете системе что курсор находится на территории окна. Почему же он не должен реагировать ?
  • DevilDevil © (27.07.06 17:17) [16]

    > DimaBr   (27.07.06 16:58) [15]
    Я не понимаю чего вы хотите добиться.

    Пока надо в дизайн тайм изменять ширину столбцов таблицы. В рантайм работает, в дизайнтайм - не воспринимает
  • DimaBr (27.07.06 17:24) [17]
    Начнём сначала. Что из себя представляет таблица ?
  • DevilDevil © (27.07.06 17:33) [18]
    таблица - двумерная матрица M x N :)

    Предаставляй TStringGrid, у которого есть шапка, слева ничё нету. Можно задавать количество строк и столбцов. Получается M x N ячеек. Ширину каждого столбца можно менять [мышкой, если между 2-мя столбцами в шапке]. Так вот в рантайм всё работает, в дизайн - нет
  • Степан (27.07.06 21:27) [19]
    Такой компонент уже изобрели :) TListView называется с параметром Style = vsReport!!! Ну а если серьезно, то нафига тебе настраивать ширину столбцов в Дезигн-Тайм... Делай програмно, ненадо самому себе придумывать мозго***тва... Чем проще, тем лучше...
  • DimaBr (28.07.06 08:36) [20]

    > Предаставляй TStringGrid, у которого есть шапка, слева ничё
    > нету.

    Это TStringGrid и есть, и в дизайнере колонки двигаются.
  • DevilDevil © (28.07.06 12:04) [21]
    ну это понятно. Так как в дизайн тайм обрабатывать?
  • DimaBr (28.07.06 13:16) [22]
    Находим подходящий компонент, с походими действиями и смотрим реализацию. Например TCustomGrid
    Смотрим
    procedure CMDesignHitTest(var Msg: TCMDesignHitTest); message CM_DESIGNHITTEST;
    procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
  • DevilDevil © (13.09.06 17:31) [23]
    Вот вернулся к давнишней проблеме... воз и ныне там...

    Никак я не найду константу, которая "говорит" моему компоненту: "Отлавливай и обрабатывай мышиные сообщения так же, как отлавливаешь в рантайм!"

    Смотрел даже исходники TCustomGrid... Чё то не очень...

    Ну так что за константа?

    P.S. Заметил, чтобы компонент стандартно обрабатывался в дизайн тайм, достаточно присвоить константу HTCLIENT
  • jack128 © (14.09.06 03:35) [24]
    DevilDevil ©   (13.09.06 17:31) [23]
    Смотрел даже исходники TCustomGrid... Чё то не очень

    обратись к окулисту.  Тебе русским языком сказали:
    DimaBr   (28.07.06 13:16) [22]
    Находим подходящий компонент, с походими действиями и смотрим реализацию. Например TCustomGrid
    Смотрим
    procedure CMDesignHitTest(var Msg: TCMDesignHitTest); message CM_DESIGNHITTEST;
  • DimaBr (14.09.06 09:33) [25]
    procedure TMyComponent.CMDesignHitTest(var Msg: TCMDesignHitTest);
    begin
     Msg.Result := 1; // обрабатывать действия в дизайнере
    end;



    для грида написано вот так, то есть реагировать только тогда, когда фунцкия Sizing возвращает TRUE
    procedure TCustomGrid.CMDesignHitTest(var Msg: TCMDesignHitTest);
    begin
     Msg.Result := Longint(BOOL(Sizing(Msg.Pos.X, Msg.Pos.Y)));
    end;

  • DevilDevil © (14.09.06 14:59) [26]
    DimaBr   (14.09.06 09:33) [25]
    procedure TMyComponent.CMDesignHitTest(var Msg: TCMDesignHitTest);
    begin
    Msg.Result := 1; // обрабатывать действия в дизайнере
    end;



      Error:

      Cannot focus a disabled or invisible window.
                           _____
                          |  Ok  |
                           
  • DevilDevil © (14.09.06 15:01) [27]
    Эксперименты с перехватом WM_NCHITTEST желаемого результата не дали
  • DimaBr (14.09.06 16:15) [28]
    Ну так проверьте, может не здесь ошибка.
  • DevilDevil © (15.09.06 14:56) [29]
    > DimaBr   (14.09.06 16:15) [28]
    > Ну так проверьте, может не здесь ошибка.


    Что то я не очень понял. Где проверить?

    Если использовать предложенный Вами вариант, то при нажатии кнопки мыши над компонентом (когда компоненту даётся фокус) возникает вышеуказанная ошибка. В РанТайм всё естественно работает корректно.
  • DimaBr (15.09.06 15:29) [30]
    Предаставляй TStringGrid, у которого есть шапка, слева ничё нету.
    StringGrid.FixedCols := 0;

    Возьмите за основу CustomGrid и творите что хотите. Не можите самостоятельно реализовать движение колонок - скопируйте файл Grids в свою папочку, переименуйте, и выкидывайте потихоньку всё лишнее.
  • DevilDevil © (15.09.06 15:54) [31]
    > DimaBr   (15.09.06 15:29) [30]

    Работа над таблицей длится уже 2 месяца, отличия от стандартной существенны. Собственно и ушли от стандартов по этой причине. Есть некоторые ограничения по скорости и занимаемой оперативной памяти. К тому же всё, что написано, написано на Си. Переписывать всё на Delphi или ещё хуже переписывать с начала - естественно нецелесообразно. Поэтому я и задал на форуме элементарный вопрос, который почему то не получается решить уже 1.5 месяца

    В общем, если кто то уже сталкивался с подобной проблемой, буду рад помощи
  • Ketmar © (15.09.06 16:05) [32]
    мда... поколение младое... краткое содержание ветки: "вот в стандартном гриде работает. а у меня нет. читать не умею, потому исходник стандартного грида не предлагать!"

    ужос...
  • DevilDevil © (15.09.06 16:29) [33]
    Зануда! см [25] - [26]
  • Наиль © (18.09.06 10:23) [34]
    Глянь в Help'e
    TControlStyle
    = csDesignInteractive
    + csClickEvents
    Может оно?
  • DimaBr (21.09.06 09:26) [35]

    > DevilDevil ©

    Заглятите в почту.
  • DevilDevil © (21.09.06 15:34) [36]
    Во первых, я избавился от злостной ошибки при клике мышкой. По событию OnMouseDown происходил метод
    SetFocus

    , который я переопределил:

    if not(csDesigning in ComponentState) then inherited ;



    Во вторых, удалось реализовать нормальное изменение размеров столбцов. DimaBr, большое спасибо за пример!

    Сейчас размышляю, как реализовать сохранение этой ширины в *dfm файле
  • DimaBr (22.09.06 08:47) [37]

    > DevilDevil ©   (21.09.06 15:34) [36]

    А теперь внимательно прочтите [28]
  • Ketmar © (22.09.06 08:52) [38]
    >[37] DimaBr 22-Sep-XLI A.S., 08:47
    >А теперь внимательно прочтите [28]
    совершенно бессмысленно. адепты Ф. читают с трудом, и то только откровения кумира.
  • DimaBr (22.09.06 11:13) [39]

    > ейчас размышляю, как реализовать сохранение этой ширины
    > в *dfm файле

    Если ваши колонки элементы коллекции, то ширину в published и колекцию в published, иначе

    procedure DefineProperties( Filer: TFiler );override;
    procedure ReadMyProperty( Reader: TReader );
    procedure WriteMyProperty( Writer: TWriter );

  • DevilDevil © (22.09.06 16:14) [40]
    > DimaBr   (22.09.06 11:13) [39]

    Выглядеть это должно так: у таблицы есть свойство допустим
    Columns

    с квадратиком с троеточием. Щёлкаю по кнопке, показывается список СТОЛБЦОВ. Щёлкаю по столбцу из этого списка, настраиваю
    Width

    ,
    Title

    и пару других индивидуальных свойств столбца.

    Подскажите плиз ссылочки, примеры, методы реализации подобных задач
  • GrayFace © (22.09.06 19:14) [41]
    Наиль ©   (18.09.06 10:23) [34]
    Может оно?

    Неа.

    DevilDevil ©   (22.09.06 16:14) [40]
    Используй TCollection. Можно почитать статью "Коллекции и работа с ними" на http://www.delphikingdom.ru/
  • DimaBr (25.09.06 15:54) [42]

    > Щёлкаю по столбцу из этого списка, настраиваю Width, Title
    > и пару других индивидуальных свойств столбца.

    Настораживает, если элементы колекции разнотипные.
  • DevilDevil © (26.09.06 13:41) [43]
    > GrayFace ©   (22.09.06 19:14) [41]

    > Используй TCollection. Можно почитать статью "Коллекции  и работа с ними" на http://www.delphikingdom.ru/


    Да, спасибо, то, что нужно!
    http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=215

    Сейчас правда проблемка началась с коллекциями... может новый топик заведу
  • DimaBr (26.09.06 13:48) [44]

    > Да, спасибо, то, что нужно!

    Спасибо, многоуважаемому Юрию !!!
  • имя (21.03.07 18:11) [45]
    Удалено модератором
  • имя (21.03.07 18:12) [46]
    Удалено модератором
  • имя (21.03.07 18:12) [47]
    Удалено модератором
  • имя (21.03.07 21:00) [48]
    Удалено модератором
  • имя (21.03.07 21:01) [49]
    Удалено модератором
  • имя (21.03.07 21:02) [50]
    Удалено модератором
  • имя (21.03.07 21:07) [51]
    Удалено модератором
  • имя (21.03.07 21:10) [52]
    Удалено модератором
  • имя (22.03.07 14:21) [53]
    Удалено модератором
  • имя (22.03.07 14:24) [54]
    Удалено модератором
  • имя (22.03.07 14:38) [55]
    Удалено модератором
  • имя (22.03.07 14:40) [56]
    Удалено модератором
  • имя (22.03.07 14:41) [57]
    Удалено модератором
  • имя (22.03.07 14:41) [58]
    Удалено модератором
  • имя (22.03.07 14:41) [59]
    Удалено модератором
  • имя (22.03.07 14:42) [60]
    Удалено модератором
  • имя (23.03.07 01:50) [61]
    Удалено модератором
  • имя (23.03.07 06:54) [62]
    Удалено модератором
  • имя (23.03.07 06:55) [63]
    Удалено модератором
  • имя (23.03.07 06:56) [64]
    Удалено модератором
  • имя (23.03.07 06:56) [65]
    Удалено модератором
  • имя (23.03.07 06:59) [66]
    Удалено модератором
  • имя (23.03.07 06:59) [67]
    Удалено модератором
  • имя (23.03.07 07:02) [68]
    Удалено модератором
  • имя (23.03.07 16:46) [69]
    Удалено модератором
  • имя (23.03.07 23:22) [70]
    Удалено модератором
  • имя (23.03.07 23:28) [71]
    Удалено модератором
  • homm © (23.03.07 23:36) [72]
    Да закройте ветку. Автору надо будет - новую создаст.
 
Конференция "Компоненты" » Мышиный Перехват в дизайн-тайм
Есть новые Нет новых   [119026   +43][b:0.001][p:0.005]