我用API函数GetClassName找到了DVD控件MsWebdvd.dll的句柄hWnd,目的是使播放窗口响应我的鼠标输入。可是事与愿违,出重大问题了:1、我双击视频画面,画面有一个最大化的动作,但窗体并没有最大化,随即死机,但DVD却继续播放,程序失控,退出后程序崩溃。2、弹出的右键菜单会遮住播放窗体,DVD继续播放,程序失控,退出后程序崩溃。

解决方案 »

  1.   

    按ctrl+pausebreak中断,再进行逐行调试,
    程序崩溃,危险0。。
      

  2.   

    dvd播放控件和容纳控件的窗口是两码事,最大化要同时进行吧?
    2.程序崩溃的原因不打清楚,代码贴出来
      

  3.   

    我把代码贴出来,请高手帮我分析一下。标准模块代码
    Option Explicit
    Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Public Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As LongPublic hWndOfPlayVideo As Long  '视频播放窗口的句柄'取得Flash.ocx控件视频播放窗口的句柄
    Public Function EnumFlashChildProc(ByVal lhWnd As Long, ByVal lParam As Long) As Long
        Dim RetVal As Long
        Dim WinClassBuf As String * 255
        Dim WinClass As String
        RetVal = GetClassName(lhWnd, WinClassBuf, 255)
        If (InStr(WinClassBuf, Chr(0)) > 0) Then
            WinClass = Left(WinClassBuf, InStr(WinClassBuf, Chr(0)) - 1)
        End If
        If WinClass = "MacromediaFlashPlayerActiveX" Then
           hWndOfPlayVideo = lhWnd
           EnumChildProc = False
        Else
           If Left(WinClass, 4) = "ATL:" Then
              hWndOfPlayVideo = lhWnd
              EnumChildProc = False
           Else
               EnumChildProc = True
           End If
        End If
    End Function'取得DVD控件MsWebdvd.dll视频播放窗口的句柄
    Public Function EnumDVDChildProc(ByVal lhWnd As Long, ByVal lParam As Long) As Long
        Dim RetVal As Long
        Dim WinClassBuf As String * 255
        Dim WinClass As String
        RetVal = GetClassName(lhWnd, WinClassBuf, 255)
        Debug.Print "RetVal=" & Str(RetVal) & " WinClassBuf=" & WinClassBuf
        If InStr(WinClassBuf, "MSMFVideoClass") > 0 Then
           hWndOfPlayVideo = lhWnd
           GetDVDChildProcHwnd = False    
        Else
            GetDVDChildProcHwnd = True
        End If
    End Function
    窗体模块代码:所有变量都定义了的,这里不再定义。WndProc是我的回调函数,定义了鼠标事件(双击,右键等),在另一标准模块里。
    以下代码均在播放开始后执行。PlayScreen是容纳控件的播放窗体。  lhWnd = PlayScreen.hwnd
    lRet = EnumChildWindows(lhWnd, AddressOf EnumFlashChildProc, lParam)
    If hWndOfPlayVideo <> 0 Then
       prevWndProc = SetWindowLong(hWndOfPlayVideo , GWL_WNDPROC, AddressOf WndProc)
    End If
    CJL = hWndOfPlayVideo  
       这几行代码在播放Flash动画后被执行,然后执行playcjl后面的代码,没有任何问题,画面上完全能够响应鼠标双击和右键菜单。
       .
       .
       .
    lhWnd = PlayScreen.hwnd
    lRet = EnumChildWindows(lhWnd, AddressOf EnumDVDChildProc, lParam)
    If hWndOfPlayVideo <> 0 Then
       prevWndProc = SetWindowLong(hWndOfPlayVideo , GWL_WNDPROC, AddressOf WndProc)
    End If
    CJL = hWndOfPlayVideo 
       这几行代码在播放DVD光盘后被执行,然后执行playcjl后面的代码,这时PlayScreen播放窗体出问题了:标题栏不响应鼠标,画面上的右键菜单一个一个地遮住了画面,DVD继续播放,不能刷新。双击画面时,画面有一个最大化的动作,但PlayScreen窗体并没有最大化。我看了一下CPU使用率在60-70%,播放器几乎不能响应鼠标。偶尔能响应,但退出后程序崩溃。
       .
       .
    playcjl:  SetWindowLong Cjl, GWL_WNDPROC, prevWndProc
       .
       .
       .
    prevWndProc = GetWindowLong(Cjl, GWL_WNDPROC)
    Rtn = SetWindowLong(Cjl, GWL_WNDPROC, AddressOf WndProc)
    为什么播放Flash可以,而播放DVD会出问题。
      

  4.   

    WndProc的代码有问题
    我大概猜到是什么问题了,吧WndProc代码贴出来
      

  5.   

    '以下是我的回调函数WndProc,不知是哪个地方出错?但播放Flash动画没任何问题。
    Public Function WndProc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long '自定义窗口处理程序
             
             On Error Resume Next         If Msg = WM_LBUTTONDBLCLK Then '截获鼠标双击消息
                Dim r As Long
                On Error Resume Next
                If (Player.PDFullScreen) Then
                    r = ShowWindow(PlayScreen.Hwnd, SW_SHOWMINIMIZED)'最小化
                Else
                    r = ShowWindow(PlayScreen.Hwnd, SW_SHOWMAXIMIZED)'最大化
                End If
             Else
                If Msg = WM_RBUTTONDOWN Then '弹出右键菜单
                   PlayScreen.PopupMenu PlayScreen.PlayMenu
                Else
                   If Msg = WM_LBUTTONDOWN And LockMouseLeftClick = False Then '单击鼠标左键激活播放器
                      If ClickMouse Then
                         Call SetWindowPos(Player.hwnd, HWND_TOPMOST, 0, 0, 0, 0, 3)
                         Call ShowWindow(Player.hwnd, SW_RESTORE)
                         ClickMouse = False
                      Else
                         ClickMouse = True
                      End If
                   Else
                      WndProc = CallWindowProc(prevWndProc, hwnd, Msg, wParam,lParam) '操作系统预定义窗口处理程序
                   End If
                End If
             End If
    End Function
      

  6.   

    我估计可能是这样
    你 dvd的时候,播放线程(就是执行WndProc的线程)和主线程不是同一个线程,这个时候,wndproc是不能访问主界面的控件的,一访问就会出错,我猜测是这样解决的办法是你要控制的控件,就是那个菜单,可能要在wndproc内创建
      

  7.   

    你换个控件吧,比如说Windows Media Player,MsWebdvd.dll控件的很多接口是vb不支持的
      

  8.   

    VirtualDesktop(吴滂:欢迎到我的Blog转转 ^_^) :为什么播放Flash动画又可以呢?
      

  9.   

    因为flash控件的窗体过程没有存在可能会使你程序爆掉的东西
      

  10.   

    呵呵~没错
    因为flash播放只是用你程序本身的线程,没有用多线程,但是dvd就不同了
      

  11.   

    supergreenbean(超级绿豆(MSMVP - VB) - 升级归来~)、 VirtualDesktop(吴滂:欢迎到我的Blog转转 ^_^) 两位高手:我实在是不想换控件,用MSWebDVD可以在VB里轻松搞定“字幕”、“音频”和“区码”、“角度”等等。我知道VB6不支持多线程,但通过大家的研究我想一定可以解决这个悬而未决的问题。播放DVD时总不能NO FullScreen播放吧,FullScreen后这就有个鼠标输入的问题,......或者在MSWebDVD控件上添加一置前的命令按钮(CommandButton),我试过可以,但又太难看了,不是行伍出身!是否可用Hook技术解决呢?(本人从没有用过,怎样解决)
      

  12.   

    结贴。高手不帮我,我自己把此问题解决了。
        其实,利用HOOK技术可顺利解决。
        编写一个全局的鼠标钩子,然后:1、将鼠标事件限定在DVD视频范围内;2、窗体移动时响应鼠标的区域随之变动;3、窗体和DVD控件同时最大化。
        所有问题全解决了,简直太爽了!   
        解决了此问题,也解决了我长期以来的一个误区:以前我总认为控件最大化后,窗体一定是最大化。现在我明白了,控件最大化,窗口不一定最大化。窗口最小化,控件也可以最大化。
        高手都劝我换控件,我不想换。毕竟我太喜欢DVD控件MSWebDVD.dll(Windows2000以上的操作系统自带,在system32下面),因为MSWebDVD可以在VB里轻松搞定DVD“字幕”、“音频”和“区码”、“角度”等等。