イメージビューア1
イメージビューアを作る
今回から数回に分けて、イメージビューアを作成します。
今回はビットマップの表示を行います。
ちなみにビットマップビューアは本家の講座にあります。これの応用になります。
まず、プロジェクトを作成します。私はImageVipにしました。
スタイルをサイズ変更枠から細枠にしておきます。
最大化ボタンのチェックをはずしておきます。
次にメニューを作ります。これは本家のビットマップビューアと同じにしました。
ココまでのプロジェクトはこれ
メニューだけの何もしないウインドウです。
ファイルを選択する
まず、ファイルを開いてビットマップを表示しなければなりません。
今回はコモンダイアログを使います。こんなのを出します。

これを出すにはGetOpenFileName関数を使います。
GetOpenFileName関数にOPENFILENAME構造体を引数に渡します。
OPENFILENAME構造体は、メンバが多く大変です。このプログラムでは最小限しか使ってません。
GetOpenFileName関数はファイルを選択して、ファイルパスを得るだけです。開くなどの操作は自分で行います。
ビットマップファイルを開く
以上の処理で得たファイルパスを使って実際にファイルを読んで、画像を表示します。
Openimg関数でそれを行っています。
まず、ファイルを開きます。
次にヘッダを調べています。BITMAPFILEHEADER構造体がそれです。
正しいと判断されたら、BITMAPINFO構造体に情報を入れます。
その後は、画像の色データをpixelに入れます。
以上の処理で得たものを、CreateDIBitmap関数に渡して、DIBをDDBに変換しています。
DDB=デバイス依存ビットマップ。DIB=デバイス独立ビットマップ。
あとは、ウインドウを調整し、描写処理を行っています。
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
#include<vcrt71.sbp>
Dim hDspDC As HDC
Dim hMemDC As HDC
Dim hBmp As HBITMAP
Dim bmh As Long
Dim bmw As Long
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
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
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
'WM_DESTROY
Sub MainWnd_Destroy()
DeleteObject(hBmp)
DeleteDC(hMemDC)
ReleaseDC(hMainWnd , hDspDC)
ImgVip_DestroyObjects()
PostQuitMessage(0)
End Sub
'WM_CREATE
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
hDspDC =GetDC(hMainWnd)
hMemDC =CreateCompatibleDC(hDspDC)
End Sub
'WM_PAINT
Sub MainWnd_Paint(hDC As HDC)
BitBlt(hDspDC , 0 , 0,bmw,bmh,hMemDC , 0, 0,SRCCOPY)
End Sub
'画像ファイルを開いてhBmpに描く
Sub OpenImg(filenam As *Byte)
Dim fp As *FILE
Dim bfh As BITMAPFILEHEADER
Dim bi As *BITMAPINFO
Dim Bytes As DWord
Dim pixel As *Byte
Dim WR As RECT, CR As RECT
Dim dx As Long,dy As Long
If hBmp <> 0 Then DeleteObject(hBmp)'ビットマップがあれば削除
fp = fopen(filenam , "rb")
If fp = NULL Then
MessageBox(hMainWnd , "ファイルを開けません" , "エラー" , MB_OK)
Exit Sub
End If
fread(VarPtr(bfh) , sizeof(BITMAPFILEHEADER) , 1 , fp)
Bytes = sizeof (BITMAPFILEHEADER)
If bfh.bfType <> &h4D42 Then
MessageBox(hMainWnd , "ビットマップファイルではありません" , _
"エラー" , MB_OK)
Exit Sub
End If
bi = malloc(bfh.bfOffBits - Bytes)
fread(bi , 1 ,bfh.bfOffBits - Bytes , fp)
pixel = malloc(bfh.bfSize - bfh.bfOffBits)
fread(pixel , 1 , bfh.bfSize - bfh.bfOffBits , fp)
fclose(fp)
hBmp = CreateDIBitmap(hDspDC , bi->bmiHeader , CBM_INIT , pixel , _
ByVal bi , DIB_RGB_COLORS)
If hBmp = 0 Then
MessageBox(hMainWnd , "ビットマップを作れません" , "エラー",MB_OK)
Exit Sub
End If
bmh = bi->bmiHeader.biHeight
bmw = bi->bmiHeader.biWidth
free(bi)
free(pixel)
'ウィンドウサイズとクライアント領域サイズの差を計算
GetWindowRect(hMainWnd, WR)
GetClientRect(hMainWnd, CR)
dx = (WR.right - WR.left) - (CR.right - CR.left)
dy = (WR.bottom - WR.top) - (CR.bottom - CR.top)
'ウィンドウサイズをビットマップのサイズにあわせる
MoveWindow(hMainWnd, WR.left, WR.top, bmw+dx ,bmh+dy, 1)
SelectObject(hMemDC , hBmp)
MainWnd_Paint(hDspDC)
End Sub
'メニュー開く
Sub MainWnd_IDM_OPEN_MenuClick()
Dim ofn As OPENFILENAME
Dim file[MAX_PATH] As Byte
ofn.hwndOwner = hMainWnd
ofn.lStructSize = sizeof(OPENFILENAME)'
ofn.lpstrFilter = Ex"ビットマップ(*.bmp)\0*.bmp\0全てのファイル\0*.*\0\0"
ofn.nMaxFile = MAX_PATH
ofn.lpstrFile = file
GetOpenFileName(ofn)
If file = NULL Then Exit Sub
OpenImg(file)
End Sub
'メニュー終了
Sub MainWnd_IDM_EXIT_MenuClick()
SendMessage(hMainWnd , WM_CLOSE , 0,0)
End Sub
'メニューバージョン情報
Sub MainWnd_IDM_ABOUT_MenuClick()
MessageBox(hMainWnd , Ex"画像ビューア\nバージョン1.0" , "バージョン" , MB_OK)
End Sub
今回の完成品はこれです。