I am trying to display a simple message, which I have done probably thousands of times in the past, and NOW... The full string of text is NOT being displayed in the MessageBox. I'm not doing anything differently, so I don't see the problem. Here's my code:
if (MessageBox.Show("The text in this file has changed. Do you want to save changes?",
"TextEditor - Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
{ //Do stuff
} else {
// Do stuff }
Now, when the messagebox is displayed, the only text that is visible is this:
The text in this file has changed.
NOTE: The Yes/No buttons are visible, and the messagebox looks normal, it doesn't look broken or anything, so I have no idea why I can't display a simple dam question in there anymore!?... Does anybody know about this? Have you experienced this before?
Thanks
OK, THIS IS WIERD... (EDITED)
I have just changed the text for the above messagebox text and now it displays the following:
The text in this file has changed. Do you wa
But the most important part of the question is still not being displayed...
Couple of things to try:
1) If running the debug version, try compiling and running the release version
2) Try creating a whole new project and copying the code to the new project and run it (could be a project setting was changed, then you could diff the files)
3) Try disabling any anti-virus software you have.
have you tried - just to be sure - to escape the whole string by prefixing it with a #-sign?
like so:
if (MessageBox.Show(#"The text in this file has changed. Do you want to save changes?",
#"TextEditor - Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
{ //Do stuff
} else {
// Do stuff }
Did you try to put your text in a variable juste to see if it work?
string message = #"The text in this file has changed. Do you want to save changes?";
string title = "TextEditor - Confirmation";
if (MessageBox.Show,(message, title, MessageBoxButtons.YesNo, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1) == DialogResult.Yes){ //Do stuff } else { // Do stuff }
Its something odd/stupid - its time to act back by being stupid
First question - are all of your message boxes affected? If not then this case has something wrong with it. If they are all affected then ... well I don't know what to suggest really. More coffee?
Best thing to do is to reduce the problem down to the smallest possible. Create a new message box and only enter your current text (copy and paste it). Dont set any of the other parameters and take it out of the if statement
If that works, then the problem is with the parameters
- slowly add the parameters until it breaks
If it doesnt then the problem is with the text
- delete the text and retype it - there may be a strange character there - e.g. has the text been near MS Word...
- if that works, then you are golden
- otherwise, delete word by word until it starts working
I reckon you'll find out it something really stupid
The space between "changed." and "Do" wouldn't be some weird character (say NULL), would it? Try to delete the whole text and then type it again by hand.
Hmm... just remembered some weird old bug with McAffee antivirus and .NET whereupon the whole contents of messageboxes would disappear. This was however more than 5 years ago...
Maybe try updating your PC? And - you wouldn't happen to be running McAffee, would you? :)
Idea No. 3: Send us your compiled .EXE and the source files?
Idea No. 4: Compile it, then rip it open with Reflector and check how it has been compiled. Compilers have bugs too...
I've tried it too and it seems to work fine.
Maybe check the regional/language settings on the machine your running it on?
There's no set size for message boxes in the form.Designer.cs is there?
Have you tried creating another solution with 1 form and the following code - btw works form me vs2008 winXP en-gb lang
using System;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
if (MessageBox.Show("The text in this file has changed. Do you want to save changes?", "TextEditor - Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Hand, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
{
MessageBox.Show("yes");
}
else
{
MessageBox.Show("no");
}
}
}
}
Could you possibly try a newline \n after "changed"?
I have just solved this problem. I am using Windows XP Home Edition and am also using Stardock's WindowBlinds to pretty-up the 500-year old WindowsXP interface. This has never caused any problems in the past, I have been using WindowBlinds for years, and also doing C# stuff for about a year and a half, and this is the first time that WindowBlinds has caused any problems what so ever.
The reason why only part of the text was showing in the MessageBox still ramins a mystery, BUT as soon as I decided to try and Close WindowBlinds and apply the standard XP theme again... All MessageBox's work properly in C#.
Thank you ALL for your good suggestions they are very much appreciated. :o)
Jason Pezzimenti
Related
I have the following code (simplified to show the problem):
var wdApp = new Application();
var wdDoc = wdApp.Documents.Open("C:\foo.docx");
wdApp.StatusBar = "Updating...";
var rng = wdDoc.Range(10, 10);
if ((bool)rng.Information(WdInformation.wdWithInTable))
{
}
//StatusBar value is gone...
What could be the reason?
How can I prevent it?
Do you know of other situations where this can happen?
Here screenshots of the problem
1 F10 (step over) later
Edit:
The provided code uses NetOffice and not the interop library from Microsoft directly, therefor the syntax is correct. You may notice in the provided screenshots that they are taken from a running application. Breakpoint, highlighting of current line of code executing, aswell as the actual result of the code in the word application on the right. Where at first there is the desired statusbar "Tabelle 8 von 17 wird neu erstellt." (Table 8 out of 17 is recreating) and at the next step my statusbar is gone and its the default stuff "165 von 8227 Wörtern" (165 out of 8227 words)
What could be the reason?
I believe this is to do with the library you are using. I tested your code but with the Word Interop library, and the only way I could get the status bar to reset was to manually click/type within the Word window.
How can I prevent it?
I would say take a look into the code base of library you are using. It is likely that it is doing something that is causing the behaviour. Unless there is a specific reason you are using NetOffice I would suggest switching to the either the standard Interop or VSTO.
Do you know of other situations where this can happen?
As above, I could only get the status bar to reset if I manually carried out some sort of input into the window.
I am using a WPF TextBoxes inside my WinForm application for spell checking. Each time I create one, I load the same file in as a CustomDictionary. All has been fine until recently. Now, they take a long time to load, up to a second. Some forms have 30 or more, meaning delays of nearly half a minute. This seems to be the case Windows 10 (not Windows 8 as I originally posted). The application is running under DotNet 4.0, I have tried 4.5 and 4.6 (not 4.61) and all versions are slow.
I have seen sfaust’s question Spell check textbox in Win10 - Slow and am7zd’s answer. Thanks to these, I looked at the GLOBAL registry key in HKEY_CURRENT_USER\Software\Microsoft\Spelling\Dictionaries. I have 580 entries (after pruning out entries without matching files) and still things are slow.
At present, every time I create a TextBox and add a custom dictionary to it, a new entry seems to be generated in _GLOBAL_
Is there a better way of doing things than loading the custom dictionary in from file every time?
Is there a way of re-using the same entry in _GLOBAL_ every time instead of creating a new one?
Is there a clean way of clearing previous entries in GLOBAL created by my application and their matching .dic files when closing the application (or on restarting it)?
I could clear _GLOBAL_ completely each time I start my application. This brings back the speed I want, but what is the downside?
Any advice gratefully received.
No answers from anyone else, so this is what I have done:
I made sure I use CustomDictionaries.Remove on all textboxes with custom dictionaries before closing the form they are on. This gets rid of new entries in _GLOBAL_ and the related files in AppData\Local\Temp.
But there will be times when things go wrong or the user just ends the task, leaving _GLOBAL_ entries and .dic files in place, so:
I decided to take things a stage further. When I start my application, I will not only clean entries in _GLOBAL_ that don't have matching files (as suggested in the previous post referenced above), but also to remove all entries referring to .dic files in AppData\Local\Temp. My theory being that anyone who has left entries there didn't mean to, otherwise they would probably have saved the .dic file in a different folder (as Microsoft Office does).
try
{
string[] allDictionaries = (string[])Registry.GetValue(#"HKEY_CURRENT_USER\Software\Microsoft\Spelling\Dictionaries", "_Global_", new string[0]);
if (allDictionaries.Count() > 0)
{
List<string> realDictionaries = new List<string>();
bool changedSomething = false;
foreach (string thisD in allDictionaries)
{
if (File.Exists(thisD))
{
if (thisD.Contains(#"\AppData\Local\Temp\"))
{
// Assuming that anyone who wants to keep a permanent .dic file will not store it in \AppData\Local\Temp
// So delete the file and don't copy the name of the dictionary into the list of good dictionaries.
File.Delete(thisD);
changedSomething = true;
}
else
{
realDictionaries.Add(thisD);
}
}
else
{
// File does not exist, so don't copy the name of the dictionary into the list of good dictionaries.
changedSomething = true;
}
}
if (changedSomething)
{
Registry.SetValue(#"HKEY_CURRENT_USER\Software\Microsoft\Spelling\Dictionaries", "_Global_", realDictionaries.ToArray());
}
}
}
catch (Exception ex)
{
MessageBox.Show(this, "Error clearing up old dictionary files.\n\nFull message:\n\n" + ex.Message, "Unable to delete file", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
I am still wondering if it is totally safe to clear entries in _GLOBAL_ that refer to files in AppData\Local\Temp. Surely people shouldn't be leaving important stuff in a temp folder... should they?
What would be really nice would be an overload to CustomDictionaries.Add that allows us to set the name and folder of the .dic file, allowing all the textboxes in the same application to share the same .dic file and making sure we don't leave a load of redundant entries and files with seemingly random names hanging around in the first place..... please Microsoft.
I'm trying to display a Loading Please Wait dialog form using devex controls and I can't seem to do it. (using winforms, c#)
I'm using an older version of devex - not the latest. I can't do
SplashScreenManager.ShowDefaultWaitForm()
I need to do this in code without the designer.
1.
I tried:
SplashScreenManager.ShowForm(typeof(WaitDialogForm));
It looks right when it loads, but then it throws an error:
Unable to cast object of type 'DevExpress.Utils.WaitDialogForm' to type 'DevExpress.XtraSplashForm.SplashFormBase'
I tried:
SplashScreenManager.ShowForm(typeof(WaitForm));
This shows an empty form thats too big with no image and no text
I tried:
WaitDialogForm mWaitDialog = new WaitDialogForm() {Visible = false};
mWaitDialog.Show();
The wait form doesn't look right. There are white spaces instead of the image.
I tried:
WaitDialogForm mWaitDialog = new WaitDialogForm() {Visible = false};
mWaitDialog.ShowDialog();
The code doesn't continue executing.
I saw examples of
SplashScreenManager.ShowForm(typeof(WaitForm1));
I don't know how to do this without designer.
Can somebody please assist? I thought I'm doing something simple, but I can't seem to figure it out!
Probably this help u ;)
using (new DevExpress.Utils.WaitDialogForm("Please wait"))
{
//Do your stuff here
}
I don't know if this is in your 13.2 version but from looking at documentation you should be using ShowWaitForm instead of just ShowForm.
SplashScreenManager ssm = new SplashScreenManager();
ssm.ActiveSplashFormTypeInfo = typeof(WaitForm1);
ssm.ShowWaitForm();
If that does not work then i would just try preparing a working solution in the designer and then extracting the code from the designer.cs file.
Found a specific documentation example here
I am working from the sample project here: http://www.codeproject.com/Articles/8086/Extending-the-save-file-dialog-class-in-NET
I have hidden the address/location bar at the top and made other modifications but I can't for the life of me manage to disable the button that lets you go up to the parent folder. Ist is in the ToolbarWindow32 class which is the problem. This is what I have at the moment but it is not working:
int parentFolderWindow = GetDlgItem(parent, 0x440);
//Doesn't work
//ShowWindow((IntPtr)parentFolderWindow, SW_HIDE);
//40961 gathered from Spy++ watching messages when clicking on the control
// doesn't work
//SendMessage(parentFolderWindow, TB_ENABLEBUTTON, 40961, 0);
// doesn't work
//SendMessage(parentFolderWindow, TB_SETSTATE, 40961, 0);
//Comes back as '{static}', am I working with the wrong control maybe?
GetClassName((IntPtr)parentFolderWindow, lpClassName, (int)nLength);
Alternatively, if they do use the parent folder button and go where I don't want them to, I'm able to look at the new directory they land in, is there a way I can force the navigation to go back?
Edit: Added screenshot
//Comes back as '{static}', am I working with the wrong control maybe?
You know you are using the wrong control, you expected to see "ToolbarWindow32" back. A very significant problem, a common one for Codeproject.com code, is that this code cannot work anymore as posted. Windows has changed too much since 2004. Vista was the first version since then that added a completely new set of shell dialogs, they are based on IFileDialog. Much improved over its predecessor, in particular customizing the dialog is a lot cleaner through the IFileDialogCustomize interface. Not actually what you want to do, and customizations do not include tinkering with the navigation bar.
The IFileDialogEvents interface delivers events, the one you are looking for is the OnFolderChanging event. Designed to stop the user from navigating away from the current folder, the thing you really want to do.
While this looks good on paper, I should caution you about actually trying to use these interfaces. A common problem with anything related to the Windows shell is that they only made it easy to use from C++. The COM interfaces are the "unfriendly" kind, interfaces based on IUnknown without a type library you can use the easily add a reference to your C# or VB.NET project. Microsoft published the "Vista bridge" to make these interfaces usable from C# as well, it looks like this. Yes, yuck. Double yuck when you discover you have to do this twice, this only works on later Windows versions and there's a strong hint that you are trying to do this on XP (judging from the control ID you found).
This is simply not something you want to have to support. Since the alternative is so simple, use the supported .NET FileOk event instead. A Winforms example:
private void SaveButton_Click(object sender, EventArgs e) {
string requiredDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
using (var dlg = new SaveFileDialog()) {
dlg.InitialDirectory = requiredDir;
dlg.FileOk += (s, cea) => {
string selectedDir = System.IO.Path.GetDirectoryName(dlg.FileName);
if (string.Compare(requiredDir, selectedDir, StringComparison.OrdinalIgnoreCase) != 0) {
string msg = string.Format("Sorry, you cannot save to this directory.\r\nPlease select '{0}' instead", requiredDir);
MessageBox.Show(msg, "Invalid folder selection");
cea.Cancel = true;
}
};
if (dlg.ShowDialog() == DialogResult.OK) {
// etc...
}
}
}
I don't this is going to work. Even if you disable the button they can type ..\ and click save and it will take them up one level. You can't exactly disable the file name text box and maintain the functionality of the dialog.
You'd be better off either using the FolderBrowserDialog and setting it's RootFolder property and asking the user to type the filename in or auto generating it.
If the folder you are wanting to restrict the users to isn't an Environment.SpecialFolder Then you'll need to do some work to make the call to SHBrowseForFolder Manually using ILCreateFromPath to get a PIDLIST_ABSOLUTE for your path to pass to the BROWSEINFO.pidlRoot
You can reflect FolderBrowserDialog.RunDialog to see how to make that call.
Since you want such custom behaviors instead of developing low level code (that is likely yo break in the next versions of windows) you can try to develop your file picker form.
Basically it is a simple treeview + list view. Microsoft has a walk-through .
It will take you half a day but once you have your custom form you can define all behaviors you need without tricks and limits.
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.