回答編集履歴

2

誤字修正

2019/01/13 12:27

投稿

dodox86
dodox86

スコア9183

test CHANGED
@@ -242,7 +242,7 @@
242
242
 
243
243
 
244
244
 
245
- これについてはご質問の範囲を逸脱するように思うのであまり詳細はべられませんが、もともとのMCIのウィンドウの動作に依存するので制御には限界があると思います。ちらつきの原因はウィンドウサイズの変更中に`WM_PAINT`メッセージが発生し、子ウィンドウの再描画が連続して発生しているのだと考えられます。上記サンプルコードではウィンドウのサイズ変更中に受信する`WM_SIZING`メッセージを無視するかたちにして再描画させないようにしてみたので、試してみて、ご自分でも対応を考えてみてください。
245
+ これについてはご質問の範囲を逸脱するように思うのであまり詳細はべられませんが、もともとのMCIのウィンドウの動作に依存するので制御には限界があると思います。ちらつきの原因はウィンドウサイズの変更中に`WM_PAINT`メッセージが発生し、子ウィンドウの再描画が連続して発生しているのだと考えられます。上記サンプルコードではウィンドウのサイズ変更中に受信する`WM_SIZING`メッセージを無視するかたちにして再描画させないようにしてみたので、試してみて、ご自分でも対応を考えてみてください。
246
246
 
247
247
 
248
248
 

1

サンプルコードを追記

2019/01/13 12:27

投稿

dodox86
dodox86

スコア9183

test CHANGED
@@ -47,3 +47,203 @@
47
47
  尚、上記コードを実行すると以下のようなウィンドウが出てtest.wmvを再生します。
48
48
 
49
49
  ![実行例](971ed3440789729cd9e7714ed23c2ebd.png)
