Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / March 2005

Tip: Looking for answers? Try searching our database.

How to get the main forM handle in .NET

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Fred Hebert - 23 Mar 2005 19:53 GMT
I am trying to use a 3rd party DLL that requires the main window handle as
a parameter.

e.g. MyFunc(WHND MyHandle);

The example looks something like this:

Result = MyFunc(Handle);

Where "Handle" is the Win32 handle.

Trying to use the example as written results in a compiler error:
 cannot convert parameter 5 from 'int' to 'HWND'
 
First isn't the HWND basically an unsigned integer?  I have tried type
casting and several other things, but nothing the compiler likes.

Does anyone know how to make this work?
William DePalo [MVP VC++] - 23 Mar 2005 20:13 GMT
>I am trying to use a 3rd party DLL that requires the main window handle as
> a parameter.
>
> e.g. MyFunc(WHND MyHandle);

Typo? You mean this?

   MyFunc(HWND MyHandle);

> The example looks something like this:
>
[quoted text clipped - 4 lines]
> Trying to use the example as written results in a compiler error:
>  cannot convert parameter 5 from 'int' to 'HWND'

First, it is always a good idea to post code exactly as written; the devil
is in the details.

This is a guess: If you must, cast the 5th parameter:

change    ...(... x, ...);

to

   ...(... (HWND) x, ...);

> First isn't the HWND basically an unsigned integer?

Using Von Neumann machines, everything is basically an integer. So, what?
:-)

> I have tried type casting and several other things,
> but nothing the compiler likes.

As I said, show the bad code, the exact text of the error message and what
you have tried.

Regards,
Will
Fred Hebert - 23 Mar 2005 21:12 GMT
Sorry about the typo, was just trying to simplify.

It's pulled from various places, but here is the actual code:

typedef int (_stdcall *pOmniConnect) (char * IpAddress,
                                     unsigned int Port,
                                     unsigned int Timeout,
                                     unsigned char EncryptionKey[16],
                                     HWND NotifyWindow);
...
pOmniConnect OmniConnect;
...
The dll is loaded and addresses resolved (not relevant to problem)
...
                OmniConnect(IpEdit->Text,
                    PortEdit->Text->ToInt32,
                    TimeoutEdit->Text->ToInt32,
                    BinKey,
                    Handle);  // this line is the problem
As Written:
 error C2664: 'int(... the func template ...)': cannot convert parameter 5
from 'int' to 'HWND'

Tried type casting e.g. (HWND)Handle);
 error C2440" 'type cast' : cannot convert from 'System::IntPtr' to 'HWND'
 
Tried various this->Handle, and Handle->xxx conversions but similar
problems.
William DePalo [MVP VC++] - 23 Mar 2005 22:15 GMT
> Sorry about the typo, was just trying to simplify.
>
[quoted text clipped - 24 lines]
> Tried various this->Handle, and Handle->xxx conversions but similar
> problems.

How is Handle declared?

Regards,
Will
Fred Hebert - 23 Mar 2005 23:58 GMT
> How is Handle declared?
>
> Regards,
> Will

It's not in my code.  It should be the handle of the main form.

According to the docs:
[C++]
public: __property virtual IntPtr get_Handle();

Property Value
An IntPtr that contains the window handle (HWND) of the control.

Implements
IWin32Window.Handle

Remarks
The value of the Handle property is a Windows HWND. If the handle has not
yet been created, referencing this property will force the handle to be
created.

----

And Handle.get_Handle() doesn't work either.
William DePalo [MVP VC++] - 24 Mar 2005 00:49 GMT
> According to the docs:
> [C++]
[quoted text clipped - 10 lines]
> yet been created, referencing this property will force the handle to be
> created.

I have no idea why a window handle should be returned as an IntPtr. <Sigh>

Does this IntPtr have a ToInt32() method? If so, can you use it to get
yourself an integer and cast that to a window handle?

Regards,
Will
Tomas Restrepo \(MVP\) - 24 Mar 2005 01:08 GMT
Hi Will,

> I have no idea why a window handle should be returned as an IntPtr. <Sigh>

Because IntPtr represents a platform-specific pointer size (meaning, it
holds a 64-bit value on 64-bit platforms with the 64-bit version of the
framework).

> Does this IntPtr have a ToInt32() method? If so, can you use it to get
> yourself an integer and cast that to a window handle?

It does, but a better option is to use IntPtr::ToPointer() which returns a
void* :)

So you can just do (HWND)Handle.ToPointer();

Signature

Tomas Restrepo
tomasr@mvps.org

