客户端服务器Winform IPC之类的
本文关键字:IPC 服务器 Winform 客户端 | 更新日期: 2023-09-27 18:28:13
很抱歉标题不那么描述性或贴切,但我已经尝试了一段时间,但没有效果,而且对我来说很难。我有一个聊天服务器(控制台应用程序)和一个聊天客户端(winform应用程序)(参考:http://csharp.net-informations.com/communications/csharp-chat-server-programming.htm)和一个单独的winform应用程序,它上面只有一个按钮。每当有任何新消息时,如果客户端窗口被最小化,那么我希望该单独winform上的按钮变为红色。一旦客户端窗口被恢复或最大化,它就应该变回黄色,这也是按钮的原始颜色。当收到消息时,我可以实现颜色的改变,但不考虑最小化状态等。如果我尝试使用IsIconic这样做,则不会发生任何事情。我所做的是在服务器应用程序中获取客户端winform的句柄,并检查它是否是Iconic。请引导我,因为我被困了一段时间。代码如下:
服务器应用程序:
using System;
using System.Threading;
using System.Net.Sockets;
using System.Text;
using System.Collections;
using System.Net;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
public static Hashtable clientsList = new Hashtable();
public static void Main()
{
string mutex_id = "MY_APP";
using (Mutex mutex = new Mutex(false, mutex_id))
{
if (!mutex.WaitOne(0, false))
{
return;
}
var loaclAddress = IPAddress.Parse("127.0.0.1");
var serverSocket = new TcpListener(loaclAddress, 81);
/*
TcpListener serverSocket = new TcpListener(8888);
*/
TcpClient clientSocket = default(TcpClient);
int counter = 0;
serverSocket.Start();
Console.WriteLine("Chat Server Started ....");
counter = 0;
while ((true))
{
counter += 1;
clientSocket = serverSocket.AcceptTcpClient();
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
clientsList.Add(dataFromClient, clientSocket);
broadcast(dataFromClient + " Joined ", dataFromClient, false);
Console.WriteLine(dataFromClient + " Joined chat room ");
handleClinet client = new handleClinet();
client.startClient(clientSocket, dataFromClient, clientsList);
}
clientSocket.Close();
serverSocket.Stop();
Console.WriteLine("exit");
Console.ReadLine();
}
}
public static void broadcast(string msg, string uName, bool flag)
{
foreach (DictionaryEntry Item in clientsList)
{
TcpClient broadcastSocket;
broadcastSocket = (TcpClient)Item.Value;
NetworkStream broadcastStream = broadcastSocket.GetStream();
Byte[] broadcastBytes = null;
if (flag == true)
{
broadcastBytes = Encoding.ASCII.GetBytes(uName + " says : " + msg);
}
else
{
broadcastBytes = Encoding.ASCII.GetBytes(msg);
}
broadcastStream.Write(broadcastBytes, 0, broadcastBytes.Length);
broadcastStream.Flush();
}
} //end broadcast function
}//end Main class
public class handleClinet
{
//This is used to send custom message to your Winforms
[DllImport("user32")]
private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
//This is used to find your winforms window
[DllImport("user32", CharSet = CharSet.Auto)]
private static extern IntPtr FindWindow(string className, string windowName);
//This is used to register custom message so that it's ensured to be unique
[DllImport("user32")]
private static extern int RegisterWindowMessage(string msgName);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsIconic(IntPtr hWnd);
TcpClient clientSocket;
string clNo;
Hashtable clientsList;
public void startClient(TcpClient inClientSocket, string clineNo, Hashtable cList)
{
this.clientSocket = inClientSocket;
this.clNo = clineNo;
this.clientsList = cList;
Thread ctThread = new Thread(doChat);
ctThread.Start();
}
private void doChat()
{
int requestCount = 0;
byte[] bytesFrom = new byte[10025];
string dataFromClient = null;
Byte[] sendBytes = null;
string serverResponse = null;
string rCount = null;
requestCount = 0;
while ((true))
{
try
{
requestCount = requestCount + 1;
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
Console.WriteLine("From client - " + clNo + " : " + dataFromClient);
int msg = 0;
IntPtr hwnd = IntPtr.Zero;
int red = RegisterColorCode(Color.Red);
//Console.WriteLine(red);
int yellow = RegisterColorCode(Color.Yellow);
//Console.WriteLine(yellow);
msg = 49806;
if (hwnd == IntPtr.Zero)
hwnd = FindWindow(null, "Winforms Application");
IntPtr hwnd1 = FindWindow(null, "ClientApp");
if (IsIconic(hwnd1)) //this if-else seems to have no effect as no color changes in the button on the winform
{
if (hwnd != IntPtr.Zero)
SetBackColor(hwnd, msg);
}
else
{
msg = 50054;
SetBackColor(hwnd, msg);
}
//SetBackColor(hwnd, msg);
//If i write only this then color changes but not on minized state its changed once and for all...
//what i want is for the previous if else condition to work**
hwnd1 = IntPtr.Zero;
rCount = Convert.ToString(requestCount);
Program.broadcast(dataFromClient, clNo, true);
hwnd = IntPtr.Zero;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}//end while
}//end doChat
static int RegisterColorCode(Color c)
{
return RegisterWindowMessage(c.ToString());
}
static void SetBackColor(IntPtr hwnd, int colorCode)
{
SendMessage(hwnd, colorCode, IntPtr.Zero, IntPtr.Zero);
}
} //end class handleClinet
}//end namespace
客户端应用程序
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
namespace chatClient
{
public partial class Form1 : Form
{
TcpClient clientSocket = new System.Net.Sockets.TcpClient();
NetworkStream serverStream;//new NetworkStream(clientSocket); //default(NetworkStream);
string readData = null;
public Form1()
{
InitializeComponent();
Text = "ClientApp";
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox2.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
private void button2_Click(object sender, EventArgs e)
{
readData = "Conected to Chat Server ...";
msg();
clientSocket.Connect("127.0.0.1", 81);
serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(textBox3.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Thread ctThread = new Thread(getMessage);
ctThread.Start();
button2.Enabled = false;
}
private void getMessage()
{
while (true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[10025];
buffSize = clientSocket.ReceiveBufferSize;
serverStream.Read(inStream, 0, buffSize);
string returndata = System.Text.Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
msg();
}
}
private void msg()
{
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(msg));
else
textBox1.Text = textBox1.Text + Environment.NewLine + " >> " + readData;
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
}
}
Winform Aplication上有按钮:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace consoleMR
{
public partial class Form1 : Form
{
[DllImport("user32")]
private static extern int RegisterWindowMessage(string msgName);
int red, yellow;
public Form1()
{
InitializeComponent();
red = RegisterColorCode(Color.Red);
yellow = RegisterColorCode(Color.Yellow);
//Set your form caption to a specified (must be unique at the time it runs)
Text = "Winforms Application";
}
private int RegisterColorCode(Color c)
{
return RegisterWindowMessage(c.ToString());
}
private const int WM_SYSCOMMAND = 0x0112;
private const int SC_MINIMIZE = 0xf020;
private const int SC_MAXIMIZE = 0xf030;
private const int SC_RESTORE = 0xF120;
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_SYSCOMMAND)
{
if (m.WParam.ToInt32() == SC_MAXIMIZE || m.WParam.ToInt32() == SC_RESTORE)
{
button1.BackColor = Color.Yellow;
this.WindowState = FormWindowState.Maximized;
return;
}
}
switch (m.Msg)
{
case 49806:
button1.BackColor = Color.Red;
return;
case 570445:
button1.BackColor = Color.Yellow;
return;
}
base.WndProc(ref m);
}
private void buttonUCT_Click(object sender, EventArgs e)
{
Process.Start("C:''Users''MainUser''Documents''Visual Studio 2010''Projects''chatServer''chatServer''bin''Debug''chatServer.exe");
}
}
}
我已经被困在这个问题上一段时间了,非常感谢任何帮助、示例代码或代码更正。。。真正的任何东西
如果我理解正确,您希望只有在最小化时才能发送更改颜色的消息。要在窗口最小化时更改颜色,请尝试:
编辑(这将查看窗口是否可见-不一定要检查它是否最小化):
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowVisible(IntPtr hWnd);
msg = REDMESSAGE;
if (hwnd == IntPtr.Zero)
hwnd = FindWindow(null, "Winforms Application");
IntPtr hwnd1 = FindWindow(null, "ClientApp");
if (IsWindowVisible(hwnd1))
{
if (hwnd != IntPtr.Zero)
SetBackColor(hwnd, msg);
}
else
{
msg = YELLOWMESSAGE;
SetBackColor(hwnd, msg);
}