- ベストアンサー
ダイアログボックスでの画像処理ソフト開発におけるヒストグラム表示の問題と解決方法
- SDKを使用して画像処理ソフトを開発しているが、ダイアログボックスに入力した画像のヒストグラムを表示する際に問題が発生している。
- ヒストグラムは単に白黒で表示させたいが、任意の図形の描画方法が不明。
- コントロールの設定やデバイスコンテキストの取得方法についてアドバイスが欲しい。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
★最初に『点線』とはフォーカスを意味しています。 ・このフォーカスだけを上手く消す方法は簡単ではありません。 ボタンでも押されるとフォーカスが移り、点線が表示されます。これと同じ。 これを表示しないようにするには、やはりオーナードローでフォーカス時に 点線を描画しなければ良いことになります。でも、スライダーコントロールも オーナードローするのは大変です。 ・そこで提案。 (1)スライダーコントロールをサブクラス化します。 (2)サブクラス化したコントロールの新しいプロシージャで WM_LBUTTONUP を処理します。 (3)処理内容は WM_LBUTTONUP の時、コントロールの ID を親のプロシージャへ発行します。 (4)発行は WM_COMMAND メッセージを使ってコントロールの ID を送ります。 PostMessage( hDlg, WM_COMMAND, MAKEWPARAM(nID,0), (LPARAM)hFocus ); hDlg⇒ダイアログのウインドウハンドル hWnd⇒コントロールのウインドウハンドル nID⇒コントロールのID(GetDlgCtrlID(hWnd) で取得可能) hFocus⇒NULLか、ボタンなどの他のコントロールのウインドウハンドル (5)親のダイアログ・プロシージャの WM_COMMAND でスライダーコントロールの ID は SetFocus( NULL ); または SetFocus( (HWND)lParam ); とフォーカスを無くすように記述します。 ※これでスライダーコントロールをドラッグ移動後は、点線が表示されなくなります。 ただしドラッグ移動中は、どうしてもフォーカスを示す点線が表示されてしまいます。 コントロールの仕組み上、移動中の点線は描画されます。移動後にフォーカスを別の コントロールに移すことで点線を残さないというアイディアです。 ・サブクラス化は、GetWindowLong、SetWindowLong、CallWindowProc 関数を利用します。 下の『参考URL』をどうぞ。 ・親のダイアログ・プロシージャの WM_COMMAND だけ載せます。 case WM_COMMAND: switch ( LOWORD(wParam) ){ case IDC_BUTTON1: 他のボタン1の処理 break; case IDC_BUTTON2: 他のボタン2の処理 break; : case IDC_SLIDER1: break; ←特に処理しなくて良い。 case IDC_SLIDER2: break; 理由:SetFocus( (HWND)lParam );を下でまとめて処理するから。 case IDC_SLIDER3: break; default:return FALSE; } SetFocus( (HWND)lParam ); break; ・上記の WM_COMMAND で IDC_SLIDER1 ~ IDC_SLIDER3 を追加します。 あとはサブクラス化したコントロールの新しいプロシージャ関数を作るだけです。 関数名は自由と思いますが、 元のプロシージャ名を DefSliderProc、 新しいプロシージャ名を NewSliderProc などとしておくと分かりやすいかも。 ・以上。参考に!→上手くいかないときは次の回答でサンプルを載せます。
その他の回答 (2)
- Oh-Orange
- ベストアンサー率63% (854/1345)
★追記。 ・http://www.kumei.ne.jp/c_lang/sdk/sdk_60.htm→『第60章 ステータスバーを作る その4』 こちらのリンクの方がオーナードローが分かりやすいかな。 その他、オーナードロー、WM_DRAWITEM メッセージや、DRAWITEMSTRUCT 構造体でネット検索すると いろいろなサンプルが見つかります。 ・以上。 typedef struct tagDRAWITEMSTRUCT { UINT CtlType; UINT CtlID; ←コントロールのID(Picture ControlのID) UINT itemID; UINT itemAction; UINT itemState; HWND hwndItem; HDC hDC; ←デバイスコンテキストのハンドル(描画時はこれを使う、GetDCしなくて良い) RECT rcItem; DWORD itemData; } DRAWITEMSTRUCT;
補足
返答ありがとうございました。 早速オーナードローでやってみたところ、作成することに成功しました。 ありがとうございました^^ ついでに1つ聴いてもよいでしょうか? ダイアログボックスにスライダーをつけているのですが、プログラムを実行しダイアログボックスを開き、スライダーを操作すると、スライダー自体が選択されたように点線で囲まれてしまいます。 実際これがなければいいのですが、どのように削除するかわかりません。 もしお知りになられるなら、削除する方法を教えていただきたいです。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★サブクラス化か、オーナードロー描画を行う。 ・コントロールには独自のプロシージャがあるためその関数ルーチンで WM_PAINT の 処理から毎回消されます。よって、無理やりデバイスコンテキストを取得して描画 しても駄目です。コントロール(Picture Control)をサブクラス化してその WM_PAINT で描画するか、コントロール(Picture Control)をオーナードローに設定します。 ・オーナードローにするとオーナー(ダイアログ)のプロシージャで描画を記述できます。 この方法ならサブクラス化しないですむのでお勧めです。 ・オーナードローの場合は WM_DRAWITEM メッセージを処理します。 ここに描画を記述します。 ・下の『参考URL』をどうぞ。これはボタンですが他のコントロールも同じ考えです。 あとコントロール(Picture Control)にはオーナードロー描画のフラグをダイアログの エディタでチェックしておくこと。 ・以上。参考に!
お礼
長々と丁寧な解説ありがとうございました。 以前にサブクラス化を行ったことがあるので、この解説を参考に完成させることができると思います。 もし何か問題がありましたら、そのときはよろしくお願いします。