質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

1394閲覧

WinAPI SetLayeredWindowAttributesの挙動について

Weapon

総合スコア106

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2019/02/03 17:20

前提・実現したいこと

SetLayeredWindowAttributesについて以下のようなコードを書きました.SetLayeredWindowAttributesの第2引数で黒を指定しているため親ウィンドウの背景色は透過されます.しかし

1)chwnd1の子ウィンドウまで透過されてしまいます.SetLayeredWindowAttributesは子ウィンドウまで継承されるものなのでしょうか?子ウィンドウの指定色を変えるのではなく継承自体を断つことはできますか?

親ウィンドウの背景色をWHITE_BRUSH,chwnd1の子ウィンドウ背景色をBLACK_BRUSHにして直後にSetLayeredWindowAttributesを設定しても透過されませんでした.Win8以降は子ウィンドウにもWS_EX_LAYEREDは対応したとMSDNには書かれていますがSetLayeredWindowAttributesが適応されずその子ウィンドウが非表示になります.

2)子ウィンドウに適応することはWin32では不可能なのでしょうか?WINVERなどを定義してやる必要があるのでしょうか?

またSetLayeredWindowAttributesをそれぞれのプロシージャで回してそれぞれのウィンドウの透度を変更しようとしましたがMSDNにあるよう2回目以降は関数失敗します.

  1. 1)の質問に付随しますがウィンドウの透過設定は独立で設けられるものではないのでしょうか?

2)の質問に反するようですが子ウィンドウの透過はchwnd2の子ウィンドウのようにWS_EX_TRANSPARENTを使うもののように理解しているのですが

4)この認識でよいのでしょうか

以下のコードではWS_EX_TRANSPARENTを与えられたウィンドウはCreateWindowEx自体は成功するのですが非表示となっています.WS_EX_LAYEREDを適応した場合はデフォルトが無色になるのはわかりますが

5)WS_EX_TRANSPARENTはウィンドウまで無色になるのでしょうか?

話は変わりますが

6)もしOpenGL(WGL)での描画に対しデスクトップを透過する描画をする場合はOpenGLの処理以外でもウィンドウはウィンドウとして以上のような透過処理は必要でしょうか?

お願いします.
###コード概要
親ウィンドウ(hwnd)

  • 背景色BLACK_BRUSH
  • CreateWindowEx第1引数WS_EX_LAYERED

子ウィンドウ(chwnd1)

  • 背景色BLACK_BRUSH
  • CreateWindowEx第1引数0

子ウィンドウ(chwnd2)

  • 背景色WHITE_BRUSH
  • CreateWindowEx第1引数WS_EX_TRANSPARENT

発生している問題・エラーメッセージ

C

