c++CLI event handler's not triggered - event-handling

I am just getting into c++ CLI and am running into a problem where some event handlers are called and some are not.
here is a list of my event handlers:
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
}
private: System::Void exitToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
Application::Exit();
}
private: System::Void aboutToolStripMenuItem_Click(System::Object^ sender, System::EventArgs^ e) {
MessageBox::Show("Paul Madsen\nLab 13",
"About lab 13", MessageBoxButtons::OK,
MessageBoxIcon::Asterisk);
}
private: System::Void textBox1_TextChanged(System::Object^ sender, System::EventArgs^ e)
{
try
{
double tmp = Double::Parse(textBox1->Text);
}
catch(...)
{
textBox1->ResetText();
}
}
private: System::Void textBox2_TextChanged(System::Object^ sender, System::EventArgs^ e)
{
try
{
double tmp = Double::Parse(textBox2->Text);
}
catch(...)
{
textBox2->ResetText();
}
}
private: System::Void textBox1_Enter(System::Object^ sender, System::EventArgs^ e)
{
MessageBox::Show("Test",
"test", MessageBoxButtons::OK,
MessageBoxIcon::Asterisk);
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
double tmp = (Double::Parse(textBox1->Text) - 32) * 5/9;
textBox2->Text = System::Convert::ToString(tmp);
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
double tmp = (Double::Parse(textBox1->Text) - 32) * 5/9;
textBox1->Text = System::Convert::ToString(tmp);
}
button1_Click works just fine but button2_Click is never triggered even though they are essentially the same. Why is that?

Look back toward the beginning of the source code file, inside InitializeComponent(). You should have no trouble seeing the button1->Click event handler assignment. Do you see the one for button2->Click?
Delete the button in the designer, add it back. Double click it. Or just leave it out, no point in having two buttons doing the same thing.

Related

WinForms: topmost form loses focus on hiding dialog called from it

I have a WinForms project with a main topmost form from which a non-modal dialog is displayed. I need to hide (not close) the dialog if it loses the input focus - no matter what was the reason (the user clicked the main form, switched to another app, etc). The following bare part of the project source code shows what is going on:
public partial class MainForm : Form
{
Form _dialog = new Form();
public MainForm()
{
InitializeComponent();
this.TopMost = true;
this.Text = "Main Form";
_dialog.Text = "Dialog";
_dialog.Owner = this;
_dialog.TopMost = true;
_dialog.Deactivate += Dialog_Deactivate;
_dialog.FormClosing += Dialog_FormClosing;
}
private void Dialog_Deactivate(object sender, EventArgs e)
{
_dialog.Hide();
}
private void Dialog_FormClosing(object sender, FormClosingEventArgs e)
{
_dialog.Hide();
e.Cancel = true;
}
private void ButtonShowDialog_Click(object sender, EventArgs e)
{
_dialog.Show();
}
}
The main problem I am trying to solve is the following. If the user opened the dialog and clicks the main form like I depicted on the following screenshot
, the dialog becomes hidden as expected, but the main form loses the focus and another app that was previously active becomes active in the background - the Windows Explorer on the next screenshot:
Is it a known issue in Windows or WinForms? How to cause the main form not to lose the focus in this construction?
The issue seems to be that when the Main Form is clicked, it triggers a WM_WINDOWPOSCHANGING event. Since the child dialog is open, the hwndInsertAfter handle is the child dialog. But then in the Dialog_Deactivate the child dialog is hidden, causing the Main Form to fall behind all the other windows because the hwndInsertAfter handle is no longer a visible window.
Possible solutions are 1) set the child dialog owner to null before calling Hide() or 2) use a different event, like LostFocus, i.e:
public class MainForm3 : Form {
Form _dialog = null;
public MainForm3() {
this.Text = "Main Formmmmmmmm";
Button btn = new Button { Text = "Show" };
btn.Click += ButtonShowDialog_Click;
this.Controls.Add(btn);
}
bool b = false;
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (_dialog != null && _dialog.Visible)
b = true;
if (b)
Debug.WriteLine(m);
int WM_WINDOWPOSCHANGING = 0x46;
if (b && m.Msg == WM_WINDOWPOSCHANGING) {
var wp = Marshal.PtrToStructure<WINDOWPOS>(m.LParam);
Debug.WriteLine("hwnd: " + wp.hwnd + " " + GetWindowText(wp.hwnd));
Debug.WriteLine("hwndInsertAfter: " + wp.hwndInsertAfter + " " + GetWindowText(wp.hwndInsertAfter));
Debug.WriteLine("flags: " + wp.flags);
}
}
private void Dialog_Deactivate(object sender, EventArgs e) {
_dialog.Owner = null; // solution 1
_dialog.Hide();
}
private void _dialog_LostFocus(object sender, EventArgs e) { // solution 2
_dialog.Hide();
}
private void Dialog_FormClosing(object sender, FormClosingEventArgs e) {
if (_dialog.Visible) {
_dialog.Hide();
e.Cancel = true;
}
}
private void ButtonShowDialog_Click(object sender, EventArgs e) {
if (_dialog == null) {
_dialog = new Form();
_dialog.Text = "Dialoggggggg";
//_dialog.Deactivate += Dialog_Deactivate;
_dialog.LostFocus += _dialog_LostFocus; // solution 2, use LostFocus instead
_dialog.FormClosing += Dialog_FormClosing;
}
_dialog.Owner = this;
_dialog.Show();
}
[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS {
public IntPtr hwnd, hwndInsertAfter;
public int x, y, cx, cy;
public SWP flags;
}
[Flags]
public enum SWP : uint {
SWP_ASYNCWINDOWPOS = 0x4000,
SWP_DEFERERASE = 0x2000,
SWP_DRAWFRAME = 0x0020,
SWP_FRAMECHANGED = 0x0020,
SWP_HIDEWINDOW = 0x0080,
SWP_NOACTIVATE = 0x0010,
SWP_NOCOPYBITS = 0x0100,
SWP_NOMOVE = 0x0002,
SWP_NOOWNERZORDER = 0x0200,
SWP_NOREDRAW = 0x0008,
SWP_NOREPOSITION = 0x0200,
SWP_NOSENDCHANGING = 0x0400,
SWP_NOSIZE = 0x0001,
SWP_NOZORDER = 0x0004,
SWP_SHOWWINDOW = 0x0040
}
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
private static String GetWindowText(IntPtr hWnd) {
StringBuilder sb = new StringBuilder(256);
GetWindowText(hWnd, sb, sb.Capacity);
return sb.ToString();
}
}
Try calling Activate() on the main form after the dialog is hidden, i.e:
private void Dialog_Deactivate(object sender, EventArgs e)
{
_dialog.Hide();
this.Activate();
}

How to fix "interstitialAd.IsLoaded() returns true in offline" (unity C#)

interstitialAd.IsLoaded() is always returning true even if device is offline. its works fine when app device is online.
public class InsAdBanner : MonoBehaviour
{
public int SceneIndex;
private InterstitialAd interstitialAd;
void Start()
{
this.RequestInterstitial();
}
void RequestInterstitial()
{
string interstitial_ID = "ad_id";
interstitialAd = new InterstitialAd(interstitial_ID);
if (this.interstitialAd != null)
{
this.interstitialAd.Destroy();
}
this.interstitialAd.OnAdLoaded += HandleOnAdLoaded;
this.interstitialAd.OnAdFailedToLoad += HandleOnAdFailedToLoad;
this.interstitialAd.OnAdOpening += HandleOnAdOpened;
this.interstitialAd.OnAdClosed += HandleOnAdClosed;
this.interstitialAd.OnAdLeavingApplication += HandleOnAdLeavingApplication;
AdRequest adRequest = new AdRequest.Builder().Build();
interstitialAd.LoadAd(adRequest);
}
public void Display_InterstitialAD()
{
<!-- plz see this line below -->
if (interstitialAd.IsLoaded())
{
Debug.Log("interstitialAd " + interstitialAd.IsLoaded());
interstitialAd.Show();
}
else {
getOut();
}
}
public void getOut() {
interstitialAd.Destroy();
SceneManager.LoadScene(SceneIndex);
restertAdCounter.restertsAdCouner += 1;
}
#region Interstitial callback handlers
//Handle event
public void HandleOnAdLoaded(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdLoaded event received");
}
public void HandleOnAdFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
RequestInterstitial();
}
public void HandleOnAdOpened(object sender, EventArgs args)
{
MonoBehaviour.print("HandleAdOpened event received");
}
public void HandleOnAdClosed(object sender, EventArgs args)
{
SceneManager.LoadScene(SceneIndex);
}
public void HandleOnAdLeavingApplication(object sender, EventArgs args)
{
SceneManager.LoadScene(SceneIndex);
}
#endregion
void OnDisable()
{
this.interstitialAd.OnAdLoaded += HandleOnAdLoaded;
this.interstitialAd.OnAdFailedToLoad += HandleOnAdFailedToLoad;
this.interstitialAd.OnAdOpening += HandleOnAdOpened;
this.interstitialAd.OnAdClosed += HandleOnAdClosed;
this.interstitialAd.OnAdLeavingApplication += HandleOnAdLeavingApplication;
}
void OnDestroy()
{
interstitialAd.Destroy();
}
}
I expecting it to return false in offline..it is working fine when app device is online .. but creates this problem when device is offline..plz help.. i cant find any solution in google.
Edit: Its not working on online too.. after adding real ad in place of test ad this problem is occurring.
Solved my problem by changing Minify->Relese->Proguard to Minify->Relese->None on player setting.(Although i dont know how actually its working)

Asynchronous Client Socket ManualResetEvent holding up execution

I am attempting to utilize MSDN's Asynchronous Client Socket code sample to connect and control some home equipment. As I understand, the sample code's ReceiveCallback method uses an instance of the EventWaitHandle ManualResetEvent and the method receiveDone.WaitOne() to hold processing of the current thread until the thread receives a signal that all of the socket's data has been transmitted from the remote device. After all of the socket's data has been transmitted (the socket's data is empty and bytesRead = 0), the Waithandle is removed and the application continues processing.
Unfortunately, by stepping-through the execution of the code, it appears that after the last time that the client returns data from the remote device, ReceiveCallback never returns to see if the data-queue is empty (i.e. bytesRead = 0), and thus never enters the "else" condition in ReceiveCallback where the state of the ManualResetEvent would have been reset and the application would have continued to process. Thus, since it never enters the "else" condition, ManualResetEvent is never reset and the application freezes.
Although I can remove the "receiveDone.WaitOne()" method from the code - permitting execution without waiting for the ManualResetEvent's notification that all of the data has been received; this returns a data-string from the equipment that is typically incomplete.
Am I using this code sample incorrectly? Has anyone seen this before or had any experience on how to work-around this issue?
7/14/2012 - UPDATE: After further testing of the MSDN's Asynchronous Client Socket Example, it became clear that ReceiveCallback actually re-polls the port and the "bytesRead = 0" condition is satisfied only when the socket is released (i.e. client.Shutdown(SocketShutdown.Both); client.Close(); ). If I understand this correctly, this means that the connection has to be closed to get past the receiveDone.WaitOne() method. If the connection is closed to satisfy the WaitOne() Waithandle, it totally defeats the purpose of the application in that I had been hoping to leave the connection open so that the application could listen for equipment updates, which happen continually.
7/16/2012 - UPDATE: I have written to Microsoft Tech Support who have responded that "We're doing research on this issue. It might take some time before we get back to you." As such, it seems that it doesn't appear that this challenge can be resolved at this time through massaging this code.
Without the availability of the Asynchronous Client Socket example code as a foundation for writing asynchronous communication procedures, may I ask if anyone can please suggest a replacement routine that is more reliable? There are three pieces of equipment, each with it's own ip-address and port number. Thus, it would be ideal if a class could be utilized, where an instance could be created for each device. Additionally, the port must remain open to receive spontaneous updates continually sent by the equipment. Lastly, the updates do not have a end character or defined length signalling that the transmission of the message is complete, thus the routine must continually poll the port for available data. Any advice or suggestions would be greatly appreciated.
7/18/2012 - WORKAROUND: After spending a considerable amount of time attempting to get the MSDN's Asynchronous Client Socket code sample working, it became clear that I would have to look elsewhere to get the device responses continuously recognized by the program. In the hope to save someone else the brain-damage, I have included the work-around that I used which seems to work well to this point. If anyone has any suggestions, please don't hesitate to add to this question!
//
// ORIGINAL CODE ATTEMPT
//
public static Socket LutronClient;
public static String LutronResponse = String.Empty;
private const int LutronPort = 4999;
private const string LutronIP = "192.168.1.71";
private static ManualResetEvent LutronConnectDone = new ManualResetEvent(false);
private static ManualResetEvent LutronSendDone = new ManualResetEvent(false);
private static ManualResetEvent LutronReceiveDone = new ManualResetEvent(false);
private static void StartLutronClient()
{
try
{
var lutronIPAddress = IPAddress.Parse(LutronIP);
var lutronRemoteEP = new IPEndPoint(lutronIPAddress, LutronPort);
LutronClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
LutronClient.BeginConnect(lutronRemoteEP, LutronConnectCallback, LutronClient);
LutronConnectDone.WaitOne();
LutronSend(LutronClient, "sdl,14,100,0,S2\x0d");
LutronSendDone.WaitOne();
LutronReceive(LutronClient);
LutronReceiveDone.WaitOne(new TimeSpan(5000));
MessageBox.Show("Response received from Lutron: " + LutronResponse);
txtBoxLutron.Text = LutronResponse;
LutronClient.Shutdown(SocketShutdown.Both);
LutronClient.Close();
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
private static void LutronConnectCallback(IAsyncResult lutronAr)
{
try
{
var lutronClient = (Socket)lutronAr.AsyncState;
lutronClient.EndConnect(lutronAr);
LutronConnectDone.Set();
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
private static void LutronReceive(Socket lutronClient)
{
try
{
var lutronState = new LutronStateObject { LutronWorkSocket = lutronClient };
lutronClient.BeginReceive(lutronState.LutronBuffer, 0, LutronStateObject.BufferSize, 0, new AsyncCallback(LutronReceiveCallback), lutronState);
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
private static void LutronReceiveCallback(IAsyncResult lutronAR)
{
try
{
var lutronState = (LutronStateObject)lutronAR.AsyncState;
var lutronClient = lutronState.LutronWorkSocket;
var bytesRead = lutronClient.EndReceive(lutronAR);
if (bytesRead > 0)
{
lutronState.LutronStringBuilder.AppendLine(Encoding.ASCII.GetString(lutronState.LutronBuffer, 0, bytesRead));
lutronClient.BeginReceive(lutronState.LutronBuffer, 0, LutronStateObject.BufferSize, 0, new AsyncCallback(LutronReceiveCallback), lutronState);
}
else
{
if (lutronState.LutronStringBuilder.Length > 0) { LutronResponse = lutronState.LutronStringBuilder.ToString(); }
LutronReceiveDone.Set();
}
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
public static void LutronSend(Socket client, String data)
{
var byteData = Encoding.ASCII.GetBytes(data);
client.BeginSend(byteData, 0, byteData.Length, 0, LutronSendCallback, client);
}
private static void LutronSendCallback(IAsyncResult ar)
{
try
{
var client = (Socket)ar.AsyncState;
var bytesSent = client.EndSend(ar);
LutronSendDone.Set();
}
catch (Exception e) { MessageBox.Show(e.ToString()); }
}
public class LutronStateObject
{
public Socket LutronWorkSocket;
public const int BufferSize = 256;
public byte[] LutronBuffer = new byte[BufferSize];
public StringBuilder LutronStringBuilder = new StringBuilder();
}
}
This is the work-around I used:
//
// WORK-AROUND
//
using System;
using System.Windows.Forms;
namespace _GlobalCacheInterface
{
public partial class GlobalCacheDataScreen : Form
{
//Interface objects
private static GC_Interface _lutronInterface;
private const int LutronPort = 4999;
private const string LutronIP = "192.168.1.71";
delegate void ThreadSafeLutronCallback(string text);
private static GC_Interface _elanInterface;
private const int ElanPort = 4998;
private const string ElanIP = "192.168.1.70";
delegate void ThreadSafeElanCallback(string text);
private static GC_Interface _tuneSuiteInterface;
private const int TuneSuitePort = 5000;
private const string TuneSuiteIP = "192.168.1.70";
delegate void ThreadSafeTuneSuiteCallback(string text);
public GlobalCacheDataScreen()
{
InitializeComponent();
_lutronInterface = new GC_Interface(LutronIP, LutronPort);
_elanInterface = new GC_Interface(ElanIP, ElanPort);
_tuneSuiteInterface = new GC_Interface(TuneSuiteIP, TuneSuitePort);
// Create event handlers to notify application of available updated information.
_lutronInterface.DataAvailable += (s, e) => ThreadSafeTxtBoxLutron(_lutronInterface._returnString);
_elanInterface.DataAvailable += (s, e) => ThreadSafeTxtBoxElan(_elanInterface._returnString);
_tuneSuiteInterface.DataAvailable += (s, e) => ThreadSafeTxtBoxTuneSuite(_tuneSuiteInterface._returnString);
_lutronInterface.Connected += (s, e) => UpdateUI();
_elanInterface.Connected += (s, e) => UpdateUI();
_tuneSuiteInterface.Connected += (s, e) => UpdateUI();
UpdateUI();
}
private void UpdateUI()
{
_buttonConnectToLutron.Enabled = !_lutronInterface._isConnected;
_buttonConnectToElan.Enabled = !_elanInterface._isConnected;
_buttonConnectToTuneSuite.Enabled = !_tuneSuiteInterface._isConnected;
_buttonDisconnectFromLutron.Enabled = _lutronInterface._isConnected;
_buttonDisconnectFromElan.Enabled = _elanInterface._isConnected;
_buttonDisconnectFromTuneSuite.Enabled = _tuneSuiteInterface._isConnected;
string connectLutronStatus = _lutronInterface._isConnected ? "Connected" : "Not Connected";
string connectElanStatus = _elanInterface._isConnected ? "Connected" : "Not Connected";
string connectTuneSuiteStatus = _tuneSuiteInterface._isConnected ? "Connected" : "Not Connected";
_textBoxLutronConnectStatus.Text = connectLutronStatus;
_textBoxElanConnectStatus.Text = connectElanStatus;
_textBoxTuneSuiteConnectStatus.Text = connectTuneSuiteStatus;
}
private void ThreadSafeTxtBoxLutron(string message) { if (_lutronRichTextRxMessage.InvokeRequired) { var d = new ThreadSafeLutronCallback(ThreadSafeTxtBoxLutron); _lutronRichTextRxMessage.Invoke(d, new object[] { message }); } else { _lutronRichTextRxMessage.Text = message; } }
private void ThreadSafeTxtBoxElan(string message) { if (_elanRichTextRxMessage.InvokeRequired) { var d = new ThreadSafeElanCallback(ThreadSafeTxtBoxElan); _elanRichTextRxMessage.Invoke(d, new object[] { message }); } else { _elanRichTextRxMessage.Text = message; if (message.EndsWith("\r")) { MessageBoxEx.Show(message, "Message from Lutron Elan", 1000); } } }
private void ThreadSafeTxtBoxTuneSuite(string message) { if (_tuneSuiteRichTextRxMessage.InvokeRequired) { var d = new ThreadSafeTuneSuiteCallback(ThreadSafeTxtBoxTuneSuite); _tuneSuiteRichTextRxMessage.Invoke(d, new object[] { message }); } else { _tuneSuiteRichTextRxMessage.Text = message; if (message.EndsWith("\r")) { MessageBoxEx.Show(message, "Message from TuneSuite", 1000); } } }
private void _buttonConnectToLutron_Click(object sender, EventArgs e) { _lutronInterface.Connect(); }
private void _buttonDisconnectFromLutron_Click(object sender, EventArgs e) { _lutronInterface.Disconnect(); }
private void _buttonConnectToElan_Click(object sender, EventArgs e) { _elanInterface.Connect(); }
private void _buttonDisconnectFromElan_Click(object sender, EventArgs e) { _elanInterface.Disconnect(); }
private void _buttonConnectToTuneSuite_Click(object sender, EventArgs e) { _tuneSuiteInterface.Connect(); }
private void _buttonDisconnectFromTuneSuite_Click(object sender, EventArgs e) { _tuneSuiteInterface.Disconnect(); }
private void _buttonLutronSendMessage_Click(object sender, EventArgs e) { _lutronInterface.SendCommand(_lutronRichTextTxMessage.Text); }
private void _buttonElanSendMessage_Click(object sender, EventArgs e) { _elanInterface.SendCommand(_elanRichTextTxMessage.Text); }
private void _buttonTuneSuiteSendMessage_Click(object sender, EventArgs e) { _tuneSuiteInterface.SendCommand(_elanRichTextTxMessage.Text); }
private void _buttonLightOn_Click(object sender, EventArgs e) { _lutronInterface.SendCommand("sdl,14,100,0,S2"); }
private void _buttonLightOff_Click(object sender, EventArgs e) { _lutronInterface.SendCommand("sdl,14,0,0,S2"); }
private void _buttonStereoOnOff_Click(object sender, EventArgs e) { _elanInterface.SendCommand("sendir,4:3,1,40000,4,1,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,181,21,800"); }
private void _button30_Click(object sender, EventArgs e) { _tuneSuiteInterface.SendCommand("\xB8\x4D\xB5\x33\x30\x00\x30\x21\xB8"); }
private void _button31_Click(object sender, EventArgs e) { _tuneSuiteInterface.SendCommand("\xB8\x4D\xB5\x33\x31\x00\x30\x21\xB8"); }
private void _button26_Click(object sender, EventArgs e) { _tuneSuiteInterface.SendCommand("\xB8\x4D\xB5\x32\x36\x00\x30\x21\xB8"); }
}
}
and the GC_Interface class:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace _GlobalCacheInterface
{
class GC_Interface
{
// Declare an event handler to notify when updates are available.
public event EventHandler<EventArgs> DataAvailable;
public string _returnString = "";
// Declare an event handler to notify status of connection.
public event EventHandler<EventArgs> Connected;
public bool _isConnected;
public AsyncCallback ReceiveCallback;
public Socket Client;
private string _ipAddress;
private int _port;
private bool _waitForEndCharacter;
private byte _endCharacter;
byte[] m_DataBuffer = new byte[10];
IAsyncResult m_Result;
public GC_Interface(string ipAddress, int port) { Init(ipAddress, port, false, 0); }
private void Init(string ipAddress, int port, bool waitForEndCharacter, byte endCharacter)
{
_ipAddress = ipAddress;
_port = port;
_waitForEndCharacter = waitForEndCharacter;
_endCharacter = endCharacter;
_isConnected = false;
}
public bool Connect()
{
try
{
// Create a TCP/IP socket.
Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Establish the remote endpoint for the socket.
var address = IPAddress.Parse(_ipAddress);
var remoteEP = new IPEndPoint(address, _port);
// Connect to the remote endpoint.
Client.Connect(remoteEP);
if (Client.Connected)
{
_isConnected = true;
ConnectedEventHandler();
WaitForData();
}
return true;
}
catch (SocketException se) { MessageBox.Show("\n connection failed, is the server running?\n" + se.Message ); return false; }
}
public bool SendCommand(string command)
{
try
{
// Convert the string data to byte data using ASCII encoding.
var byteData = Encoding.Default.GetBytes(command);
// Add a carraige-return to the end.
var newArray = new byte[byteData.Length + 1];
byteData.CopyTo(newArray, 0);
newArray[newArray.Length - 1] = 13;
if (Client == null) { return false; }
Client.Send(newArray);
return true;
}
catch (SocketException se) { MessageBox.Show(se.Message); return false; }
}
public void WaitForData()
{
try
{
if (ReceiveCallback == null) { ReceiveCallback = new AsyncCallback(OnDataReceived); }
var theSocPkt = new SocketPacket { thisSocket = Client };
m_Result = Client.BeginReceive(theSocPkt.DataBuffer, 0, theSocPkt.DataBuffer.Length, SocketFlags.None, ReceiveCallback, theSocPkt);
}
catch (SocketException se) { MessageBox.Show(se.Message); }
}
public class SocketPacket
{
public System.Net.Sockets.Socket thisSocket;
public byte[] DataBuffer = new byte[1];
}
public void OnDataReceived(IAsyncResult asyn)
{
try
{
SocketPacket theSockId = (SocketPacket)asyn.AsyncState;
var iRx = theSockId.thisSocket.EndReceive(asyn);
char[] Chars = new char[iRx + 1];
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int CharLen = d.GetChars(theSockId.DataBuffer, 0, iRx, Chars, 0);
System.String szData = new System.String(Chars);
_returnString = _returnString + szData.Replace("\0", "");
// When an update is received, raise DataAvailable event
DataAvailableEventHandler();
WaitForData();
}
catch (ObjectDisposedException) { System.Diagnostics.Debugger.Log(0, "1", "\nOnDataReceived: Socket has been closed\n"); }
catch (SocketException se) { MessageBox.Show(se.Message); }
}
public bool Disconnect()
{
try
{
if (Client == null) { return false; }
Client.Close();
Client = null;
_isConnected = false;
return true;
}
catch (Exception) { return false; }
}
protected virtual void DataAvailableEventHandler()
{
var handler = DataAvailable;
if (handler != null) { handler(this, EventArgs.Empty); }
}
protected virtual void ConnectedEventHandler()
{
var handler = Connected;
if (handler != null) { handler(this, EventArgs.Empty); }
}
}
}
I had the same issue, adding an Available check to the code fixed my problem. Below is the revised code.
private static void ReceiveCallback( IAsyncResult ar ) {
try {
StateObject state = (StateObject) ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0) {
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Check if there is anymore data on the socket
if (client.Available > 0) {
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
}
if (bytesRead == 0 || client.Available == 0) {
if (state.sb.Length > 1) {
response = state.sb.ToString();
}
receiveDone.Set();
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
Hope that helps.
I'm sidestepping the question here. I try to answer what you need, not what you ask for:
Use synchronous code. It will be easier to understand, you don't need callbacks or events. Also, for low thread counts, it is likely to perform better.
You also avoid bugs that you have in your current code. If an exception occurs your computation never completes. Synchronous code does not have that problem.

Why not work drag and drop?

I need drag from window1.listbox drop in window2.panel.
A write:
public partial class Form1 : Form
{
Routers r = new Routers();
public Form1()
{
InitializeComponent();
r.Show();
panel1.DragOver += new DragEventHandler(panel1_DragOver);
panel1.DragEnter += new DragEventHandler(panel1_DragEnter);
panel1.MouseUp += new MouseEventHandler(panel1_MouseUp);
panel1.DragDrop += new DragEventHandler(panel1_DragDrop);
panel1.AllowDrop = true;
this.AllowDrop = true;
this.DragDrop += new DragEventHandler(Form1_DragDrop);
}
void Form1_DragDrop(object sender, DragEventArgs e)
{
throw new NotImplementedException();
}
void panel1_DragDrop(object sender, DragEventArgs e)
{
if (isDrop == false)
{
isDrop = true;
Button b = new Button();
b.Text = (string)e.Data.GetData(DataFormats.StringFormat);
b.Location = new Point(e.X, e.Y);
this.panel1.Controls.Add(b);
}
}
void panel1_MouseUp(object sender, MouseEventArgs e)
{
if (isDrop)
{
isDrop = false;
}
}
bool isDrop = false;
void panel1_DragEnter(object sender, DragEventArgs e)
{
isDrop = false;
if (e.Data.GetDataPresent(DataFormats.StringFormat))
e.Effect = DragDropEffects.None;
}
void panel1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.None;
}
}
write window2
public partial class Routers : Form
{
public Routers()
{
InitializeComponent();
this.listBox1.MouseDown += new MouseEventHandler(listBox1_MouseDown);
this.listBox1.DragOver += new DragEventHandler(listBox1_DragOver);
}
private void listBox1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
if (this.listBox1.SelectedItem != null)
{
string item = this.listBox1.SelectedItem.ToString();
this.listBox1.DoDragDrop(item, DragDropEffects.Move);
}
}
}
DragDrop event not work.
and does not change the cursor when dragging
You need to set e.Effect to something other than None when dragging over the destination.
See this topic for the solution:
DragDrop event not raised
private void Form1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.All;
}

Listen to msmq queue

Following the is the code I have for listening to messages from Windows form.
I have noticed that when I click on send it sends a message to MyQueue but at that time I was hoping the event mq_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e) should get called but it is not, in other words I am trying to subscribe to MyQueue from Windows form. Just wondering if I am missing something in the code:
public class Form1 : System.Windows.Forms.Form
{
public System.Messaging.MessageQueue mq;
public static Int32 j=0;
public Form1()
{
// Required for Windows Form Designer support
InitializeComponent();
// Queue Creation
if(MessageQueue.Exists(#".\Private$\MyQueue"))
mq = new System.Messaging.MessageQueue(#".\Private$\MyQueue");
else
mq = MessageQueue.Create(#".\Private$\MyQueue");
mq.ReceiveCompleted += new ReceiveCompletedEventHandler(mq_ReceiveCompleted);
mq.BeginReceive();
}
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void btnMsg_Click(object sender, System.EventArgs e)
{
// SendMessage(Handle, 1, 0, IntPtr.Zero);
System.Messaging.Message mm = new System.Messaging.Message();
mm.Body = txtMsg.Text;
mm.Label = "Msg" + j.ToString();
j++;
mq.Send(mm);
}
void mq_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
//throw new NotImplementedException();
}
private void btnRcv_Click(object sender, System.EventArgs e)
{
System.Messaging.Message mes;
string m;
try
{
mes = mq.Receive(new TimeSpan(0, 0, 3));
mes.Formatter = new XmlMessageFormatter(new String[] {"System.String,mscorlib"});
m = mes.Body.ToString();
}
catch
{
m = "No Message";
}
MsgBox.Items.Add(m.ToString());
}
}
See MSDN's example on how to use the ReceiveCompletedEventHandler .
They have a console app where the Main() does the same as your Form1(), but your handler doesn't have any code. You've said it doesn't call back into your event delegate, but perhaps check your queue name is correct on the constructor.
Consider using MSDN's sample code in a new console app to test your environment first, then go back to your WinForms code with any lessons learned.
private static void MyReceiveCompleted(Object source,
ReceiveCompletedEventArgs asyncResult)
{
MessageQueue mq = (MessageQueue)source;
Message m = mq.EndReceive(asyncResult.AsyncResult);
Console.WriteLine("Message: " + (string)m.Body);
mq.BeginReceive();
return;
}
If you want to inspect the queue and get a message on the click of a button, you can simply move the statement mq.BeginReceive(); to the btnRcv_Click() in place of .Receive();