Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Image и регионы


Страницы:   1 2

Se1lor ©   (2007-10-16 15:29:00) 

Есть 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 то ничего не получается :(
Объясните, пожалуйста, как правильно сделать, то что я задумал??


homm   (2007-10-17 14:05:00) [1]

> [21] foreverDelphi ©   (17.10.07 13:43)

1) Нужно будет следить за тем, что-бы регион постоянно был в актуальном состоянии
2) А в предложеном выше случае не достаточно OnClick ? Пишим наследника один раз (пара пустяков) и пользуемся OnClick. Быстропостроить регион по битмепу куда сложнее (как в плане реализации, так и в плане рессурсов на выполнение).


Se1lor   (2007-10-17 14:05:00) [2]


> foreverDelphi ©   (17.10.07 13:43) [21]

просто у меня в рантайме создаются куча изображений.
Если еще и для каждого панель делать..... плохо будет :(


foreverDelphi   (2007-10-17 13:43:00) [3]


> > [19] foreverDelphi ©   (17.10.07 13:26)
> Ну и зачем это крайне не гибкое рещение, требующее дополнительных
> рессурсов?

1. не нужно будет следить за цветом пикселя битмапа
2. достаточно OnClick


homm   (2007-10-17 13:33:00) [4]

> [19] foreverDelphi ©   (17.10.07 13:26)
> 1. на панель бросить Image
> 2. SetWindowRgn(panel.handle,  Rgn, TRUE )

Ну и зачем это крайне не гибкое рещение, требующее дополнительных рессурсов?


foreverDelphi   (2007-10-17 13:26:00) [5]

1. на панель бросить Image
2. SetWindowRgn(panel.handle,  Rgn, TRUE )


homm   (2007-10-17 12:45:00) [6]

> [17] TStas ©   (17.10.07 12:37)

Читать [11], думать, потом [10] и думать еше раз.


TStas   (2007-10-17 12:37:00) [7]

Так можно же проще: обрабатывать не сразу OnClick, а OnMouseUp, ведь в обработчике ВЫ получаете координаты щелчка, можно спокойно через Bitmap.Canvas.Pixels посмотреть на цвет пиксела. Если он прозрачный, то ничего не делать. Связать обработчики можно через глобальную переменную. В этом качестве можно даже Tag использовать, чтобы переменные зря не плодить. Тогда не надо писать никаких потомков и, тем более, этих потомков в среду устанавливать.


Ins   (2007-10-17 10:05:00) [8]


> так чтобы она обрабатывала не одно, а массив изображений?
> ?

Сделать своего потомка от TImage, в котором перекрыть обработчик этого сообщения, и именно этого потомка и кидать на форму.


Se1lor   (2007-10-17 05:54:00) [9]

простите за наглость, подскажите пожалуйста, как мне переделать эту процедуру

> Ins ©   (16.10.07 16:57) [13]

так чтобы она обрабатывала не одно, а массив изображений??


Se1lor   (2007-10-16 17:05:00) [10]


> Ins ©   (16.10.07 16:57) [13]

Громаднейшее спасибо!!!


homm   (2007-10-16 16:57:00) [11]

> [11] Se1lor   (16.10.07 16:55)

Обрати внимание на [8] и  [10], он правильно сказал.

*краснея* :)


Ins   (2007-10-16 16:57:00) [12]


> 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 16:55:00) [13]


> Jump   (16.10.07 16:36) [9]

Спасибо. В принципе работает, но не совсем как мне надо: если я щелкаю по прозрачной области имэйджа A, то событие не срабатывает, но событие не срабатывает также и на имэйдже B видимая часть которого располагается там, где располагается прозрачная имэйджа A


Ins   (2007-10-16 16:38:00) [14]


> способен опрелеить что в этой области имейдж только по координатам

Врешь и не краснеешь. :) Посмотри внимательно на метод ControlAtPos. Он сложнее, чем ты думаешь. Этот метод вызывается при обработке WinControl-ом мышиного сообщения. Если вкратце, то не только по координатам. Потом еще отправляется сообщение CM_HITTEST, которое TGraphicControl может обаратывать таким образом, что в некоторых точках (которые он считает прозрачными) возвращать 0. И ControlAtPos в этом случае не вернет этот TGraphicControl.


Jump   (2007-10-16 16:36:00) [15]

В OnMouseUp проверяй

if (Button = mbLeft) and PtInRegion(Rgn, X, Y) then
begin
 {Region clicked}
end;


Ins   (2007-10-16 16:20:00) [16]


> Я хочу чтобы OnClick происходил только тогда, когда я щелкаю
> по области, которая не является прозрачной.

Обрабатывайте CM_HITTEST


Сергей М.   (2007-10-16 15:47:00) [17]


> homm ©   (16.10.07 15:42) [5]


Понятно что не та.
Но почему бы имиджу не возбудить событие OnClick, если клик был именно на нем - вот это непонятно)


Se1lor   (2007-10-16 15:47:00) [18]


> Сергей М. ©   (16.10.07 15:40) [4]

Я хочу чтобы OnClick происходил только тогда, когда я щелкаю по области, которая не является прозрачной.
Просто когда у меня рядом две кнопки(уж извини :)), я тыкаю например по левой кнопке, а у меня происходит OnClick правой кнопки, потому что она на переднем плане, а клик произошел по ее прозрачной области, хотя курсок уже находится на видимой части левой кнопки.
Как по другому объяснить я не знаю :(


homm   (2007-10-16 15:42:00) [19]

> [4] Сергей М. ©   (16.10.07 15:40)
> Я спрашиваю, что тебя не устраивает в возбуждении события
> OnClick именно того граф.контрола, на канве которого щелкнули
> мышью ?

Предполагаю, что нажимается не та кнопка, которую видит пользователь в месте щелчка.


Сергей М.   (2007-10-16 15:40:00) [20]


> Se1lor   (16.10.07 15:37) [3]


Ты вопрос понимаешь ?

Я не спрашиваю, что у тебя там рядом с чем и кто кого перекрывает.

Я спрашиваю, чтотебя не устраивает в возбуждении события OnClick именно того граф.контрола, на канве которого щелкнули мышью ?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо