Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];

Вниз

Прозрачная область на форме   Найти похожие ветки 

 
Леший   (2005-04-23 16:30) [0]

Подскажите, как можно на форме сделать прозрачную область/области, или хотя бы "дыру" в форме, но чтобы она ловила события мыши?


 
Ученик   (2005-04-23 16:44) [1]


type
 TForm1 = class(TForm)
   procedure FormShow(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
   FRgn: HRgn;
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
var
 Rgn1, Rgn2: HRgn;
begin
 Rgn1 := CreateRectRgn(0, 0, Width, Height);
 try
   Rgn2 := CreateRectRgn(100, 100, 200, 200);
   try
     FRgn := CreateRectRgn(0, 0, 0, 0);
     CombineRgn(FRgn, Rgn1, Rgn2, RGN_DIFF);
     SetWindowRgn(Handle, FRgn, False)
   finally
     DeleteObject(Rgn2)
   end
 finally
   DeleteObject(Rgn1)
 end
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 DeleteObject(FRgn)
end;



 
Юрий Зотов ©   (2005-04-24 20:58) [2]

> Ученик   (23.04.05 16:44) [1]

DeleteObject(FRgn) - это лишнее. Если посмотреть результат, он будет равен нулю - то есть, функция отработала с ошибкой и ничего не освободила.

Объясняется это тем, что после вызова SetWindowRgn владельцем региона FRgn становится не наша программа, а система и освободить его может только она сама.


 
Ученик   (2005-04-24 21:28) [3]

>Юрий Зотов ©   (24.04.05 20:58) [2]

Да, действительно так

After a successful call to SetWindowRgn, the system owns the region specified by the region handle hRgn. The system does not make a copy of the region. Thus, you should not make any further function calls with this region handle. In particular, do not delete this region handle. The system deletes the region handle when it no longer needed.


 
Piter ©   (2005-04-24 22:01) [4]

Леший   (23.04.05 16:30)
но чтобы она ловила события мыши?


а зачем ей ловить события мыщи, если там дырка?


 
Леший   (2005-04-25 01:55) [5]

Ловить события мыши очень надо - я тягаю форму за "тело", да и некоторые другие события не мешало бы обработать.
С комбинацией регионов я работать уже пробовал, но при этом мышь через дыры падает на нижнее окно, а как с этим бороться я не знаю. (С хуками я не дружу.) Поэтому и написал в форум. Так что если у кого-то есть какие-либо конструктивные соображения/предложения - восприму с благодарностью.


 
alpet ©   (2005-04-25 11:44) [6]

Накрой получившуюся дыру другим окном (формой) с установленной прозрачностью (opacity), и синхронизируй его позицию относительно основного окна. В Win98 есстно это работать не будет.


 
Deka ©   (2005-04-25 12:03) [7]

Может быть сделать форму полностью прозрачной, а на нее поместить TImage c включенной прозрачностью и картинкой в виде прямоугольника (по размерам форму) с кругом посередине. Круг соотвественно тоже должен быть прозрачным. В результате рабочий стол ты по идее увидишь но мышка будет всегда оставаться над твоим окном. Может так? Сам не пробовал, чисто теоретическое предположение.


 
Чапаев ©   (2005-04-25 13:10) [8]

SetCapture()?


 
alpet ©   (2005-04-25 13:17) [9]

2 Deka
Все что помещается на прозрачное окно как дочерний элемент управления - наследует его прозрачность.


 
Deka ©   (2005-04-25 14:06) [10]

Мда...
Наверное придется как в [6]...


 
Piter ©   (2005-04-25 17:15) [11]

Deka ©   (25.04.05 14:06) [10]
Наверное придется как в [6]...


наверное, придется передумать. Ибо что это за юзабельность - я тыкаю в пустое место, а получается, что я хватаю за форму. Что за бред? Ты где-нибудь такое видел?


 
Леший   (2005-04-25 21:54) [12]

Вторая форма - это не серьезно. Есть следующее соображение: после установки новой области (см. пример) сохранять битмап дырки, устанавливать SetWindowRgn(Handle, Rgn1, True), и кидать на него сохраненный битмап. Пробую реализовать.

2 Чапаев:

Мысль интересная, но SetCapture посылает весь ввод в указанное окно. А для того чтобы передавать ввод в др. окна придется отслеживать координаты мыши и при выходе ее из области моего окна выполнять ReleaseCapture. Я правильно ловлю мысль?

И вопрос ко всем: я когда сотворял аналог примера самостоятельно использовал что-то вроде CombineRgn(Rgn1, Rgn1, Rgn2, RGN_DIFF); при этом все работало также, но при незакрепленной панели задач она отказывалась всплывать. Если сделать как в примере, то этого не наблюдается. Есть этому логическое объяснение, или это просто глюк системы?


 
Чапаев ©   (2005-04-26 09:55) [13]

> Я правильно ловлю мысль?
Ахха. WM_MOUSEMOVE перехватывай.


 
Чапаев ©   (2005-04-26 09:55) [14]

> Я правильно ловлю мысль?
Ахха. WM_MOUSEMOVE перехватывай.


 
Deka ©   (2005-04-26 11:31) [15]

А для чего нужна работа со всеми этими регионами?
Ученик, у тебя во время работы с окном рабочий стол меняется? Ну в смысле ты другие программы запускаешь? Если нет, то можно при старте скопировать рабочий стол в Bitmap, потом показать обычную прямоугольную форму на которой в TImage отрисовывать круг вырезанный из сохраненного в Bitmap рабочего стола. При перемещении из Bitmap вырезается и помещается в TImage круг с другими координатами. Получится "прозрачность". Будет видно рабочий стол, регионы будут не нужны и форма всегда получит события от мышки. Правда если открыть другое приложение (или другим способом изменить картинку на экране), то его в дырке видно не будет, пока не пересохранишь рабочий стол.
Вот такой вот вариант.


 
Леший   (2005-04-28 02:36) [16]

2 Чапаев

Думаю целесообразнее при WM_NCMOUSEMOVE возвращать ввод системе. Однако, столкнудся с тем, что не могу захватить ввод, даже при прописывании SetCapture( ) в OnCreate. Видимо выходит что при комбинации регионов форма образуется их пересечением, т.е. дырка все равно не есть форма. Но тогда не ясно почему то что осталось формой не хочет ловить весь ввод.


 
Чапаев ©   (2005-04-28 12:10) [17]

> [16]
Ну, про wm_NCmousemove я ничего не говорил...

> дырка все равно не есть форма
Да.


 
Леший   (2005-04-28 20:28) [18]

Да-то да, а как проблему решить?


 
Ученик   (2005-04-29 22:36) [19]

>Deka ©   (26.04.05 11:31) [15]
??????????


 
Deka ©   (2005-04-30 10:21) [20]

2 Леший
Так чего? Как я написал попробовать не хочешь?


 
Леший   (2005-04-30 15:32) [21]

Отчего же, хочу. Высылай.


 
Deka ©   (2005-04-30 18:04) [22]

Да текста то нет. Тебе придется самому все накропать. А идея в [15]. Буду вопросы - спрашивай.


 
Deka ©   (2005-04-30 18:05) [23]

Щас попробую сделать простенький пример с квадратной дыркой... ;)


 
Deka ©   (2005-04-30 18:52) [24]

