I am creating an app with two forms.
On my main form1 I have a scanner that gets connected through a button.
I have a text box on my form2 and in this text box is where I want the information that gets scanned to go here.
there is no textbox on my form1.
I cant seem to figure out how to do this I was wondering if any one had any tips.
Thank you
This is the code in form 1 that allows me to set up the scanner
/// Event Handler for Scanner Setup Button
/// <param name="sender"></param>
/// <param name="e"></param>
private void scannerFormBTN_Click(object sender, EventArgs e)
{
try
{
//If the Button is yellow , disconnect the hand scanner
if (scannerBTN.BackColor == Color.LightGreen)
{
scanner.ReadStringArrived -= new ReadStringArrivedHandler(OnReadStringArrived);
scanner.Disconnect();
scanner = null;
scannerFormBTN.BackColor = Color.IndianRed;
this.scannerFormBTN.Text = "Setup Hand Scanner";
MessageBox.Show("Hand Scanner Disconnected.", "Alert");
}
//If scanner is not connected
else
{
Setupscanner scannerForm = new Setupscanner(); //Instantiate the Scanner Form
//Show the form. DialogResult = yes if Scanner is connected successfully.
DialogResult connection_successfull = scannerForm.ShowDialog();
if (connection_successfull == DialogResult.Yes)
{
this.scanner = scannerForm.sys; //Set the Local Hand Scanner variable to the successfully connected scanner
if (scanner.IsConnected)
{
scanner.ReadStringArrived += new ReadStringArrivedHandler(OnReadStringArrived); //Register Read String event.
scannerFormBTN.Text = "Hand Scanner Connected. Click to Disconnect";
scannerBTN.BackColor = Color.LightGreen; //Change the color of the Hand Scanner Button
}
}
}
}
catch (Exception ex) { MessageBox.Show("There was an error. Exception reads : \n\n " + ex.Message, "Error"); }
}
/// <summary>
/// Event that gets fired when string arrives from a connected hand scanner
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void OnReadStringArrived(Object sender, ReadStringArrivedEventArgs args)
{
SetSerNumber(args.ReadString);
}
/// <summary>
/// Used to set the Serial Number to the incoming Scanner String
/// </summary>
/// <param name="msg"></param>
private void SetSerNumber(string msg)
{
//If the event is fired on a different thread than the control was created
if (Part_Code_Text_Box.InvokeRequired)
{
SetSerialNumber S = new SetSerialNumber(SetSerNumber);
this.Invoke(S, new object[] { msg }); //Invoke the delegate S on the current thread
}
else
{
Part_Code_Text_Box.Text = msg.Trim();
}
}
Create a Property Or Field in Form 2 ..let's Call It StringFromScanner For Now .
When You Want To Show another From u will most likely Create an Object From it ...Set This Object's StringFromScanner To The String You Have ..and When You Open The Second Form Will Have The value of the string in this property and u can assign it to any control
In Form 1
Form2 objectfromform2 = new Form2();
objectfromform2.StringFromScanner = MyString;
objectfromform2.Show();
in Form 2
MytextBox.Text = StringFromScanner
You Can Also Forget About The Property and Use The Constructor To Achive The Same Result
Related
I have a Winforms application where I am trying to print a pdf document which has multiple layers on it.
But the problem is, This all operation are running on UI thread and it is hanging the UI(not responding) for long time.
I know, this is happening because of UI thread is blocked so, I have tried to make this operation asynchronous by the help of powerful async/await keyword but still my long running method is not being asynchronous. It is not coming forward from the await tasks and still opearation is taking the same time as like synchronous operation.
What I tried:
Please see below:
/// <summary>
/// Show Print Dialog
/// </summary>
private void ShowPrintDialog()
{
// Initialize print dialog
System.Windows.Controls.PrintDialog prtDialog = new System.Windows.Controls.PrintDialog();
prtDialog.PageRangeSelection = PageRangeSelection.AllPages;
prtDialog.UserPageRangeEnabled = false;
_printOptions.PrintQueue = null;
_printOptions.PrintTicket = null;
Enabled = false;
// if there is a default printer then set it
string defaulPrinter = prtDialog.PrintQueue == null ? string.Empty : prtDialog.PrintQueue.FullName;
// Display the dialog. This returns true if the user selects the Print button.
if (prtDialog.ShowDialog() == true)
{
_printOptions.PrintQueue = prtDialog.PrintQueue;
_printOptions.PrintTicket = prtDialog.PrintTicket;
_printOptions.UseDefaultPrinter = (defaulPrinter == prtDialog.PrintQueue.FullName);
}
// Re-enable the form
Enabled = true;
}
/// <summary>
/// Event raised when user clicks Print
/// </summary>
/// <param name="sender">Source of the event</param>
/// <param name="e">Event specific arguments</param>
private void cmdOk_Click(object sender, EventArgs e)
{
ShowPrintDialog();
if (_printOptions.PrintTicket != null)
{
//Set search Options
_print.ExportDataItem = true;
_print.FileName = SearchTemplateName;
//shows progress bar form.
using (frmPrintSearchResultsProgress frmProgress =
new frmPrintSearchResultsProgress(_print, this, _printOptions))
{
frmProgress.ShowDialog(this);
}
if (_print.ExportDataItem && !_print.DataItemExported && !_print.CancelExport)
{
MessageBox.Show("No Document printed.");
}
}
//Store selected options for current user
SaveOptions();
if (!SkipExport)
Close();
}
/// <summary>
/// Event raised when progress form is shown.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private async void frmExportSearchResultsProgress_Shown(object sender, EventArgs e)
{
try
{
Application.DoEvents();
dispatcher = Dispatcher.CurrentDispatcher;
// record export/print job start time
_startedUtc = DateTime.UtcNow;
_print.WritingToPdfIndicator = lblWritingPdfFile;
lblProgress.Text = Properties.Resources.PrintSearchResults;
await dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(DoDataItemPrint));
}
}
/// <summary>
/// Prints the selected data items.
/// </summary>
private void DoDataItemPrint()
{
// LONG RUNNING OPERATIONS..
// THIS OPERATION IS BLOCKING THE UI.
}
So, as per mentioned in above code when I opened the PringDialogForm then it is opening a Progress Bar form to see the progress of printing the document and from here frmExportSearchResultsProgress_Shown() event is fired and inside it, I am calling the DoDataItemPrint() method which is time consuming.
So, I tried to make frmExportSearchResultsProgress_Shown event as async/await but still operation is taking the same time as previous.
Can anyone please suggest me where I am doing wrong?
your frmExportSearchResultsProgress_Shown method starts on the UI thread
it then dispatches DoDataItemPrint to the ... same UI thread
it schedules a continuation (via await) so that when that incomplete thing happens, we get back into frmExportSearchResultsProgress_Shown, and since there's probably a sync-context in play here, the sync-context capture (implicit in await) would push us to ... the UI thread
As you can see: everything is happening on the UI thread.
If you want to not block the UI, you need to get off the UI thread. That could be as simple as using Task.Run to invoke DoDataItemPrint, but without knowing what that code contains, it is impossible to know whether you're using thread-bound controls to do the printing. If you are... it will be hard to get away from that.
I'm developing a VSTO add-in for Microsoft Word and I'm having difficulty with handling the BeforeSave event. I wish to edit the document each time the user saves but the BeforeSave event appears to be triggering in a certain scenarios when the user is not saving the document.
Assuming a user opens a blank Word document, enters some text and then tries to close the document. The dialog
displays. If the user clicks "Don't Save", the BeforeSave event still triggers (the event only triggers after the Save Changes dialog closes). Is there anyway to detect the difference between the use clicking Don't Save and clicking save or else to prevent the Before Save event from triggering in this scenario?
The event handler is being assigned using Word.ApplicationEvents4_DocumentBeforeSaveEventHandler
and the event handler signature is
Application_DocumentBeforeSave(Word.Document doc, ref bool saveAsUI, ref bool cancel)
Any help would be great thanks
The Word object model doesn't provide any event property for that. The best what you can do in that case are listed below:
If the document has never been saved before, you may check out the Document.Saved property.
Cancel the default action in the Application.DocumentBeforeSave event handler by setting the Cancel parameter to true. So, you can show your own dialog which mimics the default built-in one where you may handle every action made by the user.
The solution that worked for me in the end is based on the article at https://theofficecontext.com/2013/04/26/updated-word-after-save-event/
For reference, I'm working with Office 2019 and below is the code that worked for me - a slightly simplified version to filter out the user clicking Don't Save and trigger a Post Save event.
using System.Threading;
using Word = Microsoft.Office.Interop.Word;
/// <summary>
/// The word save handler.
/// </summary>
public class WordSaveHandler
{
public delegate void AfterSaveDelegate(Word.Document doc, bool isClosed);
// public events
public event AfterSaveDelegate AfterSaveEvent;
// module level
private bool preserveBackgroundSave;
private Word.Application oWord;
private string closedFilename = string.Empty;
/// <summary>
/// Initializes a new instance of the <see cref="WordSaveHandler"/> class.
/// CONSTRUCTOR takes the Word application object to link to.
/// </summary>
/// <param name="oApp">Word Application.</param>
public WordSaveHandler(Word.Application oApp)
{
this.oWord = oApp;
// hook to before save
this.oWord.DocumentBeforeSave += this.OWord_DocumentBeforeSave;
this.oWord.WindowDeactivate += this.OWord_WindowDeactivate;
}
/// <summary>
/// Gets public property to get the name of the file
/// that was closed and saved.
/// </summary>
public string ClosedFilename
{
get
{
return this.closedFilename;
}
}
/// <summary>
/// WORD EVENT fires before a save event.
/// </summary>
/// <param name="doc"></param>
/// <param name="saveAsUI"></param>
/// <param name="cancel"></param>
private void OWord_DocumentBeforeSave(Word.Document doc, ref bool saveAsUI, ref bool cancel)
{
// This could mean one of four things:
// 1) we have the user clicking the save button
// 2) Another add-in or process firing a resular Document.Save()
// 3) A Save As from the user so the dialog came up
// 4) Or an Auto-Save event
// so, we will start off by first:
// 1) Grabbing the current background save flag. We want to force
// the save into the background so that Word will behave
// asyncronously. Typically, this feature is on by default,
// but we do not want to make any assumptions or this code
// will fail.
// 2) Next, we fire off a thread that will keep checking the
// BackgroundSaveStatus of Word. And when that flag is OFF
// no know we are AFTER the save event
this.preserveBackgroundSave = this.oWord.Options.BackgroundSave;
this.oWord.Options.BackgroundSave = true;
// kick off a thread and pass in the document object
bool uiSave = saveAsUI; // have to do this because the bool from Word is passed to us as ByRef
new Thread(() =>
{
this.Handle_WaitForAfterSave(doc, uiSave);
}).Start();
}
/// <summary>
/// This method is the thread call that waits for the same to compelte.
/// The way we detect the After Save event is to essentially enter into
/// a loop where we keep checking the background save status. If the
/// status changes we know the save is complete and we finish up by
/// determineing which type of save it was:
/// 1) UI
/// 2) Regular
/// 3) AutoSave.
/// </summary>
/// <param name="doc">Document being saved.</param>
/// <param name="uiSave">Whether a SaveAs UI is displayed.</param>
private void Handle_WaitForAfterSave(Word.Document doc, bool uiSave)
{
bool docSaved = false;
try
{
// we have a UI save, so we need to get stuck
// here until the user gets rid of the SaveAs dialog
if (uiSave)
{
while (this.IsBusy())
{
Thread.Sleep(1);
}
}
docSaved = doc.Saved;
// check to see if still saving in the background
// we will hang here until this changes.
while (this.oWord.BackgroundSavingStatus > 0)
{
Thread.Sleep(1);
}
}
catch (ThreadAbortException)
{
// we will get a thread abort exception when Word
// is in the process of closing, so we will
// check to see if we were in a UI situation
// or not
if (uiSave)
{
this.AfterSaveEvent(null, true);
return;
}
else
{
// new, close, don't save - docSaved = FALSE
// open close don't save - docSaved = FALSE
// open close save - docSaved = TRUE
if (docSaved)
{
this.AfterSaveEvent(null, true);
}
return;
}
}
catch
{
this.oWord.Options.BackgroundSave = this.preserveBackgroundSave;
return; // swallow the exception
}
try
{
// if it is a UI save, the Save As dialog was shown
// so we fire the after ui save event
if (uiSave)
{
// we need to check to see if the document is
// saved, because of the user clicked cancel
// we do not want to fire this event
try
{
if (doc.Saved == true)
{
this.AfterSaveEvent(doc, false);
// new, save
// new, save as
// open save as
// open, turn on autosave
// new, turn on autosave
}
}
catch
{
// DOC is null or invalid. This occurs because the doc
// was closed. So we return doc closed and null as the
// document
this.AfterSaveEvent(null, true);
// -- new, close, save
}
}
else
{
// if the document is still dirty
// then we know an AutoSave happened
try
{
this.AfterSaveEvent(doc, false); // fire regular save event
// open, save
// open, autosave
}
catch
{
// DOC is closed
this.AfterSaveEvent(null, true);
}
}
}
catch { }
finally
{
// reset and exit thread
this.oWord.Options.BackgroundSave = this.preserveBackgroundSave;
}
}
/// <summary>
/// WORD EVENT – Window Deactivate
/// Fires just before we close the document and it
/// is the last moment to get the filename.
/// </summary>
/// <param name="doc"></param>
/// <param name="wn"></param>
private void OWord_WindowDeactivate(Word.Document doc, Word.Window wn)
{
this.closedFilename = doc.FullName;
}
/// <summary>
/// Determines if Word is busy essentially that the File Save
/// dialog is currently open
/// </summary>
/// <param name="oApp"></param>
/// <returns></returns>
private bool IsBusy()
{
try
{
// if we try to access the application property while
// Word has a dialog open, we will fail
object o = this.oWord.ActiveDocument.Application;
return false; // not busy
}
catch
{
// so, Word is busy and we return true
return true;
}
}
}
I want to show YesNoCancel button in the message box, but at the same time, I wanted to disable YesNo button and enable only Cancel button.
The reason I wanted to do like this is I am doing a demo application where I want to show users that particular feature is available but at the same time I don't want to give them save access.
Following is my code, now to how to Disable YesNo button.
DialogResult result = MessageBox.Show("Save changes to " + this.Text.Substring(0, this.Text.Length - 1) + "?",
"Save confirmation", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
Actually I want to show YesNo buttons but I wanted to disable click acess for it. I wanted to show users 3 buttons YES , No and Cancel but click acess should be given only to cancel button. Is that possible?
edit:
Thanks all for the answers.
I have found soultion for my question
My code for custom message box, I hope this might help someone
customMsgBox.cs
enter code here { public partial class CustomMsgBox : Form
{
static CustomMsgBox MsgBox;
static string Button_id;
public CustomMsgBox()
{
InitializeComponent();
}
internal static string ShowBox(string txtMessage, enumMessageIcon messageIcon)
{
MsgBox = new CustomMsgBox();
MsgBox.labelCustomMsg.Text = txtMessage;
MsgBox.addIconImage(messageIcon);
MsgBox.ShowDialog();
return Button_id;
}
/// <summary>
/// We can use this method to add image on message box.
/// I had taken all images in ImageList control so that
/// I can easily add images. Image is displayed in
/// PictureBox control.
/// </summary>
/// <param name="MessageIcon">Type of image to be displayed.</param>
private void addIconImage(enumMessageIcon MessageIcon)
{
switch (MessageIcon)
{
case enumMessageIcon.Error:
pictureBox1.Image = imageList1.Images["Error"]; //Error is key
//name in imagelist control which uniquely identified images
//in ImageList control.
break;
case enumMessageIcon.Information:
pictureBox1.Image = imageList1.Images["Information"];
break;
case enumMessageIcon.Question:
pictureBox1.Image = imageList1.Images["Question"];
break;
case enumMessageIcon.Warning:
pictureBox1.Image = imageList1.Images["Warning"];
break;
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
Button_id = "Cancel";
MsgBox.Dispose();
}
private void btnNo_Click(object sender, EventArgs e)
{
Button_id = "No";
MsgBox.Dispose();
}
private void btnYes_Click(object sender, EventArgs e)
{
Button_id = "Yes";
MsgBox.Dispose();
}
}
#region constant defiend in form of enumration which is used in showMessage class.
internal enum enumMessageIcon
{
Error,
Warning,
Information,
Question,
}
internal enum enumMessageButton
{
OK,
YesNo,
YesNoCancel,
OKCancel
}
#endregion
}
main.cs
String customResult = CustomMsgBox.ShowBox("Save changes to " + this.Text.Substring(0, this.Text.Length - 1) + "?", enumMessageIcon.Question);
The MessageBoxButtons Enumerations does not have such options, It contains the following members
So the better option for you is a custom message box, for this you can try this, this or this, Or simply follow the recipe,
Create a Form(let it be frmMessage) with a constructor accepts a string value that is the message that you wanted to display,
Give an appropriate title Text, let it be Save confirmation,
Place a Label to display the message in the label from the constructor.
Place Three buttons, Give name and Text for them,
Disable the Two(Yes/No), Your message box is ready
Usage Example:
Now you need to create an object of this message box and call them like the following:
frmMessage frmMessageInstance = new frmMessage("Save changes to " + this.Text.Substring(0, this.Text.Length - 1) + "?");
frmMessageInstance.ShowDialog();
As explained by Un-lucky, the only way you can do that is by creating your own custom messageBox. I would do something like this
/// <summary>
/// The form internally used by <see cref="CustomMessageBox"/> class.
/// </summary>
internal partial class CustomMessageForm : Form
{
/// <summary>
/// This constructor is required for designer support.
/// </summary>
public CustomMessageForm ()
{
InitializeComponent();
}
public CustomMessageForm (string title, string description)
{
InitializeComponent();
this.titleLabel.Text = title;
this.descriptionLabel.Text = description;
}
}
/// <summary>
/// Your custom message box helper.
/// </summary>
public static class CustomMessageBox
{
public static void Show (string title, string description)
{
// using construct ensures the resources are freed when form is closed
using (var form = new CustomMessageForm (title, description)) {
form.ShowDialog ();
}
}
}
Graciously copied from an answer by Dan Abramov for question How to create a custom MessageBox?
I am developing UWP and want to use SpeechRecognizer. When I run the application, the first try is right but next tries will throw a System.InvalidOperationException at
SpeechRecognitionResult speechRecognitionResult = await speechRecognizer.RecognizeAsync();.
The error message is
"Operation is not valid due to the current state of the object."
And another situation is that when I click the button to speak, the function RecognizeAsync() seems not to be called and I immediately get the MessageDialog with blank content and the return value of the program is 1(0x1). I don't get exception in this way but if I click the button quickly, it will throw the exception above.
I have searched a lot of pages online but none of them could figure out
this problem. Any help will be greatly appreciated. Thanks.
Here is my full code
public sealed partial class VoiceMainPage : Page
{
public VoiceMainPage()
{
InitializeComponent();
}
private async void OnListenAsync(object sender, RoutedEventArgs e)
{
// Create an instance of SpeechRecognizer.
var speechRecognizer = new SpeechRecognizer();
// Compile the dictation grammar by default.
await speechRecognizer.CompileConstraintsAsync();
// Start recognition.
SpeechRecognitionResult speechRecognitionResult = await speechRecognizer.RecognizeAsync();
var messageDialog = new MessageDialog(speechRecognitionResult.Text, "Text spoken");
await messageDialog.ShowAsync();
}
}
Check this official sample code. Here is an adaptation of your code reusing part of the github sample :
public class VoiceMainPage
{
private SpeechRecognizer speechRecognizer;
private CoreDispatcher dispatcher;
private IAsyncOperation<SpeechRecognitionResult> recognitionOperation;
public VoiceMainPage()
{
InitializeComponent();
}
/// <summary>
/// When activating the scenario, ensure we have permission from the user to access their microphone, and
/// provide an appropriate path for the user to enable access to the microphone if they haven't
/// given explicit permission for it.
/// </summary>
/// <param name="e">The navigation event details</param>
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
// Save the UI thread dispatcher to allow speech status messages to be shown on the UI.
dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
bool permissionGained = await AudioCapturePermissions.RequestMicrophonePermission();
if (permissionGained)
{
// Enable the recognition buttons.
await InitializeRecognizer(SpeechRecognizer.SystemSpeechLanguage);
buttonOnListen.IsEnabled = true;
}
else
{
// Permission to access capture resources was not given by the user; please set the application setting in Settings->Privacy->Microphone.
buttonOnListen.IsEnabled = false;
}
}
private async void OnListenAsync(object sender, RoutedEventArgs e)
{
buttonOnListen.IsEnabled = false;
// Start recognition.
try
{
recognitionOperation = speechRecognizer.RecognizeAsync();
SpeechRecognitionResult speechRecognitionResult = await recognitionOperation;
// If successful, display the recognition result.
if (speechRecognitionResult.Status == SpeechRecognitionResultStatus.Success)
{
// Access to the recognized text through speechRecognitionResult.Text;
}
else
{
// Handle speech recognition failure
}
}
catch (TaskCanceledException exception)
{
// TaskCanceledException will be thrown if you exit the scenario while the recognizer is actively
// processing speech. Since this happens here when we navigate out of the scenario, don't try to
// show a message dialog for this exception.
System.Diagnostics.Debug.WriteLine("TaskCanceledException caught while recognition in progress (can be ignored):");
System.Diagnostics.Debug.WriteLine(exception.ToString());
}
catch (Exception exception)
{
var messageDialog = new Windows.UI.Popups.MessageDialog(exception.Message, "Exception");
await messageDialog.ShowAsync();
}
buttonOnListen.IsEnabled = true;
}
/// <summary>
/// Ensure that we clean up any state tracking event handlers created in OnNavigatedTo to prevent leaks.
/// </summary>
/// <param name="e">Details about the navigation event</param>
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
if (speechRecognizer != null)
{
if (speechRecognizer.State != SpeechRecognizerState.Idle)
{
if (recognitionOperation != null)
{
recognitionOperation.Cancel();
recognitionOperation = null;
}
}
speechRecognizer.StateChanged -= SpeechRecognizer_StateChanged;
this.speechRecognizer.Dispose();
this.speechRecognizer = null;
}
}
/// <summary>
/// Initialize Speech Recognizer and compile constraints.
/// </summary>
/// <param name="recognizerLanguage">Language to use for the speech recognizer</param>
/// <returns>Awaitable task.</returns>
private async Task InitializeRecognizer(Language recognizerLanguage)
{
if (speechRecognizer != null)
{
// cleanup prior to re-initializing this scenario.
speechRecognizer.StateChanged -= SpeechRecognizer_StateChanged;
this.speechRecognizer.Dispose();
this.speechRecognizer = null;
}
// Create an instance of SpeechRecognizer.
speechRecognizer = new SpeechRecognizer(recognizerLanguage);
// Provide feedback to the user about the state of the recognizer.
speechRecognizer.StateChanged += SpeechRecognizer_StateChanged;
// Add a web search topic constraint to the recognizer.
var webSearchGrammar = new SpeechRecognitionTopicConstraint(SpeechRecognitionScenario.WebSearch, "webSearch");
speechRecognizer.Constraints.Add(webSearchGrammar);
// Compile the constraint.
SpeechRecognitionCompilationResult compilationResult = await speechRecognizer.CompileConstraintsAsync();
if (compilationResult.Status != SpeechRecognitionResultStatus.Success)
{
buttonOnListen.IsEnabled = false;
}
/// <summary>
/// Handle SpeechRecognizer state changed events by updating a UI component.
/// </summary>
/// <param name="sender">Speech recognizer that generated this status event</param>
/// <param name="args">The recognizer's status</param>
private async void SpeechRecognizer_StateChanged(SpeechRecognizer sender, SpeechRecognizerStateChangedEventArgs args)
{
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
MainPage.Current.NotifyUser("Speech recognizer state: " + args.State.ToString(), NotifyType.StatusMessage);
});
}
}
The button buttonOnListen shall have its enable state set to false during the speech recognition procedure to prevent click handler reentrance. In addition it is preferrable to have the SpeechRecognizer object initialized once during page navigation landing (OnNavigatedTo) and dispose it while leaving the page (OnNavigatedFrom)
With this code:
using (pbDialog = new pbDialogs())
{
ProgressBar = new frmProgress(this, false);
ProgressBar.SetProgressLabelText("Inventory Data");
MessageBox.Show("Set progress label text to Inventory data");
typeProgress = (int) ProgressStates.ProgressQRY;
ProgressBar.label1.Text += " (Receiving)";
if (pbDialog != null)
{
MessageBox.Show("pbDialog is not null");
//pbDialog.ShowDialog(ProgressBar, this);
}
else
{
MessageBox.Show("pbDialog IS null");
ProgressBar.ShowDialog();
}
ProgressBar = null;
MessageBox.Show("Made it to compressDB()");
compressDB();
. . .
}
I see "Set progress label text to Inventory data"
then "pbDialog is not null"
then "Made it to compressDB()"
Nothing too odd there; but if I uncomment the line that is commented above, I see only "pbDialog is not null"
It is hanging for some reason as a result to the call to ShowDialog(); what is really strange, though, is that this prevents "Set progress label text to Inventory data" from displaying. Why would that be the case?
Note: I think the "pb" in the code stands for "peanut brittle" or some such; I'm pretty sure about the "brittle" part, anyway.
UPDATE
Yeah, the use of ShowDialog() with pbDialog is one of scads of examples that the original coder was practicing job security by obscurity - but then he [un]fortunately skedaddled, leaving in his wake a cesspool of spaghetti/eggshell code with no comments, misleading names and every sort of bizarre and convoluted, counterintuitive practice imaginable in the witches brew he purportedly considered a masterpiece of elegant design and clever-clever tricks.
pbDialog is an instance of a class (pbDialogs). Just to give you a taste of how macabre and convoluted and tangled it all is, here is that class:
public class pbDialogs : IDisposable
{
private static Form m_top;
public pbDialogs()
{
} // pbDialogs Constructor
public static void Activate( Form form )
{
form.Capture = true;
IntPtr hwnd = OpenNETCF.Win32.Win32Window.GetCapture();
form.Capture = false;
OpenNETCF.Win32.Win32Window.SetForegroundWindow( hwnd );
} // Activate
/// <summary>
/// This method makes ShowDialog work the way I want, I think.
/// </summary>
/// <remarks>
/// Here is what it does:
/// 1. Sets the caption of the new window to the same as the caller's.
/// 2. Clears the caption of the parent so it won't show up in the task list.
/// 3. When the ShowDialog call returns, brings the previous window
/// back to the foreground.
/// </remarks>
/// <param name="dialog"></param>
/// <param name="parent"></param>
public void ShowDialog( Form dialog, Control parent )
{
Control top = parent.TopLevelControl;
string caption = top.Text;
dialog.Text = caption;
top.Text = "--pending--"; // Don't show parent in task list
dialog.Activated += new EventHandler( form_Activated );
dialog.Closed += new EventHandler( form_Closed );
m_top = dialog; // New top-most form
dialog.ShowDialog();
m_top = (Form)top; // The top dialog just changed
dialog.Activated -= new EventHandler( form_Activated );
dialog.Closed -= new EventHandler( form_Closed );
top.Text = caption; // Make visible in task list again
Activate( (Form)top ); // And make it the active window
} // ShowDialog
/// <summary>
/// If one of our other windows, such as the main window,
/// receives an activate event, it will activate the current
/// top-most window instead.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void form_Activated( object sender, EventArgs e )
{
if( (m_top != null) && !(sender == m_top) ) // Is this the top-most window?
Activate( m_top ); // No, activate the top dialog
} // form_Activated
private static void form_Closed( object sender, EventArgs e )
{
m_top = null; // When you close the top dialog, it's not top anymore
} // form_Closed
#region IDisposable Members
public void Dispose()
{
// TODO: Add pbDialogs.Dispose implementation
}
#endregion
} // class pbDialogs
There is also a "related" ProgressBar -- a form which shares a file with pbDialogs, and whose instance variable is defined in the file that contains the code above thusly:
public static frmProgress ProgressBar;
This is definitely "whack-a-mole" code - if I make one small, seemingly innocuous change, all Dallas breaks loose in what even a semi-sane person would consider a completely unrelated part of the code.
This may be an indication of just how squirrelly this code/project is: I will make a new build after commenting out a couple of lines, and the size of the file will change from 400KB to 408, or from 412 to 408, etc. It's not normal behavior for an .exe to change that much in size (in a relative sense) with such a small change, is it?
UPATE 2
This, in frmProgress (which has both "public class frmProgress : System.Windows.Forms.Form" and "public class pbDialogs : IDisposable") scares me:
using System.Windows.Forms;
using OpenNETCF.Windows.Forms;
The second (OpenNETCF) is grayed out, indicating it's not really used, but it may be that it was previously used, and somehow that "Windows.Forms" code inadvertently got switched to "System" code, and that may be contributing to its current groundsquirellyness.
ShowDialog is generally a blocking call. The code will not continue past this until the dialog is closed.