-
Мой TCustomControl компонент должен перехватывать мышиные движения и клики. Реализую перекрытием MouseDown и MouseMove. В ран тайм всё работает нормально. Как сделать, чтобы и в дизайн-тайм всё работало?
-
Приблизительно так
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;
-
> DimaBr (26.07.06 12:28) [1]Cool, а что за сообщение такое WMNCHITTEST ? За что оно отвечает, только за мышиные или за все сообщения в DesignTime? csDesigning стало быть автоматически выставляется в DesignTime?
-
> что за сообщение такое 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.
-
> csDesigning стало быть автоматически выставляется в DesignTime?
Да, и это то прекрасно, если нужно отличить от Run Time.
-
А кто-нить знает, как в C++ вызвать типа inherited. Делаю: TCustomControl::WMNCHitTest(M) , говорит, недоступен
-
А вообще последняя строка критична? Если нет, то без неё у меня всё по прежнему; как быть?
-
Прошу прощения, код просто вырезал из компонента, а в нём переопределён GetClientRect, поэтому замените строчку R:=GetClientRect; на: with ClientRect do R := Rect(Left+1,Top+1,Right-2,Bottom-2);
-
Один Фиг реакции нет.
DimaBr, пожалуйста, если есть такая возможность, протестите свой компонент без последней строчки. Если у Вас не будет работать, значит всё дело в ней
-
Вот, работает даже без фокусировки на компоненте. 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
public
end;
TMyPanel = class(TPanel)
private
procedure WMNCHITTEST(var M: TWMNCHITTEST);message WM_NCHITTEST;
end;
var
Form1: TForm1;
APanel: TMyPanel;
procedure Register;
implementation
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.
-
Если я всё правильно понял, то мне нужно отследить, находится ли курсор в клиентской области (HTCLIENT). Вообщем я делаю табличку, сверху названия столбцов, высота которых равна TitleHeight [17 пикселей]. И всё равно блин чё та не хочет. А HTCAPTION - это что такое? Делаю так: void __fastcall TInfoTable::WMNCHitTest(Messages::TWMNCHitTest &Message) { 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; Result=HTCLIENT; } if (!Message.Result) Message.Result=HTCLIENT; }
-
К сожалению, я не силён в Си, но идея этого события такова чтобы вернуть результат системе, где находится курсор мыши, как системе отобразить курсор и как реагировать. Для этого и передаётся параметр var M: TWMNCHITTEST. который мы и заполняем. Данный код отслеживает положение курсора и если это положение у самого края компонента - то возвращается значение у какого собственно говоря края. В зависимости от вернувшегося значения система реагирует на поведение курсора. То есть, если мы находимся у правого края, отрабатывается условие if P.x>R.Right then M.Result:=HTRIGHT и возвращается значение HTRIGHT. Система отображает курсор в виде <-> и при нажатии на левую кнопку мыши и её перемещение происходит изменение ширины компонента по правому краю.
-
Ну это более менее понятно. А HTCAPTION ?
-
Курсор находится в районе заголовка окна.
-
Не катит! Вообще одну строчку оставил: Message.Result=HTCLIENT; Естественно, перекомпилировал и даже переустановил. По идее в ДизайнТайм вообще не должен реагировать... А он реагирует :( [всмысле компонент можно перемещать, изменять размеры]
-
Я не понимаю чего вы хотите добиться. > По идее в ДизайнТайм вообще не должен реагировать
Всё с точностью до наоборот. Вы сообщаете системе что курсор находится на территории окна. Почему же он не должен реагировать ?
-
> DimaBr (27.07.06 16:58) [15] Я не понимаю чего вы хотите добиться.
Пока надо в дизайн тайм изменять ширину столбцов таблицы. В рантайм работает, в дизайнтайм - не воспринимает
-
Начнём сначала. Что из себя представляет таблица ?
-
таблица - двумерная матрица M x N :)
Предаставляй TStringGrid, у которого есть шапка, слева ничё нету. Можно задавать количество строк и столбцов. Получается M x N ячеек. Ширину каждого столбца можно менять [мышкой, если между 2-мя столбцами в шапке]. Так вот в рантайм всё работает, в дизайн - нет
-
Такой компонент уже изобрели :) TListView называется с параметром Style = vsReport!!! Ну а если серьезно, то нафига тебе настраивать ширину столбцов в Дезигн-Тайм... Делай програмно, ненадо самому себе придумывать мозго***тва... Чем проще, тем лучше...
|