Implementing separate application instances in taskbar like Skype - c#

I noticed for a few updates of Skype now that if you start 2 or 3 instances of Skype, in the windows taskbar they appear as separate windows and you can drag them individually as opposed to other applications when they are "glued" together and you can drag them all at once.
My question is how can I implement the individual appearance in my application and is it possible from C# or through winapi?

The shell groups windows in the taskbar using each window's Application User Model ID (AppUserModelID).
By default, every window generated by a given EXE (even in different processes) shares a system-generated AppUserModelID.
You can give each process its own AppUserModelID by calling SetCurrentProcessExplicitAppUserModelID. From your description this is probably what Skype is doing, though I haven't checked.
You can give each window its own AppUserModelID by setting a different PKEY_AppUserModel_ID property on the windows.
Note that these IDs are required to have a particular format:
CompanyName.ProductName.SubProduct.VersionInformation
Raymond Chen wrote an article about this, and it's also worth reading the documentation I linked to.
I'm not aware of WinForms having explicit support for this, but you could certainly use interop to call the Win32 API directly.

Related

How to obtain handle to notification window in Windows 10

I would like to obtain handle to notification window (balloon) using WinAPI. How can I do it, correctly?
Currently I found the solution by enumerating all windows using FindWindowEx function and then obtaining all windows that belongs to ShellExperienceHost.exe process. The operation is executed using GetWindowThreadProcessId API call.
After that we are limited to five windows and one of that window is notification window. But, the only parameter I can base on is window name. In this certain case it is "New notification". However, for my native language it is "Nowe powiadomienie". The application I am currently working on, needs to support multiple language. So, creating set with the names is not good options. Because, the code will be difficult to maintenance and can be depend on further changes in Windows.
I will be grateful for any help in this area.

Issue with the window focus in WinRT

I've got an issue with the focus management in WinRT. The issue is specific for the application startup. Let me share the example of it:
If during the startup I change the focus (for instance I can start selecting some text in a browser), the runtime will decide that it doesn't need to show the application. The application is being started in a 'hidden mode'. It means that I do not see the UI, but I still can find it in process explorer.
So what I need here is to make the application be active in all possible cases. I tried to use several native functions such as ShowWindow, SetActiveWindow, SetForegroundWindow, but without any success.
I also noticed that any WinRT app is being started under WWAHOST.exe and mainwindowhandle is 0. The app shows up if I use 'Switch to' option in Process Explorer context menu.
WinRT applications are sandboxed and have very little control on the way the OS handles them, and almost no way to affect the behavior of other applications running on the same host. What I would suggest then is for you to design your application in such a way that it shows some UI as early as possible, then asynchronously you can load any other resources that your application may need.

Making a program operate from system tray in C# .net

I'm working on a small internal use utility ATM, and I'd like it to appear in the system tray rather than the task bar. I'd also like it to be minimised there from startup rather than loading the main form. Also I'd like to know how to customise the left click action and right click menu on the system tray icon.
I'm failing to find a detailed walk through on this, I'm pretty new to C# (and in fact Windows in general!) so not 100% sure what to search for!
Read this article, it's a good tutorial:
https://www.simple-talk.com/dotnet/.net-framework/creating-tray-applications-in-.net-a-practical-guide/
The basic answer of using a NotifyIcon is correct but, like many things .NET, there are a host of subtleties involved in doing it right. The tutorial mentioned by Brad gives a good walk-through of the very basics, but does not address any of these:
Does closing the application from the system tray properly close any open child forms?
Does the application enforce that only one instance of itself may run (applicable to most, though not all, tray apps) ?
How to open WPF child windows as well as WinForms child windows, if desired.
How to support dynamic context menus.
The standard NotifyIcon exists in WinForms space; can I do a pure WPF solution? (Yes you can!)
I just had an article published on Simple-Talk.com that addresses these points and more in great detail, providing a tray application framework that you can put to use immediately, plus a complete, real-world example application to show everything in practice. See Creating Tray Applications in .NET: A Practical Guide, published November, 2010.

interact with external application in c#

I was playing around with Microsoft Spy++ and noticed that not only does it find the open processes, but can find the individual components running in each process. For example there is this application that allows you to open a window in which there is a textbox for an IP address and textbox for a port. Spy++ can detect these components. Knowing that Spy++ can detect them, is there anyway possible to find them in a separate c# application and go on to MODIFY their contents and otherwise interact with the program? (such as firing a click event on a button)
This is feasible. Try use PInvoke (InterOp) or AutomationElement, or AutomationPeer (for WPF applications) to automate all you wish to do.
Also you might wish to try Inspect and UISpy application as well.
Automation elements/peer is a non-intrusive mechanism to control UI using accessibility framework. One of the weaknesses in windows is its lack of defence against code injection. Put simply:
As a privileged user,
- You can Open and Modify a running Process image
- Make it load your OWN DLL
- Make it run your OWN thread (that potentially listens to commands from your process) and
- allows you to read any bits of memory you want.
Look at detours (http://research.microsoft.com/en-us/projects/detours/) for how to do it with Managed Processes.. Unfortunately, Microsoft removed the inject at runtime features.
Also look at http://msdn.microsoft.com/en-us/magazine/cc163617.aspx for doing things in the managed world (Apps like Snoop utilise that)

Windows Form as child window of an unmanaged app

I am looking for a way to embed Windows Forms applications written in C# in a C++ windows application. The native application main window is subdivided into several panes. The C# app is supposed to appear within one of those panes, i.e. the root window of the C# component (the outermost form) must be a child window of the main application.
Can this be done? If so, how?
Some additional context: To my knowledge, there are two ways to go about this. First, host the CLR in the native app by using the .net hosting APIs (ICLRRuntimeHost, etc.). Second, host the CLR by putting the windows form in an ActiveX control.
Regarding the first approach, I have managed to get the CLR started up and to load a C# assembly (thanks largely to Mattias Högström). Where I am hitting a road block is that I see no way how to tell the component I am running in the CLR that it needs to be a child of a window passed in from the C++ side.
I have also experimented with the second method (using ActiveX and thanks to Daniel Yanovsky). It almost, but only almost, works for my purposes. I can let arbitrary Windows Forms components run in a child pane of the native app. BUT they always run on the main thread of the main app. This means they use the windows message loop of the main app. MSDN says this will not work reliably since the standard Windows message loops don't meet the requirements of Windows Forms (I wanted to post the link to MSDN here but have already used up my new-user-two-link-allotment).
The exceptions to the message loop issue are, according to MSDN, Internet Explorer and MFC apps. The native app I am using as a host is definitely not Internet Explorer. Also, it uses the windows API as wrapped by wxWidgets so MFC is not (or at least not a welcome) option.
The solutions Microsoft proposes involve letting the C# components run in their own message loops on their own threads. This, at least as far as I can tell, necessarily leads back to the first approach mentioned above. So I am back to the question of getting a Windows Form to work under a passed-in parent window.
Again, I am interested in any input that clarifies the child window issue, independent of the approaches I have mentioned here. But in light of the context I could reduce the general question to two specific questions (and I would need an answer to only one of them):
Given a Windows Form hosted in an ActiveX control, how can I allow the form to run in its own message loop on its own thread?
or
Given a Windows Form running in a CLR hosted by a native app, how can I make the form be a child window of a window in the native app?
yes, it can be done. We did the same thing years ago. This is our approach: .NET control also has native window handle, we get these handles through C++/CLI and pass them to Win32, and add these handles as the children of native windows. So the .NET controls run on the main thread of the main app, the problematic part is the message loop, as you have mentioned in your question. We need route the message between the nation and .NET windows if needed. As I remembered, we fixed a lot of bugs related to this, and still there were some mysterious problem we didn't figure out.
There's anothe way: using WPF interop. http://msdn.microsoft.com/en-us/library/ms742522.aspx . According to MS, this should fix the message problems, but we didn't try this approach. You can just use Win32 to host WPF, then use WPF to host Winform.
So for your last 2 questions:
You can't. Only one message loop.
Use handle. This article talks about the handle of Windows Forms: http://blogs.msdn.com/b/jfoscoding/archive/2004/11/24/269416.aspx

Categories