Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to set Height, Width and Video Format in VFP using AVICAP32.DLL

Status
Not open for further replies.

dylim

Programmer
Dec 12, 2001
106
0
16
PH
Hi Guys,

I was able to fire up a webcam on a VFP form using this link:


The problem is, every time the form shows, it will always show a Format Dialog (shown below) asking for Resolution, Pixel Depth and Size.

Screenshot_2023-10-26_155714_xnl5oy.png


Anyway I can programmatically set the three parameters?
 
Chriss,

I create class BITMAPINFOHEADER which is a subclass of Christof's STRUCT class.

The entire data structure is defined in the class I created.

My bad. I should have told you that earlier.

And yes, 'This' was used in the webcam class. Not ThisForm.

 
I don't know, let's shorten it to the fact the code works now, you can retry to factorize the code so the SetVideoFormat code becomes part of the webcam class, that's surely something to favor.

But otherwise, I'd just file this under "mystery".

Chriss
 
Chriss,

That's exactly what I did - I created method SetVideoFormat in the Webcam class so that it would be cleaner.

Turned out though that this method's code have to be explicitly in the Form Init() rather than calling oWebcam.SetVideoFormat() for it to work.
 
I don't see a reason, since you also can call the interactive dialog to change video format at any time.

The form init is also not the init of the capture window, the capture window has its own hwnd, so there's something else that you didn't transpose correctly, when you moved code into the webcam class.

Chriss
 
Chriss

Let me double check my code sir.

I appreciate your precious time. You based in the US of A? You still doing VFP apps? Are there still VFP dev going on there?
 
Hi Chriss,

And the plot thickens. Below is the code of two classes - BitMapInfoHeader class (based on Struct class) and Webcam (wrapper class to the GitHub code).

[pre]**************************************************
*-- Class Library: d:\vfpxdev\payprox\classes\webcam.vcx
**************************************************

*-- Class: bitmapinfoheader (d:\vfpxdev\payprox\classes\webcam.vcx)
*-- ParentClass: struct (d:\vfpxdev\common\classes\struct.vcx)
*-- BaseClass: label
*-- Time Stamp: 10/27/23 01:41:03 PM
*
DEFINE CLASS bitmapinfoheader AS struct
Height = 17
Width = 137
bisize = 0
biwidth = 0
biheight = 0
biplanes = 0
bibitcount = 0
bicompression = 0
bisizeimage = 0
bixpelspermeter = 0
biypelspermeter = 0
biclrused = 0
biclrimportant = 0
cmembers = "ul:biSize, sl:biWidth, sl:biHeight, uw:biPlanes, uw:biBitCount, ul:biCompression, ul:biSizeImage, sl:biXPelsPerMeter, sl:biYPelsPerMeter, ul:biClrUsed, ul:biClrImportant"
Name = "bitmapinfoheader"
ENDDEFINE
*
*-- EndDefine: bitmapinfoheader

**************************************************
*-- Class: webcam (d:\vfpxdev\payprox\classes\webcam.vcx)
*-- ParentClass: _custom (d:\vfpxdev\common\classes\base.vcx)
*-- BaseClass: custom
*-- Time Stamp: 10/28/23 03:11:07 PM
*
#INCLUDE "d:\vfpxdev\payprox\classes\webcam.h"
*
DEFINE CLASS webcam AS _custom
Height = 16
Width = 87
hwindow = 0
hcapture = 0
capwidth = 0
capheight = 0
capoverlay = 0
capleft = 0
captop = 0
bitmapinfoheaderclass = "bitmapinfoheader"
bitmapinfoheaderclasslib = "webcam.vcx"
usebitmapinfo = .F.
bisize = 0
biwidth = 0
biheight = 0
biplanes = 0
bibitcount = 0
bicompression = 0
bisizeimage = 0
bixpelspermeter = 0
biypelspermeter = 0
biclrused = 0
biclrimportant = 0
Name = "webcam"

PROCEDURE declaredlls
DECLARE INTEGER DestroyWindow IN user32 INTEGER hWindow

