| 
    
            
         
         | 
    
  | 
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 
 | 
         
        хотя наверное эта функция врет     
         | 
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |