|
Crap - it would appear that you can't initalise structures like that.
He who knows and knows that he knows, is wise; follow him
He who knows and knows not that he knows, is asleep; wake him
He who knows not, and knows that he knows not, is simple; teach him
He whoe knows not and knows not that he knows not, is a fool; kick him
|
|
|
|
|
Use the MarshalAs attribute on the struct's fields to specify how it should convert the string.
Untested/uncompiled:
[StructLayout(LayoutKind.Sequential, Pack=4, CharSet=CharSet.Ansi)]
struct FOO
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=20)]
public string szSymbol;
public uint dwVolume;
} Now if szSymbol is going to be modified by the P/Invoke'd method then you need to use a StringBuilder rather than string to avoid any problems that may occur due to string interning.
James
"It is self repeating, of unknown pattern"
Data - Star Trek: The Next Generation
|
|
|
|
|
Thanks heaps - I had just discovered this attribute myself but was going to use UnmanagedType.LPStr
James T. Johnson wrote:
Now if szSymbol is going to be modified by the P/Invoke'd method then you need to use a StringBuilder rather than string to avoid any problems that may occur due to string interning
Rrrright.
Could you elaborate on the StringBuilder part? The szSymbol is going to be modified by the P/Invoke'd method.
TIA
Andy
|
|
|
|
|
Andy Davey wrote:
I had just discovered this attribute myself but was going to use UnmanagedType.LPStr
I'm not that familiar with interop but to me LPStr means a pointer to a string rather than embedding one within a struct. I think this is also how the Interop Marshaller will interpret it.
Andy Davey wrote:
Could you elaborate on the StringBuilder part?
Sure.
Strings in .NET are considered immutable; this allows for some optimizations to be made in both memory requirements and when comparing strings.
Because they are immutable you can have two strings that contain the same value point to the same block of memory. And rather than compare every single character to see if they are equal you can just compare whether the two strings point to the same object.
That is where string-interning comes in, it takes a string and adds it to an internal table which allows you to make use of those optimizations.
But there is a down side to strings being immutable. When you want to do lots of string operations (such as concatenation) you create a lot of new string objects using up memory that isn't used after the next operation.
That is where the StringBuilder comes in (full name: System.Text.StringBuilder ) it maintains an internal buffer/array of characters (similar to C style strings) and does various operations on the array rather than creating new string objects.
When you are done modifying the StringBuilder you can then call .ToString() on it and get out the string that was built.
To link this in with P/Invoke, since you have a buffer that needs a string the proper usage is to supply that buffer with a StringBuilder object rather than a string (which isn't supposed to change).
To change the first struct (going from memory):
[StructLayout(Layout.Sequential, Pack=4, CharSet=CharSet.Ansi)]
struct FOO
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=20)]
public System.Text.StringBuilder szSymbol;
public uint dwVolume;
} Then, because structs can't have default constructors you need to initialize szSymbol to szSymbol = new System.Text.StringBuilder(20); To provide a default constructor you can change FOO from a struct to a class (despite its name StructLayout can be applied to classes )
HTH,
James
"It is self repeating, of unknown pattern"
Data - Star Trek: The Next Generation
|
|
|
|
|
I only saw this last night, but in the lastest MSDN they a very comprehensive Marshalling Tutorial
Hey leppie! Your "proof" seems brilliant and absurd at the same time. - Vikram Punathambekar 28 Apr '03
|
|
|
|
|
Hi all
OK I have a HWND from a window, can I make a Control instance from that? Even though the program is not .NET? If so, why does Control.FromHandle return null?
Help appreciated
Thanks
Hey leppie! Your "proof" seems brilliant and absurd at the same time. - Vikram Punathambekar 28 Apr '03
|
|
|
|
|
leppie wrote:
OK I have a HWND from a window, can I make a Control instance from that?
A window handle references a unique window in the desktop. Although a handle uniquely identifies a control (whether managed or not), a control is much more than a handle.
One thing I can guess is you want to create a control based on the window styles used by the window referred by the handle. In such a case, make sure to override the control class and fill the CreateParams structure. Creating a new control based on styles from an existing window requires interop (GetClassName, GetWindowLong , ...).
leppie wrote:
why does Control.FromHandle return null?
Control.FromHandle(IntPtr) does not create a control based on the passed parameter. It only tries to match the handle with one of the existing (managed) controls' handles.
|
|
|
|
|
Thanks for the reply, but I'm still a bit unclear how (and if one can, surely u must be able to) to "hook" into a window.
Let me explain:
I have a lecagy program calling a dll. That dll calls a managed function passing the HWND from the legacy program. Now surely I should be able to interact with this window. I want add some child controls to it, and change some attribute (properties).
Is this possible? Isnt it just messaging happening at some level or something?
Hey leppie! Your "proof" seems brilliant and absurd at the same time. - Vikram Punathambekar 28 Apr '03
|
|
|
|
|
You have to use the Windows API.
"Do unto others as you would have them do unto you." - Jesus
"An eye for an eye only makes the whole world blind." - Mahatma Gandhi
|
|
|
|
|
leppie wrote:
Is this possible?
Yes. To create child controls, you have to use the ::CreateWindow(...) API function. One of the parameters is the HWND that you've been passed. One thing to remember, the only difference between a child window and a "top-level" window is the WS_CHILD window style. MSDN here[^].
To change control properties, you have to use ::SendMessage(hwndTargetControl,...) with appropriate message id and params. MSDN here[^].
|
|
|
|
|
Thanks
I am in C/MC++ so I will have to learn those things then. I would have though WinForms being built on top of those classes that one could easily "tap" into them. O well, easy come, easy go.
Hey leppie! Your "proof" seems brilliant and absurd at the same time. - Vikram Punathambekar 28 Apr '03
|
|
|
|
|
What control is it that shows the actual message in Outlook Express and how do you get the panel at the top that shows who the message is from and the subject etc. etc.
|
|
|
|
|
Silverdelange wrote:
What control is it that shows the actual message in Outlook Express and how do you get the panel at the top that shows who the message is from and the subject etc. etc.
Whenever I ask myself that question, I load up something like Spy++ (in the Tools submenu below your Visual Studio menu in the start-menu).
It allows you hover a pointer over all window types and view exactly what "window class" is being used. Often Microsoft roll their own custom ones that we developers are unable to use.
Regards,
Ray
|
|
|
|
|
Ray Hayes wrote:
Often Microsoft roll their own custom ones that we developers are unable to use.
But eventually a version appears on CP.
"If you just say porn then you get all manner of chaff and low grade stuff." - Paul Watson, Lounge 25 Mar 03 "If a man is standing in the middle of the forest speaking and there is no woman around to hear him, is he still wrong?" - Anon
Jonathan 'nonny' Newman
Homepage [www.nonny.com] [^]
|
|
|
|
|
Type "WinCV" in your command prompt.
It's a Class Viewer hidden in the .NET stuff.
The beauty of this tool is it runs outside of Visual Stuio. For the Object Browser, you need to run within the Studio.
I hope this is not a repost.
Don't and drive.
|
|
|
|
|
Kant wrote:
I hope this is not a repost.
It is, but it's cool stuff.
The only thing that I find troublesome is that only public properties/methods/events are listed.
|
|
|
|
|
I've used that before. It's good but has some limitations.
"Do unto others as you would have them do unto you." - Jesus
"An eye for an eye only makes the whole world blind." - Mahatma Gandhi
|
|
|
|
|
Does anyone have a simple example of a Windows form opening a seconday, modal Windows form? I have the two forms created and have tried the following, which does not work. A button (button1) on the first form is clicked to show the next form (frmSearchPatient).
private void button1_Click(object sender, System.EventArgs e)
{
Form frmSearchPatient = new Form();
frmSearchPatient.ShowDialog();
frmSearchPatient.Dispose();
}
I am just starting out in Visual Studio .NET, coming from doing extensive programming in Delphi. I am having alot of trouble figuring out how to do basic things such as this and have found Help to be of not much help at all.
|
|
|
|
|
This code works. Here are a few suggestions :
- assume we have two forms f1 (of type Form1) and f2 (of type Form2). In the f1 button click event handler, you can do this :
Form2 f2 = new Form2();
f2.ShowDialog();
Please note the use of Form2 (instead of Form).
- Also, don't use Dispose(). In most cases, it won't destroy/recycle the object.
|
|
|
|
|
Well I wouldnt call the dispose method as soon as you load the form, the vs doc states that the dispose method "Overloaded. Releases the resources used by the Component." So throw out the dispose method and im sure youll get it to work fine.
|
|
|
|
|
The code is wrong.
Try this
frmSearchPatient frm = new frmSearchPatient();
frm.ShowDialog();
and you can go ahead and dispose of it if you want because it is modal.
The Dispose method want be called util the dialog is closed.
|
|
|
|
|
Hi!
I'm trying to handle WebBrowser control events.
I wrote program exactly as described in this document http://support.microsoft.com/?id=312777[^] but it work only partly .
I recieve event but WebBrowser is behaving strange. When I use mouse wheel to scroll in the page it does nothing, or when I click on button it doesn't change it's state to pushed (but i recieve event).
When I remove this event handler it works ok.
Thank you!
i'm only pointer to myself
|
|
|
|
|
Tomáš Petříček wrote:
When I use mouse wheel to scroll in the page it does nothing,
Try iEvent.onmousewheel instead of iEvent.onmouseover
Tomáš Petříček wrote:
when I click on button it doesn't change it's state to pushed (but i recieve event).
When I remove this event handler it works ok.
If you receive the event, it's like preventing the web control from doing the standard handling. That's probably why the OnClick event handler is rarely used.
That said, I believe that if you set IHTMLEventObj.cancelBubble = false, you can allow the event to be routed, and give it a chance to be normally processed.
|
|
|
|
|
I found another solution here[^].
It works fine .
i'm only pointer to myself
|
|
|
|
|
Hi,
Can anyone point me to a free DataGrid better than the one which comes with VS.Net, and that support binding to a DataView/DataTable?
Thanks,
Andrei Matei
andreimatei@home.ro
|
|
|
|