50
+
51
+
52
+
53
+ ---
54
+
55
+ **コメントを受けて追記:2019/01/13 21:21**
56
+
57
+
58
+
59
+ > MCIウィンドウを閉じてもプログラムが終了していないようです(リビルドするとデバッグを中止しますか?というメッセージが出る)。
60
+
61
+
62
+
63
+ `ShowWindow`を無効にしても`CreateWindow`で作成したウィンドウは生きていて、かつメッセージループがあるからです。そのウィンドウも終了させないとプログラムは正しく終了しません`MCIWndCreate`で作成したウィンドウの終了を検知して、アプリケーション(=`WinMain`)全体を終了するようなかたちにしなければなりません。
64
+
65
+
66
+
67
+ ご質問内容と主旨からすると今回はあくまでMCIウィンドウだけ使いたい、とのことだと思いましたので、メインウィンドウとしてMCIのウィンドウのみを使う方法をサンプルとして提示させていただきたいと思います。
68
+
69
+
70
+
71
+ 他サイト様のサンプルコードなどを見てみると`MCIWndCreate`で作成したウィンドウをメインにするようなものは見当たらず、主に子ウィンドウとして使うことが多いようでしたので、あまり一般的なコードではないかもしれないことをご承知おきください。
72
+
73
+
74
+
75
+ 通常ですと`MCIWndCreate`で作成したウィンドウはそれ自体で閉じていて、`WM_...`メッセージをハンドリングすることはできません。そこで「ウィンドウのサブクラス化」を利用し、既定のMCIウィンドウのプロシージャに割り込んで`WM_...`メッセージを横取りします。尚、32ビットと64ビットそれぞれでビルドすることでどちらも動作します。
76
+
77
+ ```C
78
+
79
+ #include <Windows.h>
80
+
81
+ #include <Vfw.h>
82
+
83
+ #pragma comment(lib, "vfw32.lib")
84
+
85
+
86
+
87
+ static LRESULT CALLBACK SubclassWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
88
+
89
+
90
+
91
+ static HINSTANCE g_hInstance = NULL;
92
+
93
+
94
+
95
+ static WNDPROC g_PrevWndProc = NULL;
96
+
97
+
98
+
99
+ int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow)
100
+
101
+ {
102
+
103
+ UNREFERENCED_PARAMETER(hPrevInst);
104
+
105
+ UNREFERENCED_PARAMETER(lpsCmdLine);
106
+
107
+ UNREFERENCED_PARAMETER(nCmdShow);
108
+
109
+
110
+
111
+ g_hInstance = hCurInst;
112
+
113
+
114
+
115
+ HWND hWnd = MCIWndCreate(
116
+
117
+ NULL,
118
+
119
+ g_hInstance,
120
+
121
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE | MCIWNDF_SHOWPOS | MCIWNDF_SHOWMODE | MCIWNDF_SHOWNAME,
122
+
123
+ TEXT("D:/project/test.wmv")
124
+
125
+ );
126
+
127
+
128
+
129
+ if (hWnd != NULL) {
130
+
131
+ // サブクラス化して、自ウィンドウプロシージャ内でメッセージをハンドリングできるようにする。
132
+
133
+ TCHAR szClassName[256];
134
+
135
+ GetClassName(hWnd, szClassName, _countof(szClassName));
136
+
137
+ #ifdef _WIN64
138
+
139
+ g_PrevWndProc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_WNDPROC);
140
+
141
+ SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)SubclassWndProc);
142
+
143
+ #else
144
+
145
+ g_PrevWndProc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(hWnd, GWL_WNDPROC);
146
+
147
+ SetWindowLongPtr(hWnd, GWL_WNDPROC, (LONG_PTR)SubclassWndProc);
148
+
149
+ #endif
150
+
151
+
152
+
153
+ if (MCIWndCanPlay(hWnd)) {
154
+
155
+ MCIWndPlay(hWnd);
156
+
157
+ }
158
+
159
+ else {
160
+
161
+ MessageBox(NULL, TEXT("Unable to play"), TEXT("ERROR"), MB_OK);
162
+
163
+ }
164
+
165
+ }
166
+
167
+
168
+
169
+ MSG msg;
170
+
171
+ BOOL bRet;
172
+
173
+ while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
174
+
175
+ if (bRet == -1) {
176
+
177
+ break;
178
+
179
+ }
180
+
181
+ else {
182
+
183
+ TranslateMessage(&msg);
184
+
185
+ DispatchMessage(&msg);
186
+
187
+ }
188
+
189
+ }
190
+
191
+ return (int)msg.wParam;
192
+
193
+ }
194
+
195
+
196
+
197
+ static LRESULT CALLBACK SubclassWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
198
+
199
+ {
200
+
201
+ LRESULT lResult = 0;
202
+
203
+ switch (msg) {
204
+
205
+ case WM_SIZING:
206
+
207
+ // ウィンドウサイズ変更中は無視する
208
+
209
+ break;
210
+
211
+
212
+
213
+ case WM_DESTROY:
214
+
215
+ // WM_DESTROYだけハンドリングする - 自分のメッセージループを抜ける
216
+
217
+ PostQuitMessage(0);
218
+
219
+ break;
220
+
221
+
222
+
223
+ default:
224
+
225
+ // その他のWindowメッセージをデフォルトのウィンドウプロシージャに任せる
226
+
227
+ lResult = CallWindowProc(g_PrevWndProc, hWnd, msg, wParam, lParam);
228
+
229
+ break;
230
+
231
+ }
232
+
233
+ return lResult;
234
+
235
+ }
236
+
237
+ ```
238
+
239
+
240
+
241
+ > それとMCIウィンドウのウィンドウサイズを変更した時に再生ボタンの辺りがすごくちらつくようになりました。
242
+
243
+
244
+
245
+ これについてはご質問の範囲を逸脱するように思うのであまり詳細は延べられませんが、もともとのMCIのウィンドウの動作に依存するので制御には限界があると思います。ちらつきの原因はウィンドウサイズの変更中に`WM_PAINT`メッセージが発生し、子ウィンドウの再描画が連続して発生しているのだと考えられます。上記サンプルコードではウィンドウのサイズ変更中に受信する`WM_SIZING`メッセージを無視するかたちにして再描画させないようにしてみたので、試してみて、ご自分でも対応を考えてみてください。
246
+
247
+
248
+
249
+ 基本的にはMCIのウィンドウを使う限りにおいて既定の動きを許容するしかないと思うので、それを踏まえて実装していく必要があると思います。そもそもですが、上記のようにMCIのウィンドウをメインとするよりは子ウィンドウにして制御する方が簡単だと思いますし、タイトルバーに情報が載らなくなるのは仕方ありません。もちろん上記のサブクラス化が最良だ、と言う訳ではなく、質問者さんの要望するアプリケーションのかたちで解決法は変わってくると思うので、その点もお含みおきください。今回はあくまで「タイトルバーに`MCIWNDF_SHOWPOS`で指定した情報を載せたい」が主眼です。