DECLARE INTEGER capCreateCaptureWindow IN avicap32;
STRING lpszWindowName, LONG dwStyle,;
INTEGER x, INTEGER y, INTEGER nWidth,;
INTEGER nHeight, INTEGER hParent, INTEGER nID

DECLARE INTEGER SetWindowPos IN user32;
INTEGER hWindow, INTEGER hWndInsertAfter,;
INTEGER x, INTEGER y, INTEGER cx, INTEGER cy,;
INTEGER wFlags

DECLARE INTEGER SendMessage IN user32 As SendMsgInt;
INTEGER hWindow, INTEGER Msg,;
INTEGER wParam, INTEGER lParam

DECLARE INTEGER SendMessage IN user32 As SendMsgStr;
INTEGER hWindow, INTEGER Msg,;
INTEGER wParam, STRING @lParam
ENDPROC

PROCEDURE cleardlls
CLEAR DLLS "DestroyWindow", "capCreateCaptureWindow", "SetWindowPos",;
"SendMsgInt", "SendMsgStr"
ENDPROC

PROCEDURE releasecapturewindow
IF This.hCapture # 0
This.DriverDisconnect()
= DestroyWindow( This.hCapture )
This.hCapture = 0
ENDIF
ENDPROC

PROCEDURE driverdisconnect
This.MessageCenter( WM_CAP_DRIVER_DISCONNECT, 0, 0 )
ENDPROC

PROCEDURE messagecenter
LPARAMETERS msg, wParam, lParam, nMode

DO CASE
CASE This.hCapture = 0
CASE VARTYPE( nMode ) # "N" OR nMode = 0
= SendMsgInt( This.hCapture, msg, wParam, lParam )
OTHERWISE
= SendMsgStr( This.hCapture, msg, wParam, @lParam )
ENDCASE
ENDPROC

PROCEDURE getvideoformat
LOCAL cBuffer, nBuffSize

nBuffSize = 4096
cBuffer = PADR( This.Num2DWord( BITMAPINFOHEADER_SIZE ), nBuffsize, CHR(0) )
This.MessageCenter( WM_CAP_GET_VIDEOFORMAT, nBuffsize, @cBuffer, 1 )
This.capWidth = This.Buff2DWord( SUBSTR(cBuffer, 5, 4) )
This.capHeight = This.Buff2DWord( SUBSTR(cBuffer, 9, 4) )
ENDPROC

PROCEDURE num2dword
LPARAMETERS lnValue

LOCAL b0, b1, b2, b3

#DEFINE m0 0x100
#DEFINE m1 0x10000
#DEFINE m2 0x1000000

IF lnValue < 0
lnValue = 0x100000000 + lnValue
ENDIF

b3 = INT( lnValue/m2 )
b2 = INT( (lnValue - b3*m2)/m1 )
b1 = INT( (lnValue - b3*m2 - b2*m1)/m0 )
b0 = MOD( lnValue, m0 )

RETURN CHR( b0 ) + CHR( b1 ) + CHR( b2) + CHR( b3 )
ENDPROC

PROCEDURE buff2dword
LPARAMETERS lcBuffer

RETURN Asc( SUBSTR(lcBuffer, 1,1) ) + ;
BitLShift( Asc( SUBSTR(lcBuffer, 2,1)), 8 ) +;
BitLShift( Asc( SUBSTR(lcBuffer, 3,1)), 16 ) +;
BitLShift( Asc( SUBSTR(lcBuffer, 4,1)), 24 )
ENDPROC

PROCEDURE resizecapturewindow
This.GetVideoFormat()

= SetWindowPos( This.hCapture, 0, This.capLeft, This.capTop, This.capWidth, This.capHeight, SWP_SHOWWINDOW )
ENDPROC

PROCEDURE getframe
This.MessageCenter( WM_CAP_GRAB_FRAME, 0, 0 )
ENDPROC

PROCEDURE showformatdialog
This.MessageCenter( WM_CAP_DLG_VIDEOFORMAT, 0,0 )
This.ResizeCaptureWindow()
ENDPROC


