473,756 Members | 1,808 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Invoking Win32 SendMessge

Most code on the net is wrong. This is SendMessage():
LRESULT SendMessage(HWN D hWnd, UINT Msg, WPARAM wParam, LPARAM
lParam);

All of those parameters are 32/64-bit in size depending on the
compiler, except for UINT which is a C int, which is always 32-bit,
even on a 64-bit machine, AFAIK. Most code on the net uses C# int (32-
bit) for all (or some) of these, when it should use IntPtr, which is
32/64-bit.

Now, I've seen code use HandleRef for the hWnd, instead of IntPtr, but
I cannot pass Control.Handle into a HandleRef, since it returns
IntPtr. So, should I stick with IntPtr? Or is HandleRef better?

Also, I want to do this:

const IntPtr SB_BOTTOM = 7;

But, C# doesn't allow me to make IntPtr constant, like I could do with
int! AND I cannot just store 7 into an IntPtr, since it's a type
conversion. Dammit. Is there another 32/64 integer data type that I
could use in place of IntPtr that IS allowed to be constant, which
acts like an int?

I am surprised at how annoying all of this is. No wonder people just
use int (and wait for their app to blow up on 64-bit).

Zytan

Mar 3 '07 #1
11 2003
Also, I see code like so (look at the DllImport part):

[DllImport("Kern el32.dll")]
public static extern void GetSystemTime(. ..);

But, NET Reflector shows me VB DLLs like so:

