|
What's the desired interraction between the
app instances? One instance "getting" another
isn't very specific. Give a bit more detail
and maybe someone can get you started.
|
|
|
|
|
The exact use is I need to send a string message from one instance to another (the string message being the file name the one instance wants the other one to open). This has to be done from the static Main() method.
The simplified code could be :
// this is the main "starting" class of my app
class MainForm()
{
public static void Main(string[] args)
{
// gets instance of this app already running
MainForm otherAppStance =
objCleverWidget.GetOtherInstance();
// sends message to other instance and quits
if (otherAppStance != null)
{
otherAppStance.TransferMessage(args[0]);
return;
}
}
public static void TransferMessage(string
strMessage)
{
MessageBox.Show(
"The other instance says" + strMessage
);
}
}
So what I really need to know is how to make
objCleverWidget.GetOtherInstance()
This will return the instance of the main Window Form from the other app instance, and all my problems will be solved.
That's the ideal solution. I haven't had any luck coding it, so I came up with a small but crude workaround - use P/Invoke's SendMessage. SendMessage is limited though - you can't send strings with it, just a message id in the form of an uint, and two pointers which I can't figure out properly. So I converted my string message into chars, converted each char to its uint equivalent, and sent those uints as message id's from one instance to another (obviously using some start- and end-message flags). It works and uses very little code, but I'm not too sure how well it will stand up to scrutiny. Oh, and it kinda destroys the recipient app's main form - you have to redraw after receiving messages. Doesn't sound too healthy ...
I've seen two other solutions online, one in VB (on codeproject infact) which I dont understand too well (VB + interop = brainmelt), and the other using Remoting, which raises questions of its own (assumes user pc will have network support). I was surprised by how much code was used in both solutions - my workaround was pretty light.
Anyway, associating an application with a file type is a pretty standard requirement, so I am a little puzzled by the lack of built-in functionality in the .Net framework for this kind of thing. If you can point out a practical solution that doesn't use networking, please let me know. I have reason to believe P/Invoke's SendMessage will do the trick, but I need to find out how to use it's two pointer parameters.
Thanks for your time!
|
|
|
|
|
Okay, I think a more straight-forward solution to
what you want to do, provided both applications
are on the same machine, is to use shared memory
via Memory Mapped Files. C# is a bit of a pain
in that it only gives the PInvoke mechanism for
doing Win32 stuff, but using a page of swap file
in a memory mapped file for shared memory isn't
that difficult. There are a couple articles
showing how to get at memory mapped files from
C# on Code Project. Also you can use the tool
at http://pinvoke.net to pull the prototypes
adjusted for C# right into the editor for you.
The main advantage of using a named memory mapped
file with app instances is that you don't need to
worry about handles. Using a GUID string in the
memory mapped filename makes sure it's unique.
So in your application you try to create the
Memory Mapped File with CreateFileMapping(). If you get a handle but Marshal.GetLastWin32Error() returns ERROR_ALREADY_EXISTS then you're in the secondary instance. Otherwise if the creation
succeeded you're in the primary.
The secondary instance copies info it wants to
send to the primary in the shared memory. The
primary instance reads it out. To avoid mangling
the data you can use a mutex to control access.
Before it quits, the secondary instance gets the
mutex, copies the info to the shared memory,
releases the mutex, then exits(if that's what
you want it to do.) The primary gets the mutex,
checks for new data in the shared memory, if it
finds it then it copies the data out, then releases the mutex.
It sounds a bit more complicated than it is.
I would look for examples of Memory Mapped
Files. Using one page of system swap file
is the simplest case with fewest system
quirks to worry about.
As I suggested, the TellTail component on
www.torry.net does what you're trying to
do. Delphi is pretty Enlish-like so even
if you don't program in it often you can
read the source and get the gist. Besides,
Win32 calls are going to be pretty much the
same no matter what language you call them
with.
|
|
|
|
|
I want to add ComboBoxes to some TreeNodes in a TreeView. I am unable to find a way to do this. Visual C++ 6 allowed this functionality. I am sure they have ported this over to .NET. Is there a way to do this ?
I want the user to be able to select a value from a combobox in a treenode.
Thx!
Regards,
Shardool Karnik.
|
|
|
|
|
You can do this like you would've using the Common Control APIs and Windows APIs, but you need to P/Invoke this functionality. The Handle property (inheritted from Control ) is the HWND .
The TreeView control (like most controls in Windows Forms, and even many other classes throughout the .NET BCL) encapsulates native APIs. Most of the Windows Forms controls actually wrap the common controls, so the TreeView wraps the Tree View common control.
This means that you have to override WndProc and handle the drawing messages (among other custom drawing messages) and site (or position) the ComboBox (which wraps the Combo box common control) in the edit portion of a TreeNode (which encapsulates a TVITEM struct).
Sorry I'm not providing any example code, but this is not an easy subject and is definitely a little too lengthy for the message forums. This would be better suited to an entire article.
You might try searching for such an article here on CodeProject (I've not seen one, but I haven't seen every article on this site neither). You might consider writing an article aobut it if/when (here's hoping for the latter :beef: ) you complete such a task.
If you have specific questions regarding P/Invoke and whatever else you need, don't hesitate to ask here.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
hi...
Can anyone show me how to changle the color on the statusbar?
i have not tried anything because i dont have a clue!
there is no panels on only pure text!
QzRZ
|
|
|
|
|
You can't simply set StatusBar.BackColor (inheritted from Control ) like you would normally. It is not support and, hence, is hidden.
You instead must add one StatusBarPanel (you can use the designer to do this) that covers the entire StatusBar . Set the Style property to StatusBarPanelStyle.OwnerDraw and handle the StatusBar.DrawItem event.
In your event handler, you can use the StatusBarDrawItemEventArgs properties (like Graphics and Bounds properties) to fill the background.
If you read about the StatusBar.DrawItem event in the .NET Framework SDK (see http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemWindowsFormsStatusBarClassDrawItemTopic.asp[^]) you will find an example.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi,
I'm facing troubles with SQLServerCE...
I've done a small application that looks like this :
- a GUI creates a thread that retrieves data from a (CAN) bus (using PInvoke etc.). This thread is written in C++ managed. Then, the thread calls static functions written in a C# project to create a database (using System.Data.SqlServerCE) and to store data into it (using datasets).
till this moment all of that works fine..
-but now my GUI has to retrieve and display data from the database that has been created by the thread..
Thus I use System.Data.SqlServerCE, make a connection like this :
SqlCeConnection connec = new SqlCeConnection("Data Source=\\Windows\\tyreDB.sdf");
then I type (the data retrieval is done in deconnected mode):
string Query = "SELECT * FROM tyreData";
SqlCeDataAdapter daCurrent = new SqlCeDataAdapter(Query, connec);
daCurrent.Fill(dsCurrent,"tyreD");
but in the last line ("Fill"), that actually does the connection, the application crashes and I get a
"Native Exception code=0xc0000005" (access violation I guess)
..I get the same thing when I try to connect to the database in the "connected mode" (i.e. when I type
connec.open() )
So what's going on? does it mean that SQLServerCE doesn't accept that 2 threads access to the same database???
please help me! Julien
|
|
|
|
|
FYI, a DataAdapter derivative like SqlCeDataAdapter will open the close the connection itself. Logically, there's no way to query for data unless it connects to the database. You should not open the connection yourself.
If you read the documentation for the SqlCeConnection class in the .NET Framework SDK, you might notice the following:Although SQL Server CE only supports one connection at a time, multiple commands can share the same connection. This means that it is possible to have multiple instances of SqlCeDataReader open on the same connection. This behavior differs from that of System.Data.SqlClient. Since you're using two assemblies, you do have the option of exposing the connection. Since both the MC++ and C# assemblies are .NET assemblies (both compiled to IL, although a mixed mode MC++ assembly may also contain native instructions), you can reference one from another. So perhaps you could expose the SqlCeConnection from the MC++ assembly and the C# assembly could use that. You could - through mutexes or some other locking mechanism - make sure that the SqlCeConnection in one assembly is closed and disposed (always call Dispose on IDisposable implementations when you're finished with them) before attempting to make another connection (perhaps using a broker or provider pattern).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
actually I've tried with only one connection but the problem is still the same.
My question is : does SQLServerCE support that 2 threads access the same database (with one shared connection) ??
|
|
|
|
|
You should read about it in the .NET Framework SDK, which is where that quote in my last reply came from (and there's more). It's very likely that it doesn't work on two separate threads but I honestly don't know off hand and in order for me to find out, I'd have to read the documentation anyway.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I'm trying to create a custom listbox that justifies to the bottom right of the box. Items add to the bottom list and move up but the most recent entry is always on the bottom and is always visible. I created a custom drawitemhandler that handles the right justification but setting the line.Alignment to "near" or "Far" does not have any effect on the control. Any ideas on creating a bottom aligned box or any existing code to create one?
Kam33mitch@hotmail.com
|
|
|
|
|
Use ListBox.Items.Insert(0, someObject); instead of Add , which will always add the object to the end of the collection.
Unfortunately, even if you were to extend ListBox and override CreateItemCollection , you would not be able to override Add . It is not virtual and since all references to Item refer to the actual ListBox+ObjectCollection type, your Add (if you were to hide (Shadow in VB.NET) the existing Add ) would not be called. Additionally, both ListBox+ObjectCollection.Add and ListBox+ObjectCollection.Insert call ListBox.NativeInsert , which is a private member you can't do anything about.
Perhaps not the best solution, but your only other option besides calling Insert(0, someObject) is to use another control - possibly a third-party control or one that you would write from scratch.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
OK, that makes sense if the box were already grounded to the bottom and naurally added items to the top. A regular listbox adds new items to the bottom of the control (which is good) but as the list grows larger than the control, the scroll goes top to bottom. You can scroll down to see the last entry but when you add a new one, it goes back to the top again. Picture a listbox three rows high aligned "far" to create a right alignment:
One
Two
Three
Adding a fourth item to the list should result in:
Two
Three
Four
With the ability to scroll up to see the first entry. This is what I'm trying to do. What's happening now is:
One
Two
Three
With Four below the control which requires scrolling to be visible. I'm trying to create the first scene.
Any ideas on this? Do you know of a 3rd party control that could do this?
Kam Mitchell
|
|
|
|
|
Because i want to send a bitmap object from server to client but Socket.Send method just support byte array so
is there a way to conver bitmap object to byte array and versus ?
|
|
|
|
|
System.Drawing.Image (And System.Drawing.Bitmap) implement ISerializable.
Just serialize your image using a binary serializer.
Grim (aka Toby) MCDBA, MCSD, MCP+SB
SELECT * FROM user WHERE clue IS NOT NULL
GO
(0 row(s) affected)
|
|
|
|
|
You can either serialize or save the image to a MemoryStream . Either way results in the same behavior (ISerializable.GetObjectData saves to a MemoryStream and saves the byte array).
Just using Save does save a little coding, though:
MemoryStream ms = new MemoryStream();
image.Save(ms);
byte[] arr = ms.ToArray();
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi gurus,
Can any one show me how I can add a progress bar in a status bar panel?
Best regards.
Thanks.
There is no spoon.
|
|
|
|
|
The gist of it is that you set one of the StatusBarPanel 's BorderStyle property to StatusBarPanelBorderStyle.None , its Style property to StatusBarPanelStyle.OwnerDraw , and handle the StatusBar.DrawItem event to "draw" that StatusBarPanel . What you actually end up doing is using the StatusBarDrawItemEventArgs passed to you to site (position) a ProgressBar in the area of the StatusBarPanel that you're "drawing".
A quick search on "statusbar progressbar" here on CodeProject yielded a couple good results:
http://www.codeproject.com/info/search.asp?cats=3&cats=5&cats=6&searchkw=statusbar+progressbar[^]
They're in VB.NET, but contain mostly use the BCL (for which the calls are the same for almost any managed language, and the classes/properties/methods/etc. are always the same for any managed language).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
it is not possible to put a standard progress bar in a status panel?
There is no spoon.
|
|
|
|
|
That's exactly what Gary and I told you how to do. You're siting the ProgressBar into a StatusBarPanel . There's really not a lot of difference than throwing a button on a form or something. The only real difference is that the form is the parent of the button and can (if the button sends them) receive window messages from its children. The button is still sited relative to the forum, even in non-.NET frameworks/APIs.
In .NET 2.0, IIRC, there is a more highly advanced status bar being added with a progress bar panel option. Until then, you must either site the ProgressBar into a StatusBar or handle the drawing for a particular StatusBarPanel and draw the progress yourself (it's really quite easily and involves simple math and drawing routines).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
ok, Thanks,
it works the way you said.
I added the ProgressBar in the controls collection of the StatusBar, added a dummy panel to have the progress control in second position.
There is no spoon.
|
|
|
|
|
this is one of many examples here on code project
http://www.codeproject.com/cs/miscctrl/statusbarprogresspanel.asp
Gary
"I invented the internet".
- Al Gore, former U.S. Vice President
|
|
|
|
|
it is not possible to put a standard progress bar in a status panel?
There is no spoon.
|
|
|
|
|
Try this one
Article Link[^]
Gary
"I invented the internet".
- Al Gore, former U.S. Vice President
|
|
|
|