William DePalo [MVP VC++] - 24 Mar 2005 01:29 GMT
Hi Tomas,

> Because IntPtr represents a platform-specific pointer size (meaning, it
> holds a 64-bit value on 64-bit platforms with the 64-bit version of the
> framework).

Oh. :-)

Geez, just what I need, something else new to get up to speed on.

Regards,
Will
Tomas Restrepo \(MVP\) - 24 Mar 2005 02:41 GMT
Hi Will,

> Oh. :-)
>
> Geez, just what I need, something else new to get up to speed on.

Jajajajaa. Well, in that sense, it's not all that different (source code
wise) from using ULONG_PTR and friends instead of ULONG :)

Signature

Tomas Restrepo
tomasr@mvps.org
http://www.winterdom.com/

Fred Hebert - 24 Mar 2005 21:36 GMT
> So you can just do (HWND)Handle.ToPointer();

Sounds good, but neither ToInt32 or ToPointer works, and in fact they both
return EXACTLY the same error.

error C3374: managed function 'System::IConvertible::ToInt32' requires
argument list

Any more ideas?  This is really frustrating because I am sure it is
something simple.
Tomas Restrepo \(MVP\) - 24 Mar 2005 22:02 GMT
Hi Frank,

> Sounds good, but neither ToInt32 or ToPointer works, and in fact they both
> return EXACTLY the same error.
>
> error C3374: managed function 'System::IConvertible::ToInt32' requires
> argument list

ToInt32, huh? OK, so lets review the code because in no case should
ToInt32() be getting called here.

Consider this code:

void Func(HWND hwnd)
{
  MessageBox::Show(String::Format("Handle: {0}", (ULONG_PTR)hwnd));
}

.....

 void OnButtonClick(Object^ sender, EventArgs^ e)
  {
     IntPtr handle = this->Handle;
     Func((HWND)handle.ToPointer());
  }

That compiles and runs cleanly for me.

Signature

Tomas Restrepo
tomasr@mvps.org

Fred Hebert - 24 Mar 2005 23:03 GMT
> That compiles and runs cleanly for me.

I can't get it to work so I created the simplest project I could to
demonstrate the problem:

1. Create a new VC.NET Windows Forms Application.

2. Drop 4 TextBox controls on the form and a Button.

3. Edit the properties of the text controls like this:
[textBox1]
Name: IpEdit
Text: 10.1.1.1
[textBox2]
Name: PortEdit
Text: 1234
[textBox3]
Name: TimeoutEdit
Text: 10
[textBox4]
Name: KeyEdit
Text: fffffffffffffffffffffffffffffff     << should be 32 f's

4. Double Click on the button, and enter the following code:
---------------------------------------
                unsigned char BinKey[16];  // key is entered in HEX but
must be converted to binary value for use
                for(int i=0; i < KeyEdit->Text->Length; i=i+2)
                {
                    BinKey[i>>1] = (unsigned int)(hextobin(KeyEdit->
Text->get_Chars(i)) << 4) +
                        hextobin(KeyEdit->Text->get_Chars(i+1));
                }
                OmniConnect(IpEdit->Text,
                    PortEdit->Text->ToInt32,
                    TimeoutEdit->Text->ToInt32,
                    BinKey,
                    Handle);
---------------------------------------

5. The the beginning of the Form1.h, just after the "#pragma once" line
add the following lines:
---------------------------------------
#include <windows.h>

#define hextobin(c) ((c)>='a'&&(c)<='f' ? (c)-'a'+10 : (c)>='A'&&(c)
<='F' ? (c)-'A'+10 : (c)-'0')

typedef int (_stdcall *pOmniConnect) (char * IpAddress,
                                     unsigned int Port,
                                     unsigned int Timeout,
                                     unsigned char EncryptionKey[16],
                                     HWND NotifyWindow);

pOmniConnect OmniConnect;
---------------------------------------

Now I know I left out the OnCreate of the form where the DLL is loaded
and all of the other DLL exports, but I think I have everything you need
to compile, that is once the "Handle" issue is resolved.

Of course it won't run but right now I am just trying to get past this
one problem.  In the real program, if I comment out the code in the
button click the rest of the program runs fine.  I didn't have problems
with any of the functions, but most of them just pass strings and
integers.
Tomas Restrepo \(MVP\) - 24 Mar 2005 23:40 GMT
Fred,
> 1. Create a new VC.NET Windows Forms Application.
>
[quoted text clipped - 29 lines]
>                      BinKey,
>                      Handle);