Готово. Есть форма с прозрачной квадратной областью посередине, которая может реагировать на любые стандартные для TImage события. Работает. Есть шероховатости, но это не главное. А главное в том, что никаких регионов!


 
Deka ©   (2005-05-03 13:41) [25]

Немножко модифицировал - теперь стало получше.


 
Леший   (2005-05-03 17:57) [26]

Немного  отсутствовал - праздники-с, с чем всех и поздравляю.

2 Deka

Все-то ничего, но не выходит у меня перерисовывать форму при перемещении, да и при восстановлении из панели задач после перетасовки окон фигня выходит, но об этом уже говорилось.


 
Deka ©   (2005-05-04 12:27) [27]

У меня пока не получилось отлавливать изменение экрана, но и особо этим не занимался. Думаю что надо просто отлавливать событие активации формы. Сейчас попробую. А так все работает. Все красиво и в динамике ;)


 
Леший   (2005-05-05 01:10) [28]

В смысле "в динамике"?


 
Deka ©   (2005-05-05 11:50) [29]

При перемещении. Даже быстром ;)


 
Леший   (2005-05-05 15:35) [30]

У меня не выходит.


 
GrayFace ©   (2005-05-05 16:47) [31]

Леший   (03.05.05 17:57) [26]
Пример полупрозрачного окна: http://www.grayface.chat.ru/trans.rar


 
Deka ©   (2005-05-06 09:56) [32]

