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

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

643閲覧

WinAPI AlphaBlendによるレンダリングについて

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クリップ

投稿2018/09/10 14:55

編集2018/09/11 01:18

前提・実現したいこと

AlphaBlendの練習として半透過の背景(デスクトップ)がすけるウィンドウをつくろうとしています。

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

ウィンドウを動かしても背景のデスクトップは起動時のまま再描画されず、拡大縮小しても黒くなり再描画されません。どの記述に問題があるのでしょうか?
また立ち上げるたびに透過する色の濃さが変わります。うまく開放や初期化されてないのでしょうか?
ついでにコーディング上のご指摘があればお願いします。

該当のソースコード

C

1#ifndef UNICODE 2#define UNICODE 3#endif 4 5#include <Windows.h> 6 7#pragma comment(lib,"msimg32.lib") 8 9LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 10 11int imgWidth = 300; 12int imgHeight = 500; 13 14int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow) 15{ 16 const wchar_t CLASS_NAME[] = L"Sample"; 17 18 WNDCLASSEX wc = { 19 sizeof(WNDCLASSEX),CS_VREDRAW | CS_HREDRAW,WindowProc,0, 20 0,hInstance,NULL,LoadCursor(NULL, IDC_ARROW), 21 (HBRUSH)WHITE_BRUSH,NULL,CLASS_NAME,NULL 22 }; 23 24 RegisterClassEx(&wc); 25 26 HWND hwnd = CreateWindowEx( 27 0, CLASS_NAME, L"Quick Image Rendering", WS_OVERLAPPEDWINDOW, 28 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 29 NULL, NULL, hInstance, NULL 30 ); 31 32 if (hwnd == NULL)return 0; 33 34 ShowWindow(hwnd, nCmdShow); 35 36 MSG msg = {}; 37 38 while (GetMessage(&msg, NULL, 0, 0)) 39 { 40 TranslateMessage(&msg); 41 DispatchMessage(&msg); 42 } 43 44 return 0; 45} 46LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 47 switch (uMsg) { 48 case WM_DESTROY: 49 PostQuitMessage(0); 50 return 0; 51 52 case WM_CREATE: 53 break; 54 55 case WM_SIZE: 56 InvalidateRect(hwnd, NULL, TRUE); 57 UpdateWindow(hwnd); 58 59 break; 60 61 case WM_PAINT: 62 { 63 HDC hdc; //for window 64 HDC himgdc; //for image 65 BLENDFUNCTION bf; 66 BITMAPINFO bmpi; 67 HBITMAP hbitmap; 68 VOID* pv; 69 int winWidth, winHeight; 70 RECT rClient; 71 72 hdc = GetDC(hwnd); 73 GetClientRect(hwnd, &rClient); 74 75 winWidth = rClient.right - rClient.left; 76 winHeight = rClient.bottom - rClient.top; 77 78 himgdc = CreateCompatibleDC(hdc); 79 80 ZeroMemory(&bmpi, sizeof(BITMAPINFO)); 81 82 bmpi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 83 bmpi.bmiHeader.biWidth = imgWidth; 84 bmpi.bmiHeader.biHeight = imgHeight; 85 bmpi.bmiHeader.biPlanes = 1; 86 bmpi.bmiHeader.biBitCount = 32; 87 bmpi.bmiHeader.biCompression = BI_RGB; 88 89 hbitmap = CreateDIBSection(himgdc, &bmpi, DIB_RGB_COLORS, &pv, NULL, 0x0); 90 91 SelectObject(himgdc, hbitmap); 92 93//DIBの動的作成 94 DWORD **image = (DWORD**)malloc(sizeof(DWORD*)*imgWidth); 95 DWORD *image_c = (DWORD*)malloc(sizeof(DWORD)*imgWidth*imgHeight); 96 for (int i = 0; i < imgWidth; i++)image[i] = image_c + i * imgHeight; 97 for (int i = 0; i < imgWidth; i++)for (int j = 0; j < imgHeight; j++)image[i][j] = 0x00000000; 98 99 for (int i = imgWidth/2+1; i < imgWidth; i++)for (int j = 0; j < imgHeight; j++)image[i][j] = 0x7f7f0000; 100 101 DWORD *dib = (DWORD*)calloc(sizeof(DWORD)*imgHeight*imgWidth, sizeof(sizeof(DWORD)*imgHeight*imgWidth)); 102 for (int i = 0; i < imgWidth; i++)for (int j = 0; j < imgHeight; j++)dib[i + j * imgWidth] = image[i][j]; 103//DIBの動的作成ここまで 104 105 pv = dib; 106 107 bf.BlendOp = AC_SRC_OVER; 108 bf.BlendFlags = 0; 109 bf.SourceConstantAlpha = 0xff; 110 bf.AlphaFormat = AC_SRC_ALPHA; 111 112 if (!AlphaBlend( 113 hdc, 0, 0, winWidth, winHeight, 114 himgdc, 0, 0, imgWidth, imgHeight, bf)) 115 return 0; 116 117 DeleteObject(hbitmap); 118 DeleteDC(himgdc); 119 DeleteDC(hdc); 120 free(dib); 121 free(image_c); 122 free(image); 123 124 } 125 break; 126 127 } 128 return DefWindowProc(hwnd, uMsg, wParam, lParam); 129}

補足情報(FW/ツールのバージョンなど)

Windows10
VisualStudio2017 Community

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

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

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

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

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

y_waiwai

2018/09/10 22:21 編集

> ウィンドウを動かしても背景のデスクトップは起動時のまま再描画されず、拡大縮小しても黒くなり再描画されません。 典型的な再描画がうまくいってない症状ですが、WM_PAINTがまともにうごいてないってことなんでしょうね
guest

回答1

0

ベストアンサー

AlphaBlend APIは、すでに何か描かれている状態に対して、更に画像を合成するAPIです。
そのため、

デスクトップがすけるウィンドウ

は実現できないのではないかと思います。
(擬似的には可能かもしれませんがAlphaBlendの練習題材としては好ましくないように思います。)

※実際に透けるウィンドウを目指すのでしたら「レイヤードウィンドウ」などでググってください。

投稿2018/09/11 01:10

takabosoft

総合スコア8356

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

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

Weapon

2018/09/11 03:00

"AlphaBlend APIは、すでに何か描かれている状態に対して"とのことですがこれは小ウィンドウに対して使うということでしょうか? 背景が透過したDIBを描画したい(目的としては親ウィンドウに対して透過小ウィンドウでプログレスバーの描画)のですがStretchDIBits funcではα値が使えなかったので
takabosoft

2018/09/11 04:48 編集

(小ウィンドウの意味が判りませんが)AlphaBlend APIは例えば透過PNGをアルファブレンドするケースが当てはまります。例えばゲームで言えば背景を先に描画して(これが「すでに描かれているもの」に該当)、その上に透過PNGなどのキャラクターをアルファブレンドしたい場合です。ウィンドウに対してAlphaBlendしてもウィンドウそのものが透過するわけではありません(この場合すでにウィンドウ内に描かれている(もしくは残っている)状態に対して、更に画像が合成されるだけです)。
Weapon

2018/09/11 05:14

"子"ウィンドウでした レイヤードウィンドウ調べてみます ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問