![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Image и регионы
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 именно того граф.контрола, на канве которого щелкнули мышью ?