PROCEDURE iscaptureconnected
LOCAL cBuffer, nResult
cBuffer = REPLICATE( CHR(0), CAPDRIVERCAPS_SIZE )
This.MessageCenter( WM_CAP_DRIVER_GET_CAPS, LEN(cBuffer), @cBuffer, 1 )
This.capOverlay = This.Buff2DWord( SUBSTR(cBuffer,5,4) )
nResult = ASC( SUBSTR( cBuffer, 21, 1 ) )
RETURN ( nResult # 0 )
ENDPROC


PROCEDURE driverconnect
This.MessageCenter( WM_CAP_DRIVER_CONNECT, 0, 0 )
RETURN This.IsCaptureConnected()
ENDPROC

PROCEDURE startpreview
This.MessageCenter( WM_CAP_SET_PREVIEWRATE, 30, 0 )
This.MessageCenter( WM_CAP_SET_PREVIEW, 1, 0 )

IF This.capOverlay # 0
This.MessageCenter( WM_CAP_SET_OVERLAY, 1, 0 )
ENDIF
ENDPROC

PROCEDURE stoppreview
This.MessageCenter( WM_CAP_SET_PREVIEW, 0, 0 )
ENDPROC

PROCEDURE savetodib
LPARAMETERS lcPath

LOCAL cFilename, lcTempDir

IF PCOUNT() > 0
cFilename = ADDBS( lcPath ) + SYS(2015) + ".dib" + CHR(0)
ELSE
cFilename = SYS(2015) + ".dib" + CHR(0)
ENDIF

This.MessageCenter( WM_CAP_FILE_SAVEDIB, 0, @cFilename, 1 )

RETURN cFilename
ENDPROC


PROCEDURE initcapturewindow
LPARAMETERS hParent, nLeft, nTop

WITH This

.hWindow = hParent
.capLeft = nLeft
.capTop = nTop
.capWidth = 0
.capHeight = 0
.hCapture = capCreateCaptureWindow("", BITOR( WS_CHILD, WS_VISIBLE ), .capLeft, .capTop, 1, 1, .hWindow, 1 )

IF .DriverConnect()
.MessageCenter( WM_CAP_SET_SCALE, 1, 0 )
.ResizeCaptureWindow()
ENDIF

ENDWITH

RETURN This.IsCaptureConnected()
ENDPROC

PROCEDURE setvideoformat
LOCAL loBitMapInfoHeader, lcString, lpString

IF This.UseBitMapInfo

MESSAGEBOX( 'Using BitMapInfo...' )

loBitMapInfoHeader = NEWOBJECT( This.BitMapInfoHeaderClass, This.BitMapHeaderClassLib )
&& CREATEOBJECT( This.BitMapInfoHeaderClass )

loBitMapInfoHeader.biSize = loBitMapInfoHeader.SizeOf()
loBitMapInfoHeader.biWidth = This.biWidth
loBitMapInfoHeader.biHeight = This.biHeight
loBitMapInfoHeader.biPlanes = This.biPlanes
loBitMapInfoHeader.biBitCount = This.biBitCount
loBitMapInfoHeader.biCompression = This.biCompression
loBitMapInfoHeader.biSizeImage = This.biSizeImage
loBitMapInfoHeader.biXPelsPerMeter = This.biXPelsPerMeter
loBitMapInfoHeader.biYPelsPerMeter = This.biYPelsPerMeter
loBitMapInfoHeader.biClrUsed = This.biClrUsed
loBitMapInfoHeader.biClrImportant = This.biClrImportant

lpString = loBitMapInfoHeader.GetPointer( loBitMapInfoHeader.SizeOf() )

This.MessageCenter( WM_CAP_SET_VIDEOFORMAT, loBitMapInfoHeader.SizeOf(), lpString )

ELSE

This.ShowFormatDialog()

ENDIF

This.GetVideoFormat() && ???

* Below is to check the values on SCREEN

ACTIVATE SCREEN
CLEAR

? 'loBitMapInfoHeader Values'
? TRANSFORM( loBitMapInfoHeader.biSize )
? TRANSFORM( loBitMapInfoHeader.biWidth )
? TRANSFORM( loBitMapInfoHeader.biHeight )
? TRANSFORM( loBitMapInfoHeader.biPlanes )
? TRANSFORM( loBitMapInfoHeader.biBitCount )
? TRANSFORM( loBitMapInfoHeader.biCompression )
? TRANSFORM( loBitMapInfoHeader.biSizeImage )
? TRANSFORM( loBitMapInfoHeader.biXPelsPerMeter )
? TRANSFORM( loBitMapInfoHeader.biYPelsPerMeter )
? TRANSFORM( loBitMapInfoHeader.biClrUsed )
? TRANSFORM( loBitMapInfoHeader.biClrImportant )

? 'loBitMapInfoHeader Vartypes'
? VARTYPE( loBitMapInfoHeader.biSize )
? VARTYPE( loBitMapInfoHeader.biWidth )
? VARTYPE( loBitMapInfoHeader.biHeight )
? VARTYPE( loBitMapInfoHeader.biPlanes )
? VARTYPE( loBitMapInfoHeader.biBitCount )
? VARTYPE( loBitMapInfoHeader.biCompression )
? VARTYPE( loBitMapInfoHeader.biSizeImage )
? VARTYPE( loBitMapInfoHeader.biXPelsPerMeter )
? VARTYPE( loBitMapInfoHeader.biYPelsPerMeter )
? VARTYPE( loBitMapInfoHeader.biClrUsed )
? VARTYPE( loBitMapInfoHeader.biClrImportant )

? ''
? 'This Values'
? TRANSFORM( loBitMapInfoHeader.SizeOf() )
? TRANSFORM( This.biWidth )
? TRANSFORM( This.biHeight )
? TRANSFORM( This.biPlanes )
? TRANSFORM( This.biBitCount )
? TRANSFORM( This.biCompression )
? TRANSFORM( This.biSizeImage )
? TRANSFORM( This.biXPelsPerMeter )
? TRANSFORM( This.biYPelsPerMeter )
? TRANSFORM( This.biClrUsed )
? TRANSFORM( This.biClrImportant )

? 'This. Vartypes'
? VARTYPE( loBitMapInfoHeader.SizeOf() )
? VARTYPE( This.biWidth )
? VARTYPE( This.biHeight )
? VARTYPE( This.biPlanes )
? VARTYPE( This.biBitCount )
? VARTYPE( This.biCompression )
? VARTYPE( This.biSizeImage )
? VARTYPE( This.biXPelsPerMeter )
? VARTYPE( This.biYPelsPerMeter )
? VARTYPE( This.biClrUsed )
? VARTYPE( This.biClrImportant )
ENDPROC

PROCEDURE Destroy
This.ReleaseCaptureWindow()
ENDPROC

PROCEDURE Init
This.DeclareDLLs()
ENDPROC

ENDDEFINE
*
*-- EndDefine: webcam
**************************************************
[/pre]

In the SetVideoFormat method, I instantiated the BitMapInfoHeader class, then populated its properties like biHeight, biHeight etc. with the values of Webcam class (as oWebcam) which contains the exact same properties names but actual values when I dropped the Webcam custom class onto the Form.

[pre]oWebcam.biSize = loBitMapInfoHeader.SizeOf()
oWebcam.biWidth = 640
oWebcam.biHeight = 480
oWebcam.biPlanes = 1
oWebcam.biBitCount = 16
oWebcam.biCompression = 844715353
oWebcam.biSizeImage = 614400
oWebcam.biXPelsPerMeter = 0
oWebcam.biYPelsPerMeter = 0
oWebcam.biClrUsed = 0
oWebcam.biClrImportant = 0
[/pre]

Do note that in the SetVideoFormat(), I sent to the screen the values of these properties. And voila!

Screenshot_2023-10-28_220716_x72lu4.png


It is all blanks in the BitMapInfoHeader object! What the heck!
 
Chriss,

Know what?! I changed:

[pre] loBitMapInfoHeader = NEWOBJECT( This.BitMapInfoHeaderClass, This.BitMapHeaderClassLib )[/pre]

to...

[pre] loBitMapInfoHeader = CREATEOBJECT( This.BitMapInfoHeaderClass )[/pre]

And it finally worked! Why is this so?! WTH
 
That in itseelf makes no change. I doesn't matter whether an object is created by NEWOBJECT or CREATEOBJECT. Really none.

I get the feeling you're having errors you don't see, as an error handler just supresses them. Maybe not even something you're aware of. Likely.
Becuase something working in one case and not another points out there would be an error in the non working case, which, if you would see it would enable you to fix it.

But this is for sure, if in both cases an object is created, it is the same object. Both functions have the chance to work or fail in themselves in finding or not finding the class you want to create. But that's not a problem, is it? So since both create the object, the difference in how the objects work or not has to be something else.

One more thing that can easily play a role in all your testing and experimenting is that changes you do to source code may not have an immediate effect, if classes are still loaded in memory. VFP has CLEAR CLASS and CLEAR CLASSLIB to remove classes loaded in memory. But if you ask me how to ensure every new testrun uses the most recent code, you better do a CLEAR ALL before you start anything.

You sure get different oppinions on that one as it's quite drastic. Several application development frameworks in VFP load themselves when you start VFP and CLEAR ALL then removes framework classes the framework needs even at designtime in the IDE. And then reinitializating everything everytime would slowing down development, but CLEAR ALL is surely a way to ensure you're not chagin ghosts in the form of running old code you don't expect to run.

Chriss
 
Thanks, by they way, for posting your full code, I haven't looked into that yet, I will do that later, surely.

Chriss
 
Chriss,

Before I test run each of them scenarios, I always make it a point to do CLEAR ALL. I also redo the testing by quitting VFP and getting back to it.

Crazy really. Ever since I went to CREATEOBJECT and changed to different values, it works.

FWIW, the Struct class examples use CREATEOBJECT as well, which gave me the idea to switch to it in lieu of NEWOBJECT.

Gotta hit the sack though.. so freaked out by this project..
 
I bet you can change to NEWOBJECT again and it won't make a difference. Unless you specify another classlib in the NEWOBJECT call than you SET CLASSLIB to before using CREATEOBJECT.

That's the only difference between CREATEOBJECT and NEWOBJECT. CREATEOBJECT depends on SET CLASSLIB to make classes know, in case of classes defined in PRGs that's also including SET PROCEDURE TO to looik for classes in PRGs. NEWOBJECT, on the other hand has the classlib as a parameter. It's optional, and if not specified NEWOBEJCT actuall does exactly the same as CREATEOBJECT for finding the class to instanciate.

So...
dylim said:
I went to CREATEOBJECT and changed to different values
"changed to different values" is the only thing that can have the impact of making it work.

Chriss
 
Chriss,

I am fully aware of the differences between NEWOBJECT and CREATEOBJECT, with the latter having no need of the classlib being part of Set Classlib...

I will still dig deeper to my app settings sir.

Thanks.
 
My thought onj your blank value and vartypes of loBitMapInfoHeader

Well, you only set loBitMapInfoHeader to a bitmapinfo, IF This.UseBitMapInfo, but it is .F. in the class definition, isn't it?

Do you expect getvideoformat to set that? You know the code of getvideoformat. It does only extract the 8 bytes that are the width and height and then it forgets lcBuffer, it's a local variable, that's released after the method ends.

Chriss
 
Chriss,

To make the Webcam custom class more flexible, I added a UseBitMapInfo property which is .F. by default.

If .F., it will show the default Format Dialog. If .T., which is the case when I dropped it on the form, it will create the object loBitMapInfoHeader object and populate its properties from the Webcam object's property values with same names (biHeight, biWidth etc) which I also input when dropped on said form, which then calls SetVideoFormat().

That's why it's puzzling to see the blank values, moreso the blank VARTYPES.. shouldn't VARTYPES show X if undefined? Why is it blank?
 
You would get no output (not blank output, just no output) If an error happens. That's what I suspect.

If I run the code as it, it will define the variable loBitMapInfoHeader, which then is .F.
No object is created, but the lines printing still are executed, and each line errors.

So, I don't know, the class definition as is, even if I consider this print section just for debugging purposes, is not usable, unless I modify some things, i.e. unless I make some corrections.

I'll post further findings.

You're right though, if no error suppression happens, then you should have X and never blanks from all the vartypes. And even if loBitMapInfoHeader remains .f. as the section creating it and setting its properties is skipped. All vartypes of non existing properties would be U (not X), undefined, anbd cause no error.
Edit: No, all vartypes(loBitMapInfoHeader .property) when loBitMapInfoHeader remains .f. would cause the error "Alias 'loBitMapInfoHeader' is not found".

So I wonder if you really went through all this code, did you try to use the debugger and single stepped through all of this? Because that's the most enlightneing thing, printing is bad debugging.

One conclusion is, now you posted your class code, the code you do to use that class might be enlightening.

Chriss
 
So, here are the errors in your code

1. loBitMapInfoHeader = Newobject( This.bitmapinfoheaderclass, This.BitMapHeaderClassLib )

Errormessage: Property BITMAPHEADERCLASSLIB is not found.
Indeed, the property you defined and meant is bitmap[highlight #FCE94F]info[/highlight]headerclasslib

Simple error, it's not NEWOBJECT vs CREATEOBJECT, it's simply a lack of precision.
The question is, why you didn't report this error, didn't you get it? What are you doing for error handling? Nothing I assume, but then you would get an error messagebox popping up. Are you ignoring that?

2. Your class does not have an Init routine that calls declaredlls.
SoI added this:
Code:
3. You skipped the Activate code from the example. 

That's even okay, your webcam class is not a form with an activate event, you made it a _custom class. Fine. But you need to do what the activate event does in your class usage.

Usage code like this works, without using the setvideoformat method:
[code]oForm = CreateObject("form")
oForm.show()
oWebcam = CreateObject("webcam")
      
If oWebcam.InitCaptureWindow(oForm.HWnd, 5, 5)
   oWebcam.startpreview()      
EndIf

But since the essential part is to get the setvideoformat method going. Well, first correct the NewObject usage:
[highlight #FCE94F]loBitMapInfoHeader = Newobject( This.bitmapinfoheaderclass, This.BitMapInfoHeaderClassLib )
[/highlight]
but also set the BitMapInfoHeaderClassLib classlib property to "d:\vfpxdev\payprox\classes\webcam.vcx", not just "webcam.vcx".

Usage code extended to set the video format:
Code:
oForm = CreateObject("form")
oForm.show()
oWebcam = CreateObject("webcam")
      
If oWebcam.InitCaptureWindow(oForm.HWnd, 5, 5)
   oWebcam.setvideoformat()
   oWebcam.startpreview()      
EndIf

There are still some requirements to get Christof's struct class working. The file "convert.fll" needs to be found. It is not, in my case, thus loBitmapInfoheader still is becoming .F., not an object.

Overall, I don't understand why you get no errors, they are all over the place and either you ignore all error messageboxes or you do somthing like ON ERROR *, that's not helpful to find and fix your errors.

What remains to do after fixing all the error messages is to set the struct properties to viable values that work. For that you need to understand the meaning of the struct properties and what you can set them to. I can only repeat to point out that the getvideoformat code will help you to seee what struct is after you set an option with the video format dialog. The sample code only extracts the width and height, for the setvideoformat bitmapinfoheader you need to set more than just the width and height. Calls of messagecenter with an struct that's not working don't trigger errors, but will make the webcam stick to its current resolution.

Chriss
 
Chriss,

1. loBitMapInfoHeader = NewObject( This.BitMapInfoHeaderClass, This.BitMap[highlight #FCE94F]Info[/highlight]HeaderClassLib )

How stupid of me to miss this. Yes it now works using NewObject(). Thanks!

2. Your class does not have an Init routine that calls declaredlls.

It is called in the Init() of the Form. Kindly see below:

[pre]IF ThisForm.oWebcam.InitCaptureWindow( This.HWnd, This.shpWebcam.Left, This.shpWebcam.Top )
IF ThisForm.oWebcam.capHeight # ThisForm.shpWebcam.Height OR ThisForm.oWebcam.capWidth # ThisForm.shpWebcam.Width
IF ThisForm.oWebcam.UseBitMapInfo
ThisForm.oWebcam.SetVideoFormat()
ELSE
ThisForm.oWebcam.ShowFormatDialog()
ENDIF
ENDIF
ThisForm.oWebcam.StartPreview()
ELSE
* MESSAGEBOX( "Webcam connection unsuccessful.", 0+16, ThisForm.Caption )
ENDIF

ThisForm.RefreshControls()
[/pre]

3. also set the BitMapInfoHeaderClassLib classlib property to "d:\vfpxdev\payprox\classes\webcam.vcx", not just "webcam.vcx".

All classlibs are already SET CLASSLIB TO in my MAIN.prg calling program. That's why I did not bother with it.

4. The file "convert.fll" needs to be found.

I have included file CONVERT.FLL in the folder where the EXE is.

5. Overall, I don't understand why you get no errors, they are all over the place and either you ignore all error messageboxes or you do something like ON ERROR *, that's not helpful to find and fix your errors.

I know right! I have an ON ERROR segment as well. But I find it so weird why no error messages come out! Just like the misspelled Classlibrary parameter in the NEWOBJECT() call.

Thanks for spending your precious time sir.

BTW, what sort of projects are you into nowadays? VFP still? Or the more 'main-stream' ones already?


 
Where do you have your head, dylim?

I said
myself said:
Your class does not have an Init routine that calls [highlight #FCE94F]declaredlls[/highlight]

You answer that mainly with
It is called in the Init() of the Form

And post code that has nothing to do with calling the declaredlls method.

You've turned the webcam class of the original code, which was a form to a class based on custom, so in itself, there is no form.
The post of your webcam class has no init whatsoever.

You sure need a form on top of the webcam class, but you didn't post that. And the declaredlls method is still a method of the webcam and belongs to the webcam and should be the first thing the webcam class does.

I can't help you, if you ignore what I point out.

Chriss
 
dylim said:
I know right! I have an ON ERROR segment as well. But I find it so weird why no error messages come out! Just like the misspelled Classlibrary parameter in the NEWOBJECT() call.
Indeed, that's your major problem right now. Find out, I can't tell you without knowing your environment and your class usage code.

Just one shot in the dark: If you do something like
Code:
TRY
Do webcam.prg
CATCH
ENDTRY

That will a) supress any error - also in case you have a general error handler with ON ERROR established - and b) stop at the first line having an error.
So this kind of construct will just cause puzzling about what's wrong and lead you to think of bugs in the VFP language itself like you assumed about NEWOBJECT vs CREATEOBJECT.

If your error handling just writes to a log and doesn't show a messagebox, you'll not notice errors. You best know what your error handling does.
The blank output of your print code points out your ON ERROR handling runs and eventually RETURNs, but does not output anything, this way any ? with an error triggering expression only leads to a blank line and code executiuon continues, but likely fails for many reasons. If Christofgs struct class does not find the convert.fll it does not return an object from init and loBitMapInfoHeader becomes .F., so nothing works, no matter if you use CREATEOBJECT or NEWOBJECT, even if you fix the property name and value.

So, really, fix your error handling so that you see errors happening, the simplest during development is to rely on system error handling only. Using an error handler during development also isn't wrong, if it at least logs errors and perhaps even more, like currently existing variables, then you can profit from that, but if you do all that silently, you will have to establish the habit to look into your error log or even display it life in parallel to execution of tests. Like always, many ways to do things, but surely nothing showing up and code not working does not mean your code works and there must be system or VFP language bugs. That's the least likely thing.

Chriss
 
Chriss,

Sorry for late reply. I took a couple of days off.

The webcam class has an Init() that calls the DeclareDLLs() method. Kindly check the code I sent a few posts back. You may have missed it coz it's strangely in one of the last methods in the class definition.

This class is dropped on a Form.

Thanks!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top