|
Thanks Heath, most helpful. I was planning on using an arraylist.
One more question.
I'm running my call through Next, like this:
IntPtr[] EnumerationArray = new IntPtr[10];<br />
int ArrayLengthIn = 10;<br />
int ArrayLengthOut = 0;<br />
<br />
ContentEnumeration.Next(ArrayLengthIn,EnumerationArray,out ArrayLengthOut);
But I only ever get a single value returned.
I'm not sure why this is, as i know that there is more than 1 folder on my C drive. I'll have a play with one of the pointers i get back from the array, but can you see any reason why it's only returning a single value?
Cata
|
|
|
|
|
COM requires the address of the first element of an array. IntPtr is the managed representation of that address. The COM implementation doesn't care about arrays, only that address, so declaring the method to accept an array and passing an array in does not matter - it's only going to assign the address of the first array element in its implementation. You need to offset that address to get additional elements, which the Marshal class (or unsafe code) can help with.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
AWESOME! Thanks DUDE!
I got it enumerating properly.. well... i got a sub folder name without it crashing, exploding, or whatever. I'll worry about getting multiple PIDL's later.
One thing is confusing me though.
My StrRetToStr, while working, does odd stuff. 0 seems to be the value that works, but in COM it's supposed to be 1-3. Is this because i'm using signed ints?
Also, my StrRetToStr method refuses to work with a string base type, no matter how I marshal it. But if i change it to a pointer, process it, and change it back, it works fine. I know it's trivial, but i don't understand why it's doin it, and it's bugging me.
Again, thanks for all your help. While i know i've got a long way to go, it's another step towards me grasping COM more completely. *grin*
Cheers!
Cata
|
|
|
|
|
The Catalyst wrote:
While i know i've got a long way to go, it's another step towards me grasping COM more completely.
You REALLY need to learn COM first. Thinking you'll learn COM through .NET Interop is really a naive assumption. Learn COM first - it's difficult enough. You clearly don't understand as much about marshaling as you should. Write a few COM applications first and pick up a good book on COM. You need to know both .NET and COM appart from each other before interop'ing the two. That's pretty much a universal truth.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I've been playing with the GCHandle class, and trying to get a full array, but still not having any joy with it. The array still contains only one entry when it is returned.
IntPtr[] EnumerationArray = new IntPtr[10];<br />
GCHandle handle = GCHandle.Alloc(EnumerationArray, GCHandleType.Pinned);<br />
<br />
int ArrayLengthOut;<br />
<br />
ContentEnumeration.Next(EnumerationArray.Length,handle.AddrOfPinnedObject(),out ArrayLengthOut);<br />
<br />
handle.Free();<br />
<br />
IntPtr pTest = EnumerationArray[0];
Where can i look for information on manualy offsetting arrays? I understand how it's done in structs.
Cata
|
|
|
|
|
ok i have a webservice written in foxpro and it accesses a database and passes me back information from the database how do i call this webservice
i added ref. to the webservice how do i use it can somebody give me an example
(the foxpro service generated a test.wsdl file this is the file i am adding ref. to)
thanks
chad
|
|
|
|
|
Once you've added a reference to your XML Web Services (presumably in C#, since this is the C# forum), you only need to create an instance of the proxy class and call it's methods:
MyWebService service = new MyWebService();
service.MyMethod();
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I am doing an application to print my companies invoices. Currently it uses the .net printing framework. I am looking to change that to straight Win32API to help speed it up. Plus that will use less resources. Three questions.
1) I can't seem to create a font with CreateFontIndirect(LOGFONT). I think that I am putting in the wrong value for the height. Could someone give me an example of how to create a font with that API?
2) I can't seem to use the DrawText function. I can print using the TextOut but I wanted to use the DrawText function for the formatting options. However, whenever I try to use it, it prints out a blank page. Could someone give me an example of how to print text with that API?
3) Does anyone know of a good resource to printing with pure Win32API?
Thanks alot for any help.
Shaun
|
|
|
|
|
i've have been asked to create a gui that is a mdi in a mdi. by this i mean that the main form at a mdiparent and the host mdichildern who in turn act as a mdiparents and host their own mdi children. i've this and received a clear error say a mdiparent can not be a mdichild as well. my question is does anybody know a way around this or an alternative to a "mdi in a mdi"? any reply is appreciated.
|
|
|
|
|
i've tried this too...but to no avail it wasnt possible..anyone has got any idea abt this.
CODER
|
|
|
|
|
also i don't care if there's some tool i have to buy to this. at this point i'll take anything.
|
|
|
|
|
At the very, very worst, you could completely avoid any built-in MDI functionality and write it yourself. Besides some interesting user-interface tweaks, MDI is basically a set of forms inside another set of forms, which can be done rather easily.
John
"You said a whole sentence with no words in it, and I understood you!" -- my wife as she cries about slowly becoming a geek.
|
|
|
|
|
thats fine as it seems to be my only option but, can point in the direction to find out how to that because i'm guessing it would invole some win32 calls?
|
|
|
|
|
The Win32 calls would only come in if you need to have the main form, its sub-form, and then the 3rd level sub-form all showing a title bar that indicates it is active. I'm not really if there is anything else to the base MDI document behavior.
To add a form as a child of another form, make a constructor to the (sub)form class which takes the parent as a parameter. Then, in that constructor, set TopLevel to false, and Parent to the parent form. It would look like this:
public MyMdiForm(System.Windows.Forms.Form parent)
{
InitializeComponents();
this.TopLevel = false;
this.Parent = parent;
}
To handle the look that needs multiple forms to display as active, check this[^]out.
John
"You said a whole sentence with no words in it, and I understood you!" -- my wife as she cries about slowly becoming a geek.
|
|
|
|
|
Hi, I'm creating a C# windows application and I've got a problem. I need to temporarily lock a file directory, do something to a xml file in that directory, then unlock the directory. Is this possible? Can anyone help me with this? I know I need to use the Directory object somehow.
Thanks
|
|
|
|
|
You can't really lock a directory, but why not just lock the XML document? It's simple using the FileStream class like so:
using (FileStream stream = new FileStream(
path, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
{
XmlDocument doc = new XmlDocument();
doc.Load(stream);
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Is their a way to programmatically take away permissions to a folder, then give it back? I think that is what I really need to do.
Thanks!
|
|
|
|
|
Yes there is, but no pure .NET way. Read NT Security Class for .NET[^], which of course only works on NT. Pay attention to the note toward the top of the page, too. There's a library written by Microsoft developers for NT security that you should use instead. That library will be included in .NET 2.0 in Q1 of 2005. Getting familiar with it now will help in the future if you upgrade your code base.
Still, though - what's the point? All you're doing is updating an XML document, so that's all that needs to be locked. Taking away permission and giving them back is dangerous if you don't account for every single exception. What if your code bombs and permissions are restored? It's not an effective solution.
If you need to update the XML document with a list of files in that directory and don't want that list to be modified while updating the XML document, the solution is simple: get a collection of filenames - which is a read-only collection of the files in that directory when you got the files. This can easily be achieved with the Directory.GetFiles static method, or the DirectoryInfo.GetFiles instance method. Update your XML document with those collections. That's an effective and proper solution.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi there. I'm working on a custom control where each side can have a different border thickness. I found this code while googling which allows me to modify the controls non-client area so I can draw my borders:
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
enum WM_MESSAGE
{
WM_NCCALCSIZE = 131,
WM_NCPAINT = 133,
WM_NCHITTEST = 132,
WM_NCLBUTTONDOWN = 161,
}
[StructLayout(LayoutKind.Sequential)]
struct NCCALCSIZE_PARAMS
{
public RECT rgrc0, rgrc1, rgrc2;
public IntPtr lppos;
}
[DllImport("User32.dll")]
private extern static IntPtr GetWindowDC( IntPtr hWnd );
[DllImport("User32.dll")]
private extern static int ReleaseDC( IntPtr hWnd, IntPtr hDC );
private Rectangle _rcButton = Rectangle.Empty;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case (int)WM_MESSAGE.WM_NCCALCSIZE :
if (m.WParam == IntPtr.Zero)
{
NCCALCSIZE_PARAMS csp;
csp = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALCSIZE_PARAMS));
csp.rgrc0.Left += 1;
csp.rgrc0.Top += 5;
csp.rgrc0.Right -= 1;
csp.rgrc0.Bottom -= 1;
Marshal.StructureToPtr( csp, m.LParam, false );
}
break;
case (int)WM_MESSAGE.WM_NCPAINT :
{
IntPtr hDC = GetWindowDC(m.HWnd);
Graphics g = Graphics.FromHdc(hDC);
g.FillRectangle(SystemBrushes.Highlight, 0, 0, this.Width, 5);
g.FillRectangle(SystemBrushes.Highlight, 0, 0, 1, this.Height);
g.FillRectangle(SystemBrushes.Highlight, this.Width-1, 0, 1, this.Height);
g.FillRectangle(SystemBrushes.Highlight, 0, this.Height-1, this.Width, 1);
ReleaseDC( m.HWnd, hDC );
break;
}
}
base.WndProc(ref m);
} This works fine until the control is resized - it's client area gets reset. Any ideas on how to fix this?
"I think I speak on behalf of everyone here when I say huh?" - Buffy
|
|
|
|
|
My guess is that the reason it works until the control is resized is that the client area was never successfully change the the size you are wanting.
I took a look at the WM_NCCALCSIZE documentation here[^]. It says that if WParam is FALSE (zero), that a RECT is passed in LParam, not an NCCALCSIZE_PARAMS structure. On the other hand, if WParam is TRUE (non-zero), then you are supposed to get an NCCALCSIZE_PARAMS in LParam.
So, it looks like the WM_NCCALCSIZE handling code is never doing anything. I suspect that if you put a breakpoint on the first line of the WM_NCCALCSIZE handling code, then stepped through it, that it would throw an exception at
csp.rgrc0.Left += 1;
John
"You said a whole sentence with no words in it, and I understood you!" -- my wife as she cries about slowly becoming a geek.
|
|
|
|
|
Thanks for the tip. I managed to get it to "remember" the resized non-client area by changing the offending case statememt to:
case (int)WM_MESSAGE.WM_NCCALCSIZE :
if ( m.WParam == IntPtr.Zero )
{
RECT rect = (RECT) Marshal.PtrToStructure(m.LParam, typeof(RECT));
rect.Left += 1;
rect.Top += 5;
rect.Right -= 1;
rect.Bottom -= 1;
Marshal.StructureToPtr(rect, m.LParam, false);
}
else
{
NCCALCSIZE_PARAMS csp;
csp = (NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(NCCALCSIZE_PARAMS));
csp.rgrc0.Left += 1;
csp.rgrc0.Top += 5;
csp.rgrc0.Right -= 1;
csp.rgrc0.Bottom -= 1;
Marshal.StructureToPtr(csp, m.LParam, false);
}
Only problem was that sometimes the right and bottom border widths were out by 1. Managed to fix this by overriding OnSizeChanged:
[DllImport("User32.dll")]
public static extern int RedrawWindow(IntPtr hwnd, IntPtr lprcUpdate, IntPtr hrgnUpdate, int fuRedraw);
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
RedrawWindow(this.Handle, IntPtr.Zero, IntPtr.Zero, RDW_FRAME | RDW_UPDATENOW | RDW_INVALIDATE);
}
Works like a charm
"I think I speak on behalf of everyone here when I say huh?" - Buffy
|
|
|
|
|
Great!
John
"You said a whole sentence with no words in it, and I understood you!" -- my wife as she cries about slowly becoming a geek.
|
|
|
|
|
How could I be able to catch a message that was sent to an application which I have its handle(Window handle)?
thanks for help.
|
|
|
|
|
Override WndProc .
Stability. What an interesting concept. -- Chris Maunder
|
|
|
|
|
Or if you want a more dynamic solution look up the IMessageFilter interface. Message filters can be added and removed from windows forms application at runtime.
|
|
|
|
|