How to consistently search and replace RTF text - outlook

Thanks for looking.
Background
I am working on a MS Outlook plug in that requires certain text to be injected into the body of a new meeting request when a button click event fires.
The meeting request window only allows plain text or RTF (no HTML). The text that my application needs to enter should be able to be swapped out when the button is clicked again, but should not remove any text that the user may have added either above or below mine.
For now, I use a string of underscores with a leading and trailing set of hidden slashes like this:
\v//\v0__________________________________________________________________
{MY CUSTOM TEXT GOES IN BETWEEN}
__________________________________________________________________\v//\v0
Problem
With plain text, this is not a problem, but the problem arises when the user edits the body, and then clicks the update button again, it seems that the structure of the RTF encoding changes in a way that is not predictable and I therefore can not search for my text boundaries. For example, after the user adds their own text and clicks the "update button", my code now receives the following which I am unable to find using IndexOf():
//}{\\rtlch _______________________________________________________________
Question
Is their an easier, more consistent way to have essentially merge fields in RTF that the user may edit? I essentially just need to swap in or out a chunk of very simple text regardless of whether the user has written above or below it.
Thanks.

Actually HTML for appointments is supported by Outlook 2016. In any case however, Inspector.WordEditor returns an instance of the Word's Document object, so you can add a bookmark around your text using the Word Object Model rather then by injecting text visible to the end user.

Related

How to check textual user input in a PowerPoint presentation?

Is it possible to check textual user input in a PowerPoint presentation?
I would like to create some kind of password field that users need the fill in correctly, before they can move on to the next slide.
To be clear: This is while the presentation is running, not in the edit mode.
An ActiveX text box can receive user input while the presentation is in slideshow view and has a Password Character property which, if set, displays the chosen character instead of whatever the user is typing; keeps the password safe from prying eyes.

UIPath Robot won't type into a text box, clear selector. Clicking separately and sending hotkeys also does not work

I've tried nearly anything, The "Type Into" activity won't print plain text into the text box let alone a held variable. The textbox element in question is the update work items comment box in the acme-test website from the Level 3 RPA developer course. I am able to type into the box manually and the robot is able to find it (the cursor moves to the centre of the text box and the program continues). I've tried quite a lot, including using a click activity and then sending the string as hotkeys.
Most probably the issue is related to your selectors. Since you are on level 3 RPA developer course I assume you are using Reframework for the task and I believe because of comprehensive error handling capabilities of this template your application just continuous with the next item instead of crashing when it can't find the element.
To solve the selector issues I usually do the following:
Use partial selectors instead of full selectors
Use wildcards for dynamic parts of your selectors (* for replacing any number of characters, ? for replacing exactly 1 character)
You can also store the page you are working on in a Uipath.Core.Browser type variable to eliminate the need of reselecting browser.
Also keep in mind that if you have used basic recorder functionality of UI path it generates full selectors.

How to get text/range at a point in an Outlook Inspector?

