みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ダイアログボックス・・・・・ bySDK

現在SDKにて画像処理ソフトを作成しています。もちろん個人にて。
そこで確実にほしい機能”ヒストグラム”の表示を行おうと思ったのですが、問題が起こりました。

目的は”2値化"という処理に伴い、ダイアログボックスに入力した画像のヒストグラムを表示させたいということです。
もちろんヒストグラムは単に白黒だけで表示させたいと思っています。

問題というのはダイアログボックスに任意の図形をどのように描画するかです。ビットマップの描画は以前行ったことがあるのですが、任意の図形は行ったことがありませんでした。

試しに、ダイアログボックスにPicture Controlを貼り付け、そのPicture ControlのデバイスコンテキストをGetDCにより無理やり取得し、そのデバイスコンテキストに直線などの描画を行ってみましたが、表示はされませんでした。(あたりまえかも・・・・)


そこでまず、ダイアログボックスに使用するコントロール類は何を設定したらよいか?
そして、そのコントロールから取得したデバイスコンテキストに直接描画は可能か?

これらの質問に答えられる方はアドバイスをお願いしたいと思います。
よろしくお願いします。

投稿日時 - 2007-05-07 12:25:43

QNo.2980262

すぐに回答ほしいです

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

★最初に『点線』とはフォーカスを意味しています。
・このフォーカスだけを上手く消す方法は簡単ではありません。
 ボタンでも押されるとフォーカスが移り、点線が表示されます。これと同じ。
 これを表示しないようにするには、やはりオーナードローでフォーカス時に
 点線を描画しなければ良いことになります。でも、スライダーコントロールも
 オーナードローするのは大変です。
・そこで提案。
 (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
 などとしておくと分かりやすいかも。
・以上。参考に!→上手くいかないときは次の回答でサンプルを載せます。

参考URL:http://wisdom.sakura.ne.jp/system/winapi/win32/win64.html

投稿日時 - 2007-05-08 01:15:53

お礼

長々と丁寧な解説ありがとうございました。

以前にサブクラス化を行ったことがあるので、この解説を参考に完成させることができると思います。

もし何か問題がありましたら、そのときはよろしくお願いします。

投稿日時 - 2007-05-08 02:13:54

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

★追記。
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;

参考URL:http://www.kumei.ne.jp/c_lang/sdk/sdk_60.htm

投稿日時 - 2007-05-07 15:24:55

補足

返答ありがとうございました。

早速オーナードローでやってみたところ、作成することに成功しました。

ありがとうございました^^

ついでに1つ聴いてもよいでしょうか?
ダイアログボックスにスライダーをつけているのですが、プログラムを実行しダイアログボックスを開き、スライダーを操作すると、スライダー自体が選択されたように点線で囲まれてしまいます。
実際これがなければいいのですが、どのように削除するかわかりません。
もしお知りになられるなら、削除する方法を教えていただきたいです。

投稿日時 - 2007-05-07 18:52:14

ANo.1

★サブクラス化か、オーナードロー描画を行う。
・コントロールには独自のプロシージャがあるためその関数ルーチンで WM_PAINT の
 処理から毎回消されます。よって、無理やりデバイスコンテキストを取得して描画
 しても駄目です。コントロール(Picture Control)をサブクラス化してその WM_PAINT
 で描画するか、コントロール(Picture Control)をオーナードローに設定します。
・オーナードローにするとオーナー(ダイアログ)のプロシージャで描画を記述できます。
 この方法ならサブクラス化しないですむのでお勧めです。
・オーナードローの場合は WM_DRAWITEM メッセージを処理します。
 ここに描画を記述します。
・下の『参考URL』をどうぞ。これはボタンですが他のコントロールも同じ考えです。
 あとコントロール(Picture Control)にはオーナードロー描画のフラグをダイアログの
 エディタでチェックしておくこと。
・以上。参考に!

参考URL:http://www.kumei.ne.jp/c_lang/sdk/sdk_41.htm

投稿日時 - 2007-05-07 12:38:14

あなたにオススメの質問