|
I've written an app in C# - let's call it Foo. Foo creates *.Bar files. I want to enable double click support in Windows for *.Bar files, so Windows automatically opens the file in a running instance of Foo.
I already know how to get Windows to start Foo up when I double click on a .Bar file - simply associate the file type using Windows Explorer (for example), and use the args[] string array argument in the Main(args[]) method of Foo. This acts as a list of files to open when Foo starts up. But what happens when Foo is _already_ running? What pathway does Windows use to send an open-file instruction to Foo? Does it go through the Main() method?
I've written Foo so only one instance of it will run at a time, so I need to be able to get Windows to tell the existing instance of Foo to open a file. Any ideas how this is done?
Thanks
|
|
|
|
|
|
ok, but how do I get the previous instance then? These examples are all for preventing multiple instances. I think the 2nd one has some useful code that allows me to get the process object for the previous instance, but I can't seen to get the actual instance of the application (a winform object) from that process object, so I'm still kinda stuck. Any ideas?
|
|
|
|
|
There are several approaches you can take
to transmit the command line info(such as
the filename) from the secondary instance of
your app to the primary. You can use sockets,
windows messaging, shared memory etc..
I did an ActiveX Control that uses a page
of the system swap file with a memory mapped
file to do it. It works with just about everything I've tried that can understand
ActiveX.
If you can read Delphi, the source to the
component that the ActiveX Control is derived
from is online. http://www.torry.net
Search on "TellTail" to download the Delphi source. Basically it uses a named mutex to determine if you're in the primary or secondary instance of the app. If in the secondary, it copies command line info to the shared memory page. The primary instance has to periodically check if any info has been put in shared memory then call a method to copy it out.
I'm reworking it now to use the 'Global\'
namespace if in XP for the named kernel objects
but I may also change it to use a system event
to eliminate the polling in the primary app.
When the next revision comes out I'll have to
decide how I'm going to distribute it. But
for now the Delphi source might give you some
ideas how to do it in C#.
Good luck.
|
|
|
|
|
The first article I gave you does exactly what your talking about. All you have to do is examine the source code. There is also an article[^] on MSDN that demonstrates what you want to accomplish. There is a follow up article for that one that fixes a bug in the first article here[^].
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
Sorry, I guess I wasn't being clear enough. Yeah, that article was doing what I wanted. The solution just seemed overly complex, and it was in VB (I'm using C#). Plus I'm writing an open source application, so I have to be careful what code I compile into my app.
At the time I didn't realise it would be so much work to have one instance of an application contact another - I figured it was just a case of getting the instance via its handle, which I now understand is not enough. Thanks for your help ... guess I'll be taking a closer look at that VB code after all.
|
|
|
|
|
I am trying to take a screenshot of a window from its handle.
This is the code that takes the handle and get the image from it.
public Image gdiShot(IntPtr handle)
{
//get dc from handle
IntPtr sourceDC = USER32.GetWindowDC(handle);
//create the copy destination dc
IntPtr destDC = GDI32.CreateCompatibleDC(sourceDC);
//get dimensions of dc
USER32.Rect rect = new USER32.Rect();
USER32.GetWindowRect(handle,ref rect);
int width = rect.x2 - rect.x1;
int height = rect.y2 - rect.y1;
//create bitmap
IntPtr h_myImage = GDI32.CreateCompatibleBitmap(sourceDC,width,height);
//select bitmap object into destination device context
GDI32.SelectObject(destDC,h_myImage);
//time to blit
GDI32.BitBlt(destDC,0,0,width,height,sourceDC,0,0,0x00CC0020);
//cleanup
GDI32.DeleteDC(destDC);
USER32.ReleaseDC(handle,sourceDC);
Image myImage = Image.FromHbitmap(h_myImage);
return myImage;
}
Now this works, IF my windows style is set to the default blue,silver,or olive etc. However, I use a custom skin and I am not the only one. And when I run this code with the custom skin, I always end up having 3 extra lines of pixels on top of the image. In reality the window IS 3 pixels lower on the desktop then reported by GetWindowRect API call. At this point I was about to blame the skin, but I open SnagIt take the shot of the same window with custom skin and what do you know, no extra lines on top. In other words I know it is possible.
I am open to ANY suggestions. For ex: alternative API calls to use, a way to try and get the REAL visible coordinates of a window.
Also worth mentioning:
This only applies to windows with title bars. The device context sees the window as 500x500. In reality pasted into Photoshop its 500x497.
I get the window handle passed on to this functino from a mouse click, then GetWindowFromPoint, and then GetAncestor to get to the handle of the root window.
Any suggestions please, I'm desperate.
I've seen SnagIt do it now I have to find a way to do it too, because I know its possible.
Anybody know a way to get titlebar height?
|
|
|
|
|
maybe the style is using regions ?
use GetWindowRgn API to check ..
|
|
|
|
|
Right on target.
I just called that function and with the custom skin the output is 2 with the windows skin the output is 3. Unfortunately I do not know what exactly that means.
This is what MSDN says.
NULLREGION The region is empty.
SIMPLEREGION The region is a single rectangle.
COMPLEXREGION The region is more than one rectangle.
ERROR The specified window does not have a region, or an error occurred while attempting to return the region.
Ok thats nice, but the return type of the function is int. Go figure...
What effect would a region have. Im thinking the window is 500x500 but the reagion that allows to be painted in is smaller (the three pixel rows on top). Am I correct?
|
|
|
|
|
And those are ints:
#define ERROR 0
#define NULLREGION 1
#define SIMPLEREGION 2
#define COMPLEXREGION 3
#define RGN_ERROR ERROR There's the values. In C/C++ pre-proc defs are almost always used in place of hard-coded values because they're much easier to change.
Download the Platform SDK from http://msdn.microsoft.com/platformsdk[^] and you can find these values. If you installed the Platform SDK with Visual Studio (a default option if you install VC++ as well), the headers are already present. These pre-proc defs are found in wingdi.h.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I just used the GetWindowRgnBox call and it solved my problem. Well you, hspc, solved my problem. Thank you!
Like I said in the previous post the painting region was ofset 3 pixels down from the actual dimensions of the window. I run this call with custom skin it return 3 for top part of the RECT structure. I run it with windows skin its 0.
Thanks again.
And if you know what the return values for GetWindowRgn mean, please share. Because I suppose there could be more than one painting region, the program has to be able to react appropriately.
|
|
|
|
|
Microsoft wrote:
Although many of the filters provided with DirectShow support property pages, they are intended for debugging purposes, and are not recommended for application use. In most cases the equivalent functionality is provided through a custom interface on the filter. An application should control these filters programatically, rather than expose their property pages to users
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directX/htm/introductiontodirectshow.asp
Does anyone know how to "control these filters programatically"? Or where can I find a sample or documentation on the topic?
Very appreciate for any kind of help. Thanks.
|
|
|
|
|
|
Welcome to the world of COM interop in .NET. You must declare the interfaces in managed code, using the same GUIDs (IIDs for interfaces, CLSIDs for classes) in the GuidAttribute , define the methods in the same order and/or with the same DISPIDs (using the DispIdAttribute ),etc.
You must also P/Invoke APIs like OleCreatePropertyFrame that the same you linked (in the other post) uses.
Before just jumping into it, you really must read the .NET Framework SDK documentation covering these topics. Read Interoperating with Unmanaged Code[^] and the class documentation[^] for the System.Runtime.InteropServices namespace. For example, the Marshal class has static methods that can be very helpful in marshaling structs, alloc'ing and freeing memory, and more.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hi,
How to Prevent decompile or dis-assembly c# project (.NET)?
its possible prevent to decompile .net assembly?
thanks.
|
|
|
|
|
No, but you can use an obfuscator to make it very difficult to comprehend. You can also use ngen to compile it to native code which adds another layer of difficulty.
"If a man empties his purse into his head, no man can take it away from him, for an investment in knowledge pays the best interest." -- Joseph E. O'Donnell
The Second EuroCPian Event will be in Brussels on the 4th of September
Can't manage to P/Invoke that Win32 API in .NET? Why not do interop the wiki way!
|
|
|
|
|
Note however that you shouldn't ngen it before deploying. ngen.exe should only be run on the assemblies during or after deployment. This is only meant to boost performance by pre-JIT compiling the IL, not as obfuscation.
Yes, as Colin said, it can help your "cause" but it can also lead to problems since JIT compiling an assembly compiles the IL to native code, which may be a little different from machine to machine and may reduce portability.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
|
I created a basic C# Windows application, built it and executed the resultant executable and looked in task manager to find that it was using 7,848K of memory. Does anyone know how this can be optimized so it uses much less memory? Maybe I'm missing something very basic here, but I wasn't able to find a solution anywhere I looked.
Am I expecting too much? I'd guess and say it should only be using 100K. It is after all an empty form.
Thanks,
Ray
_____________________________
You're not an inker, you're a tracer!
|
|
|
|
|
8,000K isnt all that much... what version of windows do you have? and whats your comp's RAM?
|
|
|
|
|
I have winXP and 512MB ram running @ 2ghz. However, none of that is relevant. And I completely disagree with you that a one form executable with no controls on it should be using 8MB or RAM.
I compiled the same type of project using Managed C++ and had the same result for mamory usage. however if you run notepad.exe or calc.exe you will see they both use between 1.4 and 1.9 MB each and they both have controls as well as a decent amount of code behind them.
I don't want to start an argument of whether or not an exe would scale at the rate of 8MB per form loaded into memory, but I would like to know if someone know of a way to optimize the memory usage.
Thanks,
Ray
insurgentpyro,
Not worrying about memory consumption is very lazy programming at best. How has growing up as a VB only programmer been? Open your mind, code should be written well and made to be as efficient as possible. Don't use the expense of todays hardware as an excuse.
_____________________________
You're not an inker, you're a tracer!
|
|
|
|
|
I agree with you about your app eating up too much memory, however there is little you can do about it initially. See, when your C++ app starts up there is no run-time enviornment or virtual machine needed to be loaded because your C++ app is a native app in the windows world. When you start up your .NET app parts of the .NET framework needs to be loaded also because .NET is not yet 100% fully part of the OS. In future version of Windows (Longhorn and on) .NET will be native part of the OS so you will not have overhead like this. In the meanwhile it is true that your .NET app will eat up 20MB of RAM because of the virtual machine and the other various framework components (like winforms, exception management mechanism, etc...) but over time unused RAM will be garbage collected. I wrote a trading application's front-end using C# and upon startup it ate up 30~40MB of RAM but as it was running throughout the day it actually went down after a couple of garbage collection cycles.
|
|
|
|
|
You assuming that the program is a little .EXE with just a single form and no other controls. Since it's a MANAGED application, it has the MANAGING RUNTIME and a base class library behind it, called the .NET Framework. This is where all that memory is being used.
Can you reduce it's footprint? No...
If the memory footprint is a problem, you'll have to write your app in non-managed C++. You'll loose the ease of use of C# and the .NET Framework Base Class Library.
RageInTheMachine9532
"...a pungent, ghastly, stinky piece of cheese!" -- The Roaming Gnome
|
|
|
|
|
This is a Runtime application. The Common Language Runtime (CLR) is loaded, along with the base class libraries (BCL assemblies) and any third-party assemblies when the Type they define is needed. This can consume quite a bit of memory. The same is true for Java applications and anything that uses a runtime in this manner (C/C++ has a runtime, too, but since it compiles to native code where .NET and Java compile to bytecode, that runtime is just common functions).
There are things you can do to help eliminate waste, though. For example, when you show a modal form (when you call Form.ShowDialog ), make sure you call Dispose on the forum afterware to clean-up native resources. Native resources aren't managed by the Runtime GC (Garbage Collector), so they must be freed by calling Dispose (and there's a lot of discussion about finalizers and Dispose on the 'net you can google for).
A good way to make sure a form is always disposed is using the using block statement:
using (PromptForm form = new PromptForm())
{
DialogResult result = form.ShowDialog();
if (result == DialogResult.OK)
return form.Answer;
else return null;
} PromptForm is just a made-up form that asks a question and lets the user type in an answer. If the OK button was clicked (and it's DialogResult property is set to DialogResult.OK ), you return the answer; otherwise, you return null (again, just an example). Before the answer or null is returned, the form variable is disposed since the above translates to:
PromptForm form = new PromptForm();
try
{
}
finally
{
form.Dispose();
} In a try-catch-finally or try-finally, the finally block is always exectued even if an exception is thrown (the only case where it's not is when you call Environment.Exit , which unloads the CLR and only finalizers are called).
There are many other things you can do as well. I suggest you go to MSDN[^] and browse some of the articles about memory management and the CLR.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I want to write a new ColorTranslator class because it can't analyse the color string like "rgb(255,0,0)"
public class ExColorTranslator <br />
{<br />
public static Color ExFromHtml(string htmlColor)<br />
{<br />
...<br />
}<br />
}
but When I used the function ExColorTranslator().ExFromHtml(...) ,I had to write new ExColorTranslator().ExFromHtml(...)
How to use this function directly and need't construct a new ExColorTranslator() class? just like the class such as Pens ,ColorTranslator ,Brushes ... does
|
|
|
|
|