なぜCreateHatchBushの設定が途中で喪失するのか

このQ&Aのポイント
  • 縦縞の四角形を表示するプログラムですが、ある一定の四角形を描画すると四角形の中の縦縞がなくなり、白色になります。原因が分かりません。
  • 四角形をマウスドラッグ中に小さくすると黒い線がたくさんでてきますが、これはアプリケーションの仕様です。
  • プロシージャソースはWndProc関数で、WM_PAINTメッセージを処理して縦縞の四角形を描画しています。
回答を見る
  • ベストアンサー

なぜCreateHatchBushの設定が途中で喪失するのか

いつもお世話になります。 縦縞の四角形を表示するプログラムですが、ある一定の四角形を描画すると四角形の中の縦縞がなくなり、白色になります。 原因が分かりません。アドバイスをお願い致します。 (四角形をマウスドラッグ中に小さくすると黒い線がたくさんでてきますが、これはアプリケーションの仕様です) プロシージャソースは以下の通り。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT ps; static POINT start, end; static bool push; switch(msg) { case WM_CREATE: push = false; break; case WM_LBUTTONDOWN: start.x = LOWORD(lParam); start.y = HIWORD(lParam); push = true; break; case WM_MOUSEMOVE: if(push){ end.x = LOWORD(lParam); end.y = HIWORD(lParam); InvalidateRect(hWnd, NULL, FALSE); } break; case WM_LBUTTONUP: end.x = LOWORD(lParam); end.y = HIWORD(lParam); push = false; InvalidateRect(hWnd, NULL, FALSE); break; case WM_PAINT: HBRUSH hBrush; hDC = BeginPaint(hWnd, &ps); hBrush = CreateHatchBrush(HS_VERTICAL, RGB(255, 0, 0)); SelectObject(hDC, hBrush); Rectangle(hDC, start.x, start.y, end.x, end.y); DeleteObject(hBrush); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc(hWnd, msg, wParam, lParam); } よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • Gizensha
  • ベストアンサー率34% (207/608)
回答No.1

SelectObjectしたままDeleteObjectした場合ってきれいに破棄されましたっけ? ここでリソースリークしたせいで、最終的にブラシの生成ができないのかも。 hSukebe=SelectObject(hDC, hBrush); Rectangle(hDC, start.x, start.y, end.x, end.y); SelectObject(hDC, hSukebe); DeleteObject(hBrush); こんなのでどうかな?

oeilvert
質問者

お礼

お返事ありがとうございます。 おっしゃられた通り、SelectObjectでもとの設定に戻してDeleteObjectしたら上手くいきました。

