|
As leppie posted, there are many useful functions in the Marshal class, which is good to become familiar with if you are interfacing with external C or C++ functions. IntPtr itself also has useful methods, such as ToPointer() and ToInt32(), along with the statics Zero and operator overloads that can convert between void pointers and IntPtr types. Which ones to use depends on how you plan on calling the extern functions.
It is hard to explain the usage details without seeing a code example. If you could post one with how the calls are intended to be made, and how the parameters are to be passed, I'm sure I could explain a solution.
Regarding using the extern funcs you currently have, if the calling C# func is declared unsafe, then you can just cast your "ints" as in regular C code (including pointers and taking addresses). Or you can prototype the externs as unsafe from the start like:
DLLImport("rv.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl))
public static extern unsafe int f(void *pVoid);
DLLImport("rv.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl))
public static extern unsafe int f2(void **ppVoid);
If you are looking to do this using the non-unsafe runtime interop features, you could do:
DLLImport("rv.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl))
public static extern int f(IntPtr pVoid);
DLLImport("rv.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl))
public static extern int f2(IntPtr ppVoid);
|
|
|
|
|
Hi,
I'm getting a System.ArgumentException trying to call the following
IActiveDesktop method:
STDMETHOD (AddDesktopItem)(THIS_ LPCCOMPONENT pcomp, DWORD dwReserved) PURE;
This is how I'm marshaling the call.
void AddDesktopItem(
[In, MarshalAs( UnmanagedType.LPStruct )] COMPONENT pcomp,
[In] int dwReserved
);
I believe the problem is with marshaling the COMPONENT structure. Could
some one point out to me if I'm marshaling the nested structures correctly.
Here is the original typedef for the struct and my c# attempt at marshaling
it.
typedef struct _tagCOMPONENT
{
DWORD dwSize; //Size of this structure
DWORD dwID; //Reserved: Set it always to zero.
int iComponentType; //One of COMP_TYPE_*
BOOL fChecked; // Is this component enabled?
BOOL fDirty; // Had the component been modified and not
BOOL fNoScroll; // Is the component scrollable?
COMPPOS cpPos; // Width, height etc.,
WCHAR wszFriendlyName[MAX_PATH];
WCHAR wszSource[INTERNET_MAX_URL_LENGTH]; //URL of the component.
WCHAR wszSubscribedURL[INTERNET_MAX_URL_LENGTH]; //Subscrined URL
DWORD dwCurItemState; // Current state of the Component.
COMPSTATEINFO csiOriginal;
COMPSTATEINFO csiRestored; // Restored state of the component.
}
COMPONENT;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode )]
public class COMPONENT
{
public int dwSize; // Size of the structure.
public int dwID; // Reserved. Set to zero.
public COMP_TYPE iComponentType;
[MarshalAs( UnmanagedType.Bool )]
public bool fChecked;
[MarshalAs( UnmanagedType.Bool )]
public bool fDirty;
[MarshalAs( UnmanagedType.Bool )]
public bool fNoScroll;
[MarshalAs( UnmanagedType.Struct )]
public COMPPOS cpPos;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst = 260 )]
public string wszFriendlyName;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst = 2083 )]
public string wszSource;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst = 2083 )]
public string wszSubscribedURL;
public ITEM_STATE dwCurItemState;
[MarshalAs( UnmanagedType.Struct )]
public COMPSTATEINFO csiOriginal;
[MarshalAs( UnmanagedType.Struct )]
public COMPSTATEINFO csiRestored;
}
StructLayout( LayoutKind.Sequential )]
public class COMPSTATEINFO
{
public int dwSize;
public int iLeft;
public int iTop;
public int dwWidth;
public int dwHeight;
public ITEM_STATE dwItemState;
}
[StructLayout(LayoutKind.Sequential)]
public class COMPPOS
{
public int dwSize;
public int iLeft;
public int iTop;
public int dwWidth;
public int dwHeight;
public int izIndex;
[MarshalAs( UnmanagedType.Bool )]
public bool fCanResize;
[MarshalAs( UnmanagedType.Bool )]
public bool fCanResizeX;
[MarshalAs( UnmanagedType.Bool )]
public bool fCanResizeY;
public int iPreferredLeftPercent;
public int iPreferredTopPercent;
}
|
|
|
|
|
Nathan Tran wrote:
I'm getting a System.ArgumentException trying to call the following
IActiveDesktop method:
STDMETHOD (AddDesktopItem)(THIS_ LPCCOMPONENT pcomp, DWORD dwReserved) PURE;
This is how I'm marshaling the call.
void AddDesktopItem(
[In, MarshalAs( UnmanagedType.LPStruct )] COMPONENT pcomp,
[In] int dwReserved
);
I believe the problem is with marshaling the COMPONENT structure.
STOP! Its exactly what it says. Dont use LPStruct. Just add ref to it, or Marshall the structure to unmanaged memory 1st, then pass an IntPtr into the function (obviously you will need to change the function definition).
Once (and only then), you can lok at the HRESULT you are getting to see if the struct size is infact correct (which probably wont be the case, never is with these nested structs). Good luck NOT lol, where is the functions DllImportAttribute? Thats the problem. Not sure how it compiled...
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
leppie,
I don't need the DllImportAttribute since this COM method is being called through a c# mapped interface. Based on your suggestion to use IntPtr I have made the following changes to the code but I'm still getting System.ArgumentException.
void AddDesktopItem(
[In] IntPtr component,
[In] int dwReserved
);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode )]
public class COMPONENT
{
public int dwSize; // Size of the structure.
public int dwID; // Reserved. Set to zero.
public COMP_TYPE iComponentType;
public int fChecked;
public int fDirty;
public int fNoScroll;
public COMPPOS cpPos;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst = 260 )]
public string wszFriendlyName;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst = 2083 )]
public string wszSource;
[MarshalAs( UnmanagedType.ByValTStr, SizeConst = 2083 )]
public string wszSubscribedURL;
public ITEM_STATE dwCurItemState;
public COMPSTATEINFO csiOriginal;
public COMPSTATEINFO csiRestored;
}
and the help method to copy the struct to unmanaged mem is as follows.
public static IntPtr CreateByteBuffer( COMPONENT comp )
{
IntPtr bufferPtr = Marshal.AllocCoTaskMem( Marshal.SizeOf( comp ) );
Marshal.StructureToPtr( comp, bufferPtr, true );
return bufferPtr;
}
Note: I have verified that the size of the struct to be correct. It is 8972 bytes to be exact. I have even checked the memory location of the IntPtr and all the relevant data is there.
Any other suggestion?
Nathan.
|
|
|
|
|
Nathan Tran wrote:
Any other suggestion?
Maybe the C# mapping is wrong? I dont really know the COM stuff too well. Normal interop I do know well. You have thus checked that stuff and it checks out ok. That leads me back to that function, what happens from there?
Sorry couldnt help more
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
Hello all,
What is the quickest way to convert an image to a byte array?
Is it image -> file -> byte array ?
Or is there a short cut ?
Thanks
Smitha
Imagination is more important than knowledge.
--Albert Einstein
|
|
|
|
|
Smitha Vijayan wrote:
What is the quickest way to convert an image to a byte array?
I am not sure if you mean performance or easiest to code, but you can just use the Image's Save method, and pass a MemoryStream instead of some sort of file stream. A MemoryStream can write to an array of bytes. Saving to a file would be very slow in performance, and not necessary in this case.
Cheers
|
|
|
|
|
Thanks Jeff
Smitha
Imagination is more important than knowledge.
--Albert Einstein
|
|
|
|
|
Hi all expert:
do u have any idea on how to capture image (from media player video)?
so later i could edit it as normal image?
alternatively, it would also be good if i can directly drawing graphics on the particular frame of the video.
which way could be possible and how can I achieve that?
very appreciate for your help.
|
|
|
|
|
can you embed a wav inside a resouce file somehow ? also is it possible to PInvoke the "error" sound that accompanies a MessageBox with the MessageBoxIcon.Error property set ?
Jesse M
The Code Project Is Your Friend...
|
|
|
|
|
jtmtv18 wrote:
can you embed a wav inside a resouce file somehow ? also is it possible to PInvoke the "error" sound that accompanies a MessageBox with the MessageBoxIcon.Error property set ?
The embedding is easy, just add the wav to your project and set it embedded content, the use Assembly.GetManufestResourceStream("namespace.filename.ext") to get a stream object from this.
Playing it. The is a nice article of CP that shows you how to play wave file with P/Invoke. Let me know if you need help loading from memory.
Cheers
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
i do need help setting up the memory stream. i use directx 9.0 to play it; ie
private void PlayAudio(string fPath){<br />
Audio player = new Audio(fPath);<br />
player.Start();<br />
}
if the audio file is coming from a memory stream how do i get the bytes to stream to the above method ? thanks leppie. ps.. the audio file will be named Error.wav;
just reading the overload methods for Microsoft.DirectX.AudioVideoPlayback.Audio i find that it only takes a (strin filename) ..how can i tell it to play my embed resource instead? (which will come in a stream)
The Code Project Is Your Friend...
|
|
|
|
|
jtmtv18 wrote:
directx 9.0
Thats a bit over the top , dont you think?, use p/invoke rather
I rated this article 2 by mistake. It deserves more. I wanted to get to the second page... - vjedlicka 3:33 25 Nov '02
|
|
|
|
|
Aeru IRC project is looking for developpers and artists.
Aeru IRC is free and open source IRC Client for .NET.
Unlike most of others .NET IRC Client, I don't use a external IRC library, it's my own IRC implentation.
You can find the client at http://aeruirc.sourceforge.net/
I need developpers who can contribute their coding talent to fix bug, refactoring somes parts and adds features. I work with Windows.Forms and Magic Library(soon UtilityLibrary for the toolbar).
Also, I need artist to draw the menu icons, tab icons. In future, I will neeed an artist to doing toolbar images(I waiting for a artist to implent this feature).
If you are interested, email me at shock@shockdev.ca.tc.
Thanks in advance!
-Shock The Dark Mage
Aeru IRC programmer and project maintener.
Trully, if there evil in this world, It lies within the heard of mankind
Shock The Dark Mage
shock@romhack.net
Main Project: Aeru IRC - http://www.sf.net/projects/aeruirc
|
|
|
|
|
what exsactly is Aeru IRC ? a irc chat client right ? whats diffrent about it ? (if i may ask)... i would like to help with what ever i can. How many people are working on it ?
Jesse M
The Code Project Is Your Friend...
|
|
|
|
|
Aeru IRC is a simple irc client I started from nothing without using extern librairies to implant IRC Protocol. I'm using Magic Library for the GUI and soon Utility Library. You can use Visual Studio .NET or SharpDevelop.
You can help me by adding features, fix bugs and refactoring the core(IRCConnection and IRCParser)
Currently I'm the only developping Aeru IRC and I got one artist.
Contact me with MSN, my address is shock@shockdev.ca.tc
Trully, if there evil in this world, It lies within the heard of mankind
Shock The Dark Mage
shock@romhack.net
Main Project: Aeru IRC - http://www.sf.net/projects/aeruirc
|
|
|
|
|
I am trying to achieve the flat treeview look of VS.NET, (IE, a SystemColors.ControlDark colored FixedSingle border).
And this does appear to be massively harder than it first seemed. The border AND the scrollbars on the treeview are part of Non-Client area of the control. So, I first thought that I might subclass the sucker, paint the border in the NC area of the control, and then throw away WM_NCPAINT, cant do that, because the scrollbar doesn't paint. So, I am left with passing it back to the DefWndProc, and then painting over the border, causing massive flicker.
I also tried to update the HRGN in WM_NCPAINT and it wouldnt have any of it.
Has anyone successfully painted their own border on the TreeView, ListBox, TextBox or RichTextBox ??
Maybe there is an easier way I have overlooked? Any help would be greatly appreciated.
|
|
|
|
|
Noone got any ideas? Damn this one is a beasty.
|
|
|
|
|
In most cases you let WndProc handle the WM_NCPAINT method, then overpaint it yourself. A few of the controls will let you paint the border without having it painted by WndProc first, but many won't. I know this is double-painting, but with some controls there's just no way around it, save for rebuilding the entire control yourself. Also, after painting the border on some controls you will need to Send WM_ERASEBKGND and WM_PAINT after you've painted the border so that things like scrollbars are re-drawn.
Also, take care with the way you are creating your graphics object for painting. Some controls will work with a simple Graphics.FromHdc(Handle), but others will need to get their graphics instance from user32.dll like this:
[DllImport("user32.dll")]<br />
private static extern IntPtr GetWindowDC(IntPtr hWnd);<br />
Graphics g = Graphics.FromHdc(GetWindowDC(Handle));
One last note, make sure you don't set UserPaint, DoubleBuffer, AllPaintingInWmPaint for controls that you are going to paint borders on using the WM_NCPAINT WndProc override - doing so will only create you much frustration.
There are many controls in the base library that need to be WndProc painted, and all of them have their own little quirks. It took me a couple of days to learn the ins and outs of each, but once you've got the basic ideas it's fairly straight forward.
|
|
|
|
|
This was one of the first things I tried, I set the border to FixedSingle, so that it was 1 pixel around the edge, and then I painted over the border after the control had finished painting it. Of course, this causes flicker when resizing, which was what I was keen to avoid.
Drawing a damn rectangle isn't always as easy as it first seems
|
|
|
|
|
Are you interested in just the treeview, or all the controls previously listed?
|
|
|
|
|
Here's how to user-paint the border of the TreeView control:
1) Create a class that inherits from System.Windows.Forms.TreeView
2) Add the follwing using directive:
using System.Runtime.InteropServices;
3) In the class body, add the following user32.dll wrapper method:
[DllImport("user32.dll", CharSet=CharSet.Auto)]<br />
private static extern IntPtr GetWindowDC(IntPtr hWnd);
4) Add the follwing WndProc override method:
protected override void WndProc(ref System.Windows.Forms.Message m)<br />
{<br />
if( m.Msg == 0x0085 )<br />
PaintBorder();<br />
else<br />
base.WndProc(ref m);<br />
}
5) Add the PaintBorder method:
<br />
private void PaintBorder()<br />
{<br />
Graphics g = Graphics.FromHdc(GetWindowDC(this.Handle));<br />
Rectangle r = new Rectangle(0, 0, Width, Height);<br />
<br />
<br />
g.Dispose();<br />
}<br /> That's it! Note that every control has it's own unique methods for border painting. This particular method will work only for some of the controls,
others will require the WM_NCPAINT to be handled by WndProc before you go painting border, causing a double-paint. Other controls require you to
create the Graphics object from the actual parent form rather than the control itself.
On final note, ensure the border style is 3D, not Single or none.
Hope this helps!
|
|
|
|
|
hi!
I want to make a snapshot mh, for example if you know the programm "Hypersnap". I have an window (lets say an IE window) and now I want to have a bitmap/jpg of a foto in that window...
hope its clear what i mean...
any ideas? (im have absolute none
thx
|
|
|
|
|
Here[^]
Use the code to capture the screen, then use their crop function to crop it to you control's this.ClientRectangle
I walk these roads,
I climb these mountains,
Though they are nothing,
But paths and hills,
for the only mountain is success,
and the only road is life.
|
|
|
|
|
Dear All,
Please let me know whether you know how to have reinstall feature in a Windows Installer .msi module. Normally when you setup an application and then run the .msi again, you have the repair and remove features, Now what I must do to have some other options like reinstall or upgrade to new versions?
Regards,
Sassan Komeili Zadeh
|
|
|
|
|