I want to know the text at a point in for example an Outlook email.
In Excel and Word I am able to get the ActiveWindow. Both object models offer the RangeFromPoint method which I have working.
In Outlook the Applicaion object does have a ActiveWindow but it returns either an Explorer or Inspector object.
Further I tried the following code, however it seems the disabled Word Application object in Outlook does not offer the RangeFromPoint.
Dim ins As Outlook.Inspector = olMail.GetInspector
Dim wDoc As Word.Document = ins.WordEditor
Dim w As Word.Window = wDoc.ActiveWindow
Dim rng As Word.Range = w.RangeFromPoint(mousePosition.X, mousePosition.Y)
I am assuming that Outlook's object model will not help me.
Are there any other methods in the Word Document object model that helps me out?
If the Word Object model does not help must I rely on WinAPI?
If I must use the WinAPI what steps do I need to take?
For example;
Convert Screen point to a window point of the window holding the text (body of the email)
get the text at this point.
What is the best WinAPI to get the text at a point in a Window. Is it to SendMessage with EM_GETSEL?
I tried a few things here.
Why I want to know the text at a point.
I am building custom tooltips into office. When the mouse hovers over a point (through the use of the winapi function TrackMouseEvent) I receive from Windows the point where the mouse is. I then need to know in Outlook (Explorer / Inspector) what the mouse is over.
First Thought - Outlook and Word Object Model alone.
As you can see in the question my first thought was to use the same Window object you can use in Word and implement the RangeFromPoint method. But MS decided to not support this in Outlook. So this is a dead end.
The second option here was to use either or both of these
Selection.Information(Word.WdInformation.wdHorizontalPositionRelativeToPage)
Selection.Information(Word.WdInformation.wdVerticalPositionRelativeToPage)
and / or
Selection.Information(Word.WdInformation.wdHorizontalPositionRelativeToTextBoundary)
Selection.Information(Word.WdInformation.wdVerticalPositionRelativeToTextBoundary)
Vertical relative to page always returned -1 even when the text was clearly in view.
The Relative to Text Boundary returned numbers and they changed with positions but I did not work out where the Boundary was when in the Outlook Inspector. Margins did not help me. This could be a way to do this but i did not work it out.
IUIAutomation or Automation
I have no experience with these however my attempts to get the TextPattern failed on Outlook 2007 and Outlook 2010. I name these versions because I found questions here reporting that they were successful with 2013. I think MS at the time intentionally tried to hide the body of the email to stop ummm slow down email viruses.
WinApi
The text body of the email is in a window of Class _WwG and the contents of the window is not visible. You get "message" as the text. Seems here too MS did this intentionally. Thus trying to get the text at a position is not going to work.
Combination of WinApi and Word Object Model
The solution that I found which works with the Explorer reading panes and with all inspectors is to use a combination of the WinApi and Word.
Receive a mouse hover event with point in a window (_WwG Class for Outlook)
Use SendMessage and send a messsage to this window with the WM_LBUTTONDOWN flag.
Get the Word Document from the Inspector.WordEditor method.
The current Range selected will be where the mouse is located in the text.
Expand the range to the word or whatever you need and now you have what is under your mouse.
For read only windows in Outlook there is no caret visible to the user but it still exists and can be found and used.
I have not implemented this on Outlook items that are being drafted (Cursor is in use and visible), but I suppose I will have to move the selection to the mouse position and then move it back to be able to implement it. I could imagine this is not the best for some users.
Edit
There is one issue with this that I could not solve. By sending a click to the window, you click on what is at that point. If there is a hyperlink there, which is the case with email addresses in a mailItem then it follows the hyperlink. I could not work around this issue properly. The only thing I did find in the WinProc was that when the mouse is over a hyperlink then Outlook shows a tooltip and there is a WM_USER + 2 message. Listen for this message and do not click if this message is received.

How to blur the subject field in a compose mail inspector?

I have an Outlook VSTO 2010 add-in providing a button to insert text from a custom lookup, into the subject. The basics of this work just fine by grabbing the inspectors CurrentItem (MailItem) and appending to the Subject string.
Where it comes unstuck, is if the user is focused in the subject field, enters some text, then clicks the custom button to add some more text to the subject. The text that the user entered, isn't yet saved to the underlying MailItem, so manipulating MailItem.Subject ignores the users text.
I can work around this by saving the mail item before manipulating the subject, ensuring that the subject input field is saved to the object, but this is at odds with the standard Outlook behaviour, and could lead to a lot of un-sent drafts saved to the users mailbox. What alternatives are there? Anything that blurs the subject field would work (I can't find a way to even do that), but there might be a more elegant solution?

Any way to extend or modify drag-and-drop in Outlook with VSTO?

I have an add-in I'm working on in Outlook that relies on drag-and-drop to save an Outlook file to a file automagically. The problem is that the default behaviour is to use the email's subject line as the filename, and emails with extremely long subject lines send an error as there's not enough space in 250 characters to store all of it plus the rest of the path.
I'd like to change Outlook's drag and drop to Explorer so that the default filename is kept to the subject line cut to say 100 characters. Any pointers on where I'd go about doing this?
Ok I think you have a couple of ways to do this.
run you own pane in outlook and on the drop and look at the selection and do a saveAs on each item.
use some winapi to intercept the save ans change the name(i am not sure if this is possible)

Resources