Help with C++ to Xojo conversion - solved

Maybe the camera driver is presenting more than one camera interface for the same physical camera? The project as written only uses the first device listed.

Try creating a new blank project and copy this into the Window1.Open event:

  Declare Function capGetDriverDescriptionW Lib "Avicap32" (DriverIndex As UInt16, DriverName As Ptr, NameLen As Integer, DriverVersion As Ptr, VersionLen As Integer) As Boolean
  Dim i As Integer
  Dim nm As New MemoryBlock(1024)
  Do Until Not capGetDriverDescriptionW(i, nm, nm.Size, Nil, 0)
    MsgBox(nm.WString(0))
    i = i + 1
    nm = New MemoryBlock(1024)
  Loop

It should pop-up a msgbox for each available camera interface. I’m kind of skeptical but it’s the only thing I can think of.

If there’s more than one interface you can change the initialization code in Pushbutton5.Action to use the device by changing the index. The index is given as the last parameter to capCreateCaptureWindowA and as the third parameter to the SendMessage/WM_CAP_DRIVER_CONNECT call.

i.e.

  Dim index As Integer
  cap=capCreateCaptureWindowA("My Output Window",WS_CHILD Or WS_VISIBLE,0,0,Canvas1.Width,Canvas1.Height,canvas1.handle,index)
    CALL SendMessage (cap,WM_CAP_DRIVER_CONNECT,index,0)

Hi,
I am hoping not to disturb you both too much…
I was testing with:

Declare Function SendMessage lib “user32” alias “SendMessageA”(hwnd as integer,wMsg as integer,wParam as integer,lParam as integer)AS integer

CALL SendMessage(cap,1092,0,0)
CALL SendMessage(cap,1093,0,0)
CALL SendMessage(cap,1035,0,0)

it disconnects and i had once to click about 6 times to reconnect the webcam(looked it worked…)… but i can’t make it
‘stable’
Perhaps you need the drivername… but ill quit for now. Succes!

Hi Andrew,

I did that and on launch a window appears

Untitled

Microsoft WDM Image Capture (Win32)

                                                             OK

When I click OK an “Untitled” window with nothing in it comes up.

OK, I will erase that disk and reinstall the OS tomorrow and see what happens.

Thanks again.

Thanks Frederik, I will try that before I erase the disk.

Lennox

This sounds like a second interface. You should see what happens if you change the index to 1.

Hi Andrew,

Changing the index to 1 did not make a difference.

I’ll follow up tomorrow, it’s bedtime now, good night.

Thanks again everyone for all the help/participation.

Lennox

OK, the webcam app does not work on any of my computers but it works on others, thanks Tim for testing, I’ll have to sort that out, I will completely reformat my hard drive and see what happens.

The problem I am having is that it connect without any problems but it does not disconnect.

OK, thanks Frederick for the app and advising me to google for some information.
I did that and for the benefit of others I came up with these which are very helpful…
https://msdn.microsoft.com/en-us/library/kt7c0708.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms632682(v=vs.85).aspx
http://www.freebasic.net/forum/viewtopic.php?t=12479
https://channel9.msdn.com/Forums/TechOff/93476-Programatically-Using-A-Webcam-In-C
http://forums.purebasic.com/english/viewtopic.php?p=14850
https://msdn.microsoft.com/en-us/library/windows/desktop/ms644950(v=vs.85).aspx
http://www.functionx.com/win32/Lesson05.htm
https://code.msdn.microsoft.com/windowsdesktop/how-to-create-webcam-bbdcc90f

I could not convert the code from C++ to Xcode, but after Andrew did it for me I really started to understand what it’s all about, and I recommend others like me to check these links, thanks Andrew.

So even though it does not work on my computers, and I see that Andrew’s code should work, I have learnt quite a few things in this exercise.

I trust that I would eventually get it working on my computer.

Thanks for all the input and if there are more I’ll be checking back for updates.

Thanks again.

Lennox

In the action event of PushButton5 i added:

Line 2: Const WM_CAP_DLG_VIDEOFORMAT = 1065

line 17: CALL SendMessage (cap,WM_CAP_DLG_VIDEOFORMAT,1,0)

