Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.046 c
3-1189403226
O.O
2007-09-10 09:47
2008.01.20
Конкатенация в FB


2-1198410096
Кеша
2007-12-23 14:41
2008.01.20
Запрет на запуск уже открытой программы


3-1189424450
Ulugbek
2007-09-10 15:40
2008.01.20
Как скрыть в DbLookupComboBox Drop-Down стрелку


2-1197950727
Sergiu
2007-12-18 07:05
2008.01.20
Как считывать данные с COM,LPT порта и нарисовать график


2-1197993068
авыф
2007-12-18 18:51
2008.01.20
TMemoryStream





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский