views:

73

answers:

2

Hello, I am using a code sample to connect to a webcam, and don't really understand the meaning of the variables passed to the SendMessage method.

SendMessage(DeviceHandle, WM_CAP_SET_SCALE, -1, 0)

SendMessage(DeviceHandle, WM_CAP_SET_PREVIEW, -1, 0)

What does the -1 mean? To scale/preview or not to scale/preview? I'd prefer that zero/one would be used, zero meaning false, and have no idea what the -1 means.

SendMessage(DeviceHandle, WM_CAP_EDIT_COPY, 0, 0);

What does the zero mean in this case? Or does this message is simply void and the zero has no meaning, similar to the last zero argument?

Btw, what DOES the last zero argument mean?

Thank you very much in advance :)

A: 

WM_CAP_SET_SCALE message enables or disables scaling of the preview video images

WM_CAP_SET_PREVIEW message enables or disables preview mode

WM_CAP_EDIT_COPY message copies the contents of the video frame buffer and associated palette to the clipboard

SendMessage has next signature:

LRESULT WINAPI SendMessage(
  __in  HWND hWnd,
  __in  UINT Msg,
  __in  WPARAM wParam,
  __in  LPARAM lParam
);

Where wParam and lParam - are "Additional message-specific information". Wparam type means word and Lparam means long.

This parameters are optional and can be used or can be not used. So one of them or both are used if some message requires addition data to be sent.

abatishchev
Thank you for your reply. I saw the signature, I don't understand /what/ are those additional message-specific params. What does -1 mean in messages WM_CAP_SET_SCALE/WM_CAP_SET_PREVIEW ?
Rita
Most of the time (as far as I saw) `-1` in C/C++ means 'not applicable'. If message description doesn't contain any remarks about additional params, I think this mean that this message doesn't need them. Also 0 mean `NULL` i.e. 'additional param is not sent'
abatishchev
I saw that in most cases, 0/1 is used. I think that in this case, perhaps -1 means 'not zero = true', aka simply true. Weird, but makes sense :S
Rita
Some languages use -1 as their truth value because in twos complement it results in all bits set.
rpetrich
+2  A: 

You've probably found sample code that was originally written in Visual Basic. The WParam argument for SendMessage() is documented to be a BOOL. It should be either FALSE (0) or TRUE (1). A quirk of VB6 is that its boolean TRUE value is -1. The reason is a bit obscure and related to the way its AND and OR operators work.

Your current code works by accident, the Windows code that interprets the message simply treats any non-zero value as "TRUE".

There is a bigger problem though, your SendMessage() declaration is wrong. The WParam and LParam arguments are probably declared as "int", a 32-bit value. On 64-bit operating systems they are however a 64-bit value. On such an operating system your SendMessage() call will fail badly. There's also some odds that you are already on a 64-bit operating system and have these arguments declared as Long, the way they were declared in VB6. In which case your code will fail on a 32-bit operating system.

The proper declaration for SendMessage:

 [DllImport("user32.dll")]
 private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

And the proper way to send the message:

 SendMessage(DeviceHandle, WM_CAP_SET_SCALE, (IntPtr)1, IntPtr.Zero);

That will work correctly on both 32-bit and 64-bit operating systems.

Hans Passant
Some more correct declarations http://www.pinvoke.net/default.aspx/user32.sendmessage
abatishchev
Thank you very very much, I never knew that. I will get it fixed right away.
Rita
Btw, is there a place where I could see other overloads, for any external method?
Rita
@Rita, the declaration I gave you is the natural declaration. You can "lie" to the P/Invoke marshaller and add additional ones that have different argument types. Useful to pass pointers to structures. Since anything goes, there is no comprehensive list. There however is really only one function in Windows. I would recommend you do this only when you know what you're doing.
Hans Passant
@Hans: I meant the 'standard way' of external declarations. For instance, this method:UINT WINAPI RegisterWindowMessage( __in LPCTSTR lpString);Say I wanted to import it, how would I know what is the proper way to write the declaration? Or is it just by understanding and translating the params by yourself?Something like[DllImport("User32.dll")]protected static extern int RegisterWindowMessage(string lpString)?
Rita
You can visit pinvoke.net. And download the PInvoke Interop Assistant (http://clrinterop.codeplex.com/releases/view/14120). Neither are perfect, there's always SO.
Hans Passant
@Hans: Thank you very much for all your help.
Rita