As soon as the Balloon Tool tip pops up the application gets crashed. This scenario is observed only when the application is running in Windows 8 PC.
Here is the code which we are calling
public void BalloonInfo(Control aControl, string aText, BalloonAlignment aAlignment, int aDuration)
{
lock (this)
{
if (m_mb.IsVisible) return;
//HideHint();
m_mb = new MessageBalloon();
m_mb.Parent = aControl;
m_mb.Title = "Information";
m_mb.TitleIcon = TooltipIcon.Info;
m_mb.Text = aText;
m_mb.Align = aAlignment;
m_mb.CenterStem = false;
m_mb.UseAbsolutePositioning = false;
m_mb.Show();
EnableTimer(true, aDuration);
}
}
Is there any relation that WIN 32 handlers won't work with Windows8.
Related
I want my application to be work in minimized state.this application is for detecting change in computer language..For example, I change my language from English to Russia application will detect it. But my application not working in minimized state or in taskbar.I have code for show in taskbar.Is there any solution for this problem? I want application to be detect change language(working) while minimized in toolbar
Here I have code for language change detection and to minimized application in toolbar..
private void HandleCurrentLanguage()
{
//CultureInfo.CurrentCulture.ClearCachedData();
//Thread.CurrentThread.CurrentCulture.ClearCachedData();
var newLayout = GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero));
if (_currentKeyboardLayout != newLayout)
{
Thread.Sleep(100);
_currentKeyboardLayout = newLayout;
string show = System.Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName;
// MessageBox.Show(show);
string current_language = InputLanguage.CurrentInputLanguage.Culture.Parent.DisplayName;
string current_layout = InputLanguage.CurrentInputLanguage.LayoutName;
var name = new StringBuilder(_currentKeyboardLayout.ToString());
var keyboardLayoutId = (UInt32)GetKeyboardLayout((UInt32)Thread.CurrentThread.ManagedThreadId);
var languageId = (UInt16)(keyboardLayoutId & 0xFFFF);
var keyboardId = (UInt16)(keyboardLayoutId >> 16);
if (button1.InvokeRequired)
{
button1.Invoke(new MethodInvoker(delegate
{
button1.PerformClick();
}));
}
//CultureInfo.CurrentCulture.ClearCachedData();
//Thread.CurrentThread.CurrentCulture.ClearCachedData();
}
}
// code for minimized application in toolbar
MenuItem exitMenuItem = new MenuItem("Exit", new EventHandler(Exit));
notifyIcon.Icon =SystemTray.Properties.Resources.system_tray;
notifyIcon.Click += new EventHandler(Open);
notifyIcon.ContextMenu = new ContextMenu(new MenuItem[] {
exitMenuItem });
notifyIcon.Visible = true;
I've installed com0com so that I can write a NUnit test. Just in case there is a definition difference of Keyboard wedge a brief description of it is a piece of software that listens to a Serial communications device, reads any data sent to it (in my case formats it to ASCII data) then sends that to a Virtual keyboard. This code does work in production but we are required to now either document our code or have a unit test to prove how it is supposed to be used. so here is my test
[Test()]
public void WedgeSendsTextToVirtualKeyboardTest()
{
(var form = new Form())
using(var sp = new System.IO.Ports.SerialPort("COM"+COMB, 115200))
using (var wedge = new KeyboardWedgeConfiguration(WEDGE_KEY))
{
sp.Open();
TextBox tb = SetupForm(form);
TurnOnKeyboardWedge(wedge);
form.Activate();
form.Activated += (s, e) =>
{
tb.Focus();
};
while (!tb.Focused) { }
string str = "Hello World";
sp.Write(str);
//wait 1 second. This allows data to send, and pool in the wedge
//the minimum wait time is 200ms. the string then gets put into bytes
//and shipped off to a virtual keyboard where all the keys are pressed.
System.Threading.Thread.Sleep(1000);
Expect(tb.Text, Is.EqualTo(str));
}
}
private static TextBox SetupForm(Form form)
{
TextBox tb = new TextBox();
tb.Name = "tb";
tb.TabIndex = 0;
tb.AcceptsReturn = true;
tb.AcceptsTab = true;
tb.Dock = DockStyle.Fill;
form.Controls.Add(tb);
form.Show();
return tb;
}
private static void TurnOnKeyboardWedge(KeyboardWedgeConfiguration wedge)
{
wedge.Port = COMA;
wedge.PortForwardingEnabled = true;
wedge.Baud = 115200;
System.IO.Ports.SerialPort serialPort;
wedge.StartRerouting();
Assert.IsTrue(wedge.IsAlive(out serialPort));
Assert.IsNotNull(serialPort);
}
When the test runs, the form shows, no text is put in the textbox, then the test exits and the last assert fails (Expect(tb.Text, Is.EqualTo(str));) saying that tb.Text is string.Empty. I've tried a number of different tactics to get focus on that textbox (i'm assuming that is the problem atleast). At one time I made my sleep longer so that I had time to click on the textbox and type myself, and I couldn't click on the box (I'm assuming that is because of the sleep operation... which is also probably why my wedge can't type in there as well) so how can I fix this problem and make my test pass. Again this code does work in a production environment, so I am 100% convinced it is my test (and probably that sleep operation)
I was able to make my test pass with the help of this question stackoverflow question (thank you so much Patrick Quirk). It is actually a minor variation to it. I'm not even sure if my solution is 100% correct, but when the form pops up the text is entered and my test passes. The solution was two part system. First I had to make a class that extends Form override the Text property, and listen for the Activated and FormClosing Events. On Form Closing I would set my text, and on Activated I told my TextBox to have the focus.
private class WedgeForm : Form
{
public override string Text { get { return text; } set { text = value; } }
string text = string.Empty;
private TextBox tb;
public WedgeForm()
{
InitializeControls();
Activated += (s, e) => { tb.Focus(); };
FormClosing += (s, e) => { this.Text = tb.Text; };
}
private void InitializeControls()
{
tb = new TextBox();
tb.Name = "tb";
tb.TabIndex = 0;
tb.AcceptsReturn = true;
tb.AcceptsTab = true;
tb.Multiline = true;
tb.Dock = DockStyle.Fill;
this.Controls.Add(tb);
}
}
then using the InvokeEx method that was provided in the other qustion/answer My test easy to setup
[Test()]
public void WedgeSendsTextToVirtualKeyboardTest()
{
using (var form = new WedgeForm())
using (var wedge = new KeyboardWedgeConfiguration(WEDGE_KEY))
{
TurnOnKeyboardWedge(wedge);
string actual = MakeWedgeWriteHelloWorld(form, wedge); ;
string expected = "Hello World";
Expect(actual, Is.EqualTo(expected));
}
}
private static string MakeWedgeWriteHelloWorld(WedgeForm form, KeyboardWedgeConfiguration wedge)
{
var uiThread = new Thread(() => Application.Run(form));
uiThread.SetApartmentState(ApartmentState.STA);
uiThread.Start();
string actual = string.Empty;
var thread = new Thread
(
() => actual = InvokeEx<Form, string>(form, f => f.Text)
);
using (var sp = new System.IO.Ports.SerialPort("COM" + COMB, 115200))
{
sp.Open();
sp.Write("Hello World");
}
//wait 1 second. This allows data to send, and pool in the wedge
//the minimum wait time is 200ms. the string then gets put into bytes
//and shipped off to a virtual keyboard where all the keys are pressed.
Thread.Sleep(1000);
InvokeEx<Form>(form, f => f.Close());
thread.Start();
uiThread.Join();
thread.Join();
return actual;
}
One minor thing I have to remember when running this test is to not be clicking around because if that textbox loses focus I'm sunk. But the test is only 1second long.. I think I'll live.
Every time when a user opens my app, the app needs to check that does it need to upload/download data to/from windows azure or not. However, if the user doesn't have internet connection, the app will show a last update time in System Tray. The app gets the last update time from SQLite which doesn't need to use await method to do it. So, how can I last the text in System tray for few seconds before it will be faded out.
This is my code
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
if (SessionManagement.IsLoggedIn())
{
var userLastestPoopDataInSQLite = new SQLiteFunctions().GetUserPoopData(SessionManagement.GetEmail());
if (userLastestPoopDataInSQLite.Count != 0)
{
userLastestpoopRecordInSqlite = userLastestPoopDataInSQLite.Last();
if (!NetworkInterface.GetIsNetworkAvailable())
{
SystemTray.ProgressIndicator = new ProgressIndicator();
SystemTray.ProgressIndicator.Text = GetLastUpdatedTimeInText(userLastestpoopRecordInSqlite.Date_Time);
SystemTray.ProgressIndicator.IsVisible = true;
}
else
{
isUpdateNeeded = DateTime.Compare(userLastestpoopRecordInSqlite.Date_Time, userLastestPoopRecordInAzure.Date_Time);
Debug.WriteLine("Lastest time in Sqlite" + userLastestpoopRecordInSqlite.Date_Time);
Debug.WriteLine("Lastest time in azure" + userLastestPoopRecordInAzure.Date_Time);
Debug.WriteLine(isUpdateNeeded);
if (isUpdateNeeded == 0)
{
SystemTray.ProgressIndicator = new ProgressIndicator();
SystemTray.ProgressIndicator.Text = "Data is up-to-date";
SystemTray.ProgressIndicator.IsVisible = true;
}
else
{
userLastestPoopDataInAzure = await new AzureFunctions().GetUserPoopDataInAzure(SessionManagement.GetEmail());
userLastestPoopRecordInAzure = userLastestPoopDataInAzure.Last();
StartSyncUserLastestData();
}
}
}
}
}
Thank you
There is no built in support for showing the progress bar a limited time, so you will probably need to use a timer for this:
SystemTray.ProgressIndicator = new ProgressIndicator();
SystemTray.ProgressIndicator.IsVisible = true;
SystemTray.ProgressIndicator.Text = "Data is up-to-date";
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Tick += (sender, args) =>
{
SystemTray.ProgressIndicator.IsVisible = false;
timer.Stop();
};
timer.Start();
I am modifying a windows desktop application that works with some external hardware. When the user activates the hardware from the application a progress (UI) form is started. This form creates a thread that performs all of the work with the hardware. The problem comes when I try to report progress back to the UI thread. It appears that the first of my Control.BeginInvoke ("Negotiating message") works fine. However, the second one (first adjustment to progressbar) never seems to call it's delegate and as a result the application locks up on the subsequent endinvoke. I believe the issue is that the GUI is now in an idle state, but I am not sure how to fix the situation. Any help would be appreciated. Code found below:
In the UI Load Method Thread:
private void frmTwainAquire_Load(object sender, EventArgs e)
{
try
{
//Show the GUI
this.Visible = showGUI;
pbScanningProgress.Value = 0;
btnCancel.Enabled = false;
btnCancel.Visible = false;
// Set the delegates.
SetScanMessageDelegate = new SetScanMessage(this.SetScanMessageMethod);
SetRegistrationMessageDelegate = new SetRegistrationMessage(this.SetRegistrationMessageMethod);
AddScanProgressDelegate = new AddScanProgress(this.AddScanProgressMethod);
AddRecogProgressDelegate = new AddRecogProgress(this.AddRecogProgressMethod);
// Set progress bars.
pbScanningProgress.Value = 0;
pbRecognition.Value = 0;
abortScan = false;
// Create thread here!
twainInstance = new rScan.Twain();
rScanning = new rScanThread(this, twainInstance);
// Start the thread.
rScanning.tScan = new Thread(rScanning.Scan);
rScanning.tScan.Start();
}
catch (Exception ex)
{
// Error checking here.
}
}
Delegate Methods:
public void SetScanMessageMethod(string scanMessage)
{
this.lblScanMessage.Text = scanMessage;
}
public void SetRegistrationMessageMethod(string recogMessage)
{
this.lblRecognition.Text = recogMessage;
}
public void AddScanProgressMethod(int progress)
{
this.pbScanningProgress.Value += progress;
}
public void AddRecogProgressMethod(int progress)
{
this.pbRecognition.Value += progress;
}
Thread method that is giving the problem. Please note that the thread is in a different class then the previous two code blocks (both are in the UI class):
public class rScanThread : IMessageFilter
public void Scan()
{
// Set progress bar message.
IAsyncResult result;
if (frmTwainAquireInstance.lblScanMessage.IsHandleCreated && frmTwainAquireInstance.lblScanMessage.InvokeRequired)
{
result = frmTwainAquireInstance.lblScanMessage.BeginInvoke(frmTwainAquireInstance.SetScanMessageDelegate, "Negotiating Capabilities with Scanner.");
frmTwainAquireInstance.lblScanMessage.EndInvoke(result);
}
else
{
frmTwainAquireInstance.lblScanMessage.Text = "Negotiating Capabilities with Scanner.";
}
// Start the intialization of the rScan process.
bool intializeSuccess = twainInstance.Initialize(frmTwainAquireInstance.Handle);
// If the process could not be started then quit.
if (!intializeSuccess)
{
frmTwainAquireInstance.Close();
return;
}
if (frmTwainAquireInstance.pbScanningProgress.IsHandleCreated && frmTwainAquireInstance.pbScanningProgress.InvokeRequired)
{
result = frmTwainAquireInstance.pbScanningProgress.BeginInvoke(frmTwainAquireInstance.AddScanProgressDelegate, 33);
frmTwainAquireInstance.pbScanningProgress.EndInvoke(result); // Lock up here.
}
else
{
frmTwainAquireInstance.pbScanningProgress.Value += 33;
}
// Do more work after. The code never makes it this far.
} // End of rScanThread.Scan()
I have an application with a simple gui, very few graphics but a lot of objects ie. labels text boxes and a few panels.
On some panels it runs LDAP queries, in others it queries processes running and checks NIC status.
When I go to the LDAP searcher panel, memory usage drops down to app 30mb, when I return to the main panel that only runs a timer, It jumps to about 300mb + then keeps accumulating, I run GC.Collect() as often as I can, on minimize after primary methods have been run and such still to no effect, ive used optimize code under build in project properties and ive stripped out all of the Using system.whatever. I am a reasonably new programmer, its only been about 6 months since I started doing windows forms. Any help would be nice. My application is essentially a GUI that sits there with a timer running in the background, then does the aforementioned queries and some task skills. Nothing too memory intensive. Could the gui objects themselves be eating up my memory?
public MainMethod()
{
try
{
InitializeComponent();
notifyIcon1.Visible = true;
// this.Opacity = .5;
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 1000 * 10;
pword();
this.ShowInTaskbar = false;
this.Hide();
this.Visible = false;
// GC.Collect();
}
catch (Exception ex)
{
eventWriter(ex);
}
}
public void pword()
{
try
{
bool nCheck;
string[] infoArray = new string[4];
nCheck = checker.checkNetwork();
int dayNum = 0;
if (nCheck == true)
{
infoArray = checker.checkAD(); //this is similar code to CheckNetwork except it returns values from the user's AD account properties.
label3.Text = infoArray[0];
label2.Text = infoArray[2];
label1.Text = infoArray[3];
label21.Text = infoArray[0];
label22.Text = infoArray[1];
label23.Text = infoArray[2];
label24.Text = infoArray[3];
days = infoArray[3];
dayNum = int.Parse(days);
if (dayNum <= 15)
{
timedIntervalChanger(2);
aTimer.Start();
GC.Collect();
}
}
else
{
timedIntervalChanger(1);
aTimer.Start();
GC.Collect();
}
}
catch (Exception ex)
{
eventWriter(ex);
}
}
public bool checkNetwork()
{
bool connected;
try
{
String objectName = WindowsIdentity.GetCurrent().Name;
if (objectName.Contains("administrator"))
{
connected = false;
return connected;
}
else
{
// Sets domain
string LdapDomain = "mydomain.com"
//Sets properties for directory Entry and Searcher
string connectionPrefix = "LDAP://" + LdapDomain;
DirectoryEntry entry = new DirectoryEntry(connectionPrefix);
DirectorySearcher mySearcher = new DirectorySearcher(entry);
mySearcher.Filter = "(&(objectClass=user)(objectCategory=Person)(|(cn=" + objectName + ")(sAMAccountName=" + objectName + ")))";
//instantiates result object from the search
SearchResult LDAPresult = mySearcher.FindOne();
entry = LDAPresult.GetDirectoryEntry();
connected = true;
}
return connected;
}
catch
{
connected = false;
return connected;
}
}
public void OnTimedEvent(object source, ElapsedEventArgs e)
{
try
{
notifyIcon1.Visible = true;
notifyIcon1.ShowBalloonTip(1000 * 9, "Test", "test text", ToolTipIcon.Warning);
pword();
}
catch (Exception ex)
{
eventWriter(ex);
}
}
It's when I show the form that the memory usage jumps tremendously. Each method is independant and I left out some of the object instantiation code.
We really need more info here. But a few suggestions:
Use the using keyword or call Dispose() on all disposable objects when you are done with them
Make sure you unregister event handlers when you are done listening for events
I am not sure what LDAP library you are using but in System.DirectoryServices many of the classes (like DirectoryEntry) implement IDisposable and can 'leak' if they are not disposed of
Use the .NET Memory Allocation option of the Performance Wizard found in the Analyze menu to create a Performance Session which will help you figure out what changes you need to make in your code to reduce memory usage.