関連するQ&A

  • win32apiでの動画出力

    win32apiとopenCVを使った動画出力プログラムを作りたいのですが, フリーズしてしまいます. 詳しい方,力を貸してください. 以下にプログラムを載せます. LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { int x, y; int id; int c; char* szWndName = "camera capture"; CvCapture* capture; // IplImage* img; switch (msg) { case WM_CREATE: hDC = GetDC( hWnd ); return DefWindowProc(hWnd, msg, wParam, lParam); case WM_COMMAND: switch(LOWORD(wParam)){ case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0L); break; case IDM_USB: capture = cvCaptureFromCAM(0); if(capture == NULL){ MessageBox(hWnd, (LPCTSTR)TEXT("Not camera"), (LPCTSTR)TEXT("Test"), MB_OK); return -1; } while(1){ img = cvQueryFrame(capture); bmpData = (LPDWORD)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, img->width * img->height * 4); iplTobmp(img, bmpInfo, bmpData); StretchDIBits( hDC, 0, 0, img->width, img->height, 0, 0, img->width, img->height, bmpData, &bmpInfo, DIB_RGB_COLORS, SRCCOPY); } ReleaseDC(hWnd, hDC); cvReleaseCapture(&capture); return 0; break; } break; case WM_LBUTTONDOWN: // マウスカーソルが移動したときに送られてくる // 移動先の座標を取得 x = LOWORD( lParam ); y = HIWORD( lParam ); // 座標をテキストファイルに書き込む _ftprintf( g_fp, _T("(%d %d)\n"), x, y ); return 0; case WM_CLOSE: id = MessageBox(hWnd, TEXT("Close?"), TEXT("Close"), MB_OKCANCEL | MB_ICONQUESTION); if(id == IDOK) DestroyWindow(hWnd); return (0L); case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); }

  • TextOut( ) が動かない

    LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ PAINTSTRUCT ps; HDC hdc; switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  break; エスケープキーで文字表示をやりたいけど TextOut( ) が動作していないみたいでした。 switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  hdc = BeginPaint(hWnd, &ps);  TextOut(hdc,0,0,str,strlen(str));  EndPaint(hWnd, &ps);  break; とすると、常に文字が表示されたから、やっぱり case WM_KEYDOWN: の中の TextOut( ) が 動作していないんだと思いました。 TextOut( ) は case WM_PAINT: からのつながりが ある場合でないと実行されないんですか? ソースのおかしいところがあったら教えてください。

  • ソースを見てください。お願いします

    始めまして、Missing0001と申します。 ウィンドウズプログラムをしていて、 他のところは正常に動いているのにMoveWindow関数の場所だけ思うように動きません。 どなたかソースの間違っているところを指摘していただけないでしょうか? したいことはButtonのマウスでの移動です。 BtProc・・・サブクラス(Button)のプロシージャ DrawRect・・・Buttonのサイズの四角形を描いたり消したりするもの LRESULT CALLBACK BtProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { static BOOL Btn_Flag = false; static POINTS end,old_end; char Str[512]; switch(uMsg) { case WM_LBUTTONDOWN: Btn_Flag = true; old_end = MAKEPOINTS(lParam); DrawRect(hWnd,old_end); break; case WM_MOUSEMOVE: if(Btn_Flag) { end = MAKEPOINTS(lParam); DrawRect(hWnd,old_end); DrawRect(hWnd,end); old_end = end; } else { return CallWindowProc(fnBtProc,hWnd,uMsg,wParam,lParam); } break; case WM_LBUTTONUP: if(Btn_Flag) { DrawRect(hWnd,end); MoveWindow(hWnd,end.x,end.y,50,30,true); ←ここがうまくいかない Btn_Flag = false; } else { return CallWindowProc(fnBtProc,hWnd,uMsg,wParam,lParam); } } return CallWindowProc(fnBtProc,hWnd,uMsg,wParam,lParam); }

  • C言語・Windows RECTが渡せない

    C言語のWindowsプログラムで、左クリック後に四角形の描画をしたいのですがうまくいきません。 WM_LBUTTONDOWNイベントで定義したRECT構造体を、別の関数に渡しRectangleで描画したいのですが、その関数内でRECTの値を調べるととんでもない値になっています。 何度やってもどうして値がおかしくなるのかわかりません。 WM_LBUTTONDOWNもWM_PAINTも正常に反応していると思います。 どうか知恵をお貸しくださいm(_ _)m 以下ソースコードのメッセージ処理部分です。 ウィンドウ生成のひな型はサイトの物を丸写しし、正常に動作することを確認しています。 LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rcPos; switch (msg){ case WM_LBUTTONDOWN: rcPos.top =0; rcPos.left =0; rcPos.bottom =100; rcPos.right =100; InvalidateRect(hWnd, &rcPos, FALSE); break; //ウィンドウの描画 case WM_PAINT: hdc = BeginPaint(hWnd, &ps); DrawGr(hWnd, hdc, &rcPos); EndPaint(hWnd, &ps); break; //ウィンドウの削除 case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd, msg, wParam, lParam)); } return (0L); } //描画 int DrawGr(HWND hWnd, HDC hdc, RECT *rcPos) { int i; HBRUSH hBrush, hOldBrush; char *str_org = "rc.top=%d rc.left=%d rc.bottom=%d rc.right=%d"; char strx[256]; //四角形 hBrush = CreateSolidBrush(RGB(100, 100, 255)); hOldBrush = (HBRUSH)SelectObject(hdc, hBrush); //デバッグ用 wsprintf((LPSTR)strx, (LPCSTR)str_org, rcPos->top, rcPos->left, rcPos->bottom, rcPos->right); MessageBox(hWnd, (LPCSTR)strx, (LPCSTR)"終了確認", MB_OKCANCEL | MB_ICONQUESTION); Rectangle(hdc, rcPos->left, rcPos->top, rcPos->right, rcPos->bottom); SelectObject(hdc, hOldBrush); DeleteObject(hBrush); return 0; }

  • なぜhButton1ボタンからのWM_COMMANDはフックできてクライアントエリアのWM_RBUTTONDOWNはフックできないのでしょうか?

    #define STRLBUTTON TEXT("マウス左ボタンが押されました from mainProc") #define STRRBUTTON TEXT("マウス右ボタンが押されました from my_HookProc") #define STRCOMMAND TEXT("ボタンが押されました") HWND hButton1; LRESULT CALLBACK my_HookProc(int nCode, WPARAM wParam, LPARAM lParam) { CWPRETSTRUCT *pcwpRetStruct = (CWPRETSTRUCT *)lParam; HDC hDC; if(nCode==HC_ACTION) { hDC = GetDC(pcwpRetStruct->hwnd); switch(pcwpRetStruct->message) { case WM_COMMAND: TextOut(hDC, 10, 10, STRCOMMAND, strlen(STRCOMMAND)); break; case WM_RBUTTONDOWN: TextOut(hDC, 10, 10, STRRBUTTON, strlen(STRRBUTTON)); break; } ReleaseDC(pcwpRetStruct->hwnd, hDC); } return CallNextHookEx(NULL, nCode, wParam, lParam); } LRESULT CALLBACK mainProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static HHOOK hHook; HDC hDC; switch(uMsg) { case WM_DESTROY: UnhookWindowsHookEx(hHook); PostQuitMessage(0); return 0; case WM_CREATE: hHook = SetWindowsHookEx(WH_CALLWNDPROCRET, my_HookProc, NULL, GetCurrentThreadId() ); if(!hHook) MessageBox(NULL, "hooking failed", NULL, MB_OK); hButton1 = CreateWindow( "BUTTON", "hButton1", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, 10, 40, 100, 20, hWnd, NULL, ((LPCREATESTRUCT)lParam)->hInstance, NULL ); return 0; case WM_LBUTTONDOWN: hDC = GetDC(hWnd); TextOut(hDC, 10, 10, STRLBUTTON, strlen(STRLBUTTON)); ReleaseDC(hWnd, hDC); return 0; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }

  • 変数の値の確認方法について

    Visual Studio 2010 Express WIN32 ユニコードビルド C言語 でプログラムを勉強中なのですがデバッグ中の変数の値の確認の仕方でわからないことがあります。 下のようなプログラムを作りx=HIWORD(lParam)*2;の次の行にブレークポイントを設定しました。 この式に*2がなければxを確認すればすむ話なのですが右辺に複数の値がある場合はHIWORD(lParam)の値が確認できません。 ブレークポイントで止まった時に(lParam)の上にカーソルを移動すると32637974と表示されxの上では996と表示されました。 たぶん右側はlParamの上位ワードを取り出す前の値が表示されているのだと思います。 HIWORD(lParam)の値を事前に変数に代入していない状態で、デバッグ中に上位ワード取り出し後のlParamの値を確認する方法がありましたら教えてください。(例えばxが496でHIWORD(lParam)が32506902と表示される場合に、右のHIWORD(lParam)の上にマウスを移動すると496と表示されるようにする方法) LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) { static int x; switch(message){ case WM_CREATE: break; case WM_SIZE: x=HIWORD(lParam)*2; break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd,message,wParam,lParam); } return 0; }

  • CTreeCtrlのCreate関数でエラーになります。

    Visual C++ .NET Win32 プロジェクト で、アプリケーションを作成しようと思っています。 #include<afxwin.h> #include<afxcmn.h> // マルチスレッド CTreeCtrl *m_TreeCtrl; LRESULT CALLBACK int WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: m_TreeCtrl=new CTreeCtrl; m_TreeCtrl->Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_DISABLEDRAGDROP, CRect(10, 10, 300, 100), CWnd::FromHandle(hWnd), 10000); break; case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: HDC hDC; PAINTSTRUCT Paint; hDC=BeginPaint(hWnd,&Paint); EndPaint(hWnd,&Paint); } return DefWindowProc(hWnd,message,wParam,lParam); } ・・・ と記述すると、エラーになります。 解決方法を教えてください。

  • ウィンドウが表示されない

    あるサンプルプログラムを改造しようとしているのですが、g_hWnd=CreateWindow( _T(__FILE__),_T("シューティングゲーム"),WINDOW_STYLE, CW_USEDEFAULT,CW_USEDEFAULT,rc.right-rc.left,rc.bottom-rc.top, NULL,NULL,hInst,NULL);のところのWINDOW_STYLEをWS_OVERLAPPEDWINDOWに変えたらウィンドウが表示されません。どうしたら表示されるのでしょうか。わかる方いらいしたらご教授お願いします。多分ここだろうなというところのコードを載せます。 LRESULT CALLBACK MainWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { switch(msg) { case WM_KEYDOWN: switch(wParam) { case VK_F1: ChangeDisplayMode(); return 0; case VK_ESCAPE: PostMessage(hWnd,WM_CLOSE,0,0); return 0; } return 0; case WM_DISPLAYCHANGE: // IDirect3DDevice9::Reset メソッドから Send される DisplayChange(); return 0; case WM_SIZE: if(g_bWndMode==false || wParam==SIZE_MINIMIZED) return 0; g_D3DPP.BackBufferWidth = LOWORD(lParam); g_D3DPP.BackBufferHeight = HIWORD(lParam); if(wParam==SIZE_MAXIMIZED || wParam==SIZE_RESTORED) ChangeWindowSize(); return 0; case WM_ACTIVATE: g_bActive=(LOWORD(wParam)!=WA_INACTIVE); return 0; case WM_DESTROY: CleanupD3DObject(); CleanupDXGraphics(); PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,msg,wParam,lParam); }

  • ウィンドウをつまんで動かしたい

    POPUP,TOPMOST属性のウィンドウにボタンを貼り付けたタイマーを作っています。ボタン以外の場所をクリック&ドラッグすることでウィンドウを自由に移動できるようにしたくて以下の様にコードを書いたのですが上手く動きません。 case WM_LBUTTONDOWN: SetCapture(hwnd); mPrevXPos = LOWORD(lParam); mPrevYPos = HIWORD(lParam); return 0; case WM_LBUTTONUP: ReleaseCapture(); return 0; case WM_MOUSEMOVE: if(wParam & MK_LBUTTON) { MoveX = LOWORD(lParam)-mPrevXPos+wPrevXPos; MoveY = HIWORD(lParam)-mPrevYPos+wPrevYPos; if(MoveX<0) MoveX=0; if(MoveY<0) MoveY=0; MoveWindow(hwnd,MoveX,MoveY,WIHDOW_WIDTH,WINDOW_HEIGHT,TRUE); } return 0; case WM_MOVE: wPrevXPos = LOWORD(lParam); wPrevYPos = HIWORD(lParam); return 0; このようにしてウィンドウの左のほうを掴んで左方向にくいっと動かすとウィンドウが消滅してしまいます。MoveWindow関数はTRUEを返しています。SetCaptureを外すとウィンドウは消滅しなくなるので、マウス座標にマイナスの値が入るのがイケナイようなのですがどうすればよいのか分かりません。またMoveWindow関数にマイナスの座標が入ってもウィンドウが消えてしまうためスクリーンの左隅でストップするようにしてますが、この制約も取り除きたいのですがどうすればよいでしょう?

  • wsprintf( ) でポインタに代入

    wsprintf(p, "%d" , i); を書いたせいで、i の値が変わります。 wsprintf(p, "%d" , i); によってどんなことが起こっているのか詳しく知りたいです。 ポインタのことがまだよく分かってないんです。 #include <windows.h> LPCSTR szStr = "\n char c[255];\n char *p = \"\\0\";\n int i = 12345;\n\n switch (msg){\n case WM_LBUTTONDOWN:\n  wsprintf(c, \"%d\" , i);\n  wsprintf(p, \"%d\" , i);\n  MessageBox(hWnd , c , \"\" , MB_OK);\n break;"; LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM); int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE , LPSTR , int){ 省略 return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wParam , LPARAM lParam){ HDC hDC; PAINTSTRUCT ps; RECT rt; char c[255]; char *p = "\0"; int i = 12345; switch (msg){ case WM_LBUTTONDOWN: wsprintf(c, "%d" , i); wsprintf(p, "%d" , i); MessageBox(hWnd , c , "" , MB_OK); break; case WM_PAINT: GetClientRect(hWnd, &rt); hDC = BeginPaint(hWnd, &ps); DrawText(hDC, szStr, lstrlen(szStr), &rt, DT_WORDBREAK); EndPaint(hWnd, &ps); break; case WM_DESTROY: PostQuitMessage(0); break; default: return(DefWindowProc(hWnd , msg , wParam , lParam)); } return (0L); }

専門家に質問してみよう