[DllImport("user 32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SendMessage(... );

Is the extra ", CharSet = CharSet.Auto, SetLastError = true"
required? MSDN fails to explain this extra stuff.

Zytan

Mar 3 '07 #2
>Most code on the net uses C# int (32-
bit) for all (or some) of these, when it should use IntPtr, which is
32/64-bit.
Well some people don't care about 64-bit, and as long as you stay on
Win32 ints will work. Other people simply don't know how to write
proper P/Invoke declarations and use trial and error until they get
something that seemingly works. Or they start from old VB6 Declare
statements that often lack proper type info for the parameters.

>Now, I've seen code use HandleRef for the hWnd, instead of IntPtr, but
I cannot pass Control.Handle into a HandleRef, since it returns
IntPtr.
You can't use it directly, but you can create a new HandleRef when you
need it.

SendMessage(new HandleRef(yourC ontrol, yourControl.Han dle), ...

>So, should I stick with IntPtr? Or is HandleRef better?
You can use IntPtr if you know what you're doing. Nowadays, HandleRef
has sort of been superseded by SafeHandles which is an even better
wrapper type.

>Also, I want to do this:

const IntPtr SB_BOTTOM = 7;
Use int for the const, then cast it to IntPtr when you use it.

const int SB_BOTTOM = 7;

SendMessage(... , (IntPtr)SB_BOTT OM, ...

Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Mar 3 '07 #3
>Also, I see code like so (look at the DllImport part):

[DllImport("Kern el32.dll")]
public static extern void GetSystemTime(. ..);

But, NET Reflector shows me VB DLLs like so:

[DllImport("user 32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SendMessage(... );
>Is the extra ", CharSet = CharSet.Auto, SetLastError = true"
required? MSDN fails to explain this extra stuff.
It's not required, but recommended. It ensures that SendMessageW is
called instead of SendMessageA on NT-based systems. And since .NET and
most APIs use Unicode internally that's usually good for performance
reasons.

SetLastError=tr ue only makes sense if you also use
Marshal.GetLast Win32Error to tell the reason for failure when a
function returns an error code.

Since GetSystemTime doesn't have a return value and doesn't deal with
text data, it's fine to leave out CharSet and SetLastError.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Mar 3 '07 #4
Also, I want to do this:
>
const IntPtr SB_BOTTOM = 7;

But, C# doesn't allow me to make IntPtr constant, like I could do with
int!
Is the reason for this beacuse IntPtr is a struct? I didn't realize
it was a struct until just now.

Zytan

Mar 3 '07 #5
Is the extra ", CharSet = CharSet.Auto, SetLastError = true"
required? MSDN fails to explain this extra stuff.

It's not required, but recommended. It ensures that SendMessageW is
called instead of SendMessageA on NT-based systems. And since .NET and
most APIs use Unicode internally that's usually good for performance
reasons.
It explains it here had I looked a bit more before posting:
http://msdn2.microsoft.com/en-us/library/7b93s42f.aspx
"CharSet.Au to: Platform invoke chooses between ANSI and Unicode
formats at run time, based on the target platform."

So, this is precisely what I want. I don't know how it knows how to
choose the right format, but what this, I can't see any reason to use
the other possibilities. This must be slower due to the extra checks
at run-time. CharSet.Ansi is default, so all the SendMessage imports
I've seen on the internet were calling SendMessageA!

MSDN shows a great example:

[DllImport("user 32.dll")]
public static extern int MessageBoxA(int hWnd, String text,
String caption, uint type);
[DllImport("user 32.dll", CharSet=CharSet .Unicode)]
public static extern int MessageBoxW(int hWnd, String text,
String caption, uint type);
[DllImport("user 32.dll", CharSet=CharSet .Auto)]
public static extern int MessageBox(int hWnd, String text,
String caption, uint type);
SetLastError=tr ue only makes sense if you also use
Marshal.GetLast Win32Error to tell the reason for failure when a
function returns an error code.
Oh cool, thanks. It just passed the Win32 error into
Marshal.GetLast Win32Error? So, no harm done if I have it there and
don't use it. So, I might as well leave it there, in case in the
future I want to use it.
Since GetSystemTime doesn't have a return value and doesn't deal with
text data, it's fine to leave out CharSet and SetLastError.
Right.

Thanks, Mattias!

Oh, something that wasn't clear: I think you need this:
using System.Runtime. InteropServices ;
to make all this work.

Zytan

Mar 3 '07 #6
Well some people don't care about 64-bit, and as long as you stay on
Win32 ints will work. Other people simply don't know how to write
proper P/Invoke declarations and use trial and error until they get
something that seemingly works. Or they start from old VB6 Declare
statements that often lack proper type info for the parameters.
Right.
You can use IntPtr if you know what you're doing. Nowadays, HandleRef
has sort of been superseded by SafeHandles which is an even better
wrapper type.
Well, yourControl.Han dle returns IntPtr, and I know I just want to
pass this directly to SendMessage, so I think I'll stay with IntPtr
for now.
Use int for the const, then cast it to IntPtr when you use it.

const int SB_BOTTOM = 7;

SendMessage(... , (IntPtr)SB_BOTT OM, ...
I think I will do this. Either way is ugly. I wish a real non-struct
int_ptr / int3264 type existed, instead.

Thanks, Mattias

Zytan

Mar 3 '07 #7
"Zytan" <zy**********@y ahoo.comwrote in message
news:11******** **************@ 30g2000cwc.goog legroups.com...
Most code on the net is wrong. This is SendMessage():
LRESULT SendMessage(HWN D hWnd, UINT Msg, WPARAM wParam, LPARAM
lParam);

All of those parameters are 32/64-bit in size depending on the
compiler, except for UINT which is a C int, which is always 32-bit,
even on a 64-bit machine, AFAIK. Most code on the net uses C# int (32-
bit) for all (or some) of these, when it should use IntPtr, which is
32/64-bit.

Now, I've seen code use HandleRef for the hWnd, instead of IntPtr, but
I cannot pass Control.Handle into a HandleRef, since it returns
IntPtr. So, should I stick with IntPtr? Or is HandleRef better?

Also, I want to do this:

const IntPtr SB_BOTTOM = 7;
Why do you want this to be an IntPtr (machine dependent integer)?
I suppose you want to use this as a Msg parameter value, but Msg is Int32 on both 32 and 64
bit, so an IntPtr is wrong and will blow on 64 bit.

Willy.

Mar 3 '07 #8
Also, I want to do this:
const IntPtr SB_BOTTOM = 7;

Why do you want this to be an IntPtr (machine dependent integer)?
I suppose you want to use this as a Msg parameter value, but Msg is Int32 on both 32 and 64
bit, so an IntPtr is wrong and will blow on 64 bit.
Actually, WM_VSCROLL is the message, which is only 32-bit. I caught
this myself, but never thought to repost here with the correction.
SB_BOTTOM is WPARAM which is 32/64-bit.

But, you made me think of something else:

I want to use IntPtr for 4 of the 5 parameters/return value, since 4
of the 5 should be 32/64-bit depending on the compilation (32/64-
bit). But, that's for a single source that can be compiled both in 32
and 64-bit. Doesn't both compilations need to refer to two
*different* SendMessage? Thus, using IntPtr is wrong if compiling on
64-bit but still linking to the 32-bit SendMessage. I think maybe I
am confusing myself.

Zytan

Mar 5 '07 #9
"Zytan" <zy**********@y ahoo.comwrote in message
news:11******** *************@8 g2000cwh.google groups.com...
Also, I want to do this:
const IntPtr SB_BOTTOM = 7;

Why do you want this to be an IntPtr (machine dependent integer)?
I suppose you want to use this as a Msg parameter value, but Msg is Int32 on both 32 and
64
bit, so an IntPtr is wrong and will blow on 64 bit.

Actually, WM_VSCROLL is the message, which is only 32-bit. I caught
this myself, but never thought to repost here with the correction.
SB_BOTTOM is WPARAM which is 32/64-bit.
Ok.
const int WM_VSCROLL = 0x115;
const int sb_bottom = 7;
IntPtr SB_BOTTOM = new IntPtr(sb_botto m);
....
SendMessage(wHa ndle, WM_VSCROLL, SB_BOTTOM, ...);
But, you made me think of something else:

I want to use IntPtr for 4 of the 5 parameters/return value, since 4
of the 5 should be 32/64-bit depending on the compilation (32/64-
bit). But, that's for a single source that can be compiled both in 32
and 64-bit. Doesn't both compilations need to refer to two
*different* SendMessage? Thus, using IntPtr is wrong if compiling on
64-bit but still linking to the 32-bit SendMessage. I think maybe I
am confusing myself.

Zytan

Managed code compiled as anycpu(platform :anycpu - is default) will automatically run in a 32
bit process on a 32 bit OS, and as a 64 bit process on 64 bit.
Managed code compiled as 32 bit (platform:x86), will always run as 32bit irrespective the OS
version.
Managed code compiled as 64 bit (platform:x64 or itanium), will run as 64, and this only on
X64 or IA64.
A 32 bit process will automatically get the 32 bit version of user32.dll loaded by the OS
loader, while a 64 bit version will load the 64 bit version, a 32 and 64 bit code mix isn't
possible in the same process, this means that you need to declare all machine dependent
int's as IntPtr to be portable between 32 and 64 bit, the rest is taken care of by the OS.

Willy.


Mar 5 '07 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
2117
by: Prasad | last post by:
We are invoking a SQL DTS component (lets call it Comp1) built by us in another component (Comp2).Comp1 was built by creating the DTS package using the SQL DTS wizard and then saving it as a VB .bas file - this was converted to .NET class module. To this module we added some cutom transformation tasks. An additional info - we are invoking Comp1 in a loop inside Comp2. The transformation succesfully happens for a few files in the list...
7
2021
by: ~neil~ | last post by:
hello I'm fairly new to the language, and my problem is I'm trying to write a program to run a command from the DOS prompt "C:>". I don't know all the functions in "C", however there are a few under the header file "process.h" that could be used, but I'm not really sure what they mean. I only know them by their name <prototype declaration>. I don't understand the arguments that are passed down to these functions, is why I'm seeking help...
3
8152
by: Nidhee Pathak via .NET 247 | last post by:
Hi, I am trying to run an exe present on the remote machine using the ManagementClass object. I connect to the remote machine using ObjectManagementScope class, but i am not being able to run the exe through normal Win32 process. How should I go about it? -------------------------------- From: Nidhee Pathak ----------------------- Posted by a user from .NET 247 (http://www.dotnet247.com/) <Id>s3QhesQMJ0O24aiIcMmT+w==</Id>
25
2511
by: MuZZy | last post by:
Hi, I'm currently rewriting some functionality which was using multithredaing for retrieving datasets from database and updating a grid control. I found that the grids (Infragistics UltraGrid, though it doesn't matter) were updated (i.e. grid.DataSource = dsDataSet;) and used for different purposes in the worker thread, so now i'm wrapping all those calls to grid's methods thru invoking which is a pain in the a$$ considering number of...
2
1958
by: shanmani | last post by:
Hi, I am developing a .NET application which will invoke the methods from different COM / .NET DLLs. While invoking methods from .NET DLLs, I am encountering the following error. I have also included the detail of the error stack trace and the code that I have written to invoking the methods. I would appreciate if you could let me know the cause of this error and possible workarounds to avoid this situation.
0
2059
by: balaji krishna | last post by:
Hi, I need to handle the return set from COBOL stored procedure from my invoking Java program. I do not know, how many rows the stored proc SQL fetches.I have declared the cursor in that proc, but i don't know how to return the rows the cursor has opened and I don't know how to handle the return set from the proc in my java code. My main problem with that proc is that whether I can retun the result set from the proc without closing the cursor...
3
3859
by: Monkeyfun | last post by:
Hi, I have a CAN controller from which I need to read packets whenever one is received. With the CAN controller came a WIN32 (non clr) library. When a CAN packet is received the library must trigger an event, which will read the data and process it. The library takes a __stdcall function pointer, which it uses to make a callback. The callback must be made into my clr class, in which the incomming is processed. Is it possible to create a...
2
5569
by: =?Utf-8?B?SmltIE93ZW4=?= | last post by:
Hi John, Hopefully this post will find its way back to you - or perhaps be answered by someone else. As I mentioned in my last post on the earlier portion of this thread, changing the serialization settings for the build handled the initial slows we encountered when invoking the web service. Since that time, we ported the original VB.net code over to C# - this was done to make it cleaner easier to include the project in the rest of...
0
924
by: Dobedani | last post by:
Dear All, For some time now, I have been working with the ctypes module on Windows. First I got my hands on a library developed with Delphi 7. That library is exporting plain functions. Internally, reference is made to the instance of a class, which is instantiated in a kind of initialization section. Everything works fine. Now, I have developed a library in C#. I am able to get the result from static methods, e.g. public static String...
0
9275
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10034
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9872
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9843
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9713
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7248
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5304
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3358
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2666
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.