|
Heath Stewart wrote:
is that it is ".NET", not ".Net". This is a common mistake but is not proper. ".net" is also not allowed in images (i.e., logos) as it is reserved for Microsoft use only.
.net is an internet root domain, and no-one can tell me how to spell it.
top secret
|
|
|
|
|
If, for some reason, you were having issues with getting the Advanced Networking Pack installed and started, there are updated instructions in the manual and also in the forums under tech support for WinP2P.
|
|
|
|
|
Thanks to this great site and the great people contributing source code examples, I've managed to create my first C# application! woot woot woot!
The only problem I'm having is that my application launches internet explorer for every url that I click on (from a list of urls). Instead of having a new instance of internet explorer started everytime, is there a way to find an existing instance of iexplorer and change it's url?
Currently, I can find an existing instance of iexplorer bring it to the foreground via "SetForegroundWindow" in user32.dll, but I don't know how to change it's url?
Can anyone help me on this?
Thanks.
Chris.
|
|
|
|
|
One way is to simply use ShellExecute. The default implementation in windows is to use a running instance of Internet Explorer (or whatever the default browser is, which is often the preferred way anyway):
ProcessStartInfo info = new ProcessStartInfo(url);
info.UseShellExecute = true;
Process.Start(info); You can also use the InternetExplorer out-of-process server if you want to force the user to use IE. This represents the fore-most instance of IE. First create an interop assembly of Internet Explorer by either typing the following:
tlbimp.exe /out:Interop.SHDocVw.dll %WINDIR%\system32\shdocvw.dll Or using VS.NET to add a COM reference to the "Microsoft Internet Controls" (shdocvw.dll). Then create an instance of the InternetExplorerClass like so:
InternetExplorerClass ie = new InternetExplorerClass();
object url = url;
object missing = Missing.Value;
ie.Navigate2(ref url, ref missing, ref missing, ref missing, ref missing); See Programming and Reusing the Browser[^] for more details.
If you want to host the WebBrowser control (the control that is actually IE, which also hosts MSHTML, the Microsoft HTML rendering engine), you can additionally run:
aximp.exe /out:AxInterop.SHDocVw.dll %WINDIR%\system32\shdocvw.dll to create an ActiveX host for the WebBrowser control (by default, named AxWebBrowser ), which you can host in your forms and container controls. You can find more information about this in the link above (related to the COM interfaces exposed by WebBrowser and MSHTML). There's also several articles here on CodeProject that described advanced hosting using .NET. Just search (a good query term is "IDocHostUIHandler").
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi Heath,
thanks for the quick response!
I tried the first option of using UseShellExecute but that didn't work for me. Reason was because in the IE options, the option of "Reuse Windows for Launching Shortcuts" was unchecked. When I had this checked, it worked.
Thanks.
|
|
|
|
|
Actually, you should honor the user's preferences as much as possible. Last time I checked, that option should be turned on anyway (it also affects browsing with Windows Explorer).
As I said, though, if you want to force users to use IE with your app (and there's good reasons, though they are usually more suited to hosting the WebBrowser control) you can use the second method I mentioned - the out-of-process automation server for IE.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I have made a control whice inherits from Listbox, and made it ownerdraw...
In the OnDrawItem i have the following code:
base.OnDrawItem(e);
e.DrawBackground();
Graphics g = e.Graphics;
Bitmap b = new Bitmap(30, 30);
Graphics gs = Graphics.FromImage(b);
Brush brush = Brushes.Red;
gs.FillRectangle(brush, 0f, 0f, 30f, 30f);
g.DrawImage(b, e.Bounds.Left + 5, e.Bounds.Top + 5);
Brush myBrush = Brushes.Black;
g.DrawString("hey", e.Font, myBrush,e.Bounds, StringFormat.GenericDefault);
The text is drawed fine, but the bitmaps only blinks and then they are gone. If I scroll the listbox everything is showed fine, but if I minimize and maximize the application (force a redraw) the bitmaps are now drawn.
If I select an item, the bitmap for that item is showed just fine
Any ideas?
- Anders
Money talks, but all mine ever says is "Goodbye!"
ShotKeeper, my Photo Album / Organizer Application[^]My Photos[^]
|
|
|
|
|
Not sure if this would cause that particular problem, but be sure to dispose your Graphics object that you use to fill the Bitmap . The using statement is handy for this since it would be disposed even if any exceptions occur.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
|
I didn't figure it was, but thought I'd mention it anyway.
When you click on an item after the images fail to display, and then click on another item, does the bitmap continue to display fine? What if you scroll the list again - do the items that were out of view and are not in view display the bitmaps correctly?
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
When I click an item and then click another item both images shows just fine, and when scrolling everything works as expected...
But when minimize/maximize the bitmaps goes away again...
Really strange...
- Anders
Money talks, but all mine ever says is "Goodbye!"
ShotKeeper, my Photo Album / Organizer Application[^]My Photos[^]
|
|
|
|
|
Definitely a refresh bug, then. Try setting ControlStyles.AllPaintingInWmPaint and ControlStyles.UserPaint to true using SetStyle in your constructor.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
|
All those list-type views are always funky when it comes to painting.
It's a bit of a hack, but how about calling Refresh (invalidates and forces an immediate update) in an override to Visible (when set to true ) or something along those lines.
Sorry for all the responses. I've just never seen this behavior before, and I've seen (and usually fix) a lot of painting bugs (the ubiquitous ListView being the usual suspect).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I just tried to make a simple listbox in my application, and making it ownerdraw, and added the code from my first post to the drawitem eventhandler...
Same problem when I minimize/maximize the app....
So when the control is refreshed, it erases everything, kinda strange...
And yeah, I have never seen this one before, and I have done lots of ownerdrawing in my time. (i actually prefer drawing in C++ )
- Anders
Money talks, but all mine ever says is "Goodbye!"
ShotKeeper, my Photo Album / Organizer Application[^]My Photos[^]
|
|
|
|
|
|
Running through some tests it seems as through XmlSerializer won't output any properties that don't have a set. What if wanted a read-only property? What am I missing?
|
|
|
|
|
This is obscurely documented in the XmlElementAttribute class documentation. You could get around it by implementing an empty set accessor and document it as a read-only property, or implement IXmlSerializable , even though you're not supposed to (I've done it in the past with no problems). It works similarily to ISerializable . There isn't documentation for it, per se, but it's not hard to figure out.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hadn't thought of using an empty set accessor, that should work for what I need. Thanks
|
|
|
|
|
I have an application that has a C# GUI that displays OpenGL images created by a C++ DLL, and what I am trying to do is elegantly control C++ variables using C# GUI menus. While I could create a public function for every menu option in the C++ DLL and call it from the appropriate C# callback, I don't want to (mostly because I'm lazy); what I would really like is to create a singleton class CGraphicsOptions to which both the C# GUI and the C++ DLL have access. If this is possible, the the C# interface could update the boolean variables therein, and the C++ code just look at them when it's time to render.
Is this possible? Or does anyone have any solutions to this type of problem?
Thanks,
Chris
|
|
|
|
|
You could make an unmanaged interface which CGraphicsOptions would implement as a COM object. Declare this interface using the appropriate GuidAttribute and InterfaceTypeAttribute . If this interface was exposed in a typelib, you could simply use tlbimp.exe (or VS.NET can do it when you add a COM reference to your project) to create an interop assembly (RCW, Runtime Callable Wrapper). That would be one way.
The reason the interface would have to be a COM interface is because casting to an interface causes the CLR to QI (QueryInterface ) for the interface. Your class's implementation of QueryInterface (ATL encapsulate all this nicely, BTW) returns a pointer to the class that implements that interface (most likely the class being QI'd) which the CLR treats as a reference to that interface.
The class wouldn't even necessarily have to be registered. So long as your C++ app's class factory creates a valid instance of it, you wouldn't even need a COM class factory (that which implements IClassFactory ), so long as the managed code could get a reference to it even if all it does is use a pointer (see the Marshal class documentation to find easy ways to QI for an interface from an IntPtr ).
Finally, there's always the ThisCall calling convention. If you export your CGraphicsOptions class in your native DLL, you need to create a class factory to create and destroy your class, but then declare managed methods using DllImportAttribute and the CallingConvention.ThisCall value for the DllImportAttribute.CallingConvention property.
So, besides exporting your class from the native DLL, also export your class factory functions:
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) LPVOID CreateGOClass();
__declspec(dllexport) void DestroyGOClass(LPVOID lpClass);
#ifdef __cplusplus
}
#endif Using the CallingConvention.ThisCall convention, you pass a pointer to your class instances as the first parameter, so each would have an IntPtr as the first param. Your methods would be declared like so:
[DllImport("mylib.dll")]
private static extern IntPtr CreateGOClass();
[DllImport("mylib.dll")]
private static extern void DestroyGOClass(IntPtr inst);
[DllImport("mylib.dll", CallingConvention=CallingConvention.ThisCall)]
private static extern void SomeMethod(IntPtr inst, int param1, int param2); For a good OO design, encapsulate all this in a singleton class that implements IDisposable . In the constructor, call CreateGOClass() to get the pointer and in Dispose call DestroyGOClass :
public sealed class GraphicsOptions : IDisposable
{
private static GraphicsOptions instance;
private IntPtr inst;
private GraphicsOptions()
{
inst = CreateGOClass();
}
private static GraphicsOptions Instance
{
get
{
if (instance == null)
lock (typeof(GraphicsOptions))
if (instance == null)
instance = new GraphicsOptions();
return instance;
}
}
public static void SomeMethod(int param1, int param2)
{
SomeMethod(Instance.inst, param1, param2);
}
void IDisposable.Dispose()
{
DestroyGOClass(inst);
GC.SuppressFinalize(this);
}
[DllImport("mylib.dll")]
private static extern IntPtr CreateGOClass();
[DllImport("mylib.dll")]
private static extern void DestroyGOClass(IntPtr inst);
[DllImport("mylib.dll", CallingConvention=CallingConvention.ThisCall)]
private static extern void SomeMethod(IntPtr inst, int param1, int param2);
} Then all you have to do to call it is:
GraphicsOptions.SomeMethod(1, 2); It wouldn't have to be a singleton, though. I just did so because you mentioned something along those lines in your request for ideas.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hi everybody,
i want to make a little programm that detect (and logging) all the new launched process on my computer.
i do not know which event is fire when a new process is opened :/
if someone could help thx a lot
|
|
|
|
|
Well, there is no event fired that signals a new process has been launched. At least not a normal one.
In theory, what you could do is use the System.Management classes to subscribe to a WMI generated event, that you have to setup, that fires when the Process list changes.
...in theory...
I've never done it, so I couldn't give you all the sticky details of the WMI part of the project.
RageInTheMachine9532
|
|
|
|
|
You could also implement a system hook (see Using Hooks from C#[^]) using the WH_CBT message to no when a window is being created, but this doesn't necessarily mean a process is being started. You can P/Invoke GetWindowModuleFileName to pass the HWND (as an IntPtr ) and get the path to the module that loaded it. If you keep these in a lookup table (like a Hashtable ), then you could quickly see if the process was already loaded. If not, add it and run your "event" handler.
Otherwise Dave's idea should work, but as he said it's untested. I've used WMI events for other things, so it should work.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
thx for your replys !
i found a possible WMI event :
Win32_ProcessStartTrace
The Win32_ProcessStartTrace event WMI class indicates that a new process has started.
but i don't know how to use WMI event, if you have an example ?
thx a lot
|
|
|
|
|