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

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

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

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

Win32 API

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

Q&A

解決済

1回答

2043閲覧

WinAPI 自作の円形プログレスバーの描画

Weapon

総合スコア106

C

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

Win32 API

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

0グッド

0クリップ

投稿2018/10/27 03:20

前提・実現したいこと

自作の円形プログレスバーを作成しましたがバーの描画がウィンドウのリサイズ時のみ一瞬表示されるのですが常には表示されません.どこが問題となっているのでしょうか.
また全体としてボトルネックとなっている箇所,自作ウィンドウメッセージのデザイン等ご教授願いたいです.

コードの内容

親ウィンドウに対して子ウィンドウ二つ
親ウィンドウはタイマー生成
子ウィンドウ1(chwnd)はステータスのプレビューおよびタイマーを受けたステータスの更新
子ウィンドウ2(graphhwnd)は子ウィンドウ1のメッセージに応じてグラフの描画

自作メッセージ
OPRBM_SETRANGE バーの最大値定義 default:100(今回未使用)
OPRBM_SETSTEP OPRBM_SETINC/OPRBM_SETDECのステップを定義
OPRBM_SETINC OPRBM_SETSTEPの定義分値を増やす
OPRBM_SETDEC OPRBM_SETSTEPの定義分値を減らす(今回未使用)
OPRBM_SET 進捗ステータスをLPARAMで投げる(今回未使用)
なお最大値,ステータスをグローバル定義

CalcArg(int, int)については2つの値から得られる角度をarctangentの[-pi/2,pi/2]から[-pi,pi]に拡張したもの

該当のソースコード

C

