今回は、メニューコントロールや「
ファイルを開く」ダイアログボックス、ビットマップ用の
API関数を活用し、ビットマップビューワの作成にチャレンジしてみます。
プロジェクトの作成
ノーマル ウィンドウ
ベースのプロジェクト(プロジェクト名を "BmpViewer" とします)を作成し、メニューの作成(IDは "MainMenu")、メインウィンドウへのメニューの貼り付けを行っておきましょう。
"MainWnd" のプロパティ設定
まずは、ベースとなる "MainWnd" を開き、ウィンドウ プロパティの設定を行います。
背景色のボタンをクリックし、"NULL" に設定しておきます。
メニューを "なし" から "MainMenu" に変更し、"サイズ変更枠" を "細枠" に変更しておきます。今回作るビットマップビューワは、最大化ボタンの使いみちがないため、「最大化ボタン」のチェックもはずしておきましょう。
メニューの編集
"MainMenu" を開き、下のような構成になるよう、メニューの追加を行っていきます。メニュー項目を挿入する場合は、挿入したい場所の1つ上の項目を選択し、「挿入」ボタンをクリックしていくことを思い出しましょう。メニューの編集方法は、ステップ6、ステップ7で解説しています。
キャプション ID 備考
ファイル(&F) - ポップアップ
開く(&O) IDM_OPEN -
終了(&X) IDM_EXIT -
ヘルプ(&H) - ポップアップ
バージョン情報(&A) IDM_ABOUT -
メニュー デザインが完了したら、それぞれのメニューに対するイベント コーディングを行います。
イベント コーディング前の準備
プロジェクト ビューのFileタブから、"MainWnd.sbp" を開き、ファイルの先頭部(「ここから」、「ここまで」の間の部分)に以下の定義文を記述しておきます。これらの変数は
グローバル変数として管理され、プログラム内のあらゆる
プロシージャが参照することができます。
' ----------------------------------ここから----------------------------------
'ビットマップのファイル名
Dim FileName As String
'「開く」ダイアログの拡張子フィルター
Dim BitmapFileFilter As String
BitmapFileFilter = "ビットマップ ファイル(*.bmp)" + Chr$(0) + "*.bmp" + Chr$(0) + _
"すべてのファイル(*.*)" + Chr$(0) + "*" + Chr$(0)
' ----------------------------------ここまで----------------------------------
「開く」メニュー イベント
OPENFILENAME
構造体を定義、初期化したのち、GetOpenFileName関数を呼び出しています。
ユーザーが「キャンセル」ボタンを押したときはプロシージャから抜け出し(Exit Sub)、「開く」ボタンをクリックしたときは、グローバル文字列変数のFileNameにパスをコピーし、InvalidateRect関数で、hMainWndに対して再描画を要求します。このInvalidateRect関数は、後ほどコーディングする
Paintイベントを呼び出し、このPaintイベント内で実際にビットマップの描画が行われる形になります。
Sub MainWnd_IDM_OPEN_MenuClick()
Dim ofn As OPENFILENAME
Dim buffer As String
'ファイル名を取得
ofn.lStructSize=[[Len]](ofn)
ofn.hwndOwner=hMainWnd
ofn.lpstrFilter=[[StrPtr]](BitmapFileFilter)
ofn.nFilterIndex=1
buffer=ZeroString(MAX_PATH)
ofn.lpstrFile=StrPtr(buffer)
ofn.nMaxFile=MAX_PATH
If GetOpenFileName(ofn)=0 Then Exit Sub
FileName=ofn.lpstrFile
'再描画要求を出す
InvalidateRect(hMainWnd,ByVal 0,1)
「終了」メニュー イベント
終了メニューがクリックされると、WM_CLOSEメッセージを送るようにします。WM_CLOSEメッセージは、ウィンドウの「閉じる(×)」ボタンが押されたときに呼び出されるメッセージです。
Sub MainWnd_IDM_EXIT_MenuClick()
SendMessage(hMainWnd,WM_CLOSE,0,0)
End Sub
「バージョン情報」メニュー イベント
ここは単純に、プログラム名とバージョン情報をメッセージボックスを利用して表示します。
Sub MainWnd_IDM_ABOUT_MenuClick()
MessageBox(hMainWnd, "ビットマップ ビューワ Ver1.00","バージョン情報",MB_OK or MB_ICONINFORMATION)
End Sub
"MainWnd" のPaintイベント
"MainWnd" の
RAD画面を開き、ウィンドウ内の適当な場所を右クリックしたのち、「イベント コード」をクリックして「イベント処理」ダイアログを開きます。ここでPaintイベントを選択し、「コーディング」ボタンをクリックします。下のコードがPaintイベント プロシージャになります。
まずは、LoadImage関数でFileNameが示すパスのビットマップ ファイルをロードします。
GetObject関数でビットマップの高さ、幅を取得、計算した後、ウィンドウ サイズをビットマップのサイズに変更します。
いったん
メモリ デバイス コンテキスト内にビットマップを展開し、BitBlt関数でビットマップを描画します。
最後に、利用したデバイス コンテキスト、
オブジェクト(ビットマップ)を破棄して終わりです。
この一連の動作が、再描画要求が出されるたびに行われることになります。再描画要求というと、ちょっとピンとこないかもしれませんが、他のウィンドウに隠れている、画面の外にはみ出しているときなどに、ウィンドウを移動したり、最前面に表示したりすると、隠れていた部分に対して再描画が要求されることになります。また、「開く」メニューのイベント プロシージャからInvalidateRect関数が呼び出されたときも、このイベントが実行されます。
Sub MainWnd_Paint(hDC As Long)
Dim hBmp As Long 'ビットマップ [[ハンドル]]
Dim hMemDC As Long 'メモリ内 デバイスコンテキストのハンドル
Dim BitmapReport As BITMAP 'ビットマップ情報を格納するための構造体
Dim dx As Long, dy As Long 'ウィンドウサイズとクライアント領域サイズの差
'ファイルが開かれていない場合は抜け出す
If FileName="" Then Exit Sub
'ビットマップをロード
hBmp=LoadImage(GetWindowLong(hMainWnd, GWL_HINSTANCE), FileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
If hBmp=0 Then
MessageBox(hMainWnd, "ビットマップのオープンに失敗", "BmpViewer", MB_OK)
Exit Sub
End If
'ビットマップのサイズを取得
GetObject(hBmp, Len(BitmapReport), BitmapReport)
'ウィンドウサイズとクライアント領域サイズの差を計算
Dim rc_[[Window]] As RECT, rc_Client As RECT
GetWindowRect(hMainWnd, rc_Window)
GetClientRect(hMainWnd, rc_Client)
dx = (rc_Window.right - rc_Window.left) - (rc_Client.right - rc_Client.left)
dy = (rc_Window.bottom - rc_Window.top) - (rc_Client.bottom - rc_Client.top)
'ウィンドウサイズをビットマップのサイズにあわせる
MoveWindow(hMainWnd, rc_Window.left, rc_Window.top, BitmapReport.bmWidth+dx ,BitmapReport.bmHeight+dy, 1)
hMemDC=CreateCompatibleDC(hDC) 'メモリ内にデバイスコンテキストを作成する
SelectObject(hMemDC, hBmp) 'ビットマップを選択
'ビットマップを描画
BitBlt(hDC, 0, 0, BitmapReport.bmWidth, BitmapReport.bmHeight, hMemDC, 0, 0, SRCCOPY)
DeleteDC(hMemDC) 'メモリ内のデバイスコンテキストを解放する
DeleteObject(hBmp) 'ビットマップ ハンドルを破棄する
End Sub
これですべての作業が完了です。
コンパイル、実行をしてみて、ビットマップがしっかりと表示されるかどうか、試してみて下さい。
最終更新:2010年06月16日 17:10