-1

抱歉,标题不那么具有描述性或贴切性,但我一直在尝试这样做一段时间,但没有任何效果,它对我来说很重要。我有一个聊天服务器(控制台应用程序)和一个聊天客户端(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 应用程序:

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");
        }

    }
}

我已经坚持了一段时间了,非常感谢任何帮助或示例代码或代码更正......真的任何东西

4

1 回答 1

1

如果我理解正确,您希望能够发送消息以仅在最小化时更改颜色。要在窗口最小化时更改颜色,请尝试:

编辑(这将查看窗口是否可见 - 不确定是否已最小化):

    [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);
    }
于 2013-08-19T12:20:30.677 回答