C言語でAPIのプログラミングを行っている者です。
ソースはこちらとなります。
http://onegaisimasune.web.fc2.com/main6.txt
mux2.vはこちらです。
http://onegaisimasune.web.fc2.com/main5.txt
そこで、二つ程今のとこバグがあり、
1つ目は何度かウィンドウ上で左クリックしていると、
23回目くらいの所でウィンドウ上の文字が消えてしまう、
と言う問題と、
2つめはウィンドウを画面の外に追い出すと
ウィンドウ上の文字が消えてしまうというものです。
どこが問題なのか、ご指摘願います。
どうか宜しくお願い致します。
No.4ベストアンサー
- 回答日時:
私が書くとこんな感じでしょうか。
(行数稼ぐ為に括弧とかの対応が少し見辛いかもしれませんが。。)全角スペースでインデントつけてます。
#include <windows.h>
#define WS_WINDOWMODE (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
const char * ApplicationClassName = "WindowsApplication";
const char * WindowTitleName = "WindowTitle";
BOOL bActive = FALSE;
BOOL OnIdle( VOID );
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message ) {
case WM_CREATE:
bActive = TRUE;
break;
case WM_CLOSE:
DestroyWindow( hWnd );
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
case WM_ACTIVATE:
if ( LOWORD( wParam ) == WA_INACTIVE ){
bActive = FALSE;
} else {
bActive = TRUE;
}
break;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
return 0L;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
HWND hWnd;
WNDCLASS wc;
ZeroMemory(&wc, sizeof(WNDCLASS));
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WndProc);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor( hInstance, MAKEINTRESOURCE(IDC_ARROW));
wc.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTIONTEXT);
wc.lpszMenuName = NULL;
wc.lpszClassName = ApplicationClassName;
if(!RegisterClass(&wc)){
MessageBox(NULL,"ウィンドウクラスの登録に失敗しました。",NULL,MB_OK);
return 0;
}
hWnd = CreateWindowEx( NULL, wc.lpszClassName, WindowTitleName, WS_WINDOWMODE,
0, 0, 320, 240, NULL, NULL, wc.hInstance, NULL );
if ( hWnd == NULL )
{
MessageBox(NULL,"ウィンドウの作成に失敗しました。",NULL,MB_OK);
return 1;
}
ShowWindow( hWnd, SW_SHOW );
MSG Msg;
do{
if( PeekMessage( &Msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}else if ( bActive != FALSE ){
if (!OnIdle()){ break; }
}else{
WaitMessage();
}
}while( Msg.message != WM_QUIT );
return Msg.wParam;
}
BOOL OnIdle( VOID )
{
if(GetAsyncKeyState( VK_ESCAPE ) & 0x0001){
return FALSE;
}
return TRUE;
}
殆どのメッセージは戻り値が0なので、戻り値0のものは
breakさせていますが、メッセージに応じて必要な戻り値が
ある場合はそのメッセージの処理後にreturnを入れる感じです。
後は、処理をプロシージャなどに書かず、OnCreateとか適当に
造って処理を分離すると見やすくなると思います
この回答への補足
回答どうもありがとうございます。
これは何のプログラムなのでしょうか?
実行してみましたが、黒いウィンドウが現れるだけでしたが。。
No.5
- 回答日時:
>これは何のプログラムなのでしょうか?
WinMain雛型、スケルトンプログラムと呼ばれるものです。
(ウィンドウを表示するだけのものです)
質問者さんのコードはかなりごちゃごちゃに成りつつあります。
一度、不要な変数、おかしいインデント、不要な関数呼び出し、
などの整理をした上でトレースしていかなければ、バグを特定出来ません。
プロシージャなどの戻り値や、関数の構造はある程度参考に出来ると
思います。また、各メッセージの処理をWndProcの中で書かずに、
関数にしてから、そのメッセージが来たらWndProcから
呼び出すことで、WndProcの肥大化をある程度なくせると思います。
とりあえず、先にバグをつぶすより、コードをクリーンにしてください。そうすれば自ずとおかしい所が、見えてくる場合もあります。
No.3
- 回答日時:
そうですね。
NO.2さんのおっしゃる通りです。case WM_LBUTTONDOWNとcase WM_PAINTが直通していたので、
とりあえずそれを直したく説明していました。
1.最初に描画リソース処理の手直し
2.他のメッセージ処理や、WndProc内の変数定義。(ループ内で使いまわすフォントハンドル等はstaicで定義)
3.更新タイミングの調整。現状はLBUTTONDOWN内で背景描画なしのInalidateRectで、ループを抜けた後の更新になります。
の順で話の確認するつもりでした。
自分で手を入れた流れを勢いで書いたので勘違いしてますね。
×・WM_LBUTTON~の1167行付近の return;もbreak; に変える。(WM_CREATE以外は最後にDefWindowProc()を通すようにする)
○・WM_LBUTTON~の1167行付近の return;もbreak; に変える。(switchの最後にdefault: return(DefWindowProc());を書いて、最終行はreturn 0;にする)
サブクラス化等で用意した処理があるわけではないですし、今のDefWndProcが最後に書かれており、
switchにdefaultがないので、全てreturn 0;で問題ないですね。(戻り値はキー処理等ないので0でいいと思います。)
よろしければWin32SDKのWinMain雛型を貼って指摘して頂けるとありがたいです。
No.2
- 回答日時:
1点気になったことを。
No1さんが
>WM_CREATE以外は最後にDefWindowProc()を通すようにする
と書かれていますが、デフォルトのプロシージャに委託するのは、
メッセージを処理しなかった場合のみです。
通常、メッセージを処理した場合、ウィンドウプロシージャは
処理したメッセージに応じて戻り値を返さなければなりません。
No.1
- 回答日時:
mux2.vについては前の質問の
http://onegaisimasune.web.fc2.com/verilog/mux2.txt を使用しました。
main6.cについて、こちらでも20回ほどクリックしたらで同様の症状が再現しました。
とりあえずざっと見た部分
・case WM_XX~ は最後 break; で終える。今WM_LBUTTON~とWM_PAINT はそのまま繋がって実行されています。
・WM_PAINT もbreak;で終える
・WM_LBUTTON~の1167行付近の return;もbreak; に変える。(WM_CREATE以外は最後にDefWindowProc()を通すようにする)
・hdc と hDCが2種類混在使用してありhDCは値が取得されてない(多分NULL)
*描画ロジックの基本的な組み方 --------------------------------------------------------
// 1.描画オブジェクトの生成
hpen = CreatePen(PS_SOLID , 0 , RGB(100 , 0 , 50));
// 2.描画オブジェクトの選択(このとき従前のオブジェクトを保管する)
hOldbr = (HBRUSH)SelectObject(hdc , CreateHatchBrush(HS_DIAGCROSS , 0xFF));
hOldpen = (HPEN)SelectObject( hdc, hPen );
// 3.出力処理
TextOut(hdc , 30, 300, "hello", sizeof("hello")); // なんらかの出力処理
// 4.描画オブジェクトを戻す(保管してあったもの)
SelectObject( hdc, hOldpen );
SelectObject( hdc, hOldbr );
// 5.Createした描画オブジェクトは消去
DeleteObject(hpen);
※1と5についてはロジックの一番外側でのみ行いキープしていてもよい
--------------------------------------------------------------------------------------
描画が不安定になるのは、描画オブジェクトの生成消去等うまく処理されてないからと思われます。
リソースが不安定になってます。
WM_PAINT内の繰り返し存在する描画部分は、上記のルールに合わせるようにして下さい。
この回答への補足
申し訳ございません、
http://onegaisimasune.web.fc2.com/verilog/mux2.txt
で合っています。
質問文のURLは間違いです。
回答ありがとうございます。
ご指摘の点を修正してまた改めて補足させていただきます。
ありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・【お題】絵本のタイトル
- ・【大喜利】世界最古のコンビニについて知ってる事を教えてください【投稿~10/10(木)】
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Minecraft 統合版(PC)の描画距...
-
エクセルでガンチャートを作成...
-
MFCでOnPaintのタイミング
-
NVIDIAのシェーダーキャッシュ
-
InvalidateRectの使い方について
-
PCで「使用可能な場合はグラフ...
-
google Colabでmatplotlibの描...
-
ドローソフトのダブルバッファ...
-
Androidのスマホについての質問...
-
word
-
OpenCV処理画像をpictureBoxへ。
-
ボタン形のラベル
-
OpenGLのテクスチャマッピング
-
TextBoxに文字を書いても表示さ...
-
Wave波形の描画について
-
OneNote 2010 文字と描画がずれる
-
うまく表示されない。(API・C言...
-
グラフの交点の求め方(Excel)
-
エクセルで作った新しいウイン...
-
コントロールの書式設定で、“コ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB6,リストボックスの特定行の...
-
Minecraft 統合版(PC)の描画距...
-
[VB.net] DataGridViewの列ヘッ...
-
MFCでOnPaintのタイミング
-
TextBoxに文字を書いても表示さ...
-
word
-
NVIDIAのシェーダーキャッシュ
-
InvalidateRectの使い方について
-
UpdateData( FALSE); による文...
-
CStaticコントロールの静的イメ...
-
CScrollViewの使用方法について
-
VB.netでのライン描画方法がわ...
-
VBAにGDI+を参照させる方法
-
この二つの違いは・・・?
-
Form1 Load で実行されない。
-
OneNote 2010 文字と描画がずれる
-
OnDrawが呼び出されません
-
C# ラバーバンドの描画を快適に...
-
コンボボックスの高さを変えたい
-
panelのスクロール表示について
おすすめ情報