Ok, Леший, вот мой код...
Сперва сделай в дельфи новый проект, потом брось на форму TIMage, ну а дальше думаю разберешься...

procedure TForm1.FormCreate(Sender: TObject);
var
 ScreenDC: HDC;
begin
 TmpBmp:= TBitmap.Create;
 ScreenDC:= GetDC(0);
 try
   TmpBmp.Width:= GetSystemMetrics(SM_CXSCREEN);
   TmpBmp.Height:= GetSystemMetrics(SM_CYSCREEN);

   BitBlt(TmpBmp.Canvas.Handle, 0, 0, TmpBmp.Width, TmpBmp.Height, ScreenDC, 0, 0, SRCCOPY);
 finally
   ReleaseDC(0, ScreenDC);
 end;

 Image1.Picture.Bitmap.Width:= Image1.Width;
 Image1.Picture.Bitmap.Height:= Image1.Height;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 TmpBmp.Free;
end;

// Второй способ
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
const
 SC_DRAGMOVE: Longint = $F012;
begin
 if Button <> mbRight then
 begin
   ReleaseCapture;
   SendMessage(Handle, WM_SYSCOMMAND, SC_DRAGMOVE, 0);
 end;
end;

type
 PRect = ^TRect;

procedure TForm1.WMMoving(var M: TMessage);
begin
 Caption:= IntToStr(Form1.Left) + " / " + IntToStr(Form1.Top);
 // Теперь скопируем картинку
 BitBlt(Image1.Picture.Bitmap.Canvas.Handle, 0, 0, Image1.Width, Image1.Height,
        TmpBmp.Canvas.Handle,
        PRect(M.LParam)^.Left + GetSystemMetrics(SM_CXBORDER) + Image1.Left + 2,
        PRect(M.LParam)^.Top + 20 + Image1.Top + 1,
        SRCCOPY);
 Image1.Refresh;
end;

procedure TForm1.Image1Click(Sender: TObject);
begin
 ShowMessage("Это дырка обрабатывающая события...");
end;

P.S. Осталось пару проблем, но главное сделано ;)


 
Deka ©   (2005-05-06 09:59) [33]

Да! Совсем забыл сказать, что BorderStyle у Form1 надо поставить в bsToolWindow. Иначе придется подкорректировать смещения в процедуре копирования.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2005.06.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.048 c
14-1117834399
Profi
2005-06-04 01:33
2005.06.29
СтоИт ли?


4-1115503256
g-l-u-k
2005-05-08 02:00
2005.06.29
ASM в Delphi


14-1117610965
Skier
2005-06-01 11:29
2005.06.29
Построение буферной зоны.


3-1116577596
MAGix
2005-05-20 12:26
2005.06.29
Непонятный глюк в Locate


10-1094645321
bSava
2004-09-08 16:08
2005.06.29
Кто запутил программу?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский