I'm writing a regular class library in .NET Framework (Windows). When someone is calling a certain method in that class library, I want to move the caller's main window (if any) on top of other application's windows (although not permanently).
At first I assumed I could use the Application class to get the main window (Application.Current.MainWindow) but the Application class seems not available...?
Is there a way to do what I want without resorting to native P/Invoke calls? If not - what can be done with P/Invoke when all I know is my current thread?
Related
I'm using the ShowWindow function to hide and show the main window of a external process. Now, I would like to use the AnimateWindow function before calling ShowWindow to animate that window when I show or hide it, however, as the documentation says on MSDN, the Animatewindow function will fail if the thread (on which I'm calling Animatewindow) does not own the window that I want to animate...
Is there any solution for this?, I can "own" the thread in some way to remotely execute the Animatewindow function on the UI thread of that external process, or any other simpler solution to do this?. At least I know the window handle, and I can retrieve the thread id of the thread that created that window with the GetWindowThreadProcessId function.
So, this can be done in any way?.
If this info could be helpful: the external process is a .NET executable (a WPF desktop app), and I want to animate its main window. That application has support for plugins in form of dll files that the application wil load at startup, so I'm calling ShowWindow and AnimateWindow within a class library, running my code in a new thread on which I run a message-loop (for other needs). I don't have access to the source-code of that application to implement any kind of Inter-process communication features like named pipes or shared memory blocks.
I'm asking for a solution using C# or VB.NET, does not matter.
As the documentation says, only the thread that owns the window can call AnimateWindow() on the window.
You can't take ownership of someone else's threads or windows. So, the only way to accomplish your goal is to inject code into the thread that owns the window.
Have your plugin DLL call GetWindowThreadProcessId() to get the ID of the thread that owns the window, and then call SetWindowsHookEx() to install a thread-specific message hook for that thread.
Then, you can send a custom message to the window, and your message hook handler will run in the context of the thread that owns the window, and can then call AnimateWindow() on the window.
I would like to create a multithreaded Usercontrol with C#.
Is this possible with VisualStudio or only in C++? The idea behind is to initiate several instances of the control, so that each instance has its own memory segments and works inependent from the other instances...
Background:
I would like to use the control within SAP. In SAP I am able to create multiple instances of SAP GUI. Each SAP GUI instance contains my own (ActiveX) control. The example is a stop watch. Currently i start the stop watch in the first instance and all other instances are in sync. This is fine so far - but now I would like to change the UserControl (which is obviously a STA DLL) to an MTA DLL so that each instance of the control has its own time... Do I have any chance to compile it as an MTA DLL or is this not solving the issue (without changing the architecure)? Or am I completly wrong?
Assumption: The stopwatch is GDI based... The actual error which I am seeing is from code inside GDI+ that ensures the same Graphics object cannot be used in multiple threads. But how can I use the graphics object in multiple threads?
Base on the info you provided, yes you can, but for memory segment, its per process not controls inside the process, for 32-bit applications, max is 2GB, can be extended to 3GB but not recommended.
if you want independent memory then you must create multiple executables where each exe has its own address space.
so what you can do is create a C# application that has usercontrol or form and add your logic, this will be compiled into a separate exe, then create another C# application to start a process(es) for the first C# application.
I am writing a plugin for a C# application and would like to add a dialog window. I have no control over the application, rather, the application loads plugins dynamically using reflection. I am a newbie with windows forms (this is a forms application) but would like to have a dialog window come up to control my plugin. How can I accomplish this?
If I just add a windows form to my application via visual studio no form appears. Application.Run has presumably already been called by the main application. I am almost completely new to forms.
How can I start the form with with my plugin (the plugin has a method that is called when it is started) and make it active?
Edit: I should clarify, the main application application window will not respond (even to minimize or maximize the window) when a plugin is running, so presumably whatever thread is devoted to handling windows messages is used to run the plugin and is, temporarily, not handling any windows messages. Thus my form needs its own thread handling windows messages.
You will need to initialize your code from whatever method the plugin architecture defined as the entry point (where the application will call your plugin).
To show a form, you can call the Show method on it.
// In a method that the plugin framework calls
myPluginForm.Show();
The application that loads your plugin should have some facility to load a window. Check the API documentation. Also, do you know if there are other plugins that can create arbitrary new windows? Usually, the host application can allow the plugin to create certain predefined (by the host) types of windows (such as config, load a file, etc...).
It might also be possible to programmaticaly create a new form and then load it. See here for an example: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.aspx and look for the "examples" section.
I am developing a (in-process) plug-in to application and as part of my plug-in I want to replace the application's tool-tips with my own. However, there is no API available for me to do so, so I've decided to go low-level.
I know the window class of the tool tip, but the question is, how do I detect it being created and how do I close it afterward?
Here's what I thought to do so far:
Create a system-wide hook on WM_CREATE
When caught, check the class and the process of the WM_CREATE target
Verify it is indeed the window I care about:
If the process is the one my plug-in is sitting in
And if the class is of the correct type
And if the correct application is in focus (in case of multiple applications)
Send a WM_DESTROY to the created window and create my own window at its position instead
How does it sound? Assuming there is indeed no API to handle the tooltips, is there a simpler way for what I need?
Thanks!
P.S Tagged as C++/C# as I intend to write it in these 2 languages (C++ for system-wide hook, C# for everything else)
If you know the type of the window you want to block, you can simply subclass it and handle the destruction in your own WndProc. Use GetClassLongPtr() with GCL_WNDPROC on the tooltip class, use SetClassLongPtr() with GCL_WNDPROC to set your own WndProc and have it call DestroyWindow() on WM_CREATE and call the old WndProc for the rest..
This won't work. Consider the view of the application that you're replacing the tooltips of and assuming that you could tell it to destroy windows. What will happen when the app decides that it needs to close the tooltip? It doesn't have the handle of your new window, it has the handle of the old window, which you've destroyed. Time for things to go wrong.
Your plugin system needs to explicitly support replacing the tooltips if you want this to work smoothly. Perhaps an optional part of the plugin framework could be a RequestTooltip function. If it doesn't exist, or returns null, or whatever then the default tooltips are used, otherwise your plugin provided ones are used.
I have a taskBarIcon element extending Application Context from which my entire UI is designed. This is because the original functionality of the application was to run a background process and simply provide the icon as a confirmation that the app was running.
However, I am now adding additional functionality in the form of a menu that may be accessed by right clicking the icon, and since the core functionality is running on one thread, and the icon on the main thread, I am having issues accessing the icon in the simple case of needing to display a notification bubble. There are no other points at which the two threads may be accessing the same memory, so synchronization is not really an issue.
I am used to Java, in which this process is far simpler. I've read the articles I can find regarding the Invoke-Delegate dance that C# requires, but none are specific to an object extending Application Context. My current implementation is far too unpredictable to be production safe.
My question is this: How do I send the message to the other process to display the notification bubble, without disturbing the accessibility of the menu? Specifically, a simple example with a UI class extending Application Context and a class on a separate thread calling the invoke method would be very helpful.
I really appreciate any help!
badPanda
You could just as well use a SynchronizationContext object that you assign to SynchronizationContext.Current on the same thread that you create the notification bubble. You would then pass your SynchronizationContext object into whatever component the menu is on and it would use context.Send(....) to send a message. Or, if you have access to the notification bubble component or the form it's on, you could do form.Invoke((MethodInvoker)delegate {....});