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

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

新規登録して質問してみよう
ただいま回答率
85.50%
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回答

3874閲覧

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/02/24 11:32

編集2019/02/24 18:30

前提・実現したいこと

子ウィンドウを"閉じるボタン"として親ウィンドウ子ウィンドウともにSetLayeredWindowAttributesの指定色で透過しました.
あとから全体に描画はする予定で一時的にGRAY_BRUSHで中央に色が塗ってありますが"閉じるボタン"としての子ウィンドウ部分は透過部分もボタンとして作用してほしいです.
SetLayeredWindowAttributesの透過部分のLBUTTONDOWN等のメッセージは受け取るようにはできませんか?

該当のソースコード

C

1#define UNICODE 2 3#include <Windows.h> 4 5LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); 6LRESULT CALLBACK WindowDestroyProc(HWND, UINT, WPARAM, LPARAM); 7HINSTANCE hGlobalInstance; 8 9const wchar_t CLASS_NAME[] = L"CLASS NAME"; 10const wchar_t DESTROY_CLASS_NAME[] = L"DESTROY CONTROL CLASS NAME"; 11 12HWND mhwnd; 13 14int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR nCmdLine, int nCmdShow) { 15 UNREFERENCED_PARAMETER(hPrevInstance); 16 UNREFERENCED_PARAMETER(nCmdLine); 17 hGlobalInstance = hInstance; 18 19 WNDCLASSEX wc = { 20 sizeof(WNDCLASSEX), CS_VREDRAW | CS_HREDRAW, WindowProc, 21 0, 0, hInstance, 22 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), 23 NULL, CLASS_NAME, NULL 24 }; 25 26 RegisterClassEx(&wc); 27 28 HWND hwnd = CreateWindowEx( 29 WS_EX_LAYERED, CLASS_NAME, NULL, WS_POPUP | WS_BORDER, 30 100, 100, 960, 540, 31 NULL, NULL, hInstance, NULL 32 ); 33 34 mhwnd = hwnd; 35 36 SetLayeredWindowAttributes(hwnd, 0x0, 0, LWA_COLORKEY); 37 38 ShowWindow(hwnd, nCmdShow); 39 UpdateWindow(hwnd); 40 41 MSG msg = {}; 42 43 while (GetMessage(&msg, NULL, 0, 0) > 0) { 44 TranslateMessage(&msg); 45 DispatchMessage(&msg); 46 } 47 48 return (int)msg.wParam; 49} 50 51LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 52 switch (uMsg) { 53 case WM_CREATE: 54 { 55 WNDCLASSEX wdc = { 56 sizeof(WNDCLASSEX), NULL, WindowDestroyProc, 57 0, 0, hGlobalInstance, 58 NULL, (HCURSOR)LoadCursor(NULL,IDC_ARROW), (HBRUSH)GetStockObject(BLACK_BRUSH), 59 NULL, DESTROY_CLASS_NAME, NULL 60 }; 61 RegisterClassEx(&wdc); 62 HWND dwnd = CreateWindowEx( 63 0, DESTROY_CLASS_NAME, NULL, WS_CHILD, 64 815, 30, 105, 30, 65 hwnd, NULL, hGlobalInstance, NULL 66 ); 67 68 ShowWindow(dwnd, SW_SHOW); 69 UpdateWindow(dwnd); 70 } 71 break; 72 73 case WM_LBUTTONDOWN: 74 PostMessage(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, NULL); 75 break; 76 77 case WM_PAINT: 78 { 79 PAINTSTRUCT ps; 80 HDC hdc = BeginPaint(hwnd, &ps); 81 RECT rc = { 50, 50, 910, 530 }; 82 83 FillRect(hdc, &rc, (HBRUSH)GetStockObject(GRAY_BRUSH)); 84 85 EndPaint(hwnd, &ps); 86 } 87 break; 88 89 case WM_DESTROY: 90 PostQuitMessage(0); 91 return 0; 92 } 93 94 return DefWindowProc(hwnd, uMsg, wParam, lParam); 95} 96 97LRESULT CALLBACK WindowDestroyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 98 switch (uMsg) { 99 case WM_LBUTTONUP: 100 SendMessage(mhwnd, WM_DESTROY, 0, 0); 101 return 0; 102 103 case WM_PAINT: 104 { 105 PAINTSTRUCT ps; 106 HDC hdc = BeginPaint(hwnd, &ps); 107 RECT rc = { 5, 5, 100, 25 }; 108 109 FillRect(hdc, &rc, (HBRUSH)GetStockObject(GRAY_BRUSH)); 110 111 EndPaint(hwnd, &ps); 112 } 113 break; 114 115 } 116 return DefWindowProc(hwnd, uMsg, wParam, lParam); 117}

補足情報

Windows10 Pro
VisualStudio2017 Community

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

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

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

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

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

guest

回答1

0

ベストアンサー

SetLayeredWindowAttributesの透過部分のLBUTTONDOWN等のメッセージは受け取るようにはできませんか?

非常に残念ですが、WS_EX_LAYERED なウィンドウを LWA_COLORKEY で透過させた場合、そのウィンドウで直接マウスメッセージを受け取る手段はおそらくありません。とりあえず、回避策として私が提案できるのは以下のものになります。

#1.別のトップレベルウィンドウを透明に近い半透明にして重ね合わせる手法

LWA_COLORKEY で透過させたウィンドウの同じ位置・同じサイズに LWA_ALPHA を指定した別ウィンドウを配置する手法です。そのウィンドウでマウスを処理させることにより透過されつつマウス動作を実現します。アルファ値が 0 だとマウスが透過してしまうので、必ず1以上を指定する必要があります。アルファブレンドされるため、完全に元のイメージのままではありませんが、下の案よりは比較的ましな動きをします。
実際には LWA_ALPHA を指定しなくても WS_EX_LAYERED スタイルを指定すれば、完全に透過してマウスメッセージを受け取れるウィンドウが作成可能でした。元のウィンドウの位置にピッタリ合わせて動かす部分も含めて検証したので、以下のコードを確認してみてください。
https://github.com/atata0319/teratail176225

#2.SetCapture でマウスメッセージをキャプチャする手法

透明部分のマウスメッセージをキャプチャして、自ウィンドウで処理する手法です。該当のウィンドウの外をクリックされた際に下のウィンドウにマウスを PostMessage するなど、標準動作ではない動きが必要になるため作ろうとしているアプリケーション以外の操作性に難が出る可能性があります。

#3.ウィンドウの下側にあるウィンドウをキャプチャして透明にしたい部分に描画する手法

直近に関係のある質問(ウィンドウの後ろ側をキャプチャする方法(win10))がありましたが、実装難度が高いのでお勧めしません。うまく動作させるまでが大変です。

#4.フックでマウスメッセージを受け取る手法

2とほぼ同じですが問題も多いので、あまりお勧めしません。グローバルフック側でマウスメッセージを処理しなかった場合、怪しい動作が多いもので・・・。

投稿2019/02/24 18:54

編集2019/02/25 18:04
atata0319

総合スコア881

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問