-
Мой 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!!! Ну а если серьезно, то нафига тебе настраивать ширину столбцов в Дезигн-Тайм... Делай програмно, ненадо самому себе придумывать мозго***тва... Чем проще, тем лучше...
-
> Предаставляй TStringGrid, у которого есть шапка, слева ничё > нету.
Это TStringGrid и есть, и в дизайнере колонки двигаются.
-
ну это понятно. Так как в дизайн тайм обрабатывать?
-
Находим подходящий компонент, с походими действиями и смотрим реализацию. Например TCustomGrid Смотрим procedure CMDesignHitTest(var Msg: TCMDesignHitTest); message CM_DESIGNHITTEST; procedure WMNCHitTest(var Msg: TWMNCHitTest); message WM_NCHITTEST;
-
Вот вернулся к давнишней проблеме... воз и ныне там...
Никак я не найду константу, которая "говорит" моему компоненту: "Отлавливай и обрабатывай мышиные сообщения так же, как отлавливаешь в рантайм!"
Смотрел даже исходники TCustomGrid... Чё то не очень...
Ну так что за константа?
P.S. Заметил, чтобы компонент стандартно обрабатывался в дизайн тайм, достаточно присвоить константу HTCLIENT
-
DevilDevil © (13.09.06 17:31) [23] Смотрел даже исходники TCustomGrid... Чё то не очень обратись к окулисту. Тебе русским языком сказали: DimaBr (28.07.06 13:16) [22] Находим подходящий компонент, с походими действиями и смотрим реализацию. Например TCustomGrid Смотрим procedure CMDesignHitTest(var Msg: TCMDesignHitTest); message CM_DESIGNHITTEST;
-
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;
-
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 |
-
Эксперименты с перехватом WM_NCHITTEST желаемого результата не дали
-
Ну так проверьте, может не здесь ошибка.
-
> DimaBr (14.09.06 16:15) [28] > Ну так проверьте, может не здесь ошибка.
Что то я не очень понял. Где проверить?
Если использовать предложенный Вами вариант, то при нажатии кнопки мыши над компонентом (когда компоненту даётся фокус) возникает вышеуказанная ошибка. В РанТайм всё естественно работает корректно.
-
Предаставляй TStringGrid, у которого есть шапка, слева ничё нету. StringGrid.FixedCols := 0;
Возьмите за основу CustomGrid и творите что хотите. Не можите самостоятельно реализовать движение колонок - скопируйте файл Grids в свою папочку, переименуйте, и выкидывайте потихоньку всё лишнее.
-
> DimaBr (15.09.06 15:29) [30]
Работа над таблицей длится уже 2 месяца, отличия от стандартной существенны. Собственно и ушли от стандартов по этой причине. Есть некоторые ограничения по скорости и занимаемой оперативной памяти. К тому же всё, что написано, написано на Си. Переписывать всё на Delphi или ещё хуже переписывать с начала - естественно нецелесообразно. Поэтому я и задал на форуме элементарный вопрос, который почему то не получается решить уже 1.5 месяца
В общем, если кто то уже сталкивался с подобной проблемой, буду рад помощи
-
мда... поколение младое... краткое содержание ветки: "вот в стандартном гриде работает. а у меня нет. читать не умею, потому исходник стандартного грида не предлагать!"
ужос...
-
Зануда! см [25] - [26]
-
Глянь в Help'e TControlStyle = csDesignInteractive + csClickEvents Может оно?
-
> DevilDevil ©
Заглятите в почту.
-
Во первых, я избавился от злостной ошибки при клике мышкой. По событию OnMouseDown происходил метод SetFocus , который я переопределил: if not(csDesigning in ComponentState) then inherited ; Во вторых, удалось реализовать нормальное изменение размеров столбцов. DimaBr, большое спасибо за пример! Сейчас размышляю, как реализовать сохранение этой ширины в *dfm файле
-
> DevilDevil © (21.09.06 15:34) [36]
А теперь внимательно прочтите [28]
-
>[37] DimaBr 22-Sep-XLI A.S., 08:47 >А теперь внимательно прочтите [28] совершенно бессмысленно. адепты Ф. читают с трудом, и то только откровения кумира.
-
> ейчас размышляю, как реализовать сохранение этой ширины > в *dfm файле
Если ваши колонки элементы коллекции, то ширину в published и колекцию в published, иначе
procedure DefineProperties( Filer: TFiler );override;
procedure ReadMyProperty( Reader: TReader );
procedure WriteMyProperty( Writer: TWriter );
-
> DimaBr (22.09.06 11:13) [39]Выглядеть это должно так: у таблицы есть свойство допустим Columns с квадратиком с троеточием. Щёлкаю по кнопке, показывается список СТОЛБЦОВ. Щёлкаю по столбцу из этого списка, настраиваю Width , Title и пару других индивидуальных свойств столбца. Подскажите плиз ссылочки, примеры, методы реализации подобных задач
-
Наиль © (18.09.06 10:23) [34] Может оно?Неа. DevilDevil © (22.09.06 16:14) [40]Используй TCollection. Можно почитать статью "Коллекции и работа с ними" на http://www.delphikingdom.ru/
-
> Щёлкаю по столбцу из этого списка, настраиваю Width, Title > и пару других индивидуальных свойств столбца.
Настораживает, если элементы колекции разнотипные.
-
-
> Да, спасибо, то, что нужно!
Спасибо, многоуважаемому Юрию !!!
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Да закройте ветку. Автору надо будет - новую создаст.
|