1#define UNICODE 2 3#include <windows.h> 4 5LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); 6LRESULT CALLBACK WindowChildProc_1(HWND, UINT, WPARAM, LPARAM); 7LRESULT CALLBACK WindowChildProc_2(HWND, UINT, WPARAM, LPARAM); 8HINSTANCE hInst; 9 10const wchar_t CLASS_NAME[] = L"MOTHERE CLASS"; 11const wchar_t CHILD_CLASS_1[] = L"CHILD CLASS 1"; 12const wchar_t CHILD_CLASS_2[] = L"CHILD CLASS 2"; 13 14int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR nCmdLine, int nCmdShow) { 15 UNREFERENCED_PARAMETER(hPrevInstance); 16 UNREFERENCED_PARAMETER(nCmdLine); 17 18 hInst = hInstance; 19 20 WNDCLASSEX wc = { 21 sizeof(WNDCLASSEX),CS_VREDRAW | CS_HREDRAW, WindowProc, 22 0, 0, hInstance, 23 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(WHITE_BRUSH), 24 NULL, CLASS_NAME, NULL 25 }; 26 27 RegisterClassEx(&wc); 28 29 HWND hwnd = CreateWindowEx( 30 WS_EX_LAYERED, CLASS_NAME, L"Template", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 31 50, 50, 960, 525, 32 NULL, NULL, hInstance, NULL 33 ); 34 35 SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 0x0, LWA_COLORKEY); 36 37 ShowWindow(hwnd, nCmdShow); 38 UpdateWindow(hwnd); 39 40 MSG msg = {}; 41 42 while (GetMessage(&msg, NULL, 0, 0) != 0) { 43 TranslateMessage(&msg); 44 DispatchMessage(&msg); 45 } 46 47 return (int)msg.wParam; 48} 49 50LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 51 switch (uMsg) { 52 case WM_CREATE: 53 { 54 WNDCLASSEX c1wc = { 55 sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, WindowChildProc_1, 56 0, 0, hInst, 57 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), 58 NULL, CHILD_CLASS_1, NULL 59 }; 60 RegisterClassEx(&c1wc); 61 62 HWND chwnd1 = CreateWindowEx( 63 0, CHILD_CLASS_1, L"Child 1", WS_CHILD | WS_DLGFRAME, 64 50, 50, 400, 225, 65 hwnd, NULL, hInst, NULL 66 ); 67 ShowWindow(chwnd1, SW_SHOW); 68 69 WNDCLASSEX c2wc = { 70 sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, WindowChildProc_2, 71 0, 0, hInst, 72 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(WHITE_BRUSH), 73 NULL, CHILD_CLASS_2, NULL 74 }; 75 RegisterClassEx(&c2wc); 76 77 HWND chwnd2 = CreateWindowEx( 78 WS_EX_TRANSPARENT, CHILD_CLASS_2, L"Child 2", WS_CHILD | WS_THICKFRAME, 79 500, 50, 400, 225, 80 hwnd, NULL, hInst, NULL 81 ); 82 83 if (chwnd2==NULL)MessageBox(hwnd, L"SetLayeredWindowAttributes Failed", L"Child Window 1 status", MB_OK); 84 85 ShowWindow(chwnd2, SW_SHOW); 86 87 break; 88 } 89 case WM_PAINT: 90 { 91 PAINTSTRUCT ps = {}; 92 HDC hdc = GetDC(hwnd); 93 94 BeginPaint(hwnd, &ps); 95 FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(BLACK_BRUSH)); 96 EndPaint(hwnd, &ps); 97 } 98 break; 99 100 case WM_DESTROY: 101 PostQuitMessage(0); 102 return 0; 103 } 104 105 return DefWindowProc(hwnd, uMsg, wParam, lParam); 106} 107 108LRESULT CALLBACK WindowChildProc_1(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 109 switch (uMsg) { 110 case WM_CREATE: 111 112 break; 113 114 case WM_PAINT: 115 { 116 PAINTSTRUCT ps = {}; 117 HDC hdc = GetDC(hwnd); 118 119 BeginPaint(hwnd, &ps); 120 FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(BLACK_BRUSH)); 121 EndPaint(hwnd, &ps); 122 } 123 break; 124 125 case WM_DESTROY: 126 PostQuitMessage(0); 127 return 0; 128 } 129 130 return DefWindowProc(hwnd, uMsg, wParam, lParam); 131} 132 133LRESULT CALLBACK WindowChildProc_2(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 134 switch (uMsg) { 135 case WM_CREATE: 136 137 break; 138 139 case WM_PAINT: 140 141 break; 142 143 case WM_DESTROY: 144 PostQuitMessage(0); 145 return 0; 146 } 147 148 return DefWindowProc(hwnd, uMsg, wParam, lParam); 149}

補足情報

Windows10 Pro
VisualStudio2017 Community

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wwbQzhMkhhgEmhU

2019/02/04 06:20

透過も階層も触ったことがないですが、MSDNを見ると、 透過(Transparent)=下のウィンドウ描画が終わるまで上のウィンドウ描画が待たされる 階層(Layered)=アルファブレンディングで合成される といった違いがあるようで、階層ウィンドウは子ウィンドウとかと同列の概念のようです。 察するに階層ウィンドウの子ならもうその枠組みの中に入るのではないかと思います。 実際にGetWindowLogなどでスタイルを取ったときも、親ウィンドウは階層と返ってきますが、子ウィンドウは階層とは返ってきませんでした。 Windows 8より前では階層指定できるのはトップレベル(以下のウィンドウ群)だけだったところが、それ以降で特定の子ウィンドウ(以下のウィンドウ群)を指定できるようになっただけ、というように読むとしっくり来ます。 なお、説明によると、本来は階層ウィンドウ指定は拡張ウィンドウスタイルできちんと指定するもののようです。今回はSetLayeredWindowAttributes()で勝手に階層ウィンドウ指定されたんでしょうね。 それ以上のことは読み取れませんでした。以上です。
guest

回答1

0

ベストアンサー

なんとなく覚えているところだけ・・・

1)chwnd1の子ウィンドウまで透過されてしまいます.SetLayeredWindowAttributesは子ウィンドウまで継承されるものなのでしょうか?

YESです。
もともとトップレベルのウィンドウに適用すると、子ウィンドウ含むウィンドウ全体が半透明にできるようになっている機能だと思われます。

子ウィンドウの指定色を変えるのではなく継承自体を断つことはできますか?

これはわからないですが、出来ているのを見たことはないです。

Win8以降は子ウィンドウにもWS_EX_LAYEREDは対応したとMSDNには書かれていますがSetLayeredWindowAttributesが適応されずその子ウィンドウが非表示になります.

2)子ウィンドウに適応することはWin32では不可能なのでしょうか?WINVERなどを定義してやる必要があるのでしょうか?

Win8から子ウィンドウ単体をレイヤードウィンドウにする事ができるようになりましたが、
アプリケーションのマニフェストでWin8対応を宣言する必要があります。

ちなみに単色で色を抜きたいだけでしたらレイヤードにしなくとも
SetWindowRgn APIを使ってウィンドウを透過っぽくする手もあります。
これならば「抜き色を黒にしたら子ウィンドウの無関係なところまで抜けてしまった」という事故は防げます。
ちょっとコードが増えますが。

投稿2019/02/04 06:25

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問