1#ifndef UNICODE 2#define UNICODE 3#endif 4 5#define OPRBM_SETRANGE (WM_APP+0x0001) 6#define OPRBM_SETSTEP (WM_APP+0x0002) 7#define OPRBM_SETINC (WM_APP+0x0003) 8#define OPRBM_SETDEC (WM_APP+0x0004) 9#define OPRBM_SET (WM_APP+0x0005) 10 11 12#include <Windows.h> 13#include <math.h> 14 15LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 16LRESULT CALLBACK ProgressiveWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 17LRESULT CALLBACK GraphWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 18 19const wchar_t CLASS_NAME[] = L"Class Name"; 20const wchar_t CLASS_NAME_2[] = L"Class Name 2"; 21const wchar_t CLASS_NAME_3[] = L"Class Name 3"; 22 23#define PI (double)3.141592653589793 24 25/*Initial Parameter*/ 26int width = 300; 27int height = 300; 28/*Init Param End*/ 29 30long max = 100; 31long step = 1; 32long value = 0; 33 34HINSTANCE hInst; 35HWND chwnd; 36HWND graphhwnd; 37RECT rc; 38 39double CalcArg(int, int); 40 41int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow) 42{ 43 hInst = hInstance; 44 45 WNDCLASSEX wc = { 46 sizeof(WNDCLASSEX),CS_VREDRAW | CS_HREDRAW,WindowProc,0, 47 0,hInstance,NULL,LoadCursor(NULL, IDC_ARROW), 48 (HBRUSH)GetStockObject(WHITE_BRUSH),NULL,CLASS_NAME,NULL 49 }; 50 51 RegisterClassEx(&wc); 52 53 HWND hwnd = CreateWindowEx( 54 0, CLASS_NAME, L"Title", WS_OVERLAPPEDWINDOW, 55 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 56 NULL, NULL, hInstance, NULL 57 ); 58 59 if (hwnd == NULL)return 0; 60 61 ShowWindow(hwnd, nCmdShow); 62 UpdateWindow(hwnd); 63 64 MSG msg = {}; 65 66 while (GetMessage(&msg, NULL, 0, 0)) 67 { 68 TranslateMessage(&msg); 69 DispatchMessage(&msg); 70 } 71 72 return (int)msg.wParam; 73} 74 75LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 76{ 77 78 switch (uMsg) { 79 case WM_CREATE: 80 { 81 step = 1; 82 SetTimer(hwnd, 101, 10000, NULL); 83 84 WNDCLASSEX wc2 = { 85 sizeof(WNDCLASSEX),CS_VREDRAW | CS_HREDRAW,ProgressiveWindowProc,0, 86 0,hInst,NULL,LoadCursor(NULL, IDC_ARROW), 87 (HBRUSH)GetStockObject(WHITE_BRUSH),NULL,CLASS_NAME_2,NULL 88 }; 89 WNDCLASSEX wc3 = { 90 sizeof(WNDCLASSEX),CS_VREDRAW | CS_HREDRAW,GraphWindowProc,0, 91 0,hInst,NULL,LoadCursor(NULL, IDC_ARROW), 92 (HBRUSH)GetStockObject(WHITE_BRUSH),NULL,CLASS_NAME_3,NULL 93 }; 94 95 RegisterClassEx(&wc2); 96 RegisterClassEx(&wc3); 97 98 chwnd = CreateWindowEx( 99 0, CLASS_NAME_2, L"Title", WS_OVERLAPPEDWINDOW | WS_CHILD, 100 0,0,0,0, 101 hwnd, NULL, hInst, NULL 102 ); 103 graphhwnd = CreateWindowEx( 104 0, CLASS_NAME_3, L"Title", WS_OVERLAPPEDWINDOW | WS_CHILD, 105 10, 10, 500, 500, 106 hwnd, NULL, hInst, NULL 107 ); 108 109 ShowWindow(chwnd, SW_SHOW); 110 ShowWindow(graphhwnd, SW_SHOW); 111 } 112 break; 113 114 case WM_DESTROY: 115 KillTimer(hwnd, 101); 116 PostQuitMessage(0); 117 return 0; 118 119 case WM_PAINT: 120 { 121 GetClientRect(hwnd, &rc); 122 MoveWindow(chwnd, rc.right - 480, 0, 480, 360, TRUE); 123 124 PAINTSTRUCT ps; 125 HDC hdc = BeginPaint(hwnd, &ps); 126 127 FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(GRAY_BRUSH)); 128 129 EndPaint(hwnd, &ps); 130 131 } 132 break; 133 134 case WM_TIMER: 135 SendMessage(chwnd, OPRBM_SETINC, 0, 0); 136 137 break; 138 139 } 140 141 return DefWindowProc(hwnd, uMsg, wParam, lParam); 142} 143 144 145LRESULT CALLBACK ProgressiveWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 146 switch (uMsg) { 147 case WM_CREATE: 148 break; 149 150 case WM_DESTROY: 151 PostQuitMessage(0); 152 return 0; 153 154 case WM_PAINT: 155 { 156 PAINTSTRUCT ps; 157 HDC hdc = BeginPaint(hwnd, &ps); 158 159 FillRect(hdc, &ps.rcPaint, (HBRUSH)GetStockObject(WHITE_BRUSH)); 160 161 wchar_t message[256] = { 0 }; 162 wsprintf(message, L"max : %d% step: %d value : %d", max, step, value); 163 TextOut(hdc, 10, 10, message, lstrlen(message)); 164 165 EndPaint(hwnd, &ps); 166 } 167 break; 168 169 case OPRBM_SETRANGE: 170 if ((long)lParam > 0) { 171 long tmpmax = max; 172 max = (long)lParam; 173 if ((long)lParam > value)value *= (tmpmax / max); 174 } 175 176 177 InvalidateRect(hwnd, NULL, TRUE); 178 UpdateWindow(hwnd); 179 break; 180 181 case OPRBM_SETSTEP: 182 if (((long)lParam >= 0) && ((long)lParam <= max)) { 183 step = (long)lParam; 184 } 185 186 break; 187 188 case OPRBM_SETINC: 189 190 if (value > (max - step)) { 191 value = 100; 192 } 193 else { 194 value += step; 195 if (value > 100)value = 100; 196 } 197 198 199 InvalidateRect(hwnd, NULL, TRUE); 200 UpdateWindow(hwnd); 201 202 break; 203 204 case OPRBM_SETDEC: 205 if (value < step) { 206 value = 0; 207 } 208 else { 209 value -= step; 210 if (value < 0)value = 0; 211 } 212 213 214 InvalidateRect(hwnd, NULL, TRUE); 215 UpdateWindow(hwnd); 216 break; 217 218 case OPRBM_SET: 219 if ((long)lParam >= 0 && (long)lParam <= max) { 220 value = (long)lParam; 221 } 222 223 InvalidateRect(hwnd, NULL, TRUE); 224 UpdateWindow(hwnd); 225 break; 226 } 227 228 return DefWindowProc(hwnd, uMsg, wParam, lParam); 229} 230 231LRESULT CALLBACK GraphWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 232 switch (uMsg) { 233 case WM_CREATE: 234 break; 235 236 case WM_DESTROY: 237 PostQuitMessage(0); 238 return 0; 239 240 case WM_PAINT: 241 { 242 DWORD **image = (DWORD**)malloc(sizeof(DWORD*)*width); 243 DWORD *image_c = (DWORD*)malloc(sizeof(DWORD)*width*height); 244 for (int i = 0; i < width; i++)image[i] = image_c + i * height; 245 for (int i = 0; i < width; i++)for (int j = 0; j < height; j++)image[i][j] = 0xffffffff; 246 247 DWORD *dib = (DWORD*)calloc(sizeof(DWORD)*width*height, sizeof(sizeof(DWORD)*width*height)); 248 249 //from here 250 251 double center_x = 150, center_y = 150; 252 double radius = 90; 253 254 for (int i = 0; i < width; i++)for (int j = 0; j < height; j++) { 255 if (radius*radius - (i - center_x)*(i - center_x) - (j - center_y)*(j - center_y) > 0) { 256 if ((CalcArg(i - center_x, j - center_y) >= (1 - (double)value / (double)max * 2)*PI) && (CalcArg(i - center_x, j - center_y) <= PI)) { 257 image[i][j] = 0x00000000; 258 } 259 } 260 } 261 image[(int)center_x][(int)center_y] = 0x00000000; 262 263 //to here 264 265 // traca 266 for (int i = 0; i < width; i++)for (int j = 0; j < height; j++)dib[i + j * width] = image[height - j - 1][i]; 267 268 HDC hdc = GetDC(hwnd); 269 270 BITMAPINFO bmpi; 271 ZeroMemory(&bmpi, sizeof(bmpi)); 272 bmpi.bmiHeader.biSize = sizeof(bmpi); 273 bmpi.bmiHeader.biWidth = width; 274 bmpi.bmiHeader.biHeight = height; 275 bmpi.bmiHeader.biPlanes = 1; 276 bmpi.bmiHeader.biBitCount = 32; 277 bmpi.bmiHeader.biCompression = BI_RGB; 278 279 StretchDIBits( 280 hdc, 0, 0, width * 2, height * 2, 0, 0, width, height, 281 dib, &bmpi, 282 DIB_RGB_COLORS, SRCCOPY 283 ); 284 free(dib); 285 free(image_c); 286 free(image); 287 288 } 289 break; 290 } 291 return DefWindowProc(hwnd, uMsg, wParam, lParam); 292} 293 294double CalcArg(int x, int y) { 295 double arg = atan((double)y / (double)x); 296 297 if (x >= 0)return arg; 298 else { 299 if (y >= 0)return arg + PI; 300 else return arg - PI; 301 } 302}

