Невозможно щелкнуть пользовательский элемент управления во время разработки

Я создаю пользовательский элемент управления (унаследованный от TCustomControl) в Delphi XE2 (и у меня была эта проблема в других моих элементах управления), и во время разработки я не могу щелкнуть их. Я знаю, что это связано с захватом мыши, перехватом событий мыши и обработкой их во время разработки иначе, чем во время выполнения, но я не знаю, как правильно приспособиться к этому. Другими словами, из многих обходных путей, которые я могу придумать, я не могу решить, какой из них является правильным (или наиболее эффективным).

Я уверен, что для этого должен быть какой-то очень простой стандарт, скорее всего, использующий ControlStyle или CreateParams, но не знаю что.

В этом конкретном элементе управления (и я не видел шаблона в этой проблеме) я перехватываю сообщения, включая WM_NCHITTEST и WM_LBUTTONDOWN. Во время разработки элемент управления на 100% активен, как если бы он был во время выполнения, и при щелчке он вместо этого выполняет код времени выполнения.

У меня есть ощущение, что это в моем обработчике тестовых сообщений, так что вот этот код (некоторые вещи переименованы):

procedure TMyCustomControl.WMNCHitTest(var Message: TWMNCHitTest);
var
  P: TPoint;
  Poly: TPoints;
  X: Integer;
  I: TMyCollectionItem;
  Ch: Bool; //Need to improve invalidation
begin
  Ch:= False;
  P:= ScreenToClient(Point(Message.Pos.X, Message.Pos.Y));
  for X := 0 to Items.Count - 1 do begin
    I:= Items[X];
    Poly:= I.Points;
    FMouseIndex:= -1;
    FMouseState:= bmNone;
    if PointInPolygon(P, Poly) then begin //checks if point is within polygon
      FMouseIndex:= X;
      FMouseState:= bmHover;
      Ch:= True;
      Break;
    end;
  end;
  if Ch then Invalidate;
end;

А также конструктор моего управления (раздетый):

constructor TMyCustomControl.Create(AOwner: TComponent);
begin
  inherited;
  ControlStyle:= ControlStyle - [csDesignInteractive];
end;

person Jerry Dodge    schedule 13.05.2012    source источник
comment
Чтобы быть более конкретным, этот элемент управления представляет собой горизонтальный (или вертикальный) список элементов или стрелок. Каждый элемент рисуется как многоугольник один за другим, а пространство вокруг каждого элемента считается ничем (фоном). При наведении курсора на элемент я выделяю этот элемент (и выполняю другие внутренние ссылки на этот элемент). Я также планирую реализовать фокус на отдельных элементах списка.   -  person Jerry Dodge    schedule 13.05.2012


Ответы (2)


Но, конечно, вы правы. Вы ничего не возвращаете в обработчике WM_NCHITTEST. Ваш Mmessage.Result равен «0» (HTNOWHERE), когда ваш обработчик вызывается, и вы не назначаете ему ничего другого.

Либо вызовите inherited в какой-то момент, либо реализуйте свою логику и верните (установите Message.Result) HTCLIENT для точек, которые вы считаете внутренней частью вашего элемента управления.

Это уже желаемое поведение во время выполнения, вы можете включить проверку во время разработки (но я думаю, вы должны делать все эти вычисления по какой-то причине):

if csDesigning in ComponentState then
  Msg.Result := HTCLIENT;
person Sertac Akyuz    schedule 13.05.2012
comment
+1 csDesigning сделал свое дело - я знал, что это что-то вроде этого, но я искал в ControlState, а не в ComponentState, поэтому я не мог найти свой ответ с самого начала. Спасибо! - person Jerry Dodge; 13.05.2012

Официальный способ поддержки взаимодействия с мышью во время разработки — это ответ ненулевым результатом на сообщение CM_DESIGNHITTEST. Затем компонент будет получать обычные сообщения мыши.

person Remy Lebeau    schedule 13.05.2012
comment
AFAICS CM_DESIGNHITTEST отправляется только тогда, когда элемент управления возвращает HTCLIENT для WM_NCHITTEST. Кстати, я не совсем понял, как это должно работать, глядя на исходный код VCL, он также не задокументирован. Я вернул 0 для тестового контроля и не смог наблюдать никакого другого поведения. - person Sertac Akyuz; 13.05.2012
comment
Вам не нужно обрабатывать WM_NCHITTEST, пусть обработчик по умолчанию сделает это за вас. Большинству элементов управления не требуется поддержка взаимодействия во время разработки, поэтому они не реагируют на CM_DESIGNHITTEST, но некоторые встроенные элементы управления поддерживают, например те, которые позволяют визуально изменять размер столбцов вместо использования инспектора объектов. - person Remy Lebeau; 13.05.2012