Change text only temporarily - c#

I want to change the text of a Powerpoint shape only during presentation (i.e. while the slide is shown), but not change the text permanently so that it modifies the PPT file.
Currenty I'm subscribing to the event
Application.SlideShowNextSlide += OnNextSlide;
and then I change the text on one specific shape like this:
shape.TextFrame.TextRange.Text = "Hello world";
However, when the presentation ends, that text is in the PPT file and Powerpoint asks me whether I want to save the changes.
I want to avoid that my Powerpoint Add-In makes changes to the file.

UPDATE
Based on Steve's answer and your feedback in the comments. So here is an idea for you:
Why don't you just do the code that we mentioned, add Steve's line (it's actually a good way to avoid save questions), and since you'd have restore the original value at the end then just save through programmatic function in C# no matter what. So that even if the user has done any changes you would have saved file...no questions asked ;)
step by step:
1) run like normally
2) add Steve's remark
3) do the trick with the variable change I mentioned bellow
4) do save no matter what at the end of the presentation so that any user changes are saved with the document
code snippet for saving are in this answer very well documented
Remark: Remaining issues with this logic is only when the user does intentional changes and at the end does not want to save the work but this is a case not foreseen above. All the other users will not have to suffer through the "Want to save?" question :)
try to save previous state first and then before moving away or closing re-assign that old value back to it ;)
1st do
String oldValue = shape.TextFrame.TextRange.Text;
if you need to store outside the frame, use IO to store on file temporary or pass the variable on an outside function/variable value. Then do your code
shape.TextFrame.TextRange.Text = "Hello world";
and after you finish just do again
shape.TextFrame.TextRange.Text = oldValue;
or read the value from where you left it :)
hope it helps

In addition to the suggestion #oetoni made, you'll want to set the presentation's .Saved state to True after making each change or before allowing the user to quit the show/presentation.
That way, PowerPoint won't think any changes have been made, so won't offer to save the presentation when the user quits.
ActivePresentation.Saved = True

Related

Programmatically Clicking on a Web Page's Button in Windows Forms Application

I am working on a project which is Analysis of Papers from Google Scholar. What I do is basically, parsing the HTML, storing related fields into database etc. However, I am stuck at a point, while I am taking the Titles of the publications, I realized, I am able to get first twenty elements. But, there are sixty papers in related account:
http://scholar.google.com/citations?user=B7vSqZsAAAAJ
So, I think as a solution, I need to click to the 'show more' button programmatically, so I can have all the Title's, Publication Venue etc.
What do you think? How can I perform that kind of action?
Edit: I checked the 'show more' button, while there is nothing to show as a next page, its html code still remains same. As a solution I can use loop for n times. However, I am looking for more robust solution.
Thank you for your time!
If it is clicking on a button within a WebBrowser control on a Windows Form Application, then 'Yes' you can do it.
There are ways of getting more control over identification by using XPath.
(You might need to use Javascript to use XPath for object interactions - since you haven't asked for that, I will assume you don't need it)
webBrowser.Navigate("http://www.google.com");
// Or
HtmlElement textElement = webBrowser.Document.All.GetElementsByName("q")[0];
textElement.SetAttribute("value", "your text to search");
HtmlElement btnElement = webBrowser.Document.All.GetElementsByName("btnG")[0];
btnElement.InvokeMember("click");
Or even typing into text boxes with
webBrowser1.Document.GetElementById("gs_tti0").InnerText = "hello world";
If its this website specifically, there is a simple workaround. Change the query string to what records you want.
http://scholar.google.com/citations?user=B7vSqZsAAAAJ&cstart=0&pagesize=2000

Setting text of controls on form dynamically

I have a WinForms app that I am currently implementing a translation engine in. What I have so far is a bunch of text documents that follow the syntax like:
messages.manualupdate="There is a manual update available for ProgName.\n\nDo you want to update to version {0}.{1}.{2}{3}?"
messages.errorcopy="Clicking OK will copy the error so you can paste it elsewhere!"
messages.error="Error"
messages.notsupported.title="Unsupported client"
messages.notsupported.message="This version is no long supported. Please wait for an update."
I have lots of these for different languages, for example:
messages.manualupdate="é disponibile un'aggiornamento manuale del programma ProgName.\n\nVuoi aggiornare alla versione {0}.{1}.{2}{3}?"
messages.errorcopy="Cliccando OK eseguirete una copia degli errori visualizzati"
messages.error="Error"
messages.notsupported.title="Client non supportato"
messages.notsupported.message="Questa versione non è utilizzabile al momento. attendi il prossimo aggiornamento!"
I then parse this into a DynamicObject which I can access like language.messages.notsupported.error. What I would like to know is if I can somehow link all the controls on the form to use variables from the dynamic object on creation. For instance I have a button on my form that I want to have the text "Error" in. Before the form shows, I set the language variable to the users chosen language, and then when the form shows it simply loads the text from language. Is there a way to do this in the designer rather than having to write a method that is called in the Forms constructor as it seems to me like a little bit of a waste to set all the button text to a value and then change them all when the form loads. I'm looking for a sort of binding, but to the controls Text parameter.
Anyone have any ideas?
MSDN has a walkthrough on string localization that might be of use to you link
Honestly, the approach you are trying to avoid looks best to me. I will suggest you to create a property for the control where you are trying to set the Text. In Set attribute, check for the language selected and get the appropriate text for you.
public string Error
{
set { _errorLabel.Text = value; }
}
private void SetText()
{
if(EnglishSelected)
Error = "English";
}
Regarding waste of time, well, I will just suggest not to set anything in designer and directly set the property in Load form. But I would like to add one more point here that any of the approach will not hit your application speed. First its about making your application expandable and maintainable and then about making it fast. Setting logical things in designer is always a bad practice. If your application is not tiny/small then I will suggest you to follow some design patterns like MVP and move all this logical things in Presenter. Not trying to preach but just suggesting.
And yes, in our company one of team is working in localization part of the application. Using resource may be a better way of doing this.
Hope it helps.