補足情報

Windows10 Pro
VisualStudio 2017 Community

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

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

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

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

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

guest

回答1

0

ベストアンサー

親ウィンドウにWS_CLIPCHILDRENつけてないから子ウィンドウを上書きしてるんじゃないですかね?

C

1 HWND hwnd = CreateWindowEx( 2 0, CLASS_NAME, L"Title", WS_OVERLAPPEDWINDOW | WSS_CLIPCHILDREN, 3 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 4 NULL, NULL, hInstance, NULL 5 );

投稿2018/10/27 03:36

toki_td

総合スコア2850

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

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

Weapon

2018/10/29 15:53

WS_CLIPCHILDREN使わせていただき上手くいきました. もう少し質問なのですがWS_CLIPCHILDREN自体にはどういう効果があるものなのでしょうか.情報が少し少ないのでお願いします. WM_CHILDで子ウィンドウを設けた場合は基本必須の項目でしょうか?
toki_td

2018/10/29 16:29

WS_CLIPCHILDRENを付けるとウィンドウの描画を開始した時にHDCのクリッピングリージョンから自動的に子ウィンドウの領域が除外されます。 ですので、描画の順番で子ウィンドウを親が上書きしてしまうことがなくなります。 WindowsのGDIは描画の途中が見えてしまう古~~~い設計なので大抵はつけます。 ただ、例えば一昔前の音楽プレーヤーみたいに見た目上複雑な(四角形の集合でない)GUIを作るので子は置くけど透明でWM_PAINTを処理せず、親のWM_PAINTで子を含む全てを描画してしまう場合はWS_CLIPCHILDRENを付けません。 この時、一部の子ウィンドウは子が描画したい、という場合は親の描画が開始した時に描画を行う子だけは自前でクリッピングリージョンから除外してから描画するようにしないといけません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問