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

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回答

936閲覧

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グッド

0クリップ

投稿2019/03/03 16:27

前提・実現したいこと

前の質問 teratail:SetLayeredWindowAttributesの透過領域のメッセージについて トップレベルウィンドウによるマウス処理を提案していただき,コードをいじっていろいろ実験してみました.
親ウィンドウ同様,子ウィンドウの"閉じる"のコントロールにおいても同様のことをしてみたのですが上手くいきません.
想定図↓
image

親ウィンドウのようにトップレベルウィンドウ同士でしかこのようなことができないのでしょうか?子ウィンドウ同士で実験をしてみましたがイベントが透過します.そもそもどちらのウィンドウもアクティブしないのでトップレベルウィンドウとは勝手が違うのだとは思いましたが.

該当のソースコード

C

1#define UNICODE 2 3#include <Windows.h> 4#include <windowsx.h> 5 6LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); 7LRESULT CALLBACK WindowMouseProc(HWND, UINT, WPARAM, LPARAM); 8LRESULT CALLBACK DestroyProc(HWND, UINT, WPARAM, LPARAM); 9LRESULT CALLBACK DestroyMouseProc(HWND, UINT, WPARAM, LPARAM); 10 11HINSTANCE hGlobalInstance; 12HWND mhwnd; 13HWND mmouse; 14HWND chwnd; 15HWND cmhwnd; 16 17const wchar_t CLASS_WINDOW_NAME[] = L"CLASS WINDOW NAME"; 18const wchar_t CLASS_WINDOW_MOUSE_NAME[] = L"CLASS WINDOW MOUSE NAME"; 19const wchar_t CLASS_DESTROY_NAME[] = L"CLASS DESTROY NAME"; 20const wchar_t CLASS_DESTROY_MOUSE_NAME[] = L"CLASS DESTROY MOUSE NAME"; 21 22int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR nCmdLine, int nCmdShow) { 23 UNREFERENCED_PARAMETER(hPrevInstance); 24 UNREFERENCED_PARAMETER(nCmdLine); 25 hGlobalInstance = hInstance; 26 27 WNDCLASSEX wc = { 28 sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, WindowProc, 29 0, 0, hGlobalInstance, 30 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), 31 NULL, CLASS_WINDOW_NAME, NULL 32 }; 33 RegisterClassEx(&wc); 34 35 WNDCLASSEX wcm = { 36 sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, WindowMouseProc, 37 0, 0, hGlobalInstance, 38 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), 39 NULL, CLASS_WINDOW_MOUSE_NAME, NULL 40 }; 41 RegisterClassEx(&wcm); 42 43 mhwnd = CreateWindowEx( 44 WS_EX_LAYERED, CLASS_WINDOW_NAME, NULL, WS_POPUP | WS_CLIPCHILDREN, 45 100, 100, 960, 540, 46 NULL, NULL, hGlobalInstance, NULL 47 ); 48 49 SetLayeredWindowAttributes(mhwnd, 0x0, 0, LWA_COLORKEY); 50 51 mmouse = CreateWindowEx( 52 WS_EX_LAYERED, CLASS_WINDOW_MOUSE_NAME, NULL, WS_POPUP, 53 100, 100, 960, 540, 54 NULL, NULL, hGlobalInstance, NULL 55 ); 56 57 ShowWindow(mhwnd, nCmdShow); 58 59 SetWindowPos(mmouse, mhwnd, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW); 60 61 UpdateWindow(mmouse); 62 UpdateWindow(mhwnd); 63 64 MSG msg = {}; 65 while (GetMessage(&msg, NULL, 0, 0) > 0) { 66 TranslateMessage(&msg); 67 DispatchMessage(&msg); 68 } 69 70 return (int)msg.wParam; 71} 72 73LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 74 switch (uMsg) { 75 case WM_CREATE: 76 { 77 78 WNDCLASSEX wdc = { 79 sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, DestroyProc, 80 0, 0, hGlobalInstance, 81 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), 82 NULL, CLASS_DESTROY_NAME, NULL 83 }; 84 RegisterClassEx(&wdc); 85 86 WNDCLASSEX mdc = { 87 sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, DestroyMouseProc, 88 0, 0, hGlobalInstance, 89 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), 90 NULL, CLASS_DESTROY_MOUSE_NAME, NULL 91 }; 92 RegisterClassEx(&mdc); 93 94 chwnd = CreateWindowEx( 95 0, CLASS_DESTROY_NAME, NULL, WS_CHILD | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 96 815, 30, 105, 30, 97 hwnd, NULL, hGlobalInstance, NULL 98 ); 99 100 cmhwnd = CreateWindowEx( 101 0, CLASS_DESTROY_MOUSE_NAME, NULL, WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 102 815, 30, 105, 30, 103 hwnd, NULL, hGlobalInstance, NULL 104 ); 105 106 ShowWindow(cmhwnd, SW_SHOW); 107 ShowWindow(chwnd, SW_SHOW); 108 109 UpdateWindow(cmhwnd); 110 UpdateWindow(chwnd); 111 112 SetWindowPos(cmhwnd, chwnd, 815, 30, 105, 30, SWP_NOACTIVATE); 113 } 114 break; 115 116 case WM_PAINT: 117 { 118 PAINTSTRUCT ps; 119 HDC hdc = BeginPaint(hwnd, &ps); 120 RECT rc = { 50, 50, 910, 530 }; 121 FillRect(hdc, &rc, (HBRUSH)GetStockObject(GRAY_BRUSH)); 122 EndPaint(hwnd, &ps); 123 } 124 break; 125 126 case WM_APP + WM_LBUTTONDOWN - WM_MOUSEFIRST: 127 case WM_LBUTTONDOWN: 128 PostMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, NULL); 129 break; 130 131 case WM_MOVE: 132 RECT wrc; 133 GetWindowRect(hwnd, &wrc); 134 SetWindowPos(mmouse, mhwnd, wrc.left, wrc.top, wrc.right - wrc.left, wrc.bottom - wrc.top, SWP_NOACTIVATE); 135 break; 136 137 case WM_DESTROY: 138 PostQuitMessage(0); 139 return 0; 140 } 141 142 143 return DefWindowProc(hwnd, uMsg, wParam, lParam); 144} 145LRESULT CALLBACK WindowMouseProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 146 if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST) { 147 POINT pt = { GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam) }; 148 MapWindowPoints(hwnd, mhwnd, &pt, 1); 149 return SendMessage(mhwnd, WM_APP + uMsg - WM_MOUSEFIRST, wParam, MAKELPARAM(pt.x, pt.y)); 150 } 151 else if (uMsg == WM_MOUSEACTIVATE) { 152 return MA_NOACTIVATE; 153 } 154 else { 155 return DefWindowProc(hwnd, uMsg, wParam, lParam); 156 } 157} 158LRESULT CALLBACK DestroyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 159 switch (uMsg) { 160 case WM_APP + WM_LBUTTONDOWN - WM_MOUSEFIRST: 161 case WM_LBUTTONUP: 162 DestroyWindow(mmouse); 163 DestroyWindow(mhwnd); 164 return 0; 165 166 case WM_PAINT: 167 168 { 169 PAINTSTRUCT ps; 170 HDC hdc = BeginPaint(hwnd, &ps); 171 RECT crc = { 5, 5, 100, 25 }; 172 FillRect(hdc, &crc, (HBRUSH)GetStockObject(GRAY_BRUSH)); 173 EndPaint(hwnd, &ps); 174 SetWindowPos(cmhwnd, chwnd, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW); 175 } 176 break; 177 178 } 179 return DefWindowProc(hwnd, uMsg, wParam, lParam); 180} 181 182LRESULT CALLBACK DestroyMouseProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 183 if (uMsg >= WM_MOUSEFIRST && uMsg <= WM_MOUSELAST) { 184 MessageBox(mhwnd, L"CALL", L"CAUTION", MB_OK); 185 POINT ptc = { GET_X_LPARAM(lParam),GET_Y_LPARAM(lParam) }; 186 MapWindowPoints(hwnd, chwnd, &ptc, 1); 187 return SendMessage(chwnd, WM_APP + uMsg - WM_MOUSEFIRST, wParam, MAKELPARAM(ptc.x, ptc.y)); 188 } 189 else if (uMsg == WM_MOUSEACTIVATE) { 190 return MA_NOACTIVATE; 191 } 192 else { 193 return DefWindowProc(hwnd, uMsg, wParam, lParam); 194 } 195}

補足情報

Windows10 Pro
VisualStudio2017 Community

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

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

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

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

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

guest

回答1

0

ベストアンサー

問題箇所だけ指摘しますが、最終的な望みの動作にはならないんじゃないかと推測しています。

1.ウィンドウの順番が逆

C++

1 SetWindowPos(cmhwnd, chwnd, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW);

はウィンドウの指定が逆です。このためマウスメッセージを透過させたい方が上に来ていません。

C++

1 SetWindowPos(chwnd, cmhwnd, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_SHOWWINDOW);

トップレベルウィンドウを参考にされたと思いますが、あれはマウスを処理するウィンドウを最初からあったウィンドウの後ろに持って行っています。そのまま真似すると順番が逆になります。

2.ウィンドウが透過されたまま
DestroyMouseProc で重ね合わせたウィンドウに色を付けていないため、SetLayeredWindowAttributes で指定したカラーキーと黒の背景色がマッチしており、全体が透過されています。子ウィンドウは親ウィンドウの SetLayeredWindowAttributes をそのまま引き継ぐので、このような動作になります。

上記 2 点を解決すれば、マウスメッセージは届くようになるはずです。

投稿2019/03/04 14:27

atata0319

総合スコア881

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問