How to use SHOpenFolderAndSelectItems without selecting items? - winapi

I'm using SHOpenFolderAndSelectItems in order to open up a new explorer window showing a particular location (PIDL). I'm not interested in opening just file paths, so I need to use a PIDL as far as I know!
This works, however, I'm not interested in selecting any of the items in the window. If I don't pass any items to be selected, the parent folder is opened instead, as per the documentation:
A count of items in the selection array, apidl. If cidl is zero, then
pidlFolder must point to a fully specified ITEMIDLIST describing a
single item to select. This function opens the parent folder and
selects that item.
How am I able to simply open the location pointed to by my passed PIDL?
As a test, I passed one item to be selected, pointing to a null pointer. This seems to work, but I'm afraid this might have unintended side effects. This behavior doesn't seem to be documented. Is there a better way to go about what I want to achieve, or is the way I'm using this function now correct?

SHOpenFolder**AndSelectItems**() should be a good indication that this is the wrong function for you to use. If you just want to open the folder, use ShellExecuteEx() instead, eg:
SHELLEXECUTEINFO sei = {0};
sei.cbSize = sizeof(sei);
sei.fMaask = SEE_MASK_IDLIST;
sei.hwnd = ...;
sei.lpVerb = TEXT("explore"); // <-- not "open"
sei.lpIDList = ...; // <-- your pidl
sei.nShow = SW_SHOW;
ShellExecuteEx(&sei);

Related

How do you open a GUI when you touch a brick? (with Filtering Enabled)

I'm trying to make a Shop enclosure when you touch a brick, it'll open the Shop Gui,
Now the main problem is that I do not know how to make the GUI open since using scripts whilst filtering enabled just won't cut it.
Does anyone have a solid explanation?
First of all, in order to execute any action when a brick is touched, you will need to use the .Touched attribute of your brick. Your brick has this attribute because it is a data type called a Part.
Second of all, I am not sure how you want the GUI to open, but the most basic way is to enable it using the .Active attribute of your GUI element. This will simply make it appear on screen. You GUI element has this attribute because it is a GuiObject, whether it be a Frame, TextButton, or whatever else.
The code will look something like this:
brick = path.to.part.here
gui = path.to.gui.here
function activateGui() --shorthand for "activateGui = function()"
gui.Enabled = true
end
brick.Touched:connect(activateGui)
Notice that .Enabled is a boolean (true or false). Also, notice that .Touched is a special object with a :connect(func) function. This is because .Touched is actually an Event. All Events have a special :connect(func) function that take an argument of another function func which is to be executed when the event occurs. In this case, we asked the brick's .Touched event to execute activateGui when it occurs.
Also, .Enabled is set to true by default, so in order for this method to work, make sure you set it to false in ROBLOX Studio by unchecking .Enabled in the Properties tab for the GUI element. Note that you do not have to do this for every single element of the GUI; if you set .Enabled to false on a certain element, all of its children will also automatically be hidden, so you only have to do it on the parent element.
Finally, you must do this in a Local Script. Because the GUI is unique for every single player, it is actually handled by each player's computer, not the ROBLOX server itself. Local Scripts are scripts that are specifically handled by a player's computer and not the server, so it is crucial that you do not try to do this with a regular Script, which is handled by the server.
For your information, the above code can be condensed to this if you would like:
brick = path.to.part.here
gui = path.to.gui.here
brick.Touched:connect(function()
gui.Enabled = true
end)
This is because you do not have to create a function, name it, and then give that name to .Touched; instead, you can just create it right on the spot.

How to avoid watch list variable to collapse on value change in Visual studio?

I would like to avoid that the watch window collapse my list variable content on value change during the process of my application in debug mode. I don't know if i'm really clear, see pictures below:
Collapsed:
Expended:
I would like to see the content of my list and let the content of my list expanded even if a string of my list change. Is there a way to lock the watch window?
As #JasonH mentioned, list will stay expanded while variable references same object and watch will show modified element in red color. List will collapse when you assign new reference to a variable. I am not aware of any option to change this behavior.
As an alternative, you can pin items in a list you are interested in. Or you can pin all items. In this you will get list expanded event if reference changes. But It will be available only in this concrete tab. Here is an example and picture of each step:
var ints = new [] {"1", "2", "3", "4"};
ints[1] = "3";
ints = new[] { "1" };
The short answer to 'pinning a watch item open' is no, you cannot.
First, this option is just not available in VS but you can suggest it at Visual Studio User Voice if you feel that it would help you and others.
Second, and this gets a bit complicated but follow with me...
If the watch item goes out of scope, it will collapse. If the watch item is re-initialized (which in a way kind of takes it out of scope for a moment) it will also collapse. If you have a watch item (complex object) and you start changing its properties and/or fields, you will see that they (the properties and fields) will change but the watch item (object) does not collapse.
I hope this helps.

Go to code location in VS extension

