I am working on an add-in for Enterprise Architect in C# that involves tabs. Tabs as in, what there is on the bottom of the screen just as in an excel sheet. For example, if you as a user would click on one of the tabs in excel the view will change to this newly clicked tab.
In the above picture, the tab "web interface" is currently selected. Now what happens in the code when the user clicks on one of the other tabs. Lets say the user clicks on "Program on user PC".
My question addresses anyone who has any Enterprise Architect Add-In developing experience. I would like to catch the mouseclick event that is fired as soon as the user clicks on one of the tabs such that I can respond properly on this event and prepare the view for the user.
I hope it is clear what I am trying to achieve. Thanks in advance!
EA does not make raw Windows input events (keyboard, mouse) available to Add-Ins, but the Context Item event EA_OnTabChanged() tells you when the user switches tabs. This sounds like what you're after.
The event includes the name of the tab being switched to, so you just need to match that to know if the event is for you.
Related
I would like to know if it is possible to, while running a WPF window application in Visual Studio, wait for the user to click anywhere on the screen (not necessarily inside the window of my application - for the purpose of my application, the click would most likely occur inside a browser page) and then gather the information about the click (like inside the window of which application the user clicked, or the selector of the html element the user clicked)? I know this question might be very confunsing but this is basically my last resort since researching on the Internet hasn't helped me much. Just to provide a better idea of what I seek, it's like what the 'Extract Structured Data' Activity does in UiPath. Oh and I'm using C# by the way.
You can try and use this external library called GlobalMouseHook.
This library allows you to tap keyboard and mouse, detect and record their activity even when an application is inactive and runs in background.
Here is what you can do with this library:
Mouse coordinates
Mouse buttons clicked
Mouse drag actions
Mouse wheel scrolls
Key presses and releases
Special key states
Hope this helps.
The Add In
I have written a VSTO Add-In for Outlook. The crux of the add-in is to put a button on the Ribbon when a user is replying to email that will allow them to quickly set the Email Sensitivity to Confidential or back to Normal. Currently the process to do this on an email is multiple steps, and my client wants it to be one click. The button icon is Red or Green based on the sensitivity of the current email.
Sensitivity = Normal => Red Button
Sensitivity = Confidential => Green Button
There are a few basic use cases I have uncovered:
A user Creates a new Email
In this case the button should start Red and change when clicked.
A user Creates a reply to an email
In this case the button should start the same color as the parent email. If the parent email was Red, the button should be Red and if it was Green the button should be Green
A user Edits a draft
If the user has a draft the button should reflect the value of the Sensitivity property of the saved draft.
The way I chose to accomplish this was with two buttons in a ribbon XML where I override the getVisible property and based on the current MailItem set the appropriate button visible. Another way would have been to have one button and toggle the image and functionality based on MailItem sensitivity property.
Regardless of my choice I think I would have run into the same problem in that the Office Ribbon is meant to be a static object, drawn once at creation of the Explorer or Inspector and you need to force a redraw by calling the InvalidateUI method.
With that in mind, to cover my 3 use cases above I had to hook into some events from the application.
I'm not sure I can post the exact code, but the basics of it are as follows:
On Startup subscribe to:
Application.ActiveExplorer().SelectionChange
Application.Inspectors.NewInspector
On SelectionChange
If there is one item selected, and that one item is a MailItem
Refresh the Ribbon UI - Call Ribbon.InvalidateUI();
On NewInspector
If the Inspector.CurrentItem is a MailItem
Refresh the Ribbon UI - Call Ribbon.InvalidateUI();
The SelectionChange event handler covers if a user is clicking around in Outlook 2013 and up and selects an Inline Draft. It will draw the ribbon in the TabSet TabComposeTools, TabMessage. This places the icon on the main outlook window Ribbon when necessary.
The NewInspector event handler covers if the user double clicks on the draft, creating a new window.
The Problem
I have been receiving reports of Outlook crashing. At first I had limited logging and relied on the Event Logs generated by Outlook. Not very helpful.
Then I implemented log4Net, and I'm writing to a log file in the AppData folder of the user's profile. This has given me some insight
I have wrapped a try/catch around every method code block, so nothing in my add-in (that I wrote) runs outside of a try/catch, and each block just catches Exception, logs it, and throws it. This is an attempt to find the problem.
My latest log shows the UI refreshing, so it called my GetVisibility override, in there based on if the control.Context is an Explorer or Inspector I get the ActiveInlineResponse or CurrentItem as a MailItem, read the Sensitivity property and based on that return True or False if the button calling the handler should be visible. (I have one handler for both buttons)
The crash appears to happen when I am casting an ActiveInlineResponse to a MailItem. The next item in my log is the logging I do in the Startup handler of the Addin. (So the user restarted Outlook)
Other Details
The user base is currently running Outlook 2010 - Outlook 2016.
We have one add-in that runs on all of them as nothing we are doing should be specific to any version of office.
The add-in works without fail on Outlook 2010.
The add-in project selected was Outlook 2013-2016.
I'm using Ribbon XML over Designer because Designer doesn't support putting buttons in TabSets.
Update
I have put in some event handler local variables to my Add-In class as described by https://www.experts-exchange.com/questions/27305112/Problem-with-VSTO-event-handler-going-out-of-scope-in-Outlook-AddIn.html I haven't seen the error since, but also haven't had much feedback as I did this on a Friday and this Monday is a holiday. I'll update with an answer if this appears to be a "Fix".
I'm completely new to C# and the .NET framework so forgive me if this is a silly question.
Is there any way of viewing a list of all of the events that have happened on a Windows system as a result of keystrokes and mouse movements etc.? So for example when I click on the Start menu, the Start menu is displayed or when I click the "Apply" button within a settings sub-menu, the settings are applied.
Is there any part of the .NET framework that will allow me to view all of these events/actions and record them via a C# program? Any help would me greatly appreciated! Thanks in advance.
UI Automation API is what you need. For listening automation events there are few kinds of handlers: AutomationEventHandler, StructureChangedEventHandler and 2 others.
There is another way for native windows: global mouse and keyboard hooks. See SetWindowsHookEx function.
C# in visual studio designer gives you the ability to respond to all kinds of events, like mouse moves and clicks. If you click on the object you want events from, then go to the events pane, you will see a list of all the events for that object. double click in the textbox next to it and it will auto-generate an event handler in your code. When the event is triggered, it will go to this method and do any code you provide there; IE log the action however you choose.
Does anybody know if it is possible (and in that case how) to navigate programmatically in an Office 2010 addin?
The idea is to create a settings button on a ribbon tab, that when clicked, will direct the user to the settings of the add-in that would be located in the backstage view. Is there a way to programmatically change the active view being displayed to the user or something like that?
Thank you!!
As a developer putting on the user spectacles, I find your approach not convincing. If I click on a settings button, I expect a well-designed dialog, not to be thrown into backstage view. On the other hand - as a developr I'm much more at ease with a well-designed Windows Form than with the controls Microsoft provides for the backstage user interface; I guess you'll find there more limitations then you like.
As far as I understand your question, you want to have two different entry points to your settings dialogue - one from a button in the ribbon, and another from a point in the backstage view. Why not combining and showing from both positions the same form? Also Microsoft provides you with additional dialogues, if you click on controls in the backstage view.
Technically:
If you want to start the action of a ribbon control, you can use the "ExecuteMSO" command of the application.commmandbar object, e.g. in Word you may use
Application.CommandBars.ExecuteMso "ApplicationOptionsDialog"
to open this dialogue. However, I've done a limited test to call a custom button in backstage view, and it failed. Sol I guess that you can use ExecuteMSO only for built-in commands.
Folks, I am creating a MMC3.0 SnapIn program with C#. There I have some scope nodes and I have FormViewDescription's where I used C# UserControl instances to display some data. And my intent is, user must see and update those data into the UserControl and there is a Save button onto that UserControl which user should press at the end of their editing and I will persist that change then.
Now the problem is,
If after making some changes, user closes the SnapIn window, all his changes are gone :( I need to prevent user before closing this window with a dialog that "Save before quiting " (or something like that - you know the standard feature of any editor program).
But could not found a way to do so. Any suggestions for me?
Would be appreciated much!
Coincidentally, I have also just created an MMC in much the same manner as you described above but after much searching (and frustration) I could not find any way to cancel the close event. I recommend changing your approach as explained below.
First of all have a look at how most of the MMC's that are already in Windows handle changing settings. Usually if you want to change a setting you select an item in a ListView and right-click 'Properties' to bring up a settings form and make your changes there.
Bringing up a form gives the developer the ability to control the full lifecycle of the form and ensure that settings are saved before it is closed.
So my advice is:
Create your FormView
Add any status information you need
Add a button 'Edit Settings' to your
FormView
Create a Windows Form with
Save/Cancel + all your data input
controls
Launch your form with
myForm.ShowDialog() when you click your 'Edit Settings' button
Handle the Save/Cancel button
presses and cancel appropriately if
data is dirty
I hope this helps. Good luck!