This will display a window where you can choose the dimensions/resolution of the video. If the program gets wrong dimensions then you could get a black picture/window which in fact is saying the ‘chosen’ format is not supported by the driver. After selecting the / a supported resolution i got pictures with a higher resolution(640480) than originally(320240) when using this program.

Maybe before formatting the disk/reinstall the OS you could try this.
HTH Andre

Thanks Andre,

I did that and got the window where the dimensions/resolution can be selected, thanks, that’s a good feature, but I still get the previous mentioned problems.

Thanks.

Lennox

OK, this is my observation,

When the app is launched the first time and the connect button is clicked the light for the camera comes on and the video starts, all features are available and the light stays on until the app is closed.
In my opinion all connections to the camera are closed when the app is closed.
The app works as it was intended.

When the app is launched again, when the connect button is clicked, the canvas becomes black and immediately after a window comes up requesting which video device should be used, in my case there is only one and as such the window should not appear. That video device should be connected automatically.
When the window is dismissed, the canvas remains black and nothing happens, the light does not come on at any time during a relaunch, and clicking on “Take Snapshot!” will display the last snapshot that was taken before relaunching the app. This picture is saved as temp in the app’s folder.

If the computer is rebooted, everything works well the first time the app is launched, but on closing and relaunching the same process outlined above occurs.

So, in my opinion, the problem occurs when the Connect button is clicked on a second or subsequent launch of the app.

Apparently, this is not happening on your computer.

Any ideas/suggestions?

Thanks again.

Lennox

I found that I did occasionally get that window pop up, but if I dismissed it and clicked the connect button again, it would eventually connect.

OK, I have reformatted the hard drive and reinstalled Windows 10, and am still having the same problems.

So what I would have to do is to add a messagdialog indicating that if the app is closed the user will have to reboot to use it again.

If anyone should have a solution I would appreciate it.

Thanks again.

Lennox

Deleted

I have viewed this link http://guitarz.org/files/capture.r and noticed this piece of code

	sendmessage cap-result WM_CAP_END 0 0
	sendmessage cap-result WM_CAP_DRIVER_DISCONNECT 0 0
	free user32.dll
	quit

How do I code “free user32.dll” in Xojo?

Thanks.

Lennox

@Lennox Jacob ,
Could this be your problem:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/6d2d2e0f-cab7-4299-a778-cb8d9bab4b0d/avicap32dll-wmcapdriverconnect-problem?forum=csharpgeneral

At the end of that conversation there could be a solution.

Thanks Andre,

I will be trying that shortly, I am using windows 10, I would really like to have this issue laid to rest.

Thanks again.

Lennox

OK this is what is recommended and what I did…

First you need this API function
Private Declare Function GetTickCount Lib “kernel32” () As Long
So I added
Declare Function GetTickCount Lib “kernel32” () As long
but that gives a compile error
so I changed that to
Declare Function GetTickCount Lib “kernel32” () As integer

Then… after you call capCreateCaptureWindowA() you have to wait 1 second processing events, (note: sleep don’t work the same)
IniTime = GetTickCount()
While GetTickCount() < (IniTime + 1000)
DoEvents
Wend
then you call WM_CAP_DRIVER_CONNECT… and THAT’s IT… no more Video Source dialog

So, I did this…
Sub GetTickCount(IniTime As Integer)
While IniTime < (IniTime + 1000)
IniTime = IniTime + 1
Wend
End Sub

and I added this…
Dim IniTime as integer
IniTime = 100
IniTime = GetTickCount()

immediately above CALL SendMessage (cap,WM_CAP_DRIVER_CONNECT,0,0)

This is what my amended portion in the code looks like…

Declare Function GetTickCount Lib “kernel32” () As integer

Dim IniTime as integer
IniTime = 100
IniTime = GetTickCount()

CALL SendMessage (cap,WM_CAP_DRIVER_CONNECT,0,0)
CALL SendMessage (cap,WM_CAP_SET_SCALE,1,0)
CALL SendMessage (cap,WM_CAP_SET_PREVIEWRATE,20,0)
CALL SendMessage (cap,WM_CAP_SET_PREVIEW,1,0)

It compiled, but it did not work, I think I am not doing it correctly.

Kindly advise.

Thanks again.

Lennox

Hi Lennox,
No i don’t think you did it wrong as far as i know. The only thing that was needed was a little more time to find the appropriate window to connect the camera driver to, which i simply tried with putting a messagebox in the program on that place without having success either.
Because the program behaved as it should on my desktop with a very cheap usb camera, I have tried the program on my laptop (Lenovo) and there i got a black window too. After some experimenting i try the program with my addition:
In the action event of PushButton5 i added:

Line 2: Const WM_CAP_DLG_VIDEOFORMAT = 1065

line 17: CALL SendMessage (cap,WM_CAP_DLG_VIDEOFORMAT,1,0)

In the popup window you have the oportunity to change the resolution and the pixeldepth. After selecting the resolution i could select 2 settings for the pixeldepth combobox: ‘MJPG’ and ‘YUY2’. With the default ‘MJPG’ all resolutions give a black window, however choosing the ‘YUY2’ option all resolutions work as they should.
Maybe your laptop camera or your Nikon camera have also default setting for a too high pixeldepth. Please try this, maybe this is a solution for your problem.
“Pray to Play”

Thanks for your input/suggestions/recommendations Andre,

This is what I now have…

Declare Function SendMessage lib “user32” alias “SendMessageA”(hwnd as integer,wMsg as integer,wParam as integer,lParam as integer)AS integer
Const WM_CAP_DLG_VIDEOFORMAT = 1065
Const WM_CAP_SET_PREVIEW = 1074
Const WM_CAP_SET_PREVIEWRATE = 1076
Const WM_CAP_SET_SCALE = 1077
Const WM_CAP_DRIVER_DISCONNECT = 1035
Const WM_CAP_DRIVER_CONNECT = 1034
Const WS_VISIBLE = &h10000000
Const WS_CHILD = &h40000000

If cap <> 0 Then Call SendMessage(cap,WM_CAP_DRIVER_DISCONNECT,0,0)

Declare Function GetTickCount Lib “kernel32” () As integer
Dim IniTime as integer
IniTime = 100
IniTime = GetTickCount()

Declare Function capCreateCaptureWindowA lib “avicap32.dll” (lpszWindowName as CString,dwStyle as Integer,x as integer,y as integer,nWidth as integer,nHeight as integer,hWndParent as integer,nID as integer)as integer
cap=capCreateCaptureWindowA(“My Output Window”,WS_CHILD Or WS_VISIBLE,0,0,Canvas1.Width,Canvas1.Height,canvas1.handle,0)

CALL SendMessage (cap,WM_CAP_DRIVER_CONNECT,0,0)
CALL SendMessage (cap,WM_CAP_DLG_VIDEOFORMAT,1,0)
CALL SendMessage (cap,WM_CAP_SET_SCALE,1,0)
CALL SendMessage (cap,WM_CAP_SET_PREVIEWRATE,20,0)
CALL SendMessage (cap,WM_CAP_SET_PREVIEW,1,0)

In my opinion that should work.

It is not that it does not work…

  1. sometimes, not all the time, upon reboot or startup it works, but if I close the app and relaunch it, it will not work. I have to reboot and then it may not work on the first reboot, I have to reboot again and maybe, again and again until it finally works. But if I close the app and relaunch it, it will not work.

  2. right now I am testing it on an ASUS X554L laptop with Windows 10 and I am using the built-in camera.

Previously I was trying with the Nikon D3200 and Video 2 PC, http://www.ionaudio.com/products/details/video-2-pc-mkii , and also a Sony DCR-TRV203 Handicam with the Video 2 PC and all of the combination gives the same result.

I am using a “bare-bones” version of that project, just the Canvas, the connect button and the snapshot button and I replaced the snapshot canvas with an image well, nothing else.

I have added a “Freeze” PushButton" so that I can freeze the video stream, I know that I can take a snapshot, but I want to freeze the video stream in its canvas, my code for this is…

dim la as integer
la=len(app.executablefile.name)
dim bn as string
bn = app.gTheEndoscopyImagesFolder.absolutepath // bn = WebcamImagesFolder.absolutepath

dim def as string
def=bn

Declare Function SendMessage lib “user32” alias “SendMessageA”(hwnd as integer,wMsg as integer,wParam as integer,lParam as integer)AS integer

DIM START AS INTEGER
DIM SAVE AS INTEGER
DIM G AS INTEGER

START =&H400
G=START+61

CALL SendMessage(cap,G,0,0)

but it does not work as intended, maybe I am missing something there, maybe someone can help with that.

I have PowerDirector, I would like to customise it for my needs but I have no control over PowerDirector, so I have to make this app work. PowerDirector does not have these problems, it works upon launch and relaunch as often as I like without having the reason to reboot.

Thanks again Andre, and I do appreciate your input/suggestions/recommendations and most of all your time and patience.

Lennox

Hi Andre,

My understanding of …

// https://social.msdn.microsoft.com/Forums/vstudio/en-US/6d2d2e0f-cab7-4299-a778-cb8d9bab4b0d/avicap32dll-wmcapdriverconnect-problem?forum=csharpgeneral
'Finally I Found a solution for this
'The problem happen in Windows 7 / 8

'First you need this API function
'Private Declare Function GetTickCount Lib “kernel32” () As Long

'Then… after you call capCreateCaptureWindowA() you have to wait 1 second processing events, (note: sleep don’t work the same)

'IniTime = GetTickCount()
'While GetTickCount() < (IniTime + 1000)
'DoEvents
'Wend

'then you call WM_CAP_DRIVER_CONNECT… and THAT’s IT… no more Video Source dialog

is that after this

If cap <> 0 Then Call SendMessage(cap,WM_CAP_DRIVER_DISCONNECT,0,0)

the app is waiting for the capture device to be released…

so I did this…

Declare Function GetTickCount Lib “kernel32” () As integer
Dim IniTime as integer
IniTime = 100
msgbox Str(IniTime)
IniTime = GetTickCount()
msgbox Str(IniTime)

I added a message box before and after IniTime = GetTickCount()

Now no matter how long I wait before dismissing the second msgbox, the result is the same so there got to be some other problem.

I do not know if my reasoning is sound.

Thanks again.

Lennox

Thanks everyone for all their input/suggestions/recommendation, time and patience

This seems to solve my problem…

Declare Function SendMessage lib “user32” alias “SendMessageA”(hwnd as integer,wMsg as integer,wParam as integer,lParam as integer)AS integer
'Const WM_CAP_DLG_VIDEOFORMAT = 1065
Const WM_CAP_SET_PREVIEW = 1074
Const WM_CAP_SET_PREVIEWRATE = 1076
Const WM_CAP_SET_SCALE = 1077
Const WM_CAP_DRIVER_DISCONNECT = 1035
Const WM_CAP_DRIVER_CONNECT = 1034
Const WS_VISIBLE = &h10000000
Const WS_CHILD = &h40000000

If cap <> 0 Then Call SendMessage(cap,WM_CAP_DRIVER_DISCONNECT,0,0)

Declare Function capCreateCaptureWindowA lib “avicap32.dll” (lpszWindowName as CString,dwStyle as Integer,x as integer,y as integer,nWidth as integer,nHeight as integer,hWndParent as integer,nID as integer)as integer
cap=capCreateCaptureWindowA(“My Output Window”,WS_CHILD Or WS_VISIBLE,0,0,Canvas1.Width,Canvas1.Height,canvas1.handle,0)

Declare Function GetTickCount Lib “kernel32” () As integer
Dim IniTime As Double

IniTime = 100
IniTime = GetTickCount()

Dim OKAnswer As Boolean = False
For xretries As Integer = 1 To 10
’ I’ll give you Only 10 tries to connect, otherwise I AM LEAVING MICROSOFT!
If SendMessage(cap, WM_CAP_DRIVER_CONNECT, 0, 0) <> 0 Then
OKAnswer = True
Exit
End If
Next

If okanswer Then
CALL SendMessage (cap,WM_CAP_SET_SCALE,1,0)
CALL SendMessage (cap,WM_CAP_SET_PREVIEWRATE,20,0)
CALL SendMessage (cap,WM_CAP_SET_PREVIEW,1,0)
Else
Declare Function DestroyWindow Lib “User32” (HWND As Integer) As Boolean
Call DestroyWindow(cap)
End If

Maybe a little polishing may shorten it, but this works for me.

Thanks again.
Credit goes here… http://stackoverflow.com/questions/10721085/webcam-video-source-dialog-comes-up

Lennox