|
Tried [MarshalAs(UnmanagedType.LPStr)] ?
MSDN[^].
You may also implement a custom marshaler (ICustomMarshaler). That's an advanced topic, but standard marshaling is supposed to work for standard types only...
sometimes it helps to look at the IL generated code
a MS guy on develop.com "answering" .NET issues
|
|
|
|
|
[MarshalAs(UnmanagedType.LPStr)] is rather for "PChar" Delphi type
I've tried all possibilities - custom marshaler it is last possibility but I must resolve internal structure of shortstring, maybe Borland will help
|
|
|
|
|
If you can get a pointer on the actual structure of shortstring, you can hack it, that would avoid relying on Borland.
Btw, I am pretty sure lotsa people have or will have this problem too if shortstring is a lot used in applications.
Another possibility is to avoid direct use of a shortstring. For instance, if the DLL (or intermediate DLL) passes a char*, it could be the actual Delphi's dll job to convert this char* to shortstring. At this point, I don't know sh*t about Delphi.
sometimes it helps to look at the IL generated code
a MS guy on develop.com "answering" .NET issues
|
|
|
|
|
I'm sure too.
Many Delphi programmers use shortstrings because if they use normal strings, which size is dynamically counted they must use Borland Memory Manager dll which of course must be instaled in system. They don't use PChar but they could.
>Another possibility is to avoid direct use of a shortstring. For instance, if the DLL (or
>intermediate DLL) passes a char*, it could be the actual Delphi's dll job to convert this
>char* to shortstring
You're right but if you are not author of this Delphi DLL you can't do this.
I was Delphi developer - but I switched to VS .NET
|
|
|
|
|
Adam Plucinski wrote:
You're right but if you are not author of this Delphi DLL you can't do this.
Use an intermediate DLL.
VS.NET String -> marshalled as char * -> DLL -> DLL function exposes a char * as input parameter -> the implementation creates a shortstring thanks to the constructor (delphi dependency here) -> this DLL calls the initial DLL, passing a shortstring as input parameter -> you're done.
sometimes it helps to look at the IL generated code
a MS guy on develop.com "answering" .NET issues
|
|
|
|
|
Yes - with one dll it is no problem to do this.
..but academic problem still exists
when you have 10 dll's making 10 wrapper dll's is kinda boring
|
|
|
|
|
No, you need only one.
I am surprised that there is no article or existing workaround, if that's a real issue a lot of Delphi.NET developers have.
If that's a real issue, then don't miss the opportunity of writing a CP article. And get known!
It usually takes more than three weeks to prepare a good impromptu speech. Mark Twain
|
|
|
|
|
Does something look wrong with this?
ArrayList al = new ArrayList();
al.Add("Nick");
al.Add("Megan");
for(int i = 0; i < al.Count; i++)
Response.Write(al.Item[i].ToString());
I get this error, and I am looking at MSDN right now and there is an Item property.
<br />
forum.aspx.cs(54,20): error CS0117: 'System.Collections.ArrayList' does not<br />
contain a definition for 'Item'<br />
Nick Parker
The goal of Computer Science is to build something that will last at least until we've finished building it. - Unknown
|
|
|
|
|
Item[] is a special property, only [] is public in the end. So it is : al[i].ToString() .
sometimes it helps to look at the IL generated code
a MS guy on develop.com "answering" .NET issues
|
|
|
|
|
Actually, Item() is a VB.NET thing only. The equivalent in C# is the indexer which is what the [] operator means.
Norm Almond: I seen some GUI's in my life but WTF is this mess
Leppie: I made an app for my sister and she wouldnt use it till it was colorful enough
Norm:good point leppie, from that statement I can only deduce that this GUI must be aimed at children
Leppie:My sister is 25
-Norm on the MailMagic GUI
|
|
|
|
|
StephaneRodriguez wrote:
Item[] is a special property, only [] is public in the end.
First off thanks Stephane, however would you not agree with me that is misleading on MS's part?
Nick Parker
The goal of Computer Science is to build something that will last at least until we've finished building it. - Unknown
|
|
|
|
|
Nick Parker wrote:
First off thanks Stephane, however would you not agree with me that is misleading on MS's part?
It would be if Stephane were telling the truth
.Item() is the VB.NET implementation of a Collection indexer; [] is the C# implementation. If you consider how things were done in VB and C++ then it sort of makes a lot of sense.
It does become more confusing because a lot of collections in the .NET Framework are called "Items" AND Item is often the default property (another VB.NET concept), so you get used to seeing Items[], Items() and Item() but there's not much need for Item[].
... Or something like that
Paul
|
|
|
|
|
Okay, I think I've almost cracked this one. I got some more help by looking at Carlos Perez's explorer tree control which also uses some interfaces from Shell32. This is what I now have:
using System;
using Microsoft;
using Microsoft.Win32;
using System.Runtime.InteropServices;
namespace ShellTypeLib
{
// Component structure for IActiveDeskTop
[StructLayout(LayoutKind.Sequential)]
struct COMPONENT
{
uint dwSize;
uint dwID;
int iComponentType;
bool fChecked;
bool fDirty;
bool fNoScroll;
COMPPOS cpPos;
char[] wszFriendlyName;
char[] wszSource;
}
[StructLayout(LayoutKind.Sequential)]
struct COMPPOS
{
uint dwSize;
int iLeft;
int iTop;
uint dwWidth;
uint dwHeight;
int izIndex;
bool fCanResize;
bool fCanResizeX;
bool fCanResizeY;
int iPreferredLeftPercent;
int iPreferredTopPercent;
}
[StructLayout(LayoutKind.Sequential)]
struct COMPONENTSOPT
{
uint dwSize;
bool fEnableComponents;
bool fActiveDesktop;
}
[StructLayout(LayoutKind.Sequential)]
struct WALLPAPEROPT
{
uint dwSize;
uint dwStyle;
}
// Declare IActiveDesktop interface
[Guid("F490EB00-1240-11D1-9888-006097DEACF9")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IActiveDesktop
{
[PreserveSig]
uint ApplyChanges(uint dwFlags);
[PreserveSig]
uint GetWallpaper([MarshalAs(UnmanagedType.LPWStr)]out string pwszWallpaper, uint cchWallpaper, uint dwReserved);
[PreserveSig]
uint SetWallpaper([MarshalAs(UnmanagedType.LPWStr)] string pwszWallpaper, uint dwReserved);
[PreserveSig]
uint GetWallpaperOptions(ref WALLPAPEROPT pwpo,uint dwReserved);
[PreserveSig]
uint SetWallpaperOptions(ref WALLPAPEROPT pwpo, uint dwReserved);
[PreserveSig]
uint GetPattern([MarshalAs(UnmanagedType.LPWStr)] string pwszPattern, uint cchPattern, uint dwReserved);
[PreserveSig]
uint SetPattern([MarshalAs(UnmanagedType.LPWStr)] string pwszPattern, uint dwReserved);
[PreserveSig]
uint GetDesktopItemOptions(ref COMPONENTSOPT pco, uint dwReserved);
[PreserveSig]
uint SetDesktopItemOptions(ref COMPONENTSOPT pcomp, uint dwReserved);
[PreserveSig]
uint AddDesktopItem(ref COMPONENT pcomp, uint dwReserved);
[PreserveSig]
uint AddDesktopItemWithUI(IntPtr hwnd, ref COMPONENT pcomp, uint dwReserved);
[PreserveSig]
uint ModifyDesktopItem(ref COMPONENT pcomp, uint dwFlags);
[PreserveSig]
uint RemoveDesktopItem(ref COMPONENT pcomp, uint dwReserved);
[PreserveSig]
uint GetDesktopItemCount(out int lpiCount, [MarshalAs(UnmanagedType.U4)]uint dwReserved);
[PreserveSig]
uint GetDesktopItem(int nComponent, ref COMPONENT pcomp, uint dwReserved);
[PreserveSig]
uint GetDesktopItemByID(uint dwID, ref COMPONENT pcomp, uint dwReserved);
[PreserveSig]
uint GenerateDesktopItemHtml([MarshalAs(UnmanagedType.LPWStr)] string pwszFileName, ref COMPONENT pcomp, uint dwReserved);
[PreserveSig]
uint AddUrl(IntPtr hwnd, [MarshalAs(UnmanagedType.LPWStr)] string pszSource, ref COMPONENT pcomp, uint dwFlags);
[PreserveSig]
uint GetDesktopItemBySource([MarshalAs(UnmanagedType.LPWStr)] string pszSource, ref COMPONENT pcomp, uint dwReserved);
}
// Declare ActiveDesktop as a COM coclass
[ComImport, Guid("75048700-EF1F-11D0-9888-006097DEACF9")]
class ActiveDesktop
{
}
}
namespace Wallpaper_test
{
///
/// Summary description for Class1.
///
class Class1
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main(string[] args)
{
System.Console.WriteLine("Windows Wallpaper Tester\n");
ShellTypeLib.ActiveDesktop MyDesktop = new ShellTypeLib.ActiveDesktop();
Type objType = typeof(ShellTypeLib.IActiveDesktop);
System.Console.WriteLine(objType.IsInstanceOfType(MyDesktop));
ShellTypeLib.IActiveDesktop IDesk = (ShellTypeLib.IActiveDesktop) MyDesktop;
uint hresult;
hresult = IDesk.SetWallpaper(@"C:\Documents and Settings\Wjousts\My Documents\My Pictures\Test.jpg",0);
Console.WriteLine("Result from SetWallpaper: " + hresult.ToString("X"));
uint flags = 4;
hresult = IDesk.ApplyChanges(flags);
Console.WriteLine("Result from ApplyChanges: " + hresult.ToString("X"));
int count = 10;
uint reserved = 0;
hresult = IDesk.GetDesktopItemCount(out count,reserved);
System.Console.WriteLine(count);
Console.WriteLine("Result from GetDesktopItemCount: " + hresult.ToString("X"));
}
}
}
So now all three of the IActiveDesktop methods that I call return 0, which is good. Also GetDesktopItemCount is now returning the correct value. SetWallpaper returns zero and if I look at my registry with regedit I can see it has changed the ConvertedWallpaper key, but, and this is a big but, the wallpaper hasn't actually changed! What's more I could have changed that key a lot easier with Registry class in .NET. So I still have the problem of how do I get windows to actually act on the updated registry and CHANGE THE FREAKING WALLPAPER!!!
|
|
|
|
|
I have never, in any language, using any method, been able to successfully change the wallpaper. I tried to change the RegKey, I tried to use the Active Desktop interface, I tried everything. I've also never found any examples of this...I think it's impossible.
Norm Almond: I seen some GUI's in my life but WTF is this mess
Leppie: I made an app for my sister and she wouldnt use it till it was colorful enough
Norm:good point leppie, from that statement I can only deduce that this GUI must be aimed at children
Leppie:My sister is 25
-Norm on the MailMagic GUI
|
|
|
|
|
Actually this works:
// Imported COM function
[DllImport("User32.dll")]
private static extern bool SystemParametersInfo(int uiAction,int uiParam, string pvParam,int fWinIni);
// Changes desktop wallpaper
// <param name="strFileName" />string containing filename and path
public static void ChangeWP(string strFileName)
{
SystemParametersInfo(20,0,strFileName,1);
}
The reason I wanted to get IActiveDesktop working (apart from personal satisfaction) is that it also has methods for changing the wallpaper options (stretch, tile, center, etc).
|
|
|
|
|
Ah. I see. I think I saw that someplace else. I was just trying to do it with ActiveDesktop too because I had ActiveDesktop on at the time. So it was a bit of an exaggeration for me to say that I had never been able to do it...
Norm Almond: I seen some GUI's in my life but WTF is this mess
Leppie: I made an app for my sister and she wouldnt use it till it was colorful enough
Norm:good point leppie, from that statement I can only deduce that this GUI must be aimed at children
Leppie:My sister is 25
-Norm on the MailMagic GUI
|
|
|
|
|
Simulate pressing F5 while you are on the desktop (WM_KEYDOWN, VK_F5). This should do the trick.
sometimes it helps to look at the IL generated code
a MS guy on develop.com "answering" .NET issues
|
|
|
|
|
Hi,
I'm tackling the same IActiveDesktop problem and was wondering if you managed to work it out. I hope this gets through to your email.
Nathan.
|
|
|
|
|
My service is running on a computer i want to getsome information that are
is the computer in logoff state or not ?
if computer is in a logoff state
i want to login,if i have username,password and domain how to login programatically?
how many software are installed in a computer ?
i also want to get installed software list names?
is there any api available for this purpose?
r00d0034@yahoo.com
|
|
|
|
|
I can't help you with logging on programtically, but this code @ PlanetSourceCode should help you with everthing else you need to know: Son of Snoop on Steroids[^]
|
|
|
|
|
I know there is a way using PHP to controll content to display on a specific day at a specific time. I dont need to access any kind of database. I just need a way to display hidden content on a page on a specific day and time. Please help me. I am not the best with C#, so I need the simplest code possible. Please help me. Thanks.
--Peace
YakFreek
|
|
|
|
|
To set a control to appear at midday on the 30th of October:
if (DateTime.Now < DateTime.Parse("30 Oct 2002 12:00:00"))
MyControl.Visible = false; Simple enough?
Paul
|
|
|
|
|
Here is what I have currently in PHP. I need to create the same function in C#. The code loops and displays specific content until it hits the specified date and the it will display that conent. Anyways you will see what I am talking about below. Thanks for all the help..--peace
Here is the code I have now in PHP:
<? if (time()<mktime(0,0,0,9,27,2002)){?>
<table>
All this week, Monday through Firday, your chance at $100 at the following times:
6:30am, 7:30am, 8:30am
</table>
<? } else {?>
<table>
All this week, Monday through Firday, your chance at $100 at the following times:
6:30am, 7:30am, 8:30am
</table>
<? }?>
|
|
|
|
|
There are ways to do it inline like this but I would advise forgetting the way you used to do things (scripting) and thinking in terms of .NET.
In short, you can have two <asp:label ...%gt; tags and write the code you want (your two tables) into the labels "Text" properties.
eg.
<asp:label id="lblBeforeTime" runat="server">
All this week, Monday through Firday, your chance at $100 at the following times:
6:30am, 7:30am, 8:30am
</asp:label> Then add code to your Page_Load saying
if (DateTime.Now < new DateTime(2002, 9, 27, 0, 0, 0, 0))
lblAfterTime.Visible = false;
else
lblBeforeTime.Visible = false; Does this make sense? Are you using VS.NET or hand-coding?
Paul
|
|
|
|
|
Hi,
we have a web app developer under c# that, sometimes, fails to create the screen the way it should.
After debuging the code, we could find it to be the DB_E_ABORTLIMITREACHED exception being thrown.
What I need to know is what can be the cause of this exception? How can i isolate it (find what is the problem)? We just found it to be happening on some clients on the Fill method of the DataAdapter (after turning TRACE on, we saw that the Fill method was taking up to 32 seconds to return, and then came the exception).
Thanks in advance for any help
Marcelo
|
|
|
|
|