Holding on to data passed from page to page - WP7 and C#

I'm creating a WP7 application using C#, and I require to pass data from one page to the other.
I found solutions on SO, but I'm still running into problems.
On 'Page 1', I wish to display a list, that can be populated by the user, using input from 'Page 2'.
I used the following statement in 'Page 2' while navigating back to 'Page 1': NavigationService.Navigate(new Uri("/MainPage.xaml?text="+WhoBox.Text, UriKind.Relative));
WhoBox is a Text Box.
On 'Page 1', I have the following:
protected override void OnNavigateTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (NavigationContext.QueryString.ContainsKey("text"))
ListBlock.Text = ListBlock.Text + NavigationContext.QueryString["text"];
}
Now, this works, but in a limited fashion. If I try adding something from 'Page 2' for a second time, it replaces what is present in ListBlock (which is a Text Block) with the newly added text instead of appending it.
Shouldn't ListBlock.Text = ListBlock.Text + NavigationContext.QueryString["text"]; cause the new text to be appended, rather than to entirely replace the older text?
EDIT: I may have found the solution. For whatever reason, no changes in the XAML or .cs file are reflected when I run the program using F5. Am I doing something wrong? For example, even if I delete a button, it still appears when I Debug (F5) the program. Is there some setting I need to change? Or am I supposed to use some other command? I'm relatively new to Visual Studio, so please excuse me.
The problem is that the moment you again leave your page 1 it is basically disposed of. Meaning any text that was set in the Listbox is also removed. You will , in other words, need to save the state of that page before leaving it.
There several possibilites here:
Use AppSettings (see Windows phone 7 config / appSettings? )
Write the state to a local database
Do a quick'n dirty fix by saving the Text in the App.xaml.cs which all pages can work with: First you need to create the application-wide variable (and initialize if needed) inside the app.xaml.cs file. For example:
public partial class App : Application
{ public string myText;
From now on you can reach any App-variable through the Application.Current object. So if you need to access bigVar from some page in you application (e.g. MainPage) you simply type:
string Text = (Application.Current as App).myText;
Consider using sessions and datatable: Storing and retrieving datatable from session

Get highlighted text from active window

I would like to know how can I get highlighted text from any window for example: (excel, ie, firefox,…).
please note that the following message not work in the above application
WM_GETTEXT,WM_COPY,EM_GETSELTEXT.
I have also tried control C (copy) and get selected text from clipboard but it is not a good idea.
Language used: C#
I haven't tried it myself, but the Microsoft UI Automation API should have the functionality that you need.
The UI Automation API is what you would use if you were building a screen reader to assist blind people. So it should definitely be able to access the selected text in an arbitrary application.
A good place to start would be with the "Text Pattern Overview" at http://msdn.microsoft.com/en-us/library/ms745158.aspx
Also keep your eye on question 517694. I think you'll find that answers to that question will solve your problem.
No answers huh? Well, I know you can get it from Excel, Word etc using interop. Look into that. It might give you som ideas on how to proceed with ie and ff. But basically the recieving application must have some sort of fascility for letting you do this and I don't think there's any general way which works all the time.
There is no general purpose answer to this question. Each window class will have a different solution.
For instance, if the hilighted text is in an edit window, then you can use EM_GETSEL to get the range of the selection, then WM_GETTEXT to get the text (and then throw the unselected part a way) or EM_LINEFROMCHAR to turn that range into line indexes, and then EM_GETLINE to get the selected text one line at a time.
But this won't work for any other window class.
No need to write this in C# from scratch. What's wrong with using the clipboard? This script ensures that it restores what was on the clipboard when it has finished.
Autohotkey makes this much simpler.
; Hotkey: Ctrl Shift t
^!t::
; Remember what was in the clipboard
clipboardPrev = %clipboard%
; Clear the clipboard
clipboard:=
Sleep,200
; Send a Ctrl C to copy the current selection
SendInput, {Ctrl down}c{Ctrl up}
Sleep,200
; Get the current selection from the clipboard
selectedText=%Clipboard%
if SelectedText =
{
; If the first attempt didn't get any test, try again
Sleep,200
; Send a Ctrl C to copy the current selection
SendInput, {Ctrl down}c{Ctrl up}
; Get the current selection from the clipboard
selectedText=%Clipboard%
}
; Restore the clipboard
clipboard=%clipboardPrev%
MsgBox, %selectedText%
return

How to move caret position to end of current word?

I'm using a webbrowser control. How can I move the insert position for an execCommand to the end of the word, that is currently selected?
Example:
| <- current caret position
Som|eword -> move -> Someword| -> execCommand executes after current word
What I want to do is insert a line without braking the word. What happens now is:
Somew|ord -> line
Somew
ord
What should happen is:
Somew|ord -> line
Someword
This is so hacky that I'm almost embarrassed to post it, but ... you can accomplish "Inserting a line without breaking the word" "using a webbrowser control" by doing something like
webBrowser1.Url =
new Uri("javascript:" +
"var tr=document.selection.createRange();" +
"tr.expand('word');" +
"tr.collapse(false);" +
// "tr.select();" // Necessary to actually move the caret
"tr.pasteHTML('<hr>');");
After the webbrowser has loaded the document that you want to manipulate, and the user has selected the text that they'd like to insert a line after. If you really need the caret moved as well, you'd need a tr.select() after the tr.collapse().
It doesn't use the execCommand though, so it may not be suitable for your purposes. Maybe someone else can figure out a way to make this a little cleaner...

Categories