Which Command Item is activated on the Command bar - c#

I am working with Add-Ins in ArcMap using VS2010 and C#. I have a question in regards to ArcObjects ICommandBar and ICommandItem classes. I've looked at these and have been able to produce code, that on button click, will select or activate a specified command item. So I know somethings about command bars. My question is how would I go about determining which command Item is active on a Command Bar? I didn't see any helpful mehtods in which to do so. Any help on this would be greatly appreciated.
UID thisID = new UID();
thisID.Value = "esriArcMapUI.SelectTool";
IDocument ThisDoc = ArcMap.Application.Document;
ICommandBars CommandBars = ThisDoc.CommandBars as ICommandBars;
CommandBars.Find(thisID);
ICommandItem myItem = CommandBars.Find(thisID) as ICommandItem;
if (myItem.Execute() == true)
{
messagebox.show("My select element tool is selected");
}

I finally found an answer to my problem, with help from #DJKRAZE. I was making this a little harder than it was and thinking about it way too hard. The code below can be used to return the currently selected tool in ArcMap (In my case I am returning the tooltip of the currently selected tool in my diagnostic window).
public static ICommandItem CurrentTool()
{
IApplication _myApp = ArcMap.Application;
string getToolTip = _myApp.CurrentTool.Tooltip;
System.Diagnostics.Debug.Write("Current Tool Tip is: " + getToolTip);
return _myApp.CurrentTool;
}
I call this function on a button click. So, When I launch ArcMap, I select a tool from the toolbar. I look into my diagnostic window and I'm able to see the tool tip for the selected tool. I will need to tweak a few things for my own benefit, but this would be the answer I am looking for. Hope this can be of some help to any one else.

Related

Check if the current document in Visual Studio 2012 is a Code Window

I am looking for a way to have my extension check if the currently opened window in visual studio 2012 is one, where the user can write code (or any kind of text, really).
To check if the currently opened window has changed, I use
_DTE.Events.WindowEvents.WindowActivated.
This gives me the EnvDTE.Window that received the focus.
When I look at the properties of that window while debugging, and I look at EnvDTE.Window.Document.Type and it's value is "Text".
However, if I stop debugging and try to access the Document.Type property, it does not exist.
If I look for this property in the documentation of EnvDTE.Window.Document, its description says
Infrastructure. Microsoft Internal Use Only.
So now I am looking for any advice on how I could check if the currently active window is one, where I can write code (or anything else), or some other kind of document (like the solution properties for example).
Edit:
I also tried checking Window.Type and Window.Kind of the active window, but they just tell me that it's a document, not making any differentiation between a resource file, an image file or an actual source file, which is what I'm trying to find out.
Edit²:
The reason why I want to check if the current document is one where I can write code in, is because I want my extension to store information about some of those documents and I want to modify the right-click context menu based on the information I have stored, if any.
It is not a "real" answer, but you can follow status of VS GoTo command - it is available only for text editors:
bool isCodeWindow = IsCommandAvailable("Edit.GoTo");
private bool IsCommandAvailable(string commandName)
{
EnvDTE80.Commands2 commands = dte.Commands as EnvDTE80.Commands2;
if (commands == null)
return false;
EnvDTE.Command command = commands.Item(commandName, 0);
if (command == null)
return false;
return command.IsAvailable;
}
You can check to see if the document is a 'TextDocument'
bool isCodeWindow = dte.CurrentDocument.Object() is EnvDTE.TextDocument;

Cannot add icon in shell extension with C#

I've found a very nice tutorial and i am trying to understand something that is not in this tutorial (because the tut itself works fine)
http://www.codeproject.com/Articles/9163/File-Rating-a-practical-example-of-shell-extension
When you look at applications like WinRar, TortoiseSVN, Antivirus-apps and many more, there is an icon next to the Shell Extension Item.
I would like to know how this is done. (Programmatically with C#)
Adding a separator works, adding a submenu works and click+action also works, but i'm struggling with the icon. This cannot be so hard. Can somebody help me?
And please don't say that Microsoft doesn't longer support this in .NET 4.0, because it is not guaranteed and therefore they don't supply samplecode. If all those other apps can do it, then it is possible.
Please supply me some sample code, some tutorials or maybe even a working piece of code.
Please have a look at the following article, it uses .NET 4.0 it to create Windows Shell Extensions using the SharpShell nuget package.
NET Shell Extensions - Shell Context Menus
Using this library, you can set the image directly while creating the contextmenustrip as shown below
protected override ContextMenuStrip CreateMenu()
{
// Create the menu strip.
var menu = new ContextMenuStrip();
// Create a 'count lines' item.
var itemCountLines = new ToolStripMenuItem
{
Text = "Count Lines...",
Image = Properties.Resources.CountLines
};
// When we click, we'll count the lines.
itemCountLines.Click += (sender, args) => CountLines();
// Add the item to the context menu.
menu.Items.Add(itemCountLines);
// Return the menu.
return menu;
}
You only have to add to the following registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Classes*\shellex\ContextMenuHandlers
and here is the code:
string TimeStamp = DateTime.Now.ToString("dd-MM-yyyy");
string key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\*\\shellex\\ContextMenuHandlers\\Winrar";
string valueName = "MyWinrar";
Microsoft.Win32.Registry.SetValue(key, valueName, HERE WHAT YOU WANT TO START, Microsoft.Win32.RegistryValueKind.String);
i hope it works for you!
All the apps you listed use COM and unmanaged code to create overlay icon handlers. There is even a special project TortoiseOverlays that provides a common library for drawing icons for TortoiceCSV, TortoiseSVN and TortoiseGIT. You can take a look at it's source code to find out how it is done. If you want to draw similar icons, you should probably just reuse it.
Using .Net for this type of extensions is not recommended, because when multiple extensions, built against different .Net versions would attempt to load in explorer process, they will crash the explorer.

Automating Website/Web forms using C# in Firefox, using Visual Studio 2010?

If anyone can help me I'd appreciate it.
I'm working on a C# file in Visual Studio 2010 that I need to be able to test a website with multiple form pages, for the purpose of an example we'll refer to them all as 1.aspx, 2.aspx etc.
I've my code that fills out the first page (1.aspx) fine, and click the "continue" button to load the next page, but when it gets to 2.aspx it won't continue to fill out the form.
We'll say an element on the 2.aspx page is called "DOB". On trying to run from the start (I've all the pages form data in the one .cs file) I get an error like "DOB does not exist in the current context".
Anyone's insight into this would be really appreciated!
In all honesty, it sounds like you might be better off using the WatiN Framework. I have been writing automation with it for years and the way that it is implemented and its ease-of-use make it worth the slight learning curve.
Just to add a bit more to the answer; and yes, this is pseudo-code:
[Test]
public void Should_attach_to_browser()
{
ExecuteTest(browser =>
{
browser.GoTo(NewWindowUri);
browser.Link(Find.First()).Click();
var findBy = Find.ByTitle("New window");
var newWindow = Browswer.AttachTo(browser.GetType(), findBy);
newWindow.Close();
});
}
In the code above, note the Browser.AttachTo(browser.GetType(), findBy); method. Based on what I have understood of your question, the .AttachTo() method would work well since you would be able to take the focus off the current form and assign it to the next in your work/execution flow.

Drag & drop of a dynamically created shortcut

I have a C# application that creates shortcuts to launch other programs with specific arguments and initial directories. I would like the user to be able to drag a shortcut from the Windows form and drop it anywhere relevant like the desktop, the start menu, and so on but I don't really know how to handle that, could anyone point me in the right direction?
I have seen a few samples using PInvoke and IShellLink like this one, or read answers on SO like here, which already help create shortcuts and save them in a .lnk file. I assume I have to hand over data in a DoDragDrop() call when the user initiates a drag operation, for example by handling a MouseDown signal. That's as far as I got, I suppose I need to know exactly which type the target is expecting to accept the drop, and how to serialize the shortcut, but couldn't find any information on that part.
Perhaps another option would be to get the location of the drop, and manage that from my application, but there again I'm a bit clueless as how to do that.
The framework version is currently 3.5, and I'm only considering Windows platforms.
Thanks in advance for your help!
Update/Solution:
Using the ShellLink code mentioned above to create a temporary shortcut file, I simply used DataObject for the drag and drop, like in the following example:
private void picShortcut_MouseDown(object sender, MouseEventArgs e)
{
ShellLink link = new ShellLink();
// Creates the shortcut:
link.Target = txtTarget.Text;
link.Arguments = txtArguments.Text;
link.Description = txtDescription.Text;
link.IconPath = txtIconFile.Text;
link.IconIndex = (txtIconIndex.Text.Length > 0 ?
System.Int32.Parse(txtIconIndex.Text) : 0);
link.Save("tmp.lnk");
// Starts the drag-and-drop operation:
DataObject shortcut = new DataObject();
StringCollection files = new StringCollection();
files.Add(Path.GetFullPath("tmp.lnk"));
shortcut.SetFileDropList(files);
picShortcut.DoDragDrop(shortcut, DragDropEffects.Copy);
}
Quite complicated if you consider the PInvoke code (not shown here), and I still need to create this temporary file with the target name. If anyone knows a... erm, shortcut, it's welcome! Perhaps by porting the code for which John Knoeller gave a link (thanks!).
Raymond Chen did a whole article on this very topic on his blog check out dragging a virtual file
I answered a question sort of similar to this on a previous thread. This might be a starting point for you.
Drag and Drop link

In C#, is there a way to consistently be able to get the selected text contents of currently focused window?

In my c# .Net application, I've been trying to be able to retrieve the currently selected text in the currently focused window. (Note that it can be any window open in windows, such as word, or safari).
I'm able to retrieve the handle to the currently focused control. (Using a couple of interop calls to user32.dll, and kernel32.dll).
However, I've been unable to consistently be able to get back the selected text.
I've tried using SENDMESSAGE and GET_TEXT. However this only seems to work for some applications (works for simple applications like wordpad, doesn't work for more complex applications like firefox, or word).
I've tried using SENDMESSAGE and WM_COPY. However, again this only seems to work on some controls. (I would think that WM_COPY, would cause the exact same behaviour as manually pressing CTRL-C, but it doesn't).
I've tried using SENDMESSAGE and WM_KEYUP+WM_KEYDOWN to manually stimulate a copy command. BUt this doesn't constantly work either. (Perhaps of an overlap with the actual hotkey pressed by a user to invoke my applications).
Any ideas on consistently being able to retrieve the currently selected text ? (on any application).
I got this working by a combination of a couple of things. So:
Wait for whatever modifiers are currently held down to be released.
Send control+c (using this answer Trigger OS to copy (ctrl+c or Ctrl-x) programmatically)
bool stillHeld = true;
int timeSlept = 0;
do
{
// wait until our hotkey is released
if ((Keyboard.Modifiers & ModifierKeys.Control) > 0 ||
(Keyboard.Modifiers & ModifierKeys.Alt) > 0 ||
(Keyboard.Modifiers & ModifierKeys.Shift) > 0)
{
timeSlept += 50;
System.Threading.Thread.Sleep(timeSlept);
}
else
{
stillHeld = false;
}
} while (stillHeld && timeSlept < 1000);
Keyboard.SimulateKeyStroke('c', ctrl: true);
I'm using WPF so Keyboard.Modifiers is System.Windows.Input.Keyboard, whereas Keyboard.SimulateKeyStroke is from Chris Schmick's answer.
Note, timeSlept is my max time to wait for the user to let go of the key before continuing on its merry way.
I managed to get text for wordpad/notepad and anything that supports UI automation.
The code below may work for you in some cases. I'm going to get a start on using Reflector to see how windows does it for textboxes in the TextBoxBase.SelectedText property.
public static string SelectedText
{
get
{
AutomationElement focusedElement = AutomationElement.FocusedElement;
object currentPattern = null;
if (focusedElement.TryGetCurrentPattern(TextPattern.Pattern, out currentPattern))
{
TextPattern textPattern = (TextPattern)currentPattern;
TextPatternRange[] textPatternRanges = textPattern.GetSelection();
if (textPatternRanges.Length > 0)
{
string textSelection = textPatternRanges[0].GetText(-1);
return textSelection;
}
}
return string.Empty;
}
set
{
AutomationElement focusedElement = AutomationElement.FocusedElement;
IntPtr windowHandle = new IntPtr(focusedElement.Current.NativeWindowHandle);
NativeMethods.SendMessage(windowHandle, NativeMethods.EM_REPLACESEL, true, value);
}
}
I don't believe that it is possible, the currently focused may not contain any selected text. (It may not even contain any text at all). Or the current selection could be an icon, or an image.
Perhaps requiring the user to copy the selected text to the clipboard first may be a solution.
I've possibly misunderstood the question, but could you just send Ctrl+c? If you know the window is always foremost and the text to be copied is selected?
SendKeys.SendWait("^c");
Once copied to the clipboard, it's not tricky to programatically retrieve the contents (you could even check it's actually text at that point).
I think creating clipboard monitor is a good option. I suggest you to look at Klipper (KDE clipboard module), it copied everything you select in the clipboard list, either content is file, folder or some text.
More details can be found here.
Hm... you find it to be easy? How come?
The best alternative to SendKeys.SendWait("^c"); I found was this one:
http://www.c-sharpcorner.com/Forums/ShowMessages.aspx?ThreadID=46203
However, it only works for a few apps, like notepad. For web browsers, it just crashes.
Anyone got anything better?
Try the GetWindowText() API on controls for which the other methods do not work.

Categories

Resources