|
Win API. Как сделать прозрачное окно? | ☑ | ||
---|---|---|---|---|
0
Супер король
23.03.15
✎
08:11
|
Пишу прогу на MS Visual Studio под Win32, не консольную.
Создается простое окно. Нужно чтобы оно было прозрачным, с видимой нарисованной сеткой. Чтобы можно было это окно наложить поверх другой программы. И еще нужно чтобы окно не было активным и не перехватывало события мыши. Чтобы кликалась другая программа. Как такое сделать? Или это нельзя сделать? |
|||
1
Супер король
23.03.15
✎
08:14
|
Вот так создается:
CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); |
|||
2
Супер король
23.03.15
✎
08:15
|
Если сделаю все окно невидимым, то сетка тоже станет невидимой. Как победить?
|
|||
3
Кирпич
23.03.15
✎
08:42
|
Ищи про это:
CreateRectRgn CombineRgn SetWindowRgn |
|||
4
shpioleg
23.03.15
✎
08:46
|
Попробуй тут в разделе ассемблер посмотреть. http://www.manhunter.ru/assembler/page_21/
|
|||
5
PiVa123
23.03.15
✎
09:01
|
Читать баблию по Win32Api
https://msdn.microsoft.com/en-us/library/windows/desktop/ms632598(v=vs.85).aspx#layered_win |
|||
6
Кирпич
23.03.15
✎
09:39
|
вот накалякал пример
http://www.imageup.ru/img216/2081257/sc1.jpg.html окно с дырками для мыши http://www.imageup.ru/img216/2081257/sc1.jpg.html код на паскаля (извиняйте) procedure TForm1.SetRgn; var rg, rg2: HRGN; Wnd: HWND; x, y, i, z: integer; const Step = 50; //ширина ячейки сетки WW = 20; //отступ от левого края окна HH = 50; //отступ сверху S = 2; //толщина линии сетки begin Wnd := Self.Handle; GetWindowRgn(Wnd, rg); DeleteObject(rg); rg := CreateRectRgn(1, 1, Self.Width + WW, Self.Height + HH); x := Step; for i := 1 to (Self.Width - Step * 2) div Step do begin y := Step; for z := 1 to (Self.Height - Step * 2) div Step do begin rg2 := CreateRectRgn(x, y, x + Step, y + Step); CombineRgn(rg, rg, rg2, RGN_DIFF); Inc(y, Step + S); DeleteObject(rg2); end; Inc(x, Step + S); end; SetWindowRgn(Wnd, rg, True); end; |
|||
7
Rebelx
23.03.15
✎
10:03
|
(0) - прозрачность можно регулировать альфа-каналом
|
|||
8
Гёдза
23.03.15
✎
10:06
|
Тебе нужно не прозрачное окно, а окно состоящее из сетки.
Те в пустых квадратах сетки нет окна. Поэтому см (3) |
|||
9
Супер король
23.03.15
✎
11:37
|
(6) Круто, спасибо!
А если я попаду мышью в сетку, то событие получит это окно? А надо чтобы оно не получало ничего, как будто сетки нет. |
|||
10
бомболюк
23.03.15
✎
11:44
|
чтоб мышь не перехватывалась надо на WMNCHITTEST возвращать HTTRASPARENT
|
|||
11
Супер король
23.03.15
✎
11:45
|
(10) ок, погуглю про это.
|
|||
12
Супер король
23.03.15
✎
11:45
|
(6) Кирпич, куда денег слать?
|
|||
13
H A D G E H O G s
23.03.15
✎
12:24
|
(4) Спасибо тебе, добрый человек за эту ссылку.
Большое. Ежовское. Спасибо. |
|||
14
Сергей Д
23.03.15
✎
12:47
|
http://www.delphikingdom.ru - сюда вам
|
|||
15
Бертыш
23.03.15
✎
13:17
|
Неплохие ссылки
|
|||
16
Кирпич
23.03.15
✎
13:33
|
(12) пожертвуй в приют для животных
|
|||
17
Супер король
23.03.15
✎
13:39
|
(16) Ок. Куплю коту Вискас.
Кирпич, если использовать то что в (10) посоветовали, то вырезать квадратики из окна не нужно будет? Можно сделать окно прозрачным, нарисовать в окне то что нужно не прозрачным цветом, и прикрутить (10)? Или это сложнее чем с регионами делать? |
|||
18
Супер король
23.03.15
✎
13:41
|
(10) правильно так:
WM_NCHITTEST HTTRANSPARENT |
|||
19
Кирпич
23.03.15
✎
13:42
|
(17) в (10) про мышку написано. делай (6) плюс (10)
|
|||
20
Супер король
23.03.15
✎
13:44
|
Ок. Всем спасибо.
|
|||
21
Кирпич
23.03.15
✎
13:44
|
+(19) хотя попробуй как в (17). будет работать, я думаю.
|
|||
22
Кирпич
23.03.15
✎
13:47
|
я просто не знаю как ты будешь рисовать в прозрачном окне непрозрачным цветом.
|
|||
23
H A D G E H O G s
23.03.15
✎
14:08
|
Непроканает.
Обе формы должны выполняться в одном потоке. |
|||
24
H A D G E H O G s
23.03.15
✎
14:10
|
HTTRANSPARENT
-1 In a window currently covered by another window in the same thread (the message will be sent to underlying windows in the same thread until one of them returns a code that is not HTTRANSPARENT). Я проверил. Работает для 2-х форм одного процесса, не работает для 2-х форм различных процессов. |
|||
25
H A D G E H O G s
23.03.15
✎
14:16
|
Можна конечно поиграться с
AttachThreadInput() но тут у нас гемморойчик - надо узнать PID потока (ну пусть будет дескриптор окна) - подложки - а это перебор Z- ордера top level окон, поиск в нем нашего покрывающего окна и полученение предыдущего окна - подложки. Нахер-нахер. |
|||
26
Torquader
24.03.15
✎
00:39
|
А чего - полупрозрачные окна не решают проблему ?
Окно с дыркой выглядит как-то не очень. Если нужно просто изображение другого окна в своём как-то отслеживать, то можно не прозрачное окно сделать, а прозрачный фон - тогда мышь будет ездить по нашему окну, а видеть мы будем то, что было до появления нашего окна. |
|||
27
Супер король
24.03.15
✎
06:26
|
(25) Можно найти окно по названию программы или по заголовку окна. Я только не знаю как.
|
|||
28
Андрюха
24.03.15
✎
07:57
|
(0) В сях у окна нету свойства OPACITY ?
|
|||
29
Андрюха
24.03.15
✎
08:03
|
(28)+ В Delphi за это дело отвечает AlphaBlend
http://imghost.in/img/2015-03/24/29kn679spaiw878z2y2s6zmoj.jpg |
|||
30
Кирпич
24.03.15
✎
09:38
|
(0) не морочь людям голову. в гугле всё есть.
SetWindowLong(Self.WindowHandle, GWL_EXSTYLE, GetWindowLong(Self.WindowHandle, GWL_EXSTYLE) or WS_EX_TRANSPARENT or WS_EX_TOPMOST or WS_EX_LAYERED); WS_EX_TRANSPARENT - форма прозрачна для мышки SetLayeredWindowAttributes(Self.WindowHandle, RGB(0, 0, 0), 0, LWA_COLORKEY); //делает прозрачным черный цвет |
|||
31
Кирпич
24.03.15
✎
10:11
|
(0) вот еще пример http://ipic.su/img/img7/fs/test2.1427180867.png
procedure TForm1.FormPaint(Sender: TObject); var p1, p2: TPoint; i, x, y: integer; const Step = 50; begin //рисуем сетку Canvas.Pen.Color := clLtGray; Canvas.Pen.Width := 1; x := 0; y := 0; p1.y := 0; p2.y := Self.Height; for i := 1 to (Self.Width div Step) do begin p1.x := x; p2.x := x; Canvas.Line(p1, p2); Inc(x, Step); end; x := 0; y := 0; p1.x := 0; p2.x := Self.Width; for i := 1 to (Self.Height div Step) do begin p1.y := y; p2.y := y; Canvas.Line(p1, p2); Inc(y, Step); end; end; procedure TForm1.FormShow(Sender: TObject); begin Self.Color := clBlack; Self.BorderStyle := bsNone; Self.WindowState := wsMaximized; Self.FormStyle := fsSystemStayOnTop; SetWindowLong(Self.WindowHandle, GWL_EXSTYLE, GetWindowLong(Self.WindowHandle, GWL_EXSTYLE) or WS_EX_TRANSPARENT or WS_EX_TOPMOST or WS_EX_LAYERED); SetLayeredWindowAttributes(Self.WindowHandle, RGB(0, 0, 0), 0, LWA_COLORKEY); end; |
|||
32
Супер король
24.03.15
✎
11:11
|
Блин, так окно получается без заголовка, перетаскивать не получается.
|
|||
33
H A D G E H O G s
24.03.15
✎
11:20
|
(32) Перетаскивайбез заголовка
|
|||
34
Супер король
24.03.15
✎
11:20
|
Блин, не могу нагуглить чему равны эти константы: GWL_EXSTYLE
|
|||
35
necro
24.03.15
✎
11:21
|
(32) Ничего не мешает перемещать окно при захвате мышью за любое место
|
|||
36
H A D G E H O G s
24.03.15
✎
11:21
|
(34) msdn в помощь. А вообще они законстантированны в нормальных ЯП, like a Delphi
|
|||
37
H A D G E H O G s
24.03.15
✎
11:21
|
(35) Окно, прозрачное для мыши , хехехе
|
|||
38
H A D G E H O G s
24.03.15
✎
11:21
|
||||
39
Супер король
24.03.15
✎
11:22
|
(36) я бросил VS, стал на JS делать, мне так проще. А тут нет таких констант.
Нагуглил, -20 |
|||
40
Супер король
24.03.15
✎
11:22
|
(38) да, именно там
|
|||
41
necro
24.03.15
✎
11:23
|
(39) А как на JS WinAPI вызывается?
|
|||
42
Кирпич
24.03.15
✎
11:30
|
(32) у тебя же в (0) написано "Нужно чтобы оно было прозрачным, с видимой нарисованной сеткой. И еще нужно чтобы окно не было активным и не перехватывало события мыши. Чтобы кликалась другая программа."
я сделал один в один как написано и не угодил. :) |
|||
43
necro
24.03.15
✎
11:32
|
(42) Но при этом нужно чтобы мышь таки перехватывалась
|
|||
44
Супер король
24.03.15
✎
11:33
|
делаю так:
WS_OVERLAPPEDWINDOW = 0xCF0000 WS_VISIBLE = 0x10000000 WndStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE var ret = WinAPI.SetWindowLong (hWnd, -20, WndStyle | 32 | 8 | 524288) Окно появляется, но при нажатии на него мышкой оно прячется на задний план. |
|||
45
Супер король
24.03.15
✎
11:34
|
(42) Извини, я не написал что нужно чтобы можно было окно перетаскивать, чтобы правильно наложить сетку
|
|||
46
H A D G E H O G s
24.03.15
✎
11:34
|
(44) Сначало получи текущий стиль окна, к нему добавь нужные тебе.
|
|||
47
Супер король
24.03.15
✎
11:35
|
(41)
WinAPI = new ActiveXObject("DynamicWrapperX.2"); WinAPI.Register ("user32", "SetWindowLong", "i=hll", "r=l"); |
|||
48
Супер король
24.03.15
✎
11:41
|
(46) а сразу при создании окна нельзя чтоли указать стиль?
|
|||
49
Супер король
24.03.15
✎
11:41
|
Я так создал: hWnd = WinAPI.CreateWindowExW(0, "Button", "test", WndStyle, 20, 20, 400, 300, 0, 0, hModule, 0)
|
|||
50
necro
24.03.15
✎
11:48
|
(47) Извиняюсь за оффтоп, а как сообщения доставляются (WindowProc)?
|
|||
51
Кирпич
24.03.15
✎
12:02
|
(50) а мне интересно, нафиг это всё нужно вообще?
|
|||
52
Гёдза
24.03.15
✎
12:07
|
(51) Интерактивная линейка?
|
|||
53
H A D G E H O G s
24.03.15
✎
12:15
|
||||
54
necro
24.03.15
✎
12:17
|
(51) Всегда мечтал скриптовое окно создать. Но, к сожалению, что-то не заводится у меня эта библиотечка без админских прав...
|
|||
55
Супер король
25.03.15
✎
05:54
|
(50) Например так:
var pWndProc = WinAPI.RegisterCallback(WndProc, "i=hull", "r=l"); var ret = WinAPI.SetWindowLong (hWnd, -4, pWndProc); function WndProc(hWnd, uMsg, wParam, lParam){ if (uMsg == WM_CLOSE){ Close = 1; } return WinAPI.DefWindowProcW(hWnd, uMsg, wParam, lParam); } |
|||
56
Супер король
25.03.15
✎
05:57
|
(51) Для программы анализа химического состава вещества. Там в окне нужно мышкой выбирать какое место образца анализировать, а сетка нужна для удобства.
Пробовали распечатывать сетку на прозрачной пленке и накладывать на монитор, но из-за толстого стекла получается не точно и не удобно. |
|||
57
Супер король
25.03.15
✎
06:00
|
(54) заведи ее с админскими правами.
|
|||
58
Супер король
25.03.15
✎
08:00
|
(53) Оно, только нужно чтобы было всегда поверх всех окон, чтобы было поле ввода для изменения размера ячеек, чтобы можно было растягивать окно.
|
|||
59
Супер король
25.03.15
✎
08:01
|
Чтобы было поверх всех окон, я делаю так при создании окна:
dwExStyle = WS_EX_TOPMOST | WS_EX_TRANSPARENT; hWnd = WinAPI.CreateWindowExW(dwExStyle, "Button", "test", WndStyle, 20, 20, 400, 300, 0, 0, hModule, 0) |
|||
60
Супер король
25.03.15
✎
08:09
|
(6) Кирпич, зачем у тебя так написано:
|
|||
61
Супер король
25.03.15
✎
08:09
|
GetWindowRgn(Wnd, rg);
DeleteObject(rg); |
|||
62
Супер король
25.03.15
✎
08:10
|
Там получаешь регион, и тут же его удаляешь.
Еще не понятно, зачем используется два объекта rg и rg2, одним обойтись нельзя? |
|||
63
Кирпич
25.03.15
✎
08:37
|
(61) ну наверное чтобы регионы не плодить.
(62) ну там как бы два региона объединяются, поэтому их и два |
|||
64
Кирпич
25.03.15
✎
08:41
|
Начни утро с прозрачного окна!
|
|||
65
Супер король
25.03.15
✎
08:59
|
(63) зачем тогда его получать, если он нигде не используется и удаляется на следующей строке?
Регионы объединяются между собой, потом объединяются с регионом окна. Можно же сразу один регион объединять с регионом окна? |
|||
66
Кирпич
25.03.15
✎
09:09
|
(65) "зачем тогда его получать, если он нигде не используется и удаляется на следующей строке? "
затем, что ты каждый раз создаешь новый регион, а старый остается. вот старый и удаляется, чтобы не плодить регионы. понятно? "Можно же сразу один регион объединять с регионом окна?" ну так объединяй и гляди чего получится. |
|||
67
Супер король
25.03.15
✎
09:30
|
(66) Ты не понял вопрос. Я думаю что его не нужно создавать, раз он не используется.
|
|||
68
Супер король
25.03.15
✎
09:32
|
Вот так сделал:
hWnd = WinAPI.CreateWindowExW(dwExStyle, "Button", "test", WndStyle, 20, 20, 400, 300, 0, 0, hModule, 0) RGN_DIFF = 4; Fstorona = 2000; hRgnWindow = WinAPI.CreateRectRgn(0, 0, Fstorona, Fwidth); storona = 20; for (i=0; i < Fstorona; i = i + storona + 1){ for (j=30; j < Fstorona; j = j + storona + 1){ hRgnWindow2 = WinAPI.CreateRectRgn(i, j, i + storona, j + storona); retval = WinAPI.CombineRgn(hRgnWindow, hRgnWindow, hRgnWindow2, RGN_DIFF); retval = WinAPI.DeleteObject(hRgnWindow2); } } retval = WinAPI.SetWindowRgn(hWnd, hRgnWindow, true); retval = WinAPI.DeleteObject(hRgnWindow); |
|||
69
Кирпич
25.03.15
✎
09:32
|
(67) "создавать" и "получать" это разные понятия
|
|||
70
Супер король
25.03.15
✎
09:33
|
(69) Вообще мне кажется у тебя там лишние строчки.
У меня без GetWindowRgn работает. Для чего она у тебя? |
|||
71
Кирпич
25.03.15
✎
09:38
|
(70) я тебе три раза объяснил зачем оно там. ну работает, пускай работает. если на компе 8 гигов памяти, то работать будет долго.
|
|||
72
Кирпич
25.03.15
✎
09:44
|
хотя да. лишнее. справку поглядел.
|
|||
73
Кирпич
25.03.15
✎
09:45
|
я думал GetWindowRgn дескриптор региона окна возвращает, а она копию региона делает.
|
|||
74
Супер король
25.03.15
✎
10:12
|
(73) один фиг ты его в следующей строке удалял.
Щас вроде как надо работает, но цвет окна как задать? Мне нужно зеленое чтобы было. И как создать пустое окно попроще? Я могу указать класс окна, но там дается на выбор всякие кнопки, поля ввода и т.п. А создавать сложную структуру, заполнять ее через адреса в памяти - сложно на JS Мне бы задать цвет этой "кнопки" которую я создал. |
|||
75
Кирпич
25.03.15
✎
10:29
|
(74) "один фиг ты его в следующей строке удалял."
Я думал, что удалял регион окна, а на самом деле удалял его копию. Но это уже не важно. про окна на JS ничего не знаю и знать не хочу. |
|||
76
Супер король
25.03.15
✎
11:06
|
(75) А как на С++ или на паскале задать цвет окна? Я на JS сам переведу.
|
|||
77
H A D G E H O G s
25.03.15
✎
11:14
|
(76) Создавай не кнопку, а свое окно.
|
|||
78
H A D G E H O G s
25.03.15
✎
11:15
|
RegisterClassEx()
http://www.vsokovikov.narod.ru/New_MSDN_API/Win_class/fn_registerclassex.htm Структура WNDCLASSEX http://www.vsokovikov.narod.ru/New_MSDN_API/Win_class/str_wndclassex.htm HBRUSH hbrBackground; Дескриптор Кисти фона окна. |
|||
79
Супер король
25.03.15
✎
11:48
|
(78) я бы рад, но у меня RegisterClassEx() выдает ошибку постоянно, не могу победить.
|
|||
80
Супер король
25.03.15
✎
11:48
|
Причем GetLastError() возвращает 0
|
|||
81
Супер король
25.03.15
✎
11:49
|
хотя наверное эта функция врет
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |