QB64 Phoenix Edition
Dynamic Libraries (Windows) - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Prolific Programmers (https://qb64phoenix.com/forum/forumdisplay.php?fid=26)
+---- Forum: Petr (https://qb64phoenix.com/forum/forumdisplay.php?fid=52)
+---- Thread: Dynamic Libraries (Windows) (/showthread.php?tid=4197)

Pages: 1 2 3 4 5 6


RE: Dynamic Libraries - ahenry3068 - 12-13-2025

(12-13-2025, 07:06 PM)2112 Wrote: Very nice work Petr,
I tried to play an avi video in qb64
but I couldn't find a stable code.
I found the code below but it doesn't
show the video properly (flickering).
The only way to avoid flickering is to play
the avi in another window.
This happens in QB64, in QB64PE it doesn't
show anyhting.
I don't need avi playing, it's just for learning,
not something important. I have windows7-64
Does anyone know something?

Code: (Select All)

Const ACS_TRANSPARENT = 2
Const ACM_OPEN = 1124
Const ACM_PLAY = 1125
Const ACM_STOP = 1126
Const WS_VISIBLE = &H10000000
Const WS_CHILD = &H40000000

handle& = _NewImage(800, 600, 32)
Screen handle&

_Title "QB64 Video"
hwnd& = _WindowHandle 'FindWindow(0, "QB64 Video" + CHR$(0))

Dim CommandString As String, Filename As String, vbNullString As String
Dim RetVal As Long
Filename = "1.avi"

ReturnString$ = Space$(255)
ErrorString$ = Space$(255)

Declare Dynamic Library "WINMM"
    Function mciSendStringA% (lpstrCommand As String, lpstrReturnString As String, ByVal uReturnLength As Integer, ByVal hwndCallback As Integer)
    Function mciGetErrorStringA% (ByVal dwError As Integer, lpstrBuffer As String, ByVal uLength As Integer)
End Declare

'a% = mciSendStringA%("open " + Filename + " alias avifile parent " + Str$(hwnd&) + " style child", ReturnString$, Len(ReturnString$), 0) ' ==== OPENS ANOTHER WINDOW IN QB64, ==== DOES NOTHING IN QB64PE
a% = mciSendStringA%("open " + Filename + " style popup", ReturnString$, Len(ReturnString$), 0) '==== FLICKERING IN QB64, =====SHOWS NOTHING IN QB64PE

b% = mciSendStringA%("window " + Filename$ + " handle " + Str$(hwnd&), ReturnString$, Len(ReturnString$), 0)

c% = mciSendStringA%("play " + Filename, ReturnString$, Len(ReturnString$), 0)

Do
    _Delay .1
Loop Until InKey$ <> ""

           It's nice to be able to Play Windows AVI files but I don't think there's anyway for this particular code to work on any platform besides Windows.   (I would be happy to be proved wrong !)     I have a project that does Video playback of a file format I created myself and that project Also has a means of creating those custom files with another program.    The project is the Commander X16 Movie Maker (I designed this format for playback on the Commander X16 platform,  But I also made it work on the 64 bit Desktop, both Linux & Windows)    The project is posted in the program forum here:     The Playback application is pure QB64PE code without relying on outside library code ! https://qb64phoenix.com/forum/showthread.php?tid=3929


RE: Dynamic Libraries - 2112 - 12-13-2025

ahenry3068 and Petr,
That's great coding, thank you.


RE: Dynamic Libraries - Petr - 12-13-2025

So is it better. So it plays also Divx / Xvid codecs:

Code: (Select All)


Option _Explicit

Declare Dynamic Library "winmm"
    Function mciSendStringA& (lpstrCommand As String, lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As _Offset)
    Function mciGetErrorStringA& (ByVal dwerrsor As Long, lpstrBuffer As String, ByVal uLength As Long)
End Declare


Dim handle&: handle& = _NewImage(800, 600, 32)
Screen handle&
_Title "QB64 Video"

Dim hwnd As _Offset
hwnd = _WindowHandle

Dim filename As String, aliasName As String
filename = "(2014)na.avi"
aliasName = "vid"

Dim cmd As String
Dim errs As Long, N As Long
Dim dummy As String: dummy = Space$(1)

' Open AVI as avivideo, place it as CHILD to QB64PE window
'cmd = "open " + Chr$(34) + filename + Chr$(34) + " type avivideo alias " + aliasName + _
'      " parent " + LTrim$(Str$(hwnd)) + " style child"

cmd = "open " + Chr$(34) + filename + Chr$(34) + " type mpegvideo alias " + aliasName + _
      " parent " + LTrim$(Str$(hwnd)) + " style child"

errs = mciSendStringA&(cmd, dummy, 0, 0): MCI_Check errs, cmd

' Set window size and window postition
cmd = "put " + aliasName + " window at 0 0 800 600"
errs = mciSendStringA&(cmd, dummy, 0, 0): MCI_Check errs, cmd

' Play it
cmd = "play " + aliasName
errs = mciSendStringA&(cmd, dummy, 0, 0): MCI_Check errs, cmd

Do
    _Limit 60
Loop Until InKey$ <> ""

N = mciSendStringA&("stop " + aliasName, dummy, 0, 0)
N = mciSendStringA&("close " + aliasName, dummy, 0, 0)
End


Sub MCI_Check (errsCode As Long, where As String) 'error code handler if error occur
    Dim N As Long
    If errsCode <> 0 Then
        Dim msg As String
        msg = Space$(256)
        N = mciGetErrorStringA&(errsCode, msg, Len(msg))
        Print "MCI errsOR ("; errsCode; "): "; where
        Print RTrim$(msg)
        Sleep
        End
    End If
End Sub



RE: Dynamic Libraries - Petr - 12-13-2025

This version is more stable, none child / parent handle. Previous version freeze after 2 minutes (divX video), this not, is stable:

Code: (Select All)

Option _Explicit

Declare Dynamic Library "winmm"
    Function mciSendStringA& (lpstrCommand As String, lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As _Offset)
    Function mciGetErrorStringA& (ByVal dwerrsor As Long, lpstrBuffer As String, ByVal uLength As Long)
End Declare

Dim handle&: handle& = _NewImage(800, 600, 32)
Screen handle&
_Title "QB64 Video"

Dim hwnd As _Offset: hwnd = _WindowHandle

Dim filename As String, aliasName As String
filename = "(2014)na.avi"
aliasName = "vid"

Dim cm As String, e As Long
Dim dummy As String: dummy = Space$(1)

' 1) Open
cm = "open " + Chr$(34) + filename + Chr$(34) + " type mpegvideo alias " + aliasName
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check e, cm

' 2) Attach to QB64 window handle (more stable than parent/style child)
cm = "window " + aliasName + " handle " + LTrim$(Str$(hwnd))
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check e, cm

' 3) Set destination rect (not "put window at")
cm = "put " + aliasName + " destination at 0 0 800 600"
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check Err, cm

' 4) Play
cm = "play " + aliasName
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check Err, cm

Do
    _Limit 60
    _Display ' let s messages going and window as active (QB64 help)
Loop Until InKey$ <> ""
Dim N As Long
N = mciSendStringA&("stop " + aliasName, dummy, 0, 0)
N = mciSendStringA&("close " + aliasName, dummy, 0, 0)
End

Sub MCI_Check (errsCode As Long, where As String)
    Dim n As Long
    If errsCode <> 0 Then
        Dim msg As String
        msg = Space$(256)
        n = mciGetErrorStringA&(errsCode, msg, Len(msg))
        Print "MCI error ("; errsCode; "): "; where
        Print RTrim$(msg)
        Sleep
        End
    End If
End Sub



RE: Dynamic Libraries - ahenry3068 - 12-13-2025

(12-13-2025, 09:03 PM)Petr Wrote: This version is more stable, none child / parent handle. Previous version freeze after 2 minutes (divX video), this not, is stable:

Code: (Select All)

Option _Explicit

Declare Dynamic Library "winmm"
    Function mciSendStringA& (lpstrCommand As String, lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As _Offset)
    Function mciGetErrorStringA& (ByVal dwerrsor As Long, lpstrBuffer As String, ByVal uLength As Long)
End Declare

Dim handle&: handle& = _NewImage(800, 600, 32)
Screen handle&
_Title "QB64 Video"

Dim hwnd As _Offset: hwnd = _WindowHandle

Dim filename As String, aliasName As String
filename = "(2014)na.avi"
aliasName = "vid"

Dim cm As String, e As Long
Dim dummy As String: dummy = Space$(1)

' 1) Open
cm = "open " + Chr$(34) + filename + Chr$(34) + " type mpegvideo alias " + aliasName
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check e, cm

' 2) Attach to QB64 window handle (more stable than parent/style child)
cm = "window " + aliasName + " handle " + LTrim$(Str$(hwnd))
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check e, cm

' 3) Set destination rect (not "put window at")
cm = "put " + aliasName + " destination at 0 0 800 600"
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check Err, cm

' 4) Play
cm = "play " + aliasName
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check Err, cm

Do
    _Limit 60
    _Display ' let s messages going and window as active (QB64 help)
Loop Until InKey$ <> ""
Dim N As Long
N = mciSendStringA&("stop " + aliasName, dummy, 0, 0)
N = mciSendStringA&("close " + aliasName, dummy, 0, 0)
End

Sub MCI_Check (errsCode As Long, where As String)
    Dim n As Long
    If errsCode <> 0 Then
        Dim msg As String
        msg = Space$(256)
        n = mciGetErrorStringA&(errsCode, msg, Len(msg))
        Print "MCI error ("; errsCode; "): "; where
        Print RTrim$(msg)
        Sleep
        End
    End If
End Sub

     Have you done any research into duplicating this capability on Linux,  Perhaps with the VLC or FFMPEG libraries ??
(Also if you use one of those libraries I bet it's possible to more easily have $IF's  in the Code for OS targeting  !


RE: Dynamic Libraries - Petr - 12-14-2025

(12-13-2025, 11:16 PM)ahenry3068 Wrote:
(12-13-2025, 09:03 PM)Petr Wrote: This version is more stable, none child / parent handle. Previous version freeze after 2 minutes (divX video), this not, is stable:

Code: (Select All)

Option _Explicit

Declare Dynamic Library "winmm"
    Function mciSendStringA& (lpstrCommand As String, lpstrReturnString As String, ByVal uReturnLength As Long, ByVal hwndCallback As _Offset)
    Function mciGetErrorStringA& (ByVal dwerrsor As Long, lpstrBuffer As String, ByVal uLength As Long)
End Declare

Dim handle&: handle& = _NewImage(800, 600, 32)
Screen handle&
_Title "QB64 Video"

Dim hwnd As _Offset: hwnd = _WindowHandle

Dim filename As String, aliasName As String
filename = "(2014)na.avi"
aliasName = "vid"

Dim cm As String, e As Long
Dim dummy As String: dummy = Space$(1)

' 1) Open
cm = "open " + Chr$(34) + filename + Chr$(34) + " type mpegvideo alias " + aliasName
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check e, cm

' 2) Attach to QB64 window handle (more stable than parent/style child)
cm = "window " + aliasName + " handle " + LTrim$(Str$(hwnd))
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check e, cm

' 3) Set destination rect (not "put window at")
cm = "put " + aliasName + " destination at 0 0 800 600"
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check Err, cm

' 4) Play
cm = "play " + aliasName
e = mciSendStringA&(cm, dummy, 0, 0): MCI_Check Err, cm

Do
    _Limit 60
    _Display ' let s messages going and window as active (QB64 help)
Loop Until InKey$ <> ""
Dim N As Long
N = mciSendStringA&("stop " + aliasName, dummy, 0, 0)
N = mciSendStringA&("close " + aliasName, dummy, 0, 0)
End

Sub MCI_Check (errsCode As Long, where As String)
    Dim n As Long
    If errsCode <> 0 Then
        Dim msg As String
        msg = Space$(256)
        n = mciGetErrorStringA&(errsCode, msg, Len(msg))
        Print "MCI error ("; errsCode; "): "; where
        Print RTrim$(msg)
        Sleep
        End
    End If
End Sub

     Have you done any research into duplicating this capability on Linux,  Perhaps with the VLC or FFMPEG libraries ??
(Also if you use one of those libraries I bet it's possible to more easily have $IF's  in the Code for OS targeting  !
So far I've tried to deal with Linux twice. Unsuccessfully. The system is confusing to me personally. I tried it from a virtualized environment via Ubuntu, but most things there are completely different from Windows. I already have an IDE installed in Linux, I also have a C compiler there, yes, all that. But now I've been more on Windows. Of course, I would also be happy if everything in this thread could be run on Linux. I'll try. But don't expect quick progress, because there are a lot of unknowns for me. I'll definitely try. As soon as you see the Dynamic Libraries (SO) thread here, you'll know that I've succeeded with something... yes, I also thought about the use of ffmpeg dynamic libraries. This is a good option.


RE: Dynamic Libraries - Petr - 12-15-2025

This program is inspired by ask from @Mad Axeman:

Is there a menu function with a display similar to _InputBox$ and  _MessageBox ? 

Here is something like this. In addition, it allows quick search for an item by text in the upper part. Scrolling with the mouse wheel, arrows. Because it uses CallBack functions, it is in DLL (easier work). The return value is the index number. (The first line is zero index (based 0) or 1 index (based 1) .

The text is passed to the function in a string, where individual items are separated by CHR$(10) and after the last item there must be CHR$(0)! - if you do not put it there (CHR$(0)), the last item can be spread over multiple lines!

The ZIP file contains BAS program, 32 and 64 bit DLL and source code for DLL in C. Compiled via cl.


RE: Dynamic Libraries (Windows) - Petr - 12-15-2025

@Mad Axeman, I didn't forget. Here's a version of ListMenu for Windows without the top search bar. This time it's in the form of a .h file. This eliminates the need to create 32-bit and 64-bit DLLs. 

Code: (Select All)

Declare CustomType Library "listpickB"
    Function PickFromListACP& (title As String, prompt As String, items As String, ByVal startIndex As Long)
End Declare

Dim outt As String * 1024 ' buffer pro nßvratovř text (ACP), NUL-terminated
outt = String$(Len(outt), Chr$(0))


text:
Data "One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Cočka","Zelí","Pekč","Uzenáč","Pískle","Slepýš","Pakliže","One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","4očka","Zelí","Pekáč","Uzenáč","Pískle","Slepýš","Pakliže"
Restore text
For fill = 1 To 34
    Read t$
    items$ = items$ + t$ + Chr$(10)
Next fill
items$ = items$ + Chr$(0)

title$ = "Select... " + Chr$(0)
prompt$ = "Arrows / click, Enter select, Esc abort" + Chr$(0)
' Polozky oddelene LF. Na konci NUL.


idx& = PickFromListACP&(title$, prompt$, items$, 0)

Print "Selected index (0-based):"; idx&
If idx& >= 0 Then Print "1-based:"; idx& + 1
Sleep

H file is needed.


RE: Dynamic Libraries (Windows) - Pete - 12-18-2025

@Petr

I copied the code for the avi player, but I get ERROR CODE: Video not available, cannot find 'vids:mjpg' decompressor.

The sound starts to play for a second, but then just repeats as a loop. The screen shows the error message and brown diagonal lines on a white background while the sound loops.

So it's trying to work, but my guess is I have to download some zip or other file(s) with the vids:mjpg decompressor to get it to play the 3-minute vid. Please advise.

Windows 10, 64-bit. Yes, I used your latest POSTED code for the 64-bit version, but I did not find any zip file for this entry.

Pete


RE: Dynamic Libraries (Windows) - Steffan-68 - 12-18-2025

(12-18-2025, 07:45 PM)Pete Wrote: @Petr
I copied the code for the avi player, but I get ERROR CODE: Video not available, cannot find 'vids:mjpg' decompressor.
The sound starts to play for a second, but then just repeats as a loop. The screen shows the error message and brown diagonal lines on a white background while the sound loops.
So it's trying to work, but my guess is I have to download some zip or other file(s) with the vids:mjpg decompressor to get it to play the 3-minute vid. Please advise.
Windows 10, 64-bit. Yes, I used your latest POSTED code for the 64-bit version, but I did not find any zip file for this entry.
Pete
This sounds somehow like a problem with the Winmm.dll.
the wrong version is probably found on your computer.
I've had that one time before.
In the Windows folder there are several of different sizes.
Find one and copy it into your QB64 main Ortner, so the program can find it and try it out.
If not take another .