avoid click event while panel is refreshing - c#

i have two panel in ma form. panel1 with button1 on it at location let say x:10,y:10 and panel2 with button 2 on it at location x:10,y:10.
what actually button1 do:- it hide panel1 and shows panel2 at the same location.
but whenever i click on button1 twice after completion its process it fire button2 click event,
plz help me ASAP
hope below link will demonstrate my prob clearly
http://www.youtube.com/watch?v=bpojl4XMweo&feature=g-upl
EDIT:
Code used so far
void hidepanel()
{
panel1.Visible = false;
panel2.Visible = false;
}
private void Form1_Load(object sender, EventArgs e)
{
hidepanel();
panel1.Visible = true;
panel2.Location = new Point(262,19);
panel1.Location = new Point(0, 0);
}
private void button1_Click(object sender, EventArgs e)
{
hidepanel();
panel2.Location = new Point(0, 0);
panel2.Visible = true;
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("2");
}

just add some logic to hide/unhide enable/disable the oposite components. Just like this:
private void button1_Click(object sender, EventArgs e)
{
addLog("Button 1 clicked");
button1.Enabled = false;
button2.Enabled = false;
panel1.Visible = false;
panel2.Visible = true;
button2.Enabled = true;
}
private void button2_Click(object sender, EventArgs e)
{
addLog("Button 2 clicked");
button2.Enabled = false;
panel2.Visible = false;
panel1.Visible = true;
button1.Enabled = true;
}
works for me like a charme:
regards
Josef
EDIT:
Now, I see the problem, the mouse clicks are enqueued into windows message queue and will fire the click event on button2 although you clicked on a disabled/hidden button1.
I found the solution here: Ignoring queued mouse events
and changed the code to:
public static void ClearMouseClickQueue()
{
win32msg.NativeMessage message;
while (win32msg.PeekMessage(out message, IntPtr.Zero, (uint)win32msg.WM.WM_MOUSEFIRST, (uint)win32msg.WM.WM_MOUSELAST, 1))
{
}
}
...
private void button1_Click_1(object sender, EventArgs e)
{
addLog("Button 1 clicked");
button1.Enabled = false;
button2.Enabled = false;
panel1.Visible = false;
System.Threading.Thread.Sleep(2000);
ClearMouseClickQueue();
panel2.Visible = true;
button2.Enabled = true;
}
where PeekMessage etc is defined another class:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace PanelTest
{
public static class win32msg
{
[DllImport("coredll.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool PeekMessage(out NativeMessage lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg);
public enum WM : uint{
/// <summary>
/// Use WM_MOUSEFIRST to specify the first mouse message. Use the PeekMessage() Function.
/// </summary>
WM_MOUSEFIRST = 0x0200,
/// <summary>
/// Use WM_MOUSELAST to specify the last mouse message. Used with PeekMessage() Function.
/// </summary>
WM_MOUSELAST = 0x020E,
}
[StructLayout(LayoutKind.Sequential)]
public struct NativeMessage
{
public IntPtr handle;
public uint msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}
}
}
Please test.
~josef

Related

how do I bind the repeating codes shared by multiple forms in c#

I have around 10+ child forms and all the child forms have the following features
Close button: on hover displays "close" text and when mouse clicked, shows a message box to confirm the action
Minimize button: On hover, it displays "minimize" text, when the mouse is clicked, the form gets minimized
Drag anyway inside the parent form
I have to avoid using Visual Studio's default style to get a desirable customized form.
-The code below is shared by all the child forms, since the code is the same, is there a way to bind to one place and reference?
code
public const int WM_NCLBUTTONDOWN = 0xA1;
public const int HTCAPTION = 0x2;
[DllImport("User32.dll")]
public static extern bool ReleaseCapture();
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
//Dtrag the form
private void DragPanel(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
}
#region controlbox
private void minimizebtn_Click(object sender, EventArgs e)
{
WindowState = FormWindowState.Minimized;
}
private void closebtn_Click(object sender, EventArgs e)
{
if (MessageBox.Show("Are you sure you want to Close the window?", "Close", MessageBoxButtons.OKCancel) == DialogResult.OK)
{
Close();
//Application.Exit();
}
}
private void closebtn_MouseHover(object sender, EventArgs e)
{
System.Windows.Forms.ToolTip ToolTip1 = new System.Windows.Forms.ToolTip();
ToolTip1.SetToolTip(this.closebtn, "Close");
}
private void minimizebtn_MouseHover(object sender, EventArgs e)
{
System.Windows.Forms.ToolTip ToolTip1 = new System.Windows.Forms.ToolTip();
ToolTip1.SetToolTip(this.minimizebtn, "Minimize");
}
#endregion
You could create a base class which itself derives from Form. Your actual forms should then derive from that base class.

.net C# - Winform getting Deactivated after "Not responding" message on title bar

I have a ClientForm (opened from MainWindow) which has a search button which on click takes around 12 seconds to process.
During search if user has clicked on that form multiple times "Not Responding" text get appears on its title bar which is ok, but after search completes ClientForm will lose focus or will get deactivate and MainWindow will get the focus - which is an issue.
Below is the code snippet.
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
// this is a wpf window
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var cf= new ClientForm();
cf.Show();
}
}
// This is a winform
public partial class ClientForm : Form
{
public ClientForm()
{
InitializeComponent();
}
private void Search_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
// Do some processing
Thread.Sleep(12000);
Cursor.Current = Cursors.Default;
}
}
Is this a .net framework issue?
I am not using background thread for search or have not used ShowDialog to display form. Would like to know how else this can be fixed and why this issue is occurring.
Thanks!!!
Using background threads, my own example
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
button2.Enabled = false;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
for (int i = 0; i < 100; i++)
{
if (worker.CancellationPending == true)
{
e.Cancel = true;
break;
}
else
{
backgroundWorker1.ReportProgress(i);
Thread.Sleep(100);
}
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}
private void button1_Click(object sender, EventArgs e)
{
if (backgroundWorker1.IsBusy != true)
{
button1.Enabled = false;
button2.Enabled = true;
label1.Text = "Runing...";
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
button1.Enabled = true;
button2.Enabled = false;
label1.Text = "Complete";
}
private void button2_Click(object sender, EventArgs e)
{
if (backgroundWorker1.WorkerSupportsCancellation == true)
{
// Cancel the asynchronous operation.
backgroundWorker1.CancelAsync();
button1.Enabled = true;
button2.Enabled = false;
label1.Text = "Cancel";
}
}
}
}
Thanks for your help but I have got the answer to this weird behavior in below link.
https://learn.microsoft.com/en-us/windows/win32/win7appqual/preventing-hangs-in-windows-applications?redirectedfrom=MSDN
Window with "Not Responding" is not the actual window as actual one is set to hidden and thus deactivated. To resolve this, I have remove the GhostWindowFunctionality and now there is no loss of focus.
Only cons is user can not move, minimize, and close the unresponsive application but we have task manager to close/kill such app.
// This is a winform
public partial class ClientForm : Form
{
[DllImport("user32.dll")]
public static extern void DisableProcessWindowsGhosting();
public ClientForm()
{
InitializeComponent();
DisableProcessWindowsGhosting(); // This will disable it
}
private void Search_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
// Do some processing
Thread.Sleep(12000);
Cursor.Current = Cursors.Default;
}
}

Hide mouse cursor for specific time

public partial class Form3 : Form
{
private readonly KeyboardHookListener m_KeyboardHookManager;
private readonly MouseHookListener m_MouseHookManager;
[DllImport("user32")]
private static extern Int32 ClipCursor(RECT lpRect);
[DllImport("user32")]
private static extern Int32 ShowCursor(Int32 bShow);
[DllImport("user32.dll")]
public static extern bool GetCursorPos(out POINT lpPoint);
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public static implicit operator Point(POINT point)
{
return new Point(point.X, point.Y);
}
}
public static Point GetCursorPosition()
{
POINT lpPoint;
GetCursorPos(out lpPoint);
//bool success = User32.GetCursorPos(out lpPoint);
// if (!success)
return lpPoint;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public Int32 Left;
public Int32 Top;
public Int32 Right;
public Int32 Bottom;
}
public Form3()
{
InitializeComponent();
m_KeyboardHookManager = new KeyboardHookListener(new GlobalHooker());
m_KeyboardHookManager.Enabled = true;
m_KeyboardHookManager.KeyDown += HookManager_KeyDown;
m_KeyboardHookManager.KeyUp += HookManager_KeyUp;
m_MouseHookManager = new MouseHookListener(new GlobalHooker());
m_MouseHookManager.Enabled = true;
m_MouseHookManager.MouseDown += HookManager_MouseDown;
m_MouseHookManager.MouseUp += HookManager_MouseUp;
}
private void Form3_Load(object sender, EventArgs e)
{
//ShowCursor(0);
//MoveCursor();
}
private void HookManager_KeyDown(object sender, KeyEventArgs e)
{
label1.Text = e.KeyData.ToString() + " Pressed";
}
private void HookManager_KeyUp(object sender, KeyEventArgs e)
{
label1.Text = e.KeyData.ToString() + " Released";
}
private void HookManager_MouseUp(object sender, MouseEventArgs e)
{
label1.Text = e.Button.ToString() + " Released";
}
private void HookManager_MouseDown(object sender, MouseEventArgs e)
{
label1.Text = e.Button.ToString() + " Pressed";
ShowCursor(0);
MoveCursor();
System.Threading.Thread.Sleep(5000);//5 sec
RestoreCursor(this);
ShowCursor(1);
}
private void button1_Click(object sender, EventArgs e)
{
//RestoreCursor(this);
//ShowCursor(1);
}
private void Form3_MouseMove(object sender, MouseEventArgs e)
{
//MoveCursor();
}
private RECT MouseTrap;
public void RestoreCursor(System.Windows.Forms.Form ThisForm)
{
var _with1 = MouseTrap;
_with1.Top = 0;
_with1.Left = 0;
_with1.Right = Screen.PrimaryScreen.Bounds.Width;
_with1.Bottom = Screen.PrimaryScreen.Bounds.Height;
ClipCursor(_with1);
}
private void MoveCursor()
{
// set the Current cursor, move the cursor's Position,
// and set its clipping rectangle to the form.
this.Cursor = new Cursor(Cursor.Current.Handle);
Cursor.Position = new Point(this.Left, this.Top);
Cursor.Clip = new Rectangle(this.Left, this.Top, this.Width, this.Height);
}
}
I am developing one sample application My requirement is when user clicks on anywhere on desktop for example click on Windows "Start" button then Hide the cursor for 2 sec then show the cursor after 2 sec at the same position.
For that I have written above code and used Thread.Sleep(2000) for waiting but cursor position restores to Form's left.
https://stackoverflow.com/questions/16781948/how-can-i-hook-globaly-all-the-keys-and-all-the-mouse-buttons/16782294
GlobalMouseHookDLL
you can achieve that using System.Windows.Forms.Timer.
Declare Timer on your form.
public partial class Form3 : Form
{
private Timer timer = new Timer();
Set it on Form_Load
timer.Enabled = false;
timer.Tick += Timer_Tick;
timer.Interval = 5000;
When user moves mouse, instead of Thread.Sleep activate timer. When timer ticks (when specified 5000 milliseconds pass), Timer_Tick method will execute. In it, show pointer.
private void HookManager_MouseDown(object sender, MouseEventArgs e)
{
label1.Text = e.Button.ToString() + " Pressed";
ShowCursor(0);
MoveCursor();
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
RestoreCursor(this);
ShowCursor(1);
timer.Stop();
}

how to do label.text = readKey in WFA

How can I ensure that when you click on label, application expect to press any key, and when user press key, label text change to this key char?
Ok, now i have:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
bool isLabelClicked = false;
private void label1_Click(object sender, EventArgs e)
{
isLabelClicked = true;
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (isLabelClicked)
{
label1.Text = ((char)e.KeyValue).ToString();
isLabelClicked = false;
}
}
}
And if I press Up, Down, Left, Right, Tab or Enter, application not responding and still expects press key. Only when I press any other key, application works well.
If I create new project and paste the same code, all works well, for Up, Down, Left and Right also, but I need this keys for my application which I do.
This example a textBox class : when press any key show it
using System;
using System.Windows.Forms;
using System.Drawing;
namespace KeyPressDisplayTextBox {
public partial class Form1 : Form {
private TextBox textBox1;
private Label label1;
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
textBox1 = new TextBox();
textBox1.Location = new Point(10,10);
textBox1.KeyPress += textBox1_KeyPress;
Controls.Add(textBox1);
label1 = new Label();
label1.Location = new Point(10, 40);
label1.BorderStyle = BorderStyle.FixedSingle;
label1.Font = new Font("Arial", 14);
Controls.Add(label1);
}
void textBox1_KeyPress(object sender, KeyPressEventArgs e) {
label1.Text = e.KeyChar.ToString();
}
}
}
Best regards
You can handle KeyDown event on the Form and get the KeyValue as below
Try This:
You need to set the Form KeyPreview property to True to receive the key events from the Form
bool isLabelClicked = false;
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (isLabelClicked)
{
label1.Text = ((char)e.KeyValue).ToString();
isLabelClicked = false;
}
}
private void label1_Click(object sender, EventArgs e)
{
isLabelClicked = true;
}

Problem disposing the managed resources in c# window form

In the below code, i am trying to reference an external .dll, which creates a custom taskbar in the desktop. After which i am creating tabs on the taskbar as per my requirement.
Everything works fine, but after i terminate my application for creating the taskbar, the space which is occupied by the custom taskbar is blocked. which means that, the resources are not released after exiting the application.
I am trying the force the application to dispose the unmanaged resources. But it dosent help.
How to do it?? Please refer to the code below which i am trying with...
namespace Daemon
{
public partial class MDIParent : ShellLib.ApplicationDesktopToolbar , IDisposable
{
private static MDIParent MDIParentInstance = null;
public MDIParent()
{
InitializeComponent();
timer1.Interval = 50;
timer1.Enabled = true;
}
int childCount = 1;
int iHitcount = 0;
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
private void MDIParent_FormClosed(object sender, FormClosedEventArgs e)
{
Taskbar.Show();
}
public void TabIt(string strProcessName)
{
//Get the collection of opened tab names and check against the new tabs.
//If exists, dont allow to open the same tab again.
bool found = false;
if (Global.ExistingTabProcessNames.Count > 0)
{
foreach (string currentTab in Global.ExistingTabProcessNames)
{
if (currentTab.Equals(strProcessName))
{
found = true;
}
}
}
if (found == false)
{
this.Show();
//Creating MDI child form and initialize its fields
MDIChild childForm = new MDIChild();
childForm.Text = strProcessName;
childForm.MdiParent = this;
//child Form will now hold a reference value to the tab control
childForm.TabCtrl = tabControl1;
//Add a Tabpage and enables it
TabPage tp = new TabPage();
tp.Parent = tabControl1;
tp.Text = childForm.Text;
tp.Show();
//child Form will now hold a reference value to a tabpage
childForm.TabPag = tp;
//Activate the MDI child form
childForm.Show();
childCount++;
//Activate the newly created Tabpage
tabControl1.SelectedTab = tp;
tp.Height = tp.Parent.Height;
tp.Width = tp.Parent.Width;
}
}
private void MDIParent_Load(object sender, EventArgs e)
{
Edge = AppBarEdges.Top;
}
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern int ShowWindow(IntPtr hWnd, int nCmdShow);
private void tabControl1_SelectedIndexChanged(object sender, System.EventArgs e)
{
iHitcount = iHitcount + 1;
if (iHitcount != 1)
BringFront(tabControl1.SelectedTab.Text.ToString());
}
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
private const int SW_SHOWNORMAL = 1;
private const int SW_SHOWMINIMIZED = 2;
private const int SW_SHOWMAXIMIZED = 3;
private void BringFront(string ExecutablePath)
{
Process[] Processes = Process.GetProcesses();
foreach (Process clsProcess in Process.GetProcesses())
{
if (clsProcess.ProcessName.Contains(ExecutablePath))
{
ShowWindowAsync(clsProcess.MainWindowHandle, SW_SHOWMAXIMIZED);
}
else
{
ShowWindowAsync(clsProcess.MainWindowHandle, SW_SHOWMINIMIZED);
}
}
}
public static MDIParent MDIParentRef
{
get
{
if (MDIParentInstance == null)
MDIParentInstance = new MDIParent();
return MDIParentInstance;
}
}
public void showScreen()
{
if (this.InvokeRequired == true)
{
this.Invoke(new MethodInvoker(this.showScreen));
}
else
{
this.Show();
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (Global.TabProcessNames.Count > 0)
{
foreach (string strProcessName in Global.TabProcessNames)
{
TabIt(strProcessName);
}
}
}
}
}
The appbar is removed by the OnClosing event of ApplicationDesktopToolbar.
Are you using Application.Exit to exit your application? From MSDN:
The Application.Exit method does not raise the Form.Closed and Form.Closing events [...]

Categories

Resources