Форум: "Основная";
Текущий архив: 2008.01.20;
Скачать: [xml.tar.bz2];
ВнизImage и регионы Найти похожие ветки
← →
Se1lor (2007-10-16 15:29) [0]Есть Image(кнопка), на которой расположен рисунок не прямоугольной формы(прозрачная часть розовая). Я сделал у Image transparent:=true;
И вроде бы все хорошо, но, когда я щелкаю по прозрачной части рисунка, у меня срабатывает OnClick Имэйджа.
Как мне этого избежать???
Надо сделать регион??
Смотрел в интернете, инфа о регионах в основном связана с формой, скачал модуль bmp2reg(автор Jean-Edouard Lachand-Robert), попробовал для начала с формой:
rgn := BitmapToRegion( hBmp,w, h, $FF00FF, 0);
//Устанавливаем размер окна таким же, как и у битмапа
SetWindowPos(Window, 0, 0, 0, w, h, SWP_NOZORDER or SWP_NOMOVE );
//Присваиваем регион окну
SetWindowRgn(Window, Rgn, TRUE );
все получилось, а вот с Image нет :(
Window это хэндл окна, но ведь у Image нет хэндла?!
А если вместо Window пишу Image.Picture.Bitmap.Handle то ничего не получается :(
Объясните, пожалуйста, как правильно сделать, то что я задумал??
← →
Сергей М. © (2007-10-16 15:35) [1]
> когда я щелкаю по прозрачной части рисунка, у меня срабатывает
> OnClick Имэйджа
А что в этом плохого ?
← →
homm © (2007-10-16 15:36) [2]> [0] Se1lor (16.10.07 15:29)
> Надо сделать регион??
TImage — не оконный элемент. Его обработкой сообщений занимается его родитель. И когда родитель получает клик, он способен опрелеить что в этой области имейдж только по координатам, он (родительский компонент) знать не знает, нировал чт-то имейдж в месте клика, или нет.
← →
Se1lor (2007-10-16 15:37) [3]
> Сергей М. © (16.10.07 15:35) [1]
Просто рядом у меня еще одна кнопка, и получается, что они как бы перекрывают друг друга(прозрачная часть одного находится поверх прозрачной части другого)
← →
Сергей М. © (2007-10-16 15:40) [4]
> Se1lor (16.10.07 15:37) [3]
Ты вопрос понимаешь ?
Я не спрашиваю, что у тебя там рядом с чем и кто кого перекрывает.
Я спрашиваю, что тебя не устраивает в возбуждении события OnClick именно того граф.контрола, на канве которого щелкнули мышью ?
← →
homm © (2007-10-16 15:42) [5]> [4] Сергей М. © (16.10.07 15:40)
> Я спрашиваю, что тебя не устраивает в возбуждении события
> OnClick именно того граф.контрола, на канве которого щелкнули
> мышью ?
Предполагаю, что нажимается не та кнопка, которую видит пользователь в месте щелчка.
← →
Se1lor (2007-10-16 15:47) [6]
> Сергей М. © (16.10.07 15:40) [4]
Я хочу чтобы OnClick происходил только тогда, когда я щелкаю по области, которая не является прозрачной.
Просто когда у меня рядом две кнопки(уж извини :)), я тыкаю например по левой кнопке, а у меня происходит OnClick правой кнопки, потому что она на переднем плане, а клик произошел по ее прозрачной области, хотя курсок уже находится на видимой части левой кнопки.
Как по другому объяснить я не знаю :(
← →
Сергей М. © (2007-10-16 15:47) [7]
> homm © (16.10.07 15:42) [5]
Понятно что не та.
Но почему бы имиджу не возбудить событие OnClick, если клик был именно на нем - вот это непонятно)
← →
Ins © (2007-10-16 16:20) [8]
> Я хочу чтобы OnClick происходил только тогда, когда я щелкаю
> по области, которая не является прозрачной.
Обрабатывайте CM_HITTEST
← →
Jump (2007-10-16 16:36) [9]В OnMouseUp проверяй
if (Button = mbLeft) and PtInRegion(Rgn, X, Y) then
begin
{Region clicked}
end;
← →
Ins © (2007-10-16 16:38) [10]
> способен опрелеить что в этой области имейдж только по координатам
Врешь и не краснеешь. :) Посмотри внимательно на метод ControlAtPos. Он сложнее, чем ты думаешь. Этот метод вызывается при обработке WinControl-ом мышиного сообщения. Если вкратце, то не только по координатам. Потом еще отправляется сообщение CM_HITTEST, которое TGraphicControl может обаратывать таким образом, что в некоторых точках (которые он считает прозрачными) возвращать 0. И ControlAtPos в этом случае не вернет этот TGraphicControl.
← →
Se1lor (2007-10-16 16:55) [11]
> Jump (16.10.07 16:36) [9]
Спасибо. В принципе работает, но не совсем как мне надо: если я щелкаю по прозрачной области имэйджа A, то событие не срабатывает, но событие не срабатывает также и на имэйдже B видимая часть которого располагается там, где располагается прозрачная имэйджа A
← →
homm © (2007-10-16 16:57) [12]> [11] Se1lor (16.10.07 16:55)
Обрати внимание на [8] и [10], он правильно сказал.
*краснея* :)
← →
Ins © (2007-10-16 16:57) [13]
> Se1lor (16.10.07 15:29)
Простейший пример. Бросае на форму TImage с рисунком, у которого прозрачный цвет - белый.unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TForm1 = class(TForm)
Image1: TImage;
procedure FormCreate(Sender: TObject);
procedure Image1Click(Sender: TObject);
private
{ Private declarations }
OldWndProc: TWndMethod;
procedure NewWndProc(var Message: TMessage);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.NewWndProc(var Message: TMessage);
var
x, y: Integer;
begin
if Message.Msg = CM_HITTEST then begin
Message.Result:=HTCLIENT;
if Assigned(Image1.Picture.Bitmap) then begin
x:=TCmHitTest(Message).XPos;
y:=TCmHitTest(Message).YPos;
if Image1.Picture.Bitmap.Canvas.Pixels[x,y] = clWhite then
Message.Result:=HTNOWHERE;
end;
end
else
OldWndProc(Message);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OldWndProc:=Image1.WindowProc;
Image1.WindowProc:=NewWndProc;
end;
procedure TForm1.Image1Click(Sender: TObject);
begin
ShowMessage("Click");
end;
end.
← →
Se1lor (2007-10-16 17:05) [14]
> Ins © (16.10.07 16:57) [13]
Громаднейшее спасибо!!!
← →
Se1lor (2007-10-17 05:54) [15]простите за наглость, подскажите пожалуйста, как мне переделать эту процедуру
> Ins © (16.10.07 16:57) [13]
так чтобы она обрабатывала не одно, а массив изображений??
← →
Ins © (2007-10-17 10:05) [16]
> так чтобы она обрабатывала не одно, а массив изображений?
> ?
Сделать своего потомка от TImage, в котором перекрыть обработчик этого сообщения, и именно этого потомка и кидать на форму.
← →
TStas © (2007-10-17 12:37) [17]Так можно же проще: обрабатывать не сразу OnClick, а OnMouseUp, ведь в обработчике ВЫ получаете координаты щелчка, можно спокойно через Bitmap.Canvas.Pixels посмотреть на цвет пиксела. Если он прозрачный, то ничего не делать. Связать обработчики можно через глобальную переменную. В этом качестве можно даже Tag использовать, чтобы переменные зря не плодить. Тогда не надо писать никаких потомков и, тем более, этих потомков в среду устанавливать.
← →
homm © (2007-10-17 12:45) [18]> [17] TStas © (17.10.07 12:37)
Читать [11], думать, потом [10] и думать еше раз.
← →
foreverDelphi © (2007-10-17 13:26) [19]1. на панель бросить Image
2. SetWindowRgn(panel.handle, Rgn, TRUE )
← →
homm © (2007-10-17 13:33) [20]> [19] foreverDelphi © (17.10.07 13:26)
> 1. на панель бросить Image
> 2. SetWindowRgn(panel.handle, Rgn, TRUE )
Ну и зачем это крайне не гибкое рещение, требующее дополнительных рессурсов?
← →
foreverDelphi © (2007-10-17 13:43) [21]
> > [19] foreverDelphi © (17.10.07 13:26)
> Ну и зачем это крайне не гибкое рещение, требующее дополнительных
> рессурсов?
1. не нужно будет следить за цветом пикселя битмапа
2. достаточно OnClick
← →
Se1lor (2007-10-17 14:05) [22]
> foreverDelphi © (17.10.07 13:43) [21]
просто у меня в рантайме создаются куча изображений.
Если еще и для каждого панель делать..... плохо будет :(
← →
homm © (2007-10-17 14:05) [23]> [21] foreverDelphi © (17.10.07 13:43)
1) Нужно будет следить за тем, что-бы регион постоянно был в актуальном состоянии
2) А в предложеном выше случае не достаточно OnClick ? Пишим наследника один раз (пара пустяков) и пользуемся OnClick. Быстро построить регион по битмепу куда сложнее (как в плане реализации, так и в плане рессурсов на выполнение).
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2008.01.20;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.066 c