Humm... try changing that one last to:
                 OmniConnect(IpEdit->Text,
                     Convert::ToInt32(PortEdit->Text),
                     Convert::ToInt32(TimeoutEdit->Text),
                     BinKey,
                     (HWND)Handle.ToPointer());

Does that work?

Signature

Tomas Restrepo
tomasr@mvps.org
http://www.winterdom.com/

Fred Hebert - 25 Mar 2005 15:40 GMT
"Tomas Restrepo \(MVP\)" <tomasr@mvps.org> wrote in news:#f8cSKMMFHA.3328
@TK2MSFTNGP14.phx.gbl:

>  OmniConnect(IpEdit->Text,
>                       Convert::ToInt32(PortEdit->Text),
>                       Convert::ToInt32(TimeoutEdit->Text),
>                       BinKey,
>                       (HWND)Handle.ToPointer());

Unfortunately no, but I think we are getting closer.

I'm not entirely sure about the difference between PortEdit->Text->ToInt32
and  Convert::ToInt32(PortEdit->Text), but now the compiler is complaining
about not being able to convert parameter 1 from 'System::String __gc*' to
'char *'.

I am going to do more reading, but it looks like it is processing the
parameters in reverse order.
Tomas Restrepo \(MVP\) - 25 Mar 2005 16:02 GMT
Hi Fred,
> "Tomas Restrepo \(MVP\)" <tomasr@mvps.org> wrote in news:#f8cSKMMFHA.3328
> @TK2MSFTNGP14.phx.gbl:
[quoted text clipped - 14 lines]
> I am going to do more reading, but it looks like it is processing the
> parameters in reverse order.

Ahhh, no. The problem is the first argument, where you pass in IpEdit->Text.
That's a String*, and it seems you need a char*. You're gonna have to
marshal that first, using
System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(). See
http://www.winterdom.com/mcppfaq/archives/000111.html

Signature

Tomas Restrepo
tomasr@mvps.org
http://www.winterdom.com/

Fred Hebert - 25 Mar 2005 16:04 GMT
OK this is what I came up with:

 using namespace System::Runtime::InteropServices;
 ...
 char* ip = (char*)(void*)Marshal::StringToHGlobalAnsi(IpEdit->Text);
 OmniConnect(ip,
     Convert::ToInt32(PortEdit->Text),
     Convert::ToInt32(TimeoutEdit->Text),
     BinKey,
     (HWND)Handle.ToPointer());
 Marshal::FreeHGlobal(ip);

It seems to work, but what a pain.  I feel like I am going back to
programming 101 to transition to this .net stuff.  In another thread I saw
a comment something about "what's so difficult it's just C++", yea right,
now tell me the one about the Easter bunny...

I guess I better pick up a beginning .net book.  I have been programming
for 28 years and thought jumping into .net was going to be easy, but...

Without offending anyone, it think the included documentation leaves a lot
to be desired.
Severian - 25 Mar 2005 17:12 GMT
>OK this is what I came up with:
>
[quoted text clipped - 18 lines]
>Without offending anyone, it think the included documentation leaves a lot
>to be desired.

What a nightmare.

Now I be pining for the C/Win32 API simplicity of:

if (OmniConnect(GetDlgItemText(hdlg, IDC_IP),
     GetDlgItemInt(hdlg, IDC_PORT, NULL, FALSE),
     GetDlgItemInt(hdlg, IDC_TIMEOUT, NULL, TRUE),
     BinKey, hwnd) != SUCCESS)...

--
Sev
Tomas Restrepo \(MVP\) - 25 Mar 2005 17:24 GMT
Hi Fred,

> It seems to work, but what a pain.  I feel like I am going back to
> programming 101 to transition to this .net stuff.  In another thread I saw
> a comment something about "what's so difficult it's just C++", yea right,
> now tell me the one about the Easter bunny...

Well, to be honest, there are many new things, and then, some are
reappearences of things that are common in Win32 programming with a
different twist. In your question, for example, there's nothing really new.
String to Int conversions? always have been there in C/C++, and there are
tens of variants on how to do it; this is just a new one of those (and more
comfortable, imho). String to char*? not new, either, especially for someone
used to dealing with unicode-to- ascii conversions and the like.

> Without offending anyone, it think the included documentation leaves a lot
> to be desired.

That, I won't argue. The .NET framework documentation itself is good, but,
alas, the MC++ language documentation is rather terse and short, and there
is always room for improvement. I believe for C++/CLI this is improving
enormously with a proper language specification and several documents on the
design and implementation, and literally hundreds of new samples of using
C++/CLI with the .NET framework classes.

Signature

Tomas Restrepo
tomasr@mvps.org
http://www.winterdom.com/


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.