ab.com コミュニティ https://www.activebasic.com/forum/ |
|
イメージボックスへのビットマップの表示について https://www.activebasic.com/forum/viewtopic.php?t=2560 |
ページ 1 / 1 |
作成者: | jacoby [ 2009年4月03日(金) 20:34 ] |
記事の件名: | イメージボックスへのビットマップの表示について |
メイン・ウインドウ上の"イメージ・ボックス"(=ビットマップ表示スタイルを持つ スタティック・コントロール)を一つ配置して、そこにファイルからビットマップをロードして 表示させたいと思い、下のようにプログラムを書いきました。 結果的に、ビットマップの表示自体は出来たのですが、ただしロード後、 そのイメージボックスの大きさに合わせてビットマップ画像が拡大縮小されてしまう という現象に気付きました。これを何とかヤメにして実大のまま表示させたいと、 「SS_REALSIZEIMAGE」というものを見つけてスタイルとしてセットしたのですが しかしこれが効果なく、依然として画像が拡大縮小されてしまいます。 (※該当箇所、下プログラム中「'●ビットマップファイルの読み込み」内。 "And Not(SS_GRAYRECT)"とあるのは、ビットマップ画像を貼り付ける前に 「灰色ボックス」としてスタイル設定をしていたのを外すためだけの意味です。) コード: SetWindowLong(hImageBox1,GWL_STYLE, _ (GetWindowLong(hImageBox1,GWL_STYLE) _ And Not(SS_GRAYRECT)) _ Or SS_BITMAP Or SS_REALSIZEIMAGE) SendDlgItemMessage(hMainWnd,ImageBox1, _ STM_SETIMAGE,IMAGE_BITMAP,hBmp)ビットマップ画像を実寸でそのままイメージボックスに表示させるには、どのように するべきでしょうか? ここにソースが表示されます [ここをクリックすると内容が表示されます]
プログラムの主な流れは、コード: '----------------------------------------------------------------------------- ' イベント プロシージャ '----------------------------------------------------------------------------- ' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。 ' ウィンドウ ハンドル: hMainWnd ' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。 'ビットマップ表示・スタティックコントロール用 Const ImageBox1=2000 Dim hImageBox1 As HWND 'ロードしたビットマップ・ハンドル Dim hBmp As HBITMAP 'ロードしたビットマップのファイル・パス保存用 Dim fileName_fullPath[MAX_PATH] As Byte '----------------------------------------------------------------------------- ' ウィンドウメッセージを処理するためのコールバック関数 Function MainWndProc(hWnd As HWND, dwMsg As DWord, wParam As WPARAM, lParam As LPARAM) As DWord ' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。 ' イベントプロシージャの呼び出しを行います。 MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam) End Function '----------------------------------------------------------------------------- ' ここから下は、イベントプロシージャを記述するための領域になります。 ' '●デストロイ・イベント ' Sub MainWnd_Destroy() DeleteObject(hBmp) ImageBoxTest_DestroyObjects() PostQuitMessage(0) End Sub ' '●クリエイト・イベント ' Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT) 'とりあえず初めの何もない状態の時は、 '灰色ボックス(「SS_GRAYRECT」)の 'スタティックコントロールを作成。 hImageBox1=CreateWindowEx(WS_EX_CLIENTEDGE,"STATIC","", _ WS_CHILD Or WS_VISIBLE Or SS_GRAYRECT,_ 0,0,0,0,hMainWnd,ImageBox1,GetModuleHandle(0),0) End Sub ' '●リサイズ・イベント ' Sub MainWnd_Resize(SizeType As Long, cx As Integer, cy As Integer) 'ビットマップ・スタティックコントロールを '親ウインドウの大きさに合わせてリサイズ。 SetWindowPos(hImageBox1,NULL,0,0,cx,cy,SWP_NOMOVE Or SWP_NOZORDER) End Sub ' '●ビットマップファイルの読み込み ' Sub MainWnd_IDM_OPEN_FILE_MenuClick() 'OpenFileDialogを開き、 'ファイルのパスを得る(→ fileName_fullPath)。 If LoadBitMap_OpenFileDialog()<>FALSE Then 'ビットマップをファイルから読み込む。 hBmp=LoadImage(GetWindowLong(hMainWnd, GWL_HINSTANCE), fileName_fullPath, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE) 'ウインドウスタイルの灰色ボックスを外し '(「And Not(SS_GRAYRECT))」)、 'ビットマップ表示(「Or SS_BITMAP」)に変更。 '同時に「Or SS_REALSIZEIMAGE」として 'ビットマップをウインドウサイズに合わせて '拡大縮小しないように設定。 '…ところがこれが上手く行われない。 '相変わらずビットマップがウインドウに合わせて '拡大縮小されて表示される。 SetWindowLong(hImageBox1,GWL_STYLE,(GetWindowLong(hImageBox1,GWL_STYLE) And Not(SS_GRAYRECT)) Or SS_BITMAP Or SS_REALSIZEIMAGE) SendDlgItemMessage(hMainWnd,ImageBox1,STM_SETIMAGE,IMAGE_BITMAP,hBmp) '親ウインドウのクライアントエリアに合わせて 'スタティック・コントロール(=イメージ・ボックス)の '大きさを変える。 Dim clientRect As RECT GetClientRect(hMainWnd,clientRect) SetWindowPos(hImageBox1,NULL,0,0,clientRect.right,clientRect.bottom, SWP_NOZORDER) End If End Sub ' '●OpenFileDialogを開く(Bitmapファイル・ロード時) ' Function LoadBitMap_OpenFileDialog() As Long Dim ofn As OPENFILENAME 'OPENFILENAME構造体の初期化 FillMemory(VarPtr(ofn),SizeOf(OPENFILENAME),0) ofn.lStructSize=SizeOf(OPENFILENAME) ofn.hwndOwner=hMainWnd ofn.lpstrFilter=Ex"ビットマップ・ファイル(*.bmp)\0*.bmp\0すべてのファイル(*.*)\0*.*\0\0" ofn.nFilterIndex=1 ofn.lpstrFile=fileName_fullPath ofn.nMaxFile=MAX_PATH ofn.lpstrFileTitle=NULL ofn.nMaxFileTitle=MAX_PATH ofn.lpstrTitle="ビットマップ・ファイルを開く" ofn.Flags=OFN_FILEMUSTEXIST Or OFN_HIDEREADONLY Or OFN_PATHMUSTEXIST Or OFN_OVERWRITEPROMPT Or OFN_NOREADONLYRETURN ofn.lpstrDefExt="bmp" ofn.lpstrInitialDir=NULL '「ファイルの保存」ダイアログ ボックスを表示 LoadBitMap_OpenFileDialog=GetOpenFileName(ofn) End Function まず「●クリエイト・イベント / MainWnd_Create()」で イメージ・ボックスの作成、 それからメインメニューの「ファイルを開く」から 「●ビットマップファイルの読み込み / MainWnd_IDM_OPEN_FILE_MenuClick()」へ飛び、 そこでビットマップをイメージボックスに貼り付けるとなっています。 |
作成者: | イグトランス [ 2009年4月05日(日) 21:23 ] |
記事の件名: | |
私が調べた限り、SS_REALSIZEIMAGEは逆にイメージボックスに合わせて画像を拡大縮小するというもののようです。それと、このプログラムでは親ウィンドウの大きさに合わせるということを行っていますが、それもやめたほうがよいと思います。 というわけで、1つ目のSetWindowLongをSetWindowLong(hImageBox1, GWL_STYLE, (GetWindowLong(hImageBox1, GWL_STYLE) And Not(SS_GRAYRECT)) Or SS_BITMAP)にして、SetWindowPosは削除するということでどうでしょうか。 また、そうすると表示が乱れることがあったので、STM_SETIMAGEを送った後、End Ifの直前でInvalidateRect(hImageBox1, ByVal 0, FALSE)を入れました。 これで、原寸大で表示されるようになりました。 |
作成者: | jacoby [ 2009年4月07日(火) 07:42 ] |
記事の件名: | レス有難うございます。 |
イグトランスさん、レスありがとうございます。 改めて調べてみると確かに、SS_REALSIZEIMAGEは 引用:
「SS_BITMAP スタイルや SS_ICON スタイルを持つコントロールの
とあります。イメージがロードされたり描画されたりするときに、コントロールサイズが 変更されないようにします。」 また、当初自分の調べたページではこう説明されていました。 引用:
「SS_REALSIZEIMAGE : [リアル サイズ イメージ]
そう言われて改めて読み直すと"イメージを変更しない"とは一言もないですね。SS_BITMAP, SS_ICONでサイズ変更を禁止する.はみ出た分はクリップ. 」 (でもだとすると"はみ出た分はクリップ"としいうのは何を差すのか謎です、、) これは僕の思い違いかもしれません。。。にしても"リアルサイズイメージ"、 悩ましい。。(笑) ただ、親ウインドウに合わせてイメージボックスのサイズを動かしたいという のは是非実装したいところです。それはイメージボックスの画像表示エリアに 「クライアント・エッジ」(WS_EX_CLIENTEDGE)を付けたいということから です。(落ち窪んだスタイルの)。 一番初めに上のプログラムを実行させた時、その時は 「SS_REALSIZEIMAGE」は付けていなかったんですが、画像はきちんと 実大で表示されました。 ところがよく見るとイメージボックスに拡張スタイルとして付けた 「クライアント・エッジ」が右辺と下辺で消えてしまっていたんです。 どこに行ったんだろうとメインウインドウのサイズを大きくしてみると (テストしたその画像はかなり大きなものだったので) ロードした画像に"合わせて"クライアント・エッジが描かれていました。 これは、このコントロールのサイズはセットする画像に合わせて変わるんだと 思い、(ただし、イメージ・ボックスのサイズは親であるメインウインドウの「中」に 無ければ表示上とても不自然になるので)、 そこで画像ロード直後に「SetWindowPos」でサイズを整える処理を 書いたのですが、そうすると今度は画像が拡大縮小されてしまい。。。 ということで今回の質問に至ります。 もっとも今回の質問のプログラムにあるようにメインウインドウのクライアント・ エリア一杯に一枚の画像を表示したいならわざわざイメージ・ボックスを使う 必要も実際無い訳なんですが、将来的にはメインウインドウの クライアントエリアに複数の画像を表示したい。 各画像はいずれも拡大縮小せず、表示領域の大きさからはみ出ても その分は無視して、それぞれに「Windowsによく見られる窪んだエッジ」を 付け、また各表示領域は"メインウインドウの大きさに比例して可変"としたい。 例えばこんな感じで。 ■■■メイン・ウインドウ■■■ ■メイン・ウインドウ■ ■■■■■■■■■■■■■ ■■■■■■■■■ ■□□□□□■□□□□□■ ■□①□■□②□■ ■□画像①□■□画像②□■ ■■■■■■■■■ ■□□□□□■□□□□□■ ■□③□■□④□■ ■■■■■■■■■■■■■ ■■■■■■■■■ ■□□□□□■□□□□□■ ■□画像③□■□画像④□■ ■□□□□□■□□□□□■ ■■■■■■■■■■■■■ 以上のことが実装したいと思ったのです。 そう思ってRADツールをいじってると「イメージ・ボックス」というものを見つけて、 もしかしてこんな場合、これを使うのが"本筋"なのかな、と。 * とにもかくにも、レス頂いた通り、SS_REALSIZEIMAGEを外し、 SetWindowPosを取り、InvalidateRectを挿入したのですが、 やはり「リサイズイベント」に飛んだ瞬間に画像は拡大縮小が行われる ようです。加えて、(もしロードしてきた画像がメインウインドウの サイズよりも大きなもののような場合)「クライアントエッジ」が右辺、下辺で 見えなくなってしまいます。 (と言うか、これこそSS_REALSIZEIMAGEを指定すれば クライアントエッジの位置が動かなくなってもいいように思えるんですが、 仮にSS_REALSIZEIMAGEを指定してもやはりクライアントエッジは 見えなくなるようです。あくまでコントロール・サイズとそのコントロールの中の クライアント・エリア・サイズは別物ということでしょうか?だとしたら SS_REALSIZEIMAGEの存在意義って、ともつい思ってしまいますが。。) ちょっとどうしたもんかと、まだ考えています。 |
ページ 1 / 1 | 全ての表示時間は UTC+09:00 です |
Powered by phpBB® Forum Software © phpBB Limited https://www.phpbb.com/ |