I've got a VS editor extension, and when the user performs a certain action, I'd like to send them to a specific location in the code- not unlike Go To Definition or what happens when you click on a stack frame in the debugger.
So far, I used dte.ItemOperations.OpenFile to open the actual file, and I have the relevant ITextDocument, but I don't know how to set the view to the relevant place in the file. It seems like ITextView and IVsTextView and friends have the methods that I need but I'm unsure how to get the instances I need from my ITextDocument.
How can I go to the file and location I want from a VS extension?
The easiest way to do this is to take the return of ItemOperations.OpenFile and navigate from it to the IWpfTextView
IWpfTextView GetWpfTextViewForDteWindow(
Window window,
System.IServiceProvider serviceProvider,
IVsEditorAdaptersFactoryService vsEditorAdaptersFactoryService)
{
var path = Path.Combine(window.Document.Path, window.Document.Name);
IVsUIHierarchy vsuiHierarchy;
uint itemID;
IVsWindowFrame vsWindowFrame;
if (VsShellUtilities.IsDocumentOpen(
serviceProvider,
path,
Guid.Empty,
out vsuiHierarchy,
out itemID,
out vsWindowFrame))
{
// Note this may have multiple IVsTextView instances associated with it in a split window but
// this will retrieve at least one
var vsTextView = VsShellUtilities.GetTextView(vsWindowFrame);
var wpfTextView = vsEditorAdaptersFactoryService.GetWpfTextView(vsTextView);
return wpfTextView;
}
return null;
}
Do note that there is not necessarily a 1-1 mapping between a DTE Window object and ITextView instance. The Window object essentially represents what is visually displayed as a tab and a given tab can contain many ITextView instances. The most common case is when there is a horizontal split in the window. Probably doesn't matter too much for this scenario but wanted to make sure that it got called out

Get selected text from any application by means of another applicaiton

I'm working on a concept that works like copy & paste but uses my own algorithm instead of using the clipboard.
We have users that use many different programs that contain part numbers. This is how my concept would work.
User highlights part number from any application (word, excel, pdf, JDE, etc)
Either by hotkey or clicking on another application the user launches my routine.
My routine grabs that text from the original application and processes it accordingly.
I know how to use the clipboard to get text.
What I'm not sure of is how to get currently selected text from the application that was active prior to running my code? Do I need to force my user to copy to clipboard first and then run my app or can I create my own copy/paste type windows add-in?
Preferred VB for this but can also use C++ or C# if easier.
As to the question why, because we want to the action to be seamless to the user. There will be several behind the scenes actions that take place and then the user will be presented a browser with pertinent information related to that part number. Ultimately, I don't want an in-between screen to pop up, but rather completely hidden from the user. If I require them to copy and then run my routine then I'm adding in one extra step to the user path that I'm hoping to avoid.
I looked into right click menu context a bit but found that each program can have their own override. I wasn't able to locate a way to globally override all right click context menus to include a new action.
From this article:
var element = AutomationElement.FocusedElement;
if (element != null)
{
object pattern;
if (element.TryGetCurrentPattern(TextPattern.Pattern, out pattern))
{
var tp = (TextPattern) pattern;
var sb = new StringBuilder();
foreach (var r in tp.GetSelection())
{
sb.AppendLine(r.GetText(-1));
}
var selectedText = sb.ToString();
}
}
It's in C# but it should be pretty trivial to translate.

Firefox extension: How can I set the cursor position?

I have a page with possibly several content-editable iframes (editors).
Now I would like to use my custom Firefox extension to do the following:
Setting the cursor to the end (or last HTML element) of the editor the cursor actually is in.
I found many solutions to get the cursor's position, but I need one to set it.
Any suggestions?
XPCOM likely includes such functionality as part of the testing rig. Mochitest at least is capable of this (again, probably though XPCOM).
On the other hand, when a user is on the system this a generally a gross violation of user interaction practices. Be sure you have a good justification for doing it. It may seem convenient but what if they're doing something else whilst using your addon? I usually have various apps open at once, Fx extensions are only part of that. I don't want it taking control of my mouse, EVER.
Is there something wrong with setting the focus? At least that only forces the user's hand at a window level.
It also suspect it make it quite difficult to get past AMO review. You'd have to justify why it was necessary to invoke such low-level functionality. If you interact with a window, for example, the window might be able to affect the input of your functions which in turn control the mouse... and then a random web site has access to the user's window!
Found the solution to my problem myself. This code myself will set the Cursor position to the last Paragraph of my editor:
var frame = window.content.document.getElementsByTagName('iframe')[2];
var win = frame.contentWindow;
var editingSession = Components.classes["#mozilla.org/editor/editingsession;1"].createInstance(Components.interfaces.nsIEditingSession);
var editor = editingSession.getEditorForWindow(win);
selection = window.getSelection();
var body = frame.contentDocument.body;
text = frame.contentDocument.createTextNode(".");
body.lastChild.appendChild(text); // add textnode to be selected
var range = editor.document.createRange();
range.setStartBefore(text);
range.setEndAfter(text);
editor.selection.removeAllRanges();
editor.selection.addRange(range);
body.lastChild.removeChild(text); // remove Child

Resources