Announcement

Collapse
No announcement yet.

DirectShow Draws Over Controls

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • DirectShow Draws Over Controls

    Starting with the code I posted recently to display a webcam, I'd like to put a button on top of the video. But the video always writes over any control I put on the dialog.

    Thoughts on whether I can have a control show on top of the direct show video?

    With this example, you can see that the button is not visible.

    Code:
    'Compilable Example:  (Jose Includes)
    #Compile Exe
    #Dim All
    %Unicode = 1
    #Include "Win32API.inc"
    #Include Once "dshow.inc"
    
    %IDC_Button = 500
    
    Global hDlg, hLst      As Dword
    Global pGraph          As IGraphBuilder           'Filter Graph Manager
    Global pBuild          As ICaptureGraphBuilder2   'Capture Graph Builder
    Global pSysDevEnum     As ICreateDevEnum          'enumeration object
    Global pEnumCat        As IEnumMoniker
    Global pMoniker        As IMoniker                'contains information about other objects
    Global pceltFetched    As Dword
    Global pCap            As IBaseFilter             'Video capture filter
    Global pControl        As IMediaControl
    Global pWindow         As IVideoWindow            'Display Window
    
    Function PBMain() As Long
       Dialog New Pixels, 0, "Camera and Toolbar",,,640,480, %WS_OverlappedWindow Or %WS_ClipChildren Or %WS_ClipSiblings To hDlg
       Control Add Button, hDlg, %IDC_Button, "Test", 100,100,100,25
       Dialog Show Modal hDlg Call DlgProc
    End Function
    
    CallBack Function DlgProc() As Long
       Select Case Cb.Msg
          Case %WM_InitDialog
             DisplayFirstCamera
       End Select
    End Function
    
    Sub DisplayFirstCamera
       pGraph      = NewCom ClsId $CLSID_FilterGraph                              'filter graph
       pBuild      = NewCom ClsId $CLSID_CaptureGraphBuilder2                     'capture graph builder
       pSysDevEnum = NewCom ClsId $CLSID_SystemDeviceEnum                         'enumeration object
       If pSysDevEnum.CreateClassEnumerator($CLSID_VideoInputDeviceCategory, pEnumCat, 0) <> %S_Ok Then Exit Sub
       pEnumCat.next(1, pMoniker, pceltFetched)                               'cycle through monikders
       pMoniker.BindToObject(Nothing, Nothing, $IID_IBaseFilter, pCap)       'create device filter for the chosen device
       pGraph.AddFilter(pCap,"First Camera")                                 'add chosen device filter to the filter graph
       pBuild.SetFilterGraph(pGraph)                                         'initialize pBuild
       pBuild.RenderStream $Pin_Category_Preview, $MediaType_Video, pCap, Nothing, Nothing   'render the live source
       pWindow = pGraph : pWindow.Owner = hDlg : pWindow.WindowStyle = %WS_Child Or %WS_ClipChildren  'video window settings
       pWindow.SetWindowPosition(0,0,640,480)
       pControl = pGraph
       pControl.Run
    End Sub

  • #2
    One option is to use a floating dialog that contains the controls of interest. That's doable but seems overly complicated.

    Another option is to put a Graphic control on the main dialog and have the Graphic control be the parent of the DirectShow video window. I've used that approach before but it also seems overly complicated because then I have to manage two controls during resizing. I've also had some troubles closing the video window when using that tiered approach.

    A third possible option is to use the "windowless mode" Of a VMR7 DirectShow filter. MSDN discusses that approach but I haven't figured out any sample code that works just yet.

    I was hoping that a simple Style setting might solve the problem but none of the styles I've tried so far seems to allow the control to be visible.

    Comment


    • #3
      Another option is to to place the video window lower in the dialog client area, leaving the top area available for displaying various controls. However, that approach interferes with at least one method of zooming in on the video. I'll post a separate thread that shows the zoom method.

      Comment


      • #4
        The solution (at least in SDK coding style) is to use a tool window (child popup).

        I do have a few examples on my private forum.
        PB code
        http://www.objreader.com/index.php?t...sg1013#msg1013
        C++ code
        http://www.objreader.com/index.php?t....msg482#msg482

        You can also look at the PB CanaryBay project, that is also able to play a video
        http://www.objreader.com/index.php?topic=329.0
        Patrice Terrier
        www.zapsolution.com
        www.objreader.com
        Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

        Comment


        • #5
          Gary,


          did you try adding "%WS_ClipSiblings" to:
          Code:
           pWindow.WindowStyle = %WS_Child Or %WS_ClipChildren

          another thought: change the Z-order, i.e. set the button at top of it with %HWND_Top or %HWND_Topmost:
          Code:
          setwindowpos(getdlgitem(hDlg, %IDC_Button), %HWND_Top(most), 0,0,0,0, %SWP_NoSize or %SWP_NoMove)
          after DisplayFirstCamera, maybe you need some delay until the video is actually running before doing this


          JK

          Comment


          • #6
            Howdy, Juergen!

            Thanks for the suggestions. But adding %WS_ClipSiblings to pWindow did not eliminate the problem, nor did changing the z-order. I also changed the order in which the button and video windows were created - no change. I also tried delaying button creation in a PostMessage but that did not help either.

            and Howdy, Patrice!
            I'm not 100% clear on your terminology - "tool window (child popup)". Is it the same as I mentioned above, where a child window (Graphic control) is placed on the Dialog and is used as the parent of the video? I also mentioned above that a secondary Dialog that is child to the main dialog will work.

            I am looking to understand why a control on the main Dialog is overwritten by the video window - how to prevent that from happening, if possible.

            I tried to login to the link you gave but I've forgotten the login information. When I tried to have it send me credentials (as Gary Beene or [email protected]) it says I don't exist!


            Comment


            • #7
              A tool window uses the WS_EX_TOOLWINDOW extended style.

              Your account has been disabled if you didn't login for too long, i shall check and send you a new login.
              Patrice Terrier
              www.zapsolution.com
              www.objreader.com
              Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

              Comment


              • #8
                Patrice!

                Thanks for sending my the new login info!

                The Style you suggested still does not allow the button to display.

                Code:
                pWindow.WindowStyle = %WS_Child Or %WS_ClipChildren Or %WS_ClipSiblings 'video window settings
                pWindow.WindowStyleEX = %WS_Ex_ToolWindow 'video window settings
                Just for overkill, I tried the EX style on pWindow, the button and the dialog - none allows the button to display.

                I'll go look at the code in the links you posted and see if there are further details that might help.

                Comment


                • #9
                  You must work in composited mode.

                  Here is an example of a GDImage help display (ObjReader 3D viewer), working in composited mode hover a direct-draw surface.

                  Click image for larger version  Name:	help.png Views:	0 Size:	502.8 KB ID:	803824

                  However this can't be done with a limited DDT graphic window.

                  You have to take full control on your window.
                  Patrice Terrier
                  www.zapsolution.com
                  www.objreader.com
                  Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                  Comment


                  • #10
                    Gary

                    In order to work in composited mode you need to use a good PIXELFORMATDESCRIPTOR
                    with the right
                    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SUPPORT_GDI | PFD_SUPPORT_COMPOSITION

                    and CS_OWNDC.

                    This is a rather complex mechanism, and GDImage has a build-in API (WGL_CreateWindow) to create such a window (that must work in 32-bit with full alpha channel support).
                    The WGL_CreateWindow renders everything onto the Direct-Draw surface, using a back buffer to bitblt the composited scene in one single refresh cycle matching the GPU Hz frequency.

                    This is something that can't be done with DDT graphic nor with any of the DDT graphic instructions that are based on the old 24-bit GDI technology, and better to achieve this in 64-bit if you want to use directly the GPU rather than the limited CPU.
                    Patrice Terrier
                    www.zapsolution.com
                    www.objreader.com
                    Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                    Comment


                    • #11
                      Howdy, Patrice!

                      Thanks for the additional posts. The DDT app where I want to provide a visible control on top of the streaming video is very mature and quite lengthy so I'm unlikely to put the time in to switch over to composited mode as you suggest.

                      I'll just have to stick with my current approach, which is to place the streaming video on a Graphic control. I can place/size the Graphic control away from the visible control (toolbar), thus having both on the dialog, I posted an example of that back in Oct 2019.

                      I was hoping that placing a control on a dialog, where the dialog surface is used for displaying the video stream, would be a simple code change from what I put in the OP. Apparently not!

                      Comment


                      • #12
                        Gary

                        Indeed there is a much simpler solution, turn your button into a popup tool window, using the WS_Ex_ToolWindow extended style.
                        And use it the same than a spinner control animation.
                        Patrice Terrier
                        www.zapsolution.com
                        www.objreader.com
                        Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                        Comment


                        • #13
                          Howdy, Patrice!

                          Thanks! But, adding that style to the DDT button did not work..

                          Code:
                          Control Add Button, hDlg, %IDC_Button, "Test", 100,100,100,25,, %WS_Ex_ToolWindow
                          Perhaps I need to try and add an SDK button instead? I'll go try that.

                          Comment


                          • #14
                            You must use the CreateWindowEx API directly., and the WS_POPUP style. The best solution would be to use a button superclass.
                            Patrice Terrier
                            www.zapsolution.com
                            www.objreader.com
                            Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                            Comment


                            • #15
                              Howdy, Patrice!

                              Acknowledged. Will give it a try this evening.

                              Comment


                              • #16
                                Gary

                                Test the attached layered project (posted long ago on the formal José Roca's forum), and see if it works with your video display, perhaps you could just reuse the button code for your purpose.
                                Attached Files
                                Patrice Terrier
                                www.zapsolution.com
                                www.objreader.com
                                Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                                Comment


                                • #17
                                  Howdy Patrice!

                                  Thanks for the additional post!

                                  Following your basic SDK suggestion, I pulled an SDK template out of my gbSnippets library, one that displays a button.

                                  However, after integrating the DirectShow code that I posted in the OP, I find that the DirectShow video stream appears in its own window, rather than as a child of the main window.

                                  It would seem that this line of code doesn't give the expected result. Is it obvious to you why the DirectShow window is not being treated as a child of the main window? As you know, my SDK skills are limited but the code looks pretty straightforward!

                                  Code:
                                  pWindow.Owner = hMainWnd
                                  Here's the compilable example:
                                  Code:
                                  'Compilable Example:  (Jose Includes)
                                  #Compile Exe
                                  #Dim All
                                  #Include "Win32API.inc"
                                  #Include Once "dshow.inc"
                                  
                                  %IDC_Button = 500
                                  
                                  Global hMainWnd As Dword, hButton As Dword
                                  Global pGraph          As IGraphBuilder           'Filter Graph Manager
                                  Global pBuild          As ICaptureGraphBuilder2   'Capture Graph Builder
                                  Global pSysDevEnum     As ICreateDevEnum          'enumeration object
                                  Global pEnumCat        As IEnumMoniker
                                  Global pMoniker        As IMoniker                'contains information about other objects
                                  Global pceltFetched    As Dword
                                  Global pCap            As IBaseFilter             'Video capture filter
                                  Global pControl        As IMediaControl
                                  Global pWindow         As IVideoWindow            'Display Wind
                                  
                                  Function WinMain (ByVal hInst As Dword, ByVal hPrevInstance As Dword, ByVal lpCmdLine As AsciiZ Ptr, ByVal iCmdShow As Long) As Long
                                     Local Msg As tagMsg, myWin As WndClassEx, szAppName As AsciiZ * 80, hwndButton As Dword
                                     szAppName = "HelloSDK"                                    :   myWin.cbSize        = SizeOf(myWin)
                                     myWin.hIcon = LoadIcon(hInst, "aainfo")                   :   myWin.Style         = %CS_HREDRAW Or %CS_VREDRAW
                                     myWin.hCursor = LoadCursor(%NULL, ByVal %IDC_ARROW)       :   myWin.lpfnWndProc   = CodePtr(WndProc)
                                     myWin.hbrBackground = %Color_BtnFace+1                    :   myWin.cbClsExtra    = 0
                                     myWin.lpszMenuName = %NULL                                :   myWin.cbWndExtra    = 0
                                     myWin.lpszClassName = VarPtr(szAppName)                   :   myWin.hInstance     = hInst
                                     myWin.hIconSm  = LoadIcon(hInst, ByVal %IDI_APPLICATION)  : RegisterClassEx myWin
                                     hMainWnd = CreateWindow(szAppName, "SDK", %WS_OverlappedWindow, 500,400,300,400,%Null, %Null, hInst, ByVal %Null)
                                     hButton = CreateWindow("Button","Push",%WS_TabStop Or %WS_Visible Or %WS_Child Or %BS_DefPushButton, _
                                        10,10,80,20,hMainWnd,%Null,GetWindowLong(hMainWnd, %GWL_HINSTANCE), %Null)
                                     ShowWindow hMainWnd, iCmdShow : UpdateWindow hMainWnd
                                     Do While GetMessage(Msg, %NULL, 0, 0) : TranslateMessage Msg : DispatchMessage Msg : Loop
                                  End Function
                                  
                                  Function WndProc (ByVal hWnd As Dword, ByVal wMsg As Dword, ByVal wParam As Dword, ByVal lParam As Long) Export As Long
                                     ' WndProc is the message handler for all windows creating using the HelloWin class name.
                                     Local hDC As Dword, pPaint As PAINTSTRUCT, tRect  As RECT
                                     Select Case wMsg
                                        Case %WM_Create
                                           DisplayFirstCamera
                                        Case %WM_Paint
                                        Case %WM_ERASEBKGND
                                        Case %WM_Destroy
                                           PostQuitMessage 0
                                           Exit Function
                                     End Select
                                     Function = DefWindowProc(hWnd, wMsg, wParam, lParam)   'if not handled above, pass to Windows default message handler.
                                  End Function
                                  
                                  Sub DisplayFirstCamera
                                     pGraph      = NewCom ClsId $CLSID_FilterGraph                              'filter graph
                                     pBuild      = NewCom ClsId $CLSID_CaptureGraphBuilder2                     'capture graph builder
                                     pSysDevEnum = NewCom ClsId $CLSID_SystemDeviceEnum                         'enumeration object
                                     If pSysDevEnum.CreateClassEnumerator($CLSID_VideoInputDeviceCategory, pEnumCat, 0) <> %S_Ok Then Exit Sub
                                     pEnumCat.next(1, pMoniker, pceltFetched)                               'cycle through monikders
                                     pMoniker.BindToObject(Nothing, Nothing, $IID_IBaseFilter, pCap)       'create device filter for the chosen device
                                     pGraph.AddFilter(pCap,"First Camera")                                 'add chosen device filter to the filter graph
                                     pBuild.SetFilterGraph(pGraph)                                         'initialize pBuild
                                     pBuild.RenderStream $Pin_Category_Preview, $MediaType_Video, pCap, Nothing, Nothing   'render the live source
                                     pWindow = pGraph : pWindow.Owner = hMainWnd : pWindow.WindowStyle = %WS_Child Or %WS_ClipChildren  'video window settings
                                     pWindow.SetWindowPosition(0,0,640,480)
                                     pControl = pGraph
                                     pControl.Run
                                  End Sub

                                  Comment


                                  • #18
                                    Howdy, Patrice,

                                    But, dropping back to the DDT example of the OP and adding an SDK button does create a button and does show the DirectShow window as a child of the main dialog.

                                    But, the button is still hidden by the DirectShow window, even though I've used %WS_Ex_ToolWindow in the CreateWindowEX command.

                                    Perhaps I've not coded the CreateWindowEX with the style correctly?

                                    Code:
                                    'Compilable Example:  (Jose Includes)
                                    #Compile Exe
                                    #Dim All
                                    %Unicode = 1
                                    #Include "Win32API.inc"
                                    #Include Once "dshow.inc"
                                    
                                    Global hDlg, hButton   As Dword
                                    Global pGraph          As IGraphBuilder           'Filter Graph Manager
                                    Global pBuild          As ICaptureGraphBuilder2   'Capture Graph Builder
                                    Global pSysDevEnum     As ICreateDevEnum          'enumeration object
                                    Global pEnumCat        As IEnumMoniker
                                    Global pMoniker        As IMoniker                'contains information about other objects
                                    Global pceltFetched    As Dword
                                    Global pCap            As IBaseFilter             'Video capture filter
                                    Global pControl        As IMediaControl
                                    Global pWindow         As IVideoWindow            'Display Window
                                    
                                    Function PBMain() As Long
                                       Dialog New Pixels, 0, "Camera and Button",,,640,480, %WS_OverlappedWindow Or %WS_ClipChildren Or %WS_ClipSiblings To hDlg
                                       hButton = CreateWindowEX(%WS_Ex_ToolWindow, "Button","Push",%WS_TabStop Or %WS_Visible Or %WS_Child Or %BS_DefPushButton, _
                                          10,10,80,20,ByVal hDlg, ByVal 0,GetWindowLong(hDlg, %GWL_HINSTANCE), ByVal 0)
                                       Dialog Show Modal hDlg Call DlgProc
                                    End Function
                                    
                                    CallBack Function DlgProc() As Long
                                       Select Case Cb.Msg
                                          Case %WM_InitDialog
                                             DisplayFirstCamera
                                       End Select
                                    End Function
                                    
                                    Sub DisplayFirstCamera
                                       pGraph      = NewCom ClsId $CLSID_FilterGraph                              'filter graph
                                       pBuild      = NewCom ClsId $CLSID_CaptureGraphBuilder2                     'capture graph builder
                                       pSysDevEnum = NewCom ClsId $CLSID_SystemDeviceEnum                         'enumeration object
                                       If pSysDevEnum.CreateClassEnumerator($CLSID_VideoInputDeviceCategory, pEnumCat, 0) <> %S_Ok Then Exit Sub
                                       pEnumCat.next(1, pMoniker, pceltFetched)                               'cycle through monikders
                                       pMoniker.BindToObject(Nothing, Nothing, $IID_IBaseFilter, pCap)       'create device filter for the chosen device
                                       pGraph.AddFilter(pCap,"First Camera")                                 'add chosen device filter to the filter graph
                                       pBuild.SetFilterGraph(pGraph)                                         'initialize pBuild
                                       pBuild.RenderStream $Pin_Category_Preview, $MediaType_Video, pCap, Nothing, Nothing   'render the live source
                                       pWindow = pGraph : pWindow.Owner = hDlg : pWindow.WindowStyle = %WS_Child Or %WS_ClipChildren  'video window settings
                                       pWindow.SetWindowPosition(0,0,640,480)
                                       pControl = pGraph
                                       pControl.Run
                                    End Sub

                                    Comment


                                    • #19
                                      @Gary,

                                      When you set the window position ( pWindow.SetWindowPosition(0,0,640,480) ), you don't leave room in the dialog for other controls.

                                      I have modified one of my examples to leave room for a button and it works fine:

                                      Code:
                                      ' CSED_PBWIN - Use the PBWIN compiler
                                      #COMPILE EXE
                                      #DIM ALL
                                      %UNICODE = 1
                                      
                                      #INCLUDE ONCE "CWindow.inc"
                                      #INCLUDE ONCE "commdlg.inc"
                                      #INCLUDE ONCE "dshow.inc"
                                      
                                      ' Label identifier
                                      %IDC_BUTTON = 1001
                                      
                                      ' Menu identifiers
                                      %ID_FILE_OPENCLIP = 40001
                                      %ID_FILE_EXIT     = 40002
                                      
                                      ' Custom message
                                      %WM_GRAPHNOTIFY   = %WM_USER + 13
                                      
                                      GLOBAL bIsPlaying AS LONG
                                      
                                      ' Interface pointers
                                      GLOBAL pIGraphBuilder AS IGraphBuilder
                                      GLOBAL pIMediaControl AS IMediaControl
                                      GLOBAL pIMediaEventEx AS IMediaEventEx
                                      GLOBAL pIVideoWindow  AS IVideoWindow
                                      
                                      ' ========================================================================================
                                      ' Play the movie inside the window.
                                      ' ========================================================================================
                                      SUB PlayMovieInWindow (BYVAL hwnd AS DWORD, BYREF wszFileName AS WSTRINGZ)
                                      
                                         LOCAL hr AS LONG
                                      
                                         ' // If there is a clip loaded, stop it
                                         IF ISOBJECT(pIMediaControl) THEN
                                            pIMediaControl.Stop
                                            pIMediaControl = NOTHING
                                            pIVideoWindow = NOTHING
                                            pIMediaEventEx = NOTHING
                                            pIGraphBuilder = NOTHING
                                         END IF
                                      
                                         ' // Create an instance of the IGraphBuilder object
                                         pIGraphBuilder = NEWCOM CLSID $CLSID_FilterGraph
                                         IF hr <> %S_OK OR ISNOTHING(pIGraphBuilder) THEN EXIT SUB
                                      
                                         ' // Retrieve interafce pointers
                                         pIMediaControl = pIGraphBuilder
                                         IF ISNOTHING(pIMediaControl) THEN EXIT SUB
                                         pIMediaEventEx = pIGraphBuilder
                                         IF ISNOTHING(pIMediaEventEx) THEN EXIT SUB
                                         pIVideoWindow = pIGraphBuilder
                                         IF ISNOTHING(pIVideoWindow) THEN EXIT SUB
                                      
                                         ' // Render the file
                                         hr = pIGraphBuilder.RenderFile(wszFileName)
                                         IF hr <> %S_OK THEN EXIT SUB
                                      
                                         '// Set the window owner and style
                                         pIVideoWindow.Visible = %OAFALSE
                                         pIVideoWindow.Owner = hwnd
                                         pIVideoWindow.WindowStyle = %WS_CHILD OR %WS_CLIPSIBLINGS OR %WS_CLIPCHILDREN
                                      
                                         ' // Have the graph signal event via window callbacks for performance
                                         pIMediaEventEx.SetNotifyWindow(hwnd, %WM_GRAPHNOTIFY, 0)
                                      
                                         ' // Set the window position
                                         LOCAL rc AS RECT
                                         GetClientRect hwnd, rc
                                         pIVideoWindow.SetWindowPosition(rc.Left, rc.Top + 60, rc.Right, rc.Bottom - 60)
                                         ' // Make the window visible
                                         pIVideoWindow.Visible = %OATRUE
                                      
                                         ' // Run the graph
                                         pIMediaControl.Run
                                         bIsPlaying = %TRUE
                                      
                                      END SUB
                                      ' ========================================================================================
                                      
                                      ' ========================================================================================
                                      ' Main
                                      ' ========================================================================================
                                      FUNCTION WinMain (BYVAL hInstance AS DWORD, BYVAL hPrevInstance AS DWORD, BYVAL lpszCmdLine AS WSTRINGZ PTR, BYVAL nCmdShow AS LONG) AS LONG
                                      
                                         ' // Set process DPI aware
                                         AfxSetProcessDPIAware
                                      
                                         ' // Create an instance of the class
                                         LOCAL pWindow AS IWindow
                                         pWindow = CLASS "CWindow"
                                         IF ISNOTHING(pWindow) THEN EXIT FUNCTION
                                      
                                         ' // Create the main window
                                         ' // Note: CW_USEDEFAULT is used as the default value When passing 0's as the width and height
                                         pWindow.CreateWindow(%NULL, "DirectShow Demo", 0, 0, 0, 0, 0, 0, CODEPTR(WindowProc))
                                         ' // Set the client size
                                         pWindow.SetClientSize 400, 320
                                         ' // Center the window
                                         pWindow.CenterWindow
                                      
                                         ' // Add a button
                                         pWindow.AddButton(pWindow.hwnd, %IDC_BUTTON, "Button", 300, 5, 75, 23)
                                      
                                         ' // Menu
                                         LOCAL hMenu AS DWORD
                                         LOCAL hMenuFile AS DWORD
                                         hMenu = CreateMenu
                                         hMenuFile = CreatePopUpMenu
                                         AppendMenu hMenu, %MF_POPUP OR %MF_ENABLED, hMenuFile, "&File"
                                         AppendMenu hMenuFile, %MF_ENABLED, %ID_FILE_OPENCLIP, "&Open clip..."
                                         AppendMenu hMenuFile, %MF_ENABLED, %ID_FILE_EXIT, "E&xit"
                                         SetMenu pWindow.hwnd, hMenu
                                      
                                         ' // Default message pump (you can replace it with your own)
                                         pWindow.DoEvents(nCmdShow)
                                      
                                      END FUNCTION
                                      ' ========================================================================================
                                      
                                      ' ========================================================================================
                                      ' Main Window procedure
                                      ' ========================================================================================
                                      FUNCTION WindowProc (BYVAL hwnd AS DWORD, BYVAL wMsg AS DWORD, BYVAL wParam AS DWORD, BYVAL lParam AS LONG) AS LONG
                                      
                                         LOCAL hDC AS DWORD
                                         LOCAL rc AS RECT
                                         LOCAL bstrFilter AS WSTRING
                                         LOCAL bstrDefExt AS WSTRING
                                         LOCAL bstrFileName AS WSTRING
                                      
                                         SELECT CASE wMsg
                                      
                                            CASE %WM_COMMAND
                                      
                                               SELECT CASE LO(WORD, wParam)
                                      
                                                  CASE %IDCANCEL, %ID_FILE_EXIT
                                                     ' // Exit the application by sending an WM_CLOSE message
                                                     IF HI(WORD, wParam) = %BN_CLICKED THEN
                                                        SendMessage hwnd, %WM_CLOSE, 0, 0
                                                        EXIT FUNCTION
                                                     END IF
                                      
                                                  CASE %ID_FILE_OPENCLIP
                                                     ' // Open file dialog
                                                     IF HI(WORD, wParam) = %BN_CLICKED THEN
                                                        bstrFilter = CHR$("Video Files (*.MPG;*MPEG;*.AVI;*.MOV;*.QT;*.WMV)", 0, "*.MPG;*.MPEG;*.AVI;*.MOV;*.QT;*.WMV", 0)
                                                        IF AfxOpenFileDialog(hwnd, "", bstrFileName, CURDIR$, bstrFilter, "wmv", %OFN_EXPLORER OR %OFN_FILEMUSTEXIST) THEN
                                                           IF LEN(bstrFileName) THEN PlayMovieInWindow(hwnd, BYCOPY bstrFileName)
                                                        END IF
                                                     END IF
                                      
                                               END SELECT
                                      
                                            CASE %WM_GRAPHNOTIFY
                                      
                                               ' // WM_GRAPHNOTIFY is an ordinary Windows message. Whenever the Filter Graph Manager
                                               ' // puts a new event on the event queue, it posts a WM_GRAPHNOTIFY message to the
                                               ' // designated application window. The message's lParam parameter is equal to the third
                                               ' // parameter in SetNotifyWindow. This parameter enables you to send instance data with
                                               ' // the message. The window message's wParam parameter is always zero.
                                      
                                               LOCAL lEventCode AS LONG
                                               LOCAL lParam1 AS LONG
                                               LOCAL lParam2 AS LONG
                                      
                                               IF ISOBJECT(pIMediaEventEx) THEN
                                                  DO
                                                     pIMediaEventEx.GetEvent(lEventCode, lParam1, lParam2, 0)
                                                     IF OBJRESULT <> %S_OK THEN EXIT DO
                                                     pIMediaEventEx.FreeEventParams(lEventCode, lParam1, lParam2)
                                                     IF lEventCode = %EC_COMPLETE THEN
                                                        IF ISOBJECT(pIVideoWindow) THEN
                                                           pIVideoWindow.Visible = %OAFALSE
                                                           pIVideoWindow.Owner = %NULL
                                                           pIVideoWindow = NOTHING
                                                        END IF
                                                        pIMediaControl = NOTHING
                                                        pIMediaEventEx = NOTHING
                                                        pIGraphBuilder = NOTHING
                                                        bIsPlaying = %FALSE
                                                        AfxRedrawWindow hwnd
                                                        EXIT DO
                                                     END IF
                                                  LOOP
                                               END IF
                                      
                                            CASE %WM_SIZE
                                               ' // Resize the window and the video
                                               GetClientRect hwnd, rc
                                               IF ISOBJECT(pIVideoWindow) THEN
                                                  pIVideoWindow.SetWindowPosition(rc.Left, rc.Top + 60, rc.Right, rc.Bottom - 60)
                                                  RedrawWindow hwnd, rc, 0, %RDW_INVALIDATE OR %RDW_UPDATENOW
                                               END IF
                                      
                                      '      CASE %WM_ERASEBKGND
                                      '         ' // Erase the window's background
                                      '         IF bIsPlaying = %FALSE THEN
                                      '            hDC = wParam
                                      '            GetClientRect hwnd, rc
                                      '            FillRect hDC, rc, GetStockObject(%BLACK_BRUSH)
                                      '            FUNCTION = %TRUE
                                      '            EXIT FUNCTION
                                      '         END IF
                                      
                                            CASE %WM_SYSCOMMAND
                                               ' // Capture this message and send a WM_CLOSE message
                                               IF (wParam AND &HFFF0) = %SC_CLOSE THEN
                                                  SendMessage hwnd, %WM_CLOSE, 0, 0
                                                  EXIT FUNCTION
                                               END IF
                                      
                                            CASE %WM_DESTROY
                                               ' // Stop de video if it is playing
                                               IF ISOBJECT(pIMediaControl) THEN
                                                  pIMediaControl.Stop
                                                  pIMediaControl = NOTHING
                                               END IF
                                               ' // Clean resources
                                               IF ISOBJECT(pIVideoWindow) THEN
                                                  pIVideoWindow.Visible = %OAFALSE
                                                  pIVideoWindow.Owner = %NULL
                                                  pIVideoWindow = NOTHING
                                               END IF
                                               pIMediaEventEx = NOTHING
                                               pIGraphBuilder = NOTHING
                                               ' // Quit the application
                                               PostQuitMessage 0
                                               EXIT FUNCTION
                                      
                                         END SELECT
                                      
                                         ' // Default processing for unprocessed messages
                                         FUNCTION = DefWindowProc(hwnd, wMsg, wParam, lParam)
                                      
                                      END FUNCTION
                                      ' ========================================================================================
                                      Forum: http://www.jose.it-berater.org/smfforum/index.php

                                      Comment


                                      • #20
                                        The button itself should be a popup layered tool window, it couldn't be part of the dialog child, and you have to use sendmessage or postmessage to communicate with the main parent dialog.

                                        And use MoveWindow to change the button location, fortunatly a toolwindow is always shown above its parent..

                                        hButton = CreateWindowEx(WS_EX_TOOLWINDOW, ButtonClassName, "Caption",WS_POPUP, x, y, width, height, hParent, 0, hInstance, 0)
                                        Patrice Terrier
                                        www.zapsolution.com
                                        www.objreader.com
                                        Addons: GDImage.DLL 32/64-bit (Graphic library), WinLIFT.DLL 32/64-bit (Skin Engine).

                                        Comment

                                        Working...
                                        X