ページ 11

クラスを使用したコードで

Posted: 2006年9月05日(火) 19:25
by Toshi

コード: 全て選択

Class CTestWindow

Public

    hMainWnd As HWND

    Sub CTestWindow()
        Assist.TestWindowPtr=VarPtr(This)
        Dim WCE As WNDCLASSEX
        With WCE
            .cbSize=Len(WCE)
            .style=CS_DBLCLKS Or CS_HREDRAW Or CS_OWNDC Or CS_VREDRAW
            .lpfnWndProc=AddressOf(MainWindowProc)
            .cbClsExtra=0
            .cbWndExtra=0
            .hInstance=GetModuleHandle(NULL)
            .hIcon=LoadIcon(NULL,IDI_APPLICATION As BytePtr)
            .hCursor=LoadCursor(NULL,IDC_ARROW As BytePtr)
            .hbrBackground=((COLOR_3DFACE)+1) As HBRUSH
            .lpszMenuName=NULL
            .lpszClassName="TestWindowsApplication Window Class"
            .hIconSm=LoadIcon(NULL,IDI_APPLICATION As BytePtr)
        End With
        RegisterClassEx(WCE)
        hMainWnd=CreateWindowEx(NULL,"TestWindowsApplication Window Class","TestWindowsApplication",
        WS_BORDER Or WS_VISIBLE Or WS_CLIPCHILDREN Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX Or _
        WS_OVERLAPPED Or WS_SYSMENU Or WS_THICKFRAME,
        0,0,640,480,NULL,NULL,GetModuleHandle(NULL),NULL)
    End Sub

    Function MainWindowProc(hWnd As HWND,dwMsg As DWord,wParam As WPARAM,lParam As LPARAM) As LRESULT
        MainWindowProc=Assist.TestWindowPtr->MainWindowProcSecond(hWnd,dwMsg,wParam,lParam)
    End Function

    Function MainWindowProcSecond(hWnd As HWND,dwMsg As DWord,wParam As WPARAM,lParam As LPARAM) As LRESULT
        Select Case dwMsg
            Case WM_CLOSE
                DestroyWindow(hWnd)
            Case WM_DESTROY
                PostQuitMessage(0)
            Case Else
                MainWindowProcSecond=DefWindowProc(hWnd,dwMsg,wParam,lParam)
        End Select
    End Function

End Class

Class CAssist

Public

    TestWindowPtr As *CTestWindow

End Class

Dim Assist As CAssist
Dim TestWindow As CTestWindow

Dim Message As MSG
Do        'ここにブレーク ポイントを設置
    If GetMessage(Message,NULL,NULL,NULL)<>1 Then Exit Do
    TranslateMessage(Message)
    DispatchMessage(Message)
Loop
ExitProcess(0)
このコードを実行すると、
・MainWindowProc に渡される引数の値がおかしい
・下の Do の部分にブレーク ポイントを設置しても異なった場所でブレークする
といった問題が起きます。
AB5CP2, Windows XP SP2 です。

Posted: 2006年9月05日(火) 19:33
by イグトランス
これは,MainWindowProcも隠し引数としてThisを受け取るのに,
Windowsはウィンドウプロシージャの仕様にしたがってhwnd, msg, wParam, lParamしか引数に渡していないため,
おかしなことになっているのだと思います。

MainWindowProcをCTestWindowの外に出せば良いはずです。

Posted: 2006年9月06日(水) 21:31
by 山本
イグトランス様が仰りますとおり、コールバック関数はクラスメソッドとして定義することはできません(仕様ですので、バグではないです)。

コールバック関数内から自身のウィンドウ(ようは、This)へアクセスしたい場合などが、なかなか悩ましい問題として浮上しますが、こちらはSetWindowLong関数のGWL_USERDATAなどを上手く活用することで回避できます。