Тема: Як звернутись до елементу форми з своєї dll?
Привітульки. Значить є проект ВіндовсФорм. В цьому проекті є звичайний клас, котрий призначений для працювання з контролами форми, і є клаc Server, котрий є сервером. Так от, при натисканні на кніпочку в класі форми, створюється новий об'єкт Server, цьому серверу передається посилання на цю форму, і тепер він може управляти контролами форми. Але цей сервер є асинхронним, і до контролів форми необхідно звертатись з інших потоків, для цього я використовую делегат та метод Invoke. Також є деяка dll, котра має необхідні класи, з котрими працює сервер, і в методах класів, котрі описані в dll необхідно звертатись до контролів форми. От я ніяк не можу зрозуміти, як дати знати тій dll, що існує деяка форма Form1, і що в ній є RichTextBox з іменем rtbSystemMessage. От код форми
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GameServer.GServer;
namespace GameServer
{
public partial class Form1 : Form
{
private Server server;
public Form1()
{
InitializeComponent();
statusLabel.ForeColor = Color.Red;
statusLabel.Text = "Stoped.";
}
private void btnStart_Click(object sender, EventArgs e)
{
if (server == null)
{
server = new Server(int.Parse(tbPort.Text), this);
server.Start();
statusLabel.Text = "Running...";
statusLabel.ForeColor = Color.GreenYellow;
}
}
private void btnStop_Click(object sender, EventArgs e)
{
if (server.IsRunning)
{
server.Stop();
statusLabel.ForeColor = Color.Red;
statusLabel.Text = "Stoped.";
}
}
}
}
От клас Server
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using SCdll;
namespace GameServer.GServer
{
class Server
{
private delegate void Del();
private int _port;
private Socket _socket;
private MySqlConnection _mySqlConnection;
private string _db_connect;
private List<Client> clients;
private Form1 form;
private bool serverStatus;
public bool IsRunning
{
get { return serverStatus; }
set { serverStatus = value; }
}
public Server(int port, Form1 form)
{
serverStatus = false;
_port = port;
_db_connect = "Database=supercourse;Data Source=localhost;User Id=root;Password=пуроль))0";
clients=new List<Client>();
this.form = form;
}
public void Start()
{
_socket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
EndPoint _endPoint = new IPEndPoint(IPAddress.Any,_port);
_socket.Bind(_endPoint);
_socket.Listen((int) SocketOptionName.MaxConnections);
_socket.BeginAccept(new AsyncCallback(AcceptCallback), _socket);
IsRunning = true;
}
public void Stop()
{
foreach (var client in clients)
{
client.socket.Shutdown(SocketShutdown.Both);
client.socket.Close();
}
clients.Clear();
IsRunning = false;
}
private void AcceptCallback(IAsyncResult result)
{
try
{
Socket acceptSocket = (Socket)result.AsyncState;
Client client = new Client();
client.socket = (Socket)acceptSocket.EndAccept(result);
lock(clients) clients.Add(client);
AddSystemMessage("New client has been added");
client.socket.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None,
new AsyncCallback(ReceiveCallback), client);
_socket.BeginAccept(new AsyncCallback(AcceptCallback), _socket);
}
catch (Exception e)
{
AddSystemMessage(e.Message);
}
}
private void ReceiveCallback(IAsyncResult result)
{
try
{
Client client = (Client) result.AsyncState;
int nBytes = client.socket.EndReceive(result);
if (nBytes > 0)
{
AddSystemMessage("Received: " + nBytes + " bytes");
lock (clients)
{
foreach (var client1 in clients)
{
if (client1.socket != client.socket)
client1.socket.Send(client.buffer, nBytes, SocketFlags.None);
}
}
}
client.socket.BeginReceive(client.buffer, 0, client.buffer.Length, SocketFlags.None,
new AsyncCallback(ReceiveCallback), client);
}
catch (SocketException e)
{
AddSystemMessage(e.Message + " ErrorCode: " + e.ErrorCode.ToString());
}
catch (Exception e)
{
AddSystemMessage(e.Message);
}
}
public void AddSystemMessage(string message)
{
form.rtbSystemMessage.Invoke(new Del(() => form.rtbSystemMessage.AppendText(message + "\n")));
}
}
}
А озьдо код dll'ки
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
namespace SCdll
{
public delegate void Del();
public class Client
{
public byte[] buffer = new byte[1024];
public Socket socket;
public double userId;
}
public class Character
{
private readonly double char_id;
private readonly string nick;
private readonly float pos_x;
private readonly float pos_y;
private readonly float pos_z;
private readonly double user_id;
public Character(double userId, double charId, string nick, float posX, float posY, float posZ)
{
user_id = userId;
char_id = charId;
this.nick = nick;
pos_x = posX;
pos_y = posY;
pos_z = posZ;
}
public double UserId
{
get { return user_id; }
}
public double CharId
{
get { return char_id; }
}
public string Nick
{
get { return nick; }
}
public float PosX
{
get { return pos_x; }
}
public float PosY
{
get { return pos_y; }
}
public float PosZ
{
get { return pos_z; }
}
}
public interface ICommand
{
void Execute(Client client);
}
public abstract class SQLString : ICommand
{
protected MySqlConnection connection = new MySqlConnection();
private string connectionString = "Database=supercourse;Data Source=localhost;User Id=root;Password=пуроль))0";
public virtual void Execute(Client client)
{
}
}
public class Login : SQLString
{
private readonly string login;
private readonly string password;
private double cmdId;
public Login(string login, string password)
{
this.login = login;
this.password = password;
cmdId = 0;
}
public override void Execute(Client client)
{
string request = "call SP_LogIn(" + "'" + login + "'" + "," + "'" + password + "'" + ")";
var myCommand = new MySqlCommand(request, connection);
int value = 0;
try
{
Console.WriteLine("trying open connection to db");
connection.Open();
value = Int32.Parse(myCommand.ExecuteScalar().ToString());
connection.Close();
Console.WriteLine("value = " + value);
Console.WriteLine("done sending req to bd. Value = " + value);
client.userId = value;
}
catch (Exception e)
{
connection.Close();
Console.WriteLine(e.Message);
}
/*bw.Write("lgn"); //Encoding.UTF8.GetBytes("lgn").CopyTo(bf, 0);
bw.Write(value); //BitConverter.GetBytes(value).CopyTo(bf, 10);
bw.Flush();*/
}
}
public class dll
{
private readonly Form1 form = new Form1();
public void AddSystemMessage(string message)
{
form.rtbSystemMessage.Invoke(new Del(() => form.rtbSystemMessage.AppendText(message + "\n")));
}
public BinaryReader createReader(Client client)
{
return new BinaryReader(new MemoryStream(client.buffer));
}
public BinaryWriter createWriter(Client client)
{
return new BinaryWriter(new BufferedStream(new NetworkStream(client.socket)), Encoding.UTF8);
}
}
}
Як бачите, метод
public void AddSystemMessage(string message)
{
form.rtbSystemMessage.Invoke(new Del(() => form.rtbSystemMessage.AppendText(message + "\n")));
}
та делегат
public delegate void Del();
описані як в dll, так і на сервері, саме цей метод необхідно винести в dll.