再描画処理をVisual Basicでもやってみよう

Visual C++プログラマーにとっては普通のこと...
再描画処理って何?という方は今月の特集は難しいかもしれません。
そういう方は特に今月の特集は読む必要はないでしょう。
なぜならVisual Basicプログラマーには基本的には必要のないものだからです。

でもそろそろVisual Basicを卒業してVisual C++にしてみようかなという方は読んでおきましょう。

基本的にWindowsのウインドウはCreateWindowEx()関数で作成します。
しかし、この関数で作成できるウィンドウはVisual BasicのFormのように親切ではなく
フォントの設定や色、再描画処理、メッセージ処理などは全て自分でやらなければなりません。

Visual C++プログラマーはこれらのことは最初からこなしているのです。
「VC++でできてVBでできないことは基本的にはない」ということでやってみましょう。
(注意:VC++でできてVBでできないこととは「IShellLink」などという意味である)
とりあえず実験
じつは私は解説するのがかなりめんどくさいので
さっそく「百聞一見にしかず」で実験してみましょう。

Public Const IDM_BUTTON1 = &H100

Public Sub Main()
Dim wcl As WNDCLASSEX, msg As Message
Dim rc As Long
Dim hDlg As Long

'メインウィンドウの登録
With wcl
    .cbSize = Len(wcl)
    .lpszClassName = "test Class Name"
    .lpfnWndProc = ChangeAddressOf(AddressOf WndProc)
    .style = 0
    .cbClsExtra = 0
    .cbWndExtra = 0
    .lpszMenuName = 0
    .hbrBackground = GetStockObject(WHITE_BRUSH)
    .hInstance = App.hInstance
    '.hIcon = LoadIcon(App.hInstance, ByVal 32512)
    .hIcon = LoadIcon(0, ByVal 32512)
    .hCursor = LoadCursor(0, ByVal 32512)
End With
Call RegisterClassEx(wcl)

'メインウィンドウの作成
hDlg = CreateWindowEx(WS_EX_CLIENTEDGE, wcl.lpszClassName, "ただいま再描画の実験中!", _
    WS_CAPTION Or WS_VISIBLE Or WS_SYSMENU Or WS_MINIMIZEBOX, _
    CW_USEDEFAULT, CW_USEDEFAULT, 370, 80, 0, 0, App.hInstance, 0)

'コマンドボタンの作成
Call CreateWindowEx(0, "Button", "押す", WS_CHILD Or BS_PUSHLIKE Or WS_VISIBLE, _
    300, 10, 50, 30, hDlg, IDM_BUTTON1, App.hInstance, 0)
    
'メインウィンドウの表示
Call ShowWindow(hDlg, SW_SHOW)

'メッセージループ
Do While (GetMessage(msg, 0, 0, 0))
    Call TranslateMessage(msg)
    Call DispatchMessage(msg)
Loop

End Sub

Public Function WndProc(ByVal hWnd As Long, ByVal msg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Dim hdc As Long, temp As String, rc As Long Select Case msg Case WM_COMMAND Select Case LWORD(wParam) Case IDM_BUTTON1 'デバイスコンテキストの取得 hdc = GetDC(hWnd) temp = "他のウィンドウを重ねてみてください!" rc = LenB(StrConv(temp, vbFromUnicode)) Call TextOut(hdc, 10, 10, temp, rc) '文字列 Call ReleaseDC(hWnd, hdc) End Select Case WM_CLOSE Call DestroyWindow(hWnd) Call PostQuitMessage(0) Case Else WndProc = DefWindowProc(hWnd, msg, wParam, lParam) End Select End Function
Public Function ChangeAddressOf(ByVal Address As Long) As Long ChangeAddressOf = Address End Function
Public Function HWORD(ByVal LongValue As Long) As Integer '長整数値から上位ワードを取得する HWORD = (LongValue And &HFFFF0000) \ &H10000 End Function
Public Function LWORD(ByVal LongValue As Long) As Integer '長整数値から下位ワードを取得する If (LongValue And &HFFFF&) > &H7FFF Then LWORD = (LongValue And &HFFFF&) - &H10000 Else LWORD = LongValue And &HFFFF& End If End Function
Public Function GetLong(ByVal UpperWord As Integer, ByVal LowerWord As Integer) As Long '下位・上位を与えて長整数値(32ビット値)を取得する GetLong = (LowerWord And &HFFFF&) Or (UpperWord * &H10000) End Function
実行画面
再描画処理をしないとどうなるかわかりましたか? ということで次は再描画処理について解説します。

次のページへ