teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

セクションの修正

2019/04/29 08:37

投稿

Weapon
Weapon

スコア106

title CHANGED
File without changes
body CHANGED
@@ -4,7 +4,7 @@
4
4
  ###追記
5
5
  指摘をもとに多少の修正と引数の変更を行いましたが上手くいきません.一応動作するサンプルも追記しましたがスクリーンDCを使用しなくても動いてしまうらしいので気をつけます.しかし動作するサンプルの`UpdateLayeredWindow func.`の第四引数のウィンドウの座標を変更したりNULLにしたりすると表示がされない上タスクバーにアイコンができないなど挙動が理解できません.
6
6
 
7
- ### 追記のコード
7
+ ### コード(修正して追記)
8
8
  指摘をもとに修正
9
9
  `UpdateLayeredWindow func.`は130行目付近
10
10
  ```C

1

修正と追記

2019/04/29 08:37

投稿

Weapon
Weapon

スコア106

title CHANGED
File without changes
body CHANGED
@@ -1,8 +1,12 @@
1
1
  ### 前提・実現したいこと
2
2
  以前`SetLayeredWindowAttibutes func.`においての透過処理はしましたがOpenGLの描画等に透過をかけれるよう,より詳細にAlfa値を使って描画したいと思い`UpdateLayeredWindow func.`を使おうとサンプル等を読み作ってみましたがうまく動作しません.DeviceContextの取り方が悪いのかAlpha値が0になっているのか一通り見てみたつもりですが関数自体は成功してもウィンドウに効きません.WS_EX_LAYERED無しの動作確認はしました.よろしくお願いします.
3
3
 
4
+ ###追記
5
+ 指摘をもとに多少の修正と引数の変更を行いましたが上手くいきません.一応動作するサンプルも追記しましたがスクリーンDCを使用しなくても動いてしまうらしいので気をつけます.しかし動作するサンプルの`UpdateLayeredWindow func.`の第四引数のウィンドウの座標を変更したりNULLにしたりすると表示がされない上タスクバーにアイコンができないなど挙動が理解できません.
6
+
4
- ### 該当のコード
7
+ ### 追記のコード
8
+ 指摘をもとに修正
5
- 80行目付近の`UpdateLayeredWindow func.`
9
+ `UpdateLayeredWindow func.`は130行目付近
6
10
  ```C
7
11
  #define UNICODE
8
12
 
@@ -49,7 +53,7 @@
49
53
  }
50
54
 
51
55
  LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
52
- static RECT wrc;
56
+ static RECT crc;
53
57
  static int iWidth = 0;
54
58
  static int iHeight = 0;
55
59
 
@@ -60,6 +64,8 @@
60
64
  AC_SRC_OVER, 0, 0x7f, AC_SRC_ALPHA
61
65
  };
62
66
 
67
+ static SIZE wsz = { 0 };
68
+ static POINT pt = { 0 };
63
69
 
64
70
  switch (uMsg) {
65
71
  case WM_ERASEBKGND:
@@ -69,36 +75,35 @@
69
75
  {
70
76
  HDC hmdc = GetDC(hwnd);
71
77
  hbufdc = CreateCompatibleDC(hmdc);
72
- ReleaseDC(hwnd, hmdc);
78
+ ReleaseDC(0, hmdc);
73
79
  }
74
80
  break;
75
81
 
76
82
  case WM_PAINT:
77
83
  {
78
- SelectObject(hbufdc, hbmp);
79
-
80
84
  PAINTSTRUCT ps = {};
81
85
  HDC hdc = BeginPaint(hwnd, &ps);
82
86
 
83
- if (BitBlt(hdc, 0, 0, iWidth, iHeight, hbufdc, 0, 0, SRCCOPY) == FALSE)MessageBox(hwnd, L"BitBlt ERROR", L"WM_PAINT ERROR", MB_OK);
87
+ if (BitBlt(hdc, 0, 0, iWidth, iHeight, hbufdc, 0, 0, SRCCOPY | CAPTUREBLT) == FALSE)MessageBox(hwnd, L"BitBlt ERROR", L"WM_PAINT ERROR", MB_OK);
84
-
85
- if (UpdateLayeredWindow(hwnd, hdc, NULL, NULL, hbufdc, NULL, 0, &bf, ULW_ALPHA) == FALSE) {
86
- MessageBox(hwnd, L"Update ERROR", L"WM_PAINT ERROR", MB_OK);
88
+ SetBkMode(hdc, TRANSPARENT);
87
- }
88
89
 
89
- EndPaint(hwnd, &ps);
90
+ EndPaint(hwnd, &ps);
90
91
  }
91
- break;
92
+ break;
92
93
 
93
94
  case WM_SIZE:
94
95
  {
95
- GetClientRect(hwnd, &wrc);
96
+ GetClientRect(hwnd, &crc);
96
- int crWidth = wrc.right - wrc.left;
97
+ int crWidth = crc.right - crc.left;
97
- int crHeight = wrc.bottom - wrc.top;
98
+ int crHeight = crc.bottom - crc.top;
98
99
  if ((crWidth != iWidth) || (crHeight != iHeight)) {
99
100
  iWidth = crWidth;
100
101
  iHeight = crHeight;
101
102
 
103
+ wsz.cx = crWidth;
104
+ wsz.cy = crHeight;
105
+
106
+ /* Create BITMAP */
102
107
  if (hbmp != NULL)DeleteObject(hbmp);
103
108
 
104
109
  void* pv;
@@ -119,12 +124,27 @@
119
124
  int mdsize = iWidth * iHeight;
120
125
  for (int i = 0; i < mdsize; i++)lpdw[i] = 0x7fff00ff;
121
126
 
127
+ SelectObject(hbufdc, hbmp);
128
+ /* END Create BITMAP */
129
+
130
+ /* TRANSPARENT Process */
131
+ RECT wrc;
132
+ GetWindowRect(hwnd, &wrc);
133
+ pt.x = wrc.left;
134
+ pt.y = wrc.top;
135
+
136
+ HDC sdc = GetDC(NULL);
137
+ if (UpdateLayeredWindow(hwnd, sdc, NULL, &wsz, hbufdc, &pt, 0, &bf, ULW_ALPHA) == FALSE) {
138
+ MessageBox(hwnd, L"Update ERROR", L"WM_SIZE ERROR", MB_OK);
139
+ DestroyWindow(hwnd);
140
+ }
141
+ ReleaseDC(0, sdc);
142
+ /* END TRANSPARENT Process */
122
143
  InvalidateRect(hwnd, NULL, FALSE);
123
144
  }
124
145
  }
125
146
  break;
126
147
 
127
-
128
148
  case WM_DESTROY:
129
149
  DeleteDC(hbufdc);
130
150
  DeleteObject(hbmp);
@@ -136,8 +156,185 @@
136
156
  }
137
157
 
138
158
  ```
159
+ ###参考にしているサンプル(追記)
160
+ ```C
161
+ #define UNICODE
162
+ #include <windows.h>
139
163
 
164
+ LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
165
+ ATOM InitApp(HINSTANCE);
166
+ BOOL InitInstance(HINSTANCE, int);
140
167
 
168
+ LPCWSTR szClassName = L"layer01"; //ウィンドウクラス
169
+ HINSTANCE hInst;
170
+
171
+ HBITMAP hBmpGra; //グラデーションを格納
172
+
173
+ int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
174
+ LPSTR lpsCmdLine, int nCmdShow) {
175
+ MSG msg;
176
+ BOOL bRet;
177
+
178
+ hInst = hCurInst;
179
+ if (!InitApp(hCurInst))
180
+ return FALSE;
181
+ if (!InitInstance(hCurInst, nCmdShow))
182
+ return FALSE;
183
+ while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
184
+ if (bRet == -1) {
185
+ break;
186
+ }
187
+ else {
188
+ TranslateMessage(&msg);
189
+ DispatchMessage(&msg);
190
+ }
191
+ }
192
+ return (int)msg.wParam;
193
+ }
194
+
195
+ //ウィンドウ・クラスの登録
196
+ ATOM InitApp(HINSTANCE hInst) {
197
+ WNDCLASSEX wc;
198
+ wc.cbSize = sizeof(WNDCLASSEX);
199
+ wc.style = CS_HREDRAW | CS_VREDRAW;
200
+ wc.lpfnWndProc = WndProc; //プロシージャ名
201
+ wc.cbClsExtra = 0;
202
+ wc.cbWndExtra = 0;
203
+ wc.hInstance = hInst;//インスタンス
204
+ wc.hIcon = (HICON)LoadImage(NULL,
205
+ MAKEINTRESOURCE(IDI_APPLICATION),
206
+ IMAGE_ICON,
207
+ 0,
208
+ 0,
209
+ LR_DEFAULTSIZE | LR_SHARED);
210
+ wc.hCursor = (HCURSOR)LoadImage(NULL,
211
+ MAKEINTRESOURCE(IDC_ARROW),
212
+ IMAGE_CURSOR,
213
+ 0,
214
+ 0,
215
+ LR_DEFAULTSIZE | LR_SHARED);
216
+ wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
217
+ wc.lpszMenuName = NULL; //メニュー名
218
+ wc.lpszClassName = szClassName;
219
+ wc.hIconSm = (HICON)LoadImage(NULL,
220
+ MAKEINTRESOURCE(IDI_APPLICATION),
221
+ IMAGE_ICON,
222
+ 0,
223
+ 0,
224
+ LR_DEFAULTSIZE | LR_SHARED);
225
+
226
+ return (RegisterClassEx(&wc));
227
+ }
228
+
229
+ //ウィンドウの生成
230
+ BOOL InitInstance(HINSTANCE hInst, int nCmdShow) {
231
+ HWND hWnd;
232
+
233
+ hWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_TOPMOST | WS_EX_TOOLWINDOW,
234
+ szClassName,
235
+ L"Test Layer Window", //Title
236
+ WS_POPUP,
237
+ 50, //X
238
+ 50, //Y
239
+ 960, //width
240
+ 520, //height
241
+ NULL, //hWnd
242
+ NULL, //Menu
243
+ hInst,
244
+ NULL);
245
+ if (!hWnd)
246
+ return FALSE;
247
+ ShowWindow(hWnd, nCmdShow);
248
+ UpdateWindow(hWnd);
249
+ return TRUE;
250
+ }
251
+
252
+ //グラデーションのBitmapの作成
253
+ HBITMAP make_gradation(HWND hWnd, unsigned height, unsigned width, BYTE _r, BYTE _g, BYTE _b) {
254
+ void* lpBits;
255
+
256
+ BITMAPINFO bi = {
257
+ sizeof(BITMAPINFOHEADER), 960, 520, 1, 32, BI_RGB, 0, 0, 0, 0, 0, 0
258
+ };
259
+
260
+ HDC hdc = GetDC(hWnd);
261
+ HBITMAP hbmp = CreateDIBSection(hdc, (BITMAPINFO*)& bi, DIB_RGB_COLORS,
262
+ (void**)& lpBits, NULL, (DWORD)0);
263
+ ReleaseDC(hWnd, hdc);
264
+
265
+ DWORD* lpdw = (DWORD*)lpBits;
266
+ int mdsize = 960 * 520;
267
+ for (int i = 0; i < mdsize; i++)lpdw[i] = 0x7fff00ff;
268
+
269
+ return hbmp;
270
+ };
271
+
272
+
273
+ //ウィンドウプロシージャ
274
+ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
275
+ int id;
276
+ HDC hdc, hdc_mem, hsdc;
277
+ HBRUSH hBrush;
278
+ PAINTSTRUCT ps;
279
+ LPCWSTR szBuf = L"Test Layer Window";
280
+ BITMAP bmp_info;
281
+ HBITMAP hBmp;
282
+ int wx, wy;
283
+ const COLORREF col = RGB(0, 255, 0);
284
+ HGDIOBJ hOldObj;
285
+ BLENDFUNCTION blend;
286
+ POINT wndPos;
287
+ SIZE wndSize;
288
+ RECT rc;
289
+ POINT po;
290
+
291
+ switch (msg) {
292
+ case WM_CREATE:
293
+ hBmpGra = make_gradation(hWnd, 520, 960, 0, 255, 60);
294
+
295
+ case WM_PAINT:
296
+ hsdc = GetDC(hWnd);
297
+ hdc = BeginPaint(hWnd, &ps);
298
+ hdc_mem = CreateCompatibleDC(hdc);
299
+ SelectObject(hdc_mem, hBmpGra);
300
+ BitBlt(hdc, 0, 0, 960, 520, hdc_mem, 0, 0, SRCCOPY | CAPTUREBLT);
301
+
302
+ wndSize.cx = 960; wndSize.cy = 520;
303
+ po.x = po.y = 0;
304
+ blend.BlendOp = AC_SRC_OVER;
305
+ blend.BlendFlags = 0;
306
+ blend.SourceConstantAlpha = 0xff;
307
+ blend.AlphaFormat = AC_SRC_ALPHA;
308
+ UpdateLayeredWindow(hWnd, hsdc, nullptr, &wndSize, hdc_mem, &po, 0, &blend, ULW_ALPHA);
309
+
310
+ DeleteDC(hdc_mem);
311
+ SetBkMode(hdc, TRANSPARENT);
312
+ EndPaint(hWnd, &ps);
313
+ ReleaseDC(0, hsdc);
314
+ break;
315
+ case WM_CLOSE:
316
+ id = MessageBox(hWnd,
317
+ L"終了してもよろしいですか",
318
+ L"確認",
319
+ MB_YESNO | MB_ICONQUESTION);
320
+ if (id == IDYES)
321
+ DestroyWindow(hWnd);
322
+ break;
323
+ case WM_RBUTTONDOWN:
324
+ SendMessage(hWnd, WM_CLOSE, 0, 0);
325
+ break;
326
+ case WM_LBUTTONDOWN:
327
+ PostMessage(hWnd, WM_NCLBUTTONDOWN, (WPARAM)HTCAPTION, lp);
328
+ break;
329
+ case WM_DESTROY:
330
+ PostQuitMessage(0);
331
+ break;
332
+ default:
333
+ return (DefWindowProc(hWnd, msg, wp, lp));
334
+ }
335
+ return 0;
336
+ }
337
+ ```
141
338
  ### 補足情報
142
339
  Windows10 Pro
143
340
  VisualStudio2019 Community