السلام
في انتظار اخينا عبد الحق الذي كان متحمسا للمشرع فارجو ان يبقى .
قمت بتحسين الواجة WPF بإظافة Style
اما في الدلفي سارى كيف سنحسن الواجة دون تثبيت مكوناة
السلام
في انتظار اخينا عبد الحق الذي كان متحمسا للمشرع فارجو ان يبقى .
قمت بتحسين الواجة WPF بإظافة Style
اما في الدلفي سارى كيف سنحسن الواجة دون تثبيت مكوناة
السلام عليكم
المشرعين ب WPF / DELPHI
في المرفقات
لكن اخينا عبد الحق اطال علينا نريد ان نكملالخطوة الموالية
السلام عليكم
ما شاء الله اخ زكيري من المتابعين
استسمحك عذرا على الغياب و الاطالة
حسنا اخ زكيري ممكن تضع اين وصلت و الخطوات القادمة ...
ملاحظة: ارجو ان تحافظ على اسم معين في الملفات و تريقيمها
للتنظيم و حسب
PartageFilesManager_1.rar
PartageFilesManager_2.rar
+ ذكر بعض المعلومات مثل
التغيير حاصل في الـ Client او في Server أخ زكيري إستخدمت نسخة XE ام Delphi 10
حتى يكون العمل على اكمل وجه
و السلام عليكم و رحمة الله
تم تعديل هذه المشاركة بواسطة M.Abdelhak في 11 أغسطس 2011 في 23:30
السلام عليكم
انا في الحقيقة لم اضف شء سو تغيير الواجهة فقط اردت ان اضع نفس الواجهة التي عملتها ب WPF على الدلفي.
كما تعلم اني اتعلم wpf .
اما عن الاصدرات موافق عندك الحق في اضافة 1 - 2- 3- ....
نسخة XE
اقتباسالتغيير حاصل في الـ Client او في Server
انا كما قلت ساعمل على السرفيس web service لكني اريد ان تقدم لي بالتفصيل التوابع التي يجب اضافتها لقد قمت سوى اتابعين فقط
السلام عليكم
ربما الكود غير واظح مما جعل عدد المشاركات في المشروع منعدمة لذا ساشرح كل شي بتالفصيل
اقتباسالمشروع ينقسم الى قسمين برنامج تنفيذي Client.exe يشغل في اجهزة المستعملين واخر عبارة عن خدة ويب ServiceWebISAPI .تقدم معلمات حول السجلات المجودة في القاعدة ويوظع هذا المشروع مع القاعدة مثلا في جهاز الخادم
1- Client.exe
------------------------------------------------------------------------------
DELPHI
------------------------------------------------------------------------------
وظعنا به الوحة UMain.pas + UMain.dfm وهي الوجهة الرئيسة للمشروع
procedure CharegInDataSet(sFListFiles:Tlist;sGrid: TDBGrid);overload; procedure CharegInDataSet(sFListFiles:ArrayOfCFile;sGrid: TDBGrid);overload;
الهدف من التابعين هو قرائة القائمة sFListFiles وضع امعلمات في DBGRID مرورا طبعا عبر DATASET
procedure TForm1.FormCreate(Sender: TObject);
begin
//********************* Get Files from Directory **************************
CharegInDataSet(_ufile.GetDirectoryContents(GetCurrentDir + c_SHARED),DBGrid1);
//********************* Get Files from WebService *************************
CharegInDataSet(GetServiceSoap.ShowAllFileinfo(),DBGrid2);
end;1- نلاحظ اننا قمنا باحظار القامة من التابع GetDirectoryContents وهو تابع static موجود في الصنف _uFile للوحدة UFile : قرائة الملفات من المجلد المحدد.
2- نلاحظ اننا قمنا باحظار القامة من التابع ShowAllFileinfo موجود في ل لوحدة UService وهي الناتجة WSDLعن استراد او الربط بخدمة الويب.
procedure TForm1.BtnSearchClick(Sender: TObject);
begin
CharegInDataSet(GetServiceSoap.SearchFileinfobyName(Edit1.Text),DBGrid2);
end;نلاحظ اننا قمنا باحظار القامة من التابع SearchFileinfobyName باعطاء اسم الملف المار اجاده ...موجود في ل لوحدة UService وهي الناتجة WSDLعن استراد او الربط بخدمة الويب.
---------------------------------------------------------------------
اما في WPF c#
---------------------------------------------------------------------
private UService.CFile[] _DlistFiles;
public UService.CFile[] DListFiles { get { return this._DlistFiles; } }
private List<CFile> _FlistFiles;
public List<CFile> FListFiles { get { return this._FlistFiles; } }
public MainVm()
{
_FlistFiles = uFile.GetDirectoryContents("C:\\Shared");
_DlistFiles = (new UService.Service()).ShowAllFileinfo();
_DlistFiles = (new UService.Service()).SearchFileinfobyName(sName); <ListView ItemsSource="{Binding DListFiles}"راجع الدرس عن طريقة ربط ListView
تم تعديل هذه المشاركة بواسطة زكيري عبد العالي في 17 أغسطس 2011 في 11:34
2- webservice
نجد التوابع التالية
-------------------------------------
Delphi
-------------------------------------
function Tservice.AppendNewFileinfo(sFile: UFile.CFile): string;
var
conn: uSqlconn.SqlConn;
begin
try
conn := uSqlconn.SqlConn.Create();
if (conn.Connect()) then
begin
conn.nonQueryOrder(Format(' INSERT INTO TFile (Name, Type, Size)' +
' VALUES (''%s'',''%s'',%d)', [sFile.FileName, sFile.FileType,
sFile.FileSize]));
end;
Result := '';
finally
conn.Free;
end;
end;
function Fill(sqlDs: TADODataSet): serviceIntf.List<CFile>;
var
olistFile: serviceIntf.List<CFile>;
I: Integer;
begin
SetLength(olistFile, sqlDs.RecordCount);
for I := 0 to sqlDs.RecordCount - 1 do
begin
sqlDs.RecNo := I;
olistFile := CFile.Create(sqlDs.FieldByName('Name').Value,
sqlDs.FieldByName('Type').Value, sqlDs.FieldByName('Size').Value);
end;
Result := olistFile;
end;
function Tservice.ShowAllFileinfo(): serviceIntf.List<CFile>;
var
conn: uSqlconn.SqlConn;
begin
try
conn := uSqlconn.SqlConn.Create();
if (conn.Connect()) then
begin
conn.Remplir('select * from Tfile');
Result := Fill(conn.sqlDs);
end;
finally
conn.Free;
end;
end;
function Tservice.SearchFileinfobyName(sName: string): serviceIntf.List<CFile>;
var
conn: uSqlconn.SqlConn;
begin
try
conn := uSqlconn.SqlConn.Create();
if (conn.Connect()) then
begin
conn.Remplir('select * from Tfile where Name Like ''%''' + sName +
'''%'' ');
Result := Fill(conn.sqlDs);
end;
finally
conn.Free;
end;
end;---------------------------
C#
---------------------------
[WebMethod]
public string AppendNewFileinfo(UFile.CFile sFile)
{
USqlConn.SqlConn conn = new USqlConn.SqlConn();
if (conn.Connect())
{
conn.nonQueryOrder(string.Format(" INSERT INTO TFile (Name, Type, Size)" +
" VALUES (''{0}'',''{1}'',{2})",
sFile.FileName, sFile.FileType, sFile.FileSize
));
}
return "";
}
public List<CFile> Fill(DataSet sqlDs)
{
List<CFile> olistFile = new List<CFile>();
foreach (DataRow row in sqlDs.Tables[0].Rows)
{
olistFile.Add(new CFile(
row["Name"].ToString(),
row["Type"].ToString(),
int.Parse(row["Size"].ToString())
));
}
return olistFile;
}
[WebMethod]
public List<CFile> ShowAllFileinfo()
{
USqlConn.SqlConn conn = new USqlConn.SqlConn();
if (conn.Connect() == true)
{
conn.Remplir("select * from Tfile");
return Fill(conn.SqlDs());
}
else
{
return null;
}
}
[WebMethod]
public List<CFile> SearchFileinfobyName(string sName)
{
USqlConn.SqlConn conn = new USqlConn.SqlConn();
if (conn.Connect() == true)
{
conn.Remplir("select * from Tfile where Name Like '%" + sName + "%' ");
return Fill(conn.SqlDs());
}
else
{
return null;
}
}اكود واظح اتصال بالقاعدة تنفيذ استعلام جعل النتجية في قائمة اشياء CFile
3- Common
1- StrConnection.UDL ملف اعدادات الاتصال بالقاعدة
2- UFile.pas :
نجد في هذه الوحد ة كل من الصنف
Cfile
Cfile = class(TRemotable) private _FileName : string; private _FileType : string; private _FileSize : real; public property FileName : string read _FileName write _FileName; public property FileType : string read _FileType write _FileType; public property FileSize : real read _FileSize write _FileSize; public constructor Create(); overload ; public constructor Create( sName:string ; sType:string ; sSize:real ) ; overload ; end;
[Serializable]
public class CFile
{
public string FileName { get; set; }
public string FileType { get; set; }
public double FileSize { get; set; }
public CFile(){ }
public CFile(string sName, string sType, double sSize)
{
this.FileName = sName;
this.FileType = sType;
this.FileSize = sSize;
}
}وهي التي نستطيع ارسالها علي شكل XML لانها كلس Serializableb وهي تمثل ملف واحد
_uFile
_uFile = class(TRemotable)
Class function GetDirectoryContents(const StrPath : String):TList;
end;واظحة اظن
3-USqlConn
نجد في هذه الوحدة الصنف SqlConn المسؤول عن الربط بالقاعدة
SqlConn = class (TRemotable)
private _sqlDs : TADODataSet;
private _sqlCnx : TADOConnection;
private _sqlCmd : TADOQuery;
// private SqlTransaction _sqlTransac;
public property sqlDs : TADODataSet read _sqlDs write _sqlDs;
public property sqlCnx : TADOConnection read _sqlCnx write _sqlCnx;
public property sqlCmd : TADOQuery read _sqlCmd write _sqlCmd;
public Constructor Create();
public Function Connect():Boolean;
public Function Disconnect():Boolean;
public Function nonQueryOrder(sSQL : string):Boolean;
public Function Remplir(sSQL : string): string;
end;........ public class SqlConn
{
private int _iNbRows;
private int _iNbCols;
private OleDbConnection _sqlCnx;
private OleDbCommand _sqlCmd;
private OleDbDataReader _sqlReader;
private OleDbTransaction _sqlTransac;
private OleDbDataAdapter _sqlDA;
private DataSet _sqlDs;
.......تم تعديل هذه المشاركة بواسطة زكيري عبد العالي في 17 أغسطس 2011 في 12:01
السلام عليكم
لم انتبه لشيئ هو اني استغلت خدمة الواب المعمولة بسي شارب في كلا المشروعين اسف .
لذلك اظفت واجهة تنفذية مع سرفر indy خاص على 8080 عوض ISAPI العادي فلاداعي ل تثبيت IIS
وهكذا الكل يستطيع المتابع وتجريب الكود اضفت
ايضا ملف log لمتابعة اداء السرفر
تم تعديل هذه المشاركة بواسطة زكيري عبد العالي في 17 أغسطس 2011 في 17:48
السلام عليكم
كنت اعتقد ان المشروع مهم فكتبته باللغتين لكن ????
المهم لقد اظفة جدولا جديد في القاعدة حيث سنخزن فيه معوماة المستعمل password user ...ex و الجهاز مثل IP MachineNAme ...ex . سنظيف لاحقا جدول الصلاحياة
اظفت كلس جديدة لتعامل مع هدا الجدول وهي
Common
CUser = class(TRemotable)
private _UserID_IP : WideString;
private _UserName : WideString;
private _PassWord : WideString;
private _PcName : WideString;
private _NBFiles : Integer;
private _Files : List<CFile>;
published
property UserID_IP : WideString read _UserID_IP write _UserID_IP;
property UserName : WideString read _UserName write _UserName;
property PassWord : WideString read _PassWord write _PassWord;
property PcName : WideString read _PcName write _PcName;
property NBFiles : Integer read _NBFiles write _NBFiles;
property Files : List<CFile> read _Files write _Files;
public constructor Create(); overload ;
public constructor Create( sUserID_IP,sUserName,sPassWord,sPcName:WideString;sFiles:List<Cfile>) ; overload ;
end;
List<CUser> = array of CUser; [Serializable]
public class CUser
{
public string UserID_IP { get; set; }
public string UserName { get; set; }
public string PassWord { get; set; }
public string PcName { get; set; }
public int NBFiles { get; set; }
public List<UFile.CFile> Files { get; set; }
public CUser() { }
public CUser(string sUserID_IP, string sUserName, string sPassWord, string sPcName, List<UFile.CFile> sFiles)
{
this.UserID_IP = sUserID_IP;
this.UserName = sUserName;
this.PassWord = sPassWord;
this.PcName = sPcName;
this.Files = sFiles;
if (sFiles != null) {this.NBFiles = sFiles.Count;}
}
}ServiceWeb
واظفت تابع ميتود جديدة في خدمة الويب لجلب معلوماة المستعملين
function Tservice.ShowAllUser: User.List<CUser>;
var
conn: uSqlconn.SqlConn;
begin
conn := uSqlconn.SqlConn.Create();
try
if (conn.Connect()) then
begin
conn.Remplir('select * from TUserPC');
Result := UsersFill(conn.sqlDs);
end;
finally
conn.Free;
end;
end;[WebMethod]
public List<CUser> ShowAllUser()
{
USqlConn.SqlConn conn = new USqlConn.SqlConn();
if (conn.Connect() == true)
{
conn.Remplir("select * from TUserPC");
return UsersFill(conn.SqlDs());
}
else
{
return null;
}
}Client
واخيرا عرض النتيجة في الواجهة
procedure TForm1.CharegUserInDataSet(sFListUsers: List_User_CUser_; sGrid: TDBGrid);
var
I:integer;
ClData : TClientDataSet;
begin
ClData := TClientDataSet.Create(nil);
ClData.FieldDefs.Add('UserID_IP',ftString,30,false);
ClData.FieldDefs.Add('UserName' ,ftString,30,false);
ClData.FieldDefs.Add('PcName' ,ftString,30,false);
ClData.FieldDefs.Add('NBFiles' ,ftString,30,false);
ClData.CreateDataSet;
for I := 0 to Length(sFListUsers)-1 do
begin
ClData.Append;
ClData.FieldByName('UserID_IP').value :=CUser(sFListUsers).UserID_IP;
ClData.FieldByName('UserName').value :=CUser(sFListUsers).UserName;
ClData.FieldByName('PcName').value :=CUser(sFListUsers).PcName;
ClData.FieldByName('NBFiles').value :=inttostr(CUser(sFListUsers).NBFiles);
ClData.Post;
end;
ClData.Open;
sGrid.DataSource:=TDataSource.Create(nil);
sGrid.DataSource.DataSet:=ClData;
end; private UService.CUser[] _FlistUsers;
public UService.CUser[] FListUsers { get { return this._FlistUsers; } }
public MainVm()
{
this._FlistFiles = uFile.GetDirectoryContents("C:\\Shared");
this._FlistUsers = oService.ShowAllUser();
OnPropertyChanged("FListUsers");
}تم تعديل هذه المشاركة بواسطة زكيري عبد العالي في 18 أغسطس 2011 في 21:16
السلام عليكم
لقد اضفة التابع في خدمت الويب اضفت استدعاءها علي مسوى الزبون" غند تحديد الزبون نعرض ملفاته"
اظفت حقل جديد لمعرفة انكان المستعل متصل او لا كما عرظتها في شكل صورة
delphi
function Tservice.SearchFileByUser(sUserID_IP: string): UFile.List<CFile>;
var
conn: uSqlconn.SqlConn;
begin
conn := uSqlconn.SqlConn.Create();
try
if (conn.Connect()) then
begin
conn.Remplir(Format('select * from Tfile where UserID_IP =''%S'' ',[sUserID_IP]));
Result := FilesFill(conn.sqlDs);
end;
finally
conn.Free;
end;
end;procedure TForm1.DgFListUsersDrawColumnCell...........
var
bitmap : TBitmap;
begin
if (Column.Title.Caption ='') then
begin
bitmap := TBitmap.Create;
try
if (DsFListUsers.DataSet.FieldByName('Active').Value) then
Bitmap.LoadFromFile('..\..\Styles\Images\Active.Bmp')
else
Bitmap.LoadFromFile('..\..\Styles\Images\DActive.Bmp');
DgFListUsers.Canvas.StretchDraw(Rect,bitmap);
finally
bitmap.Free;
end;
end;
end;c#- XAML
[WebMethod]
public List<CFile> ShowFilesByUser(string sUserID_IP)
{
USqlConn.SqlConn conn = new USqlConn.SqlConn();
if (conn.Connect() == true)
{
conn.Remplir(string.Format("select * from Tfile where UserID_IP = '{0}'", sUserID_IP));
return FilesFill(conn.SqlDs());
}
else
{
return null;
}
} <GridViewColumn Header="Active" Width="20">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding Path=ActiveIcon}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>if (sActive) { this.ActiveIcon = @"/Client;component/Styles/images/Active.JPG"; }
else { this.ActiveIcon = @"/Client;component/Styles/images/DActive.JPG"; }تم تعديل هذه المشاركة بواسطة زكيري عبد العالي في 25 أغسطس 2011 في 15:21
لقد انتهينا من وضع الخدمت وبرمجة الزبون و التعامل مع القاعدة و عنذما نريد اضافة تابع جديد نضيفه بسهولة لان المشروع عبارة عنطبقات منفصلة 3-tier
لم يبقي الا اضافة الصلاحيات و اضافة لب الموضوع وهو انتقال الملفات من الزبون الى زبون اخر P2p في الحقيقة لم استعملها من قبل لكن اضن اننا سنستعمل WCF في الدوتنت و indy دلفي .
ارجوا المشاركة شكرا
السلام عليكم
اخي عبد الحق هل انت مت اكد من وجو د طرية P2P زبون زبون دون الحاجة الي خادم كواسطة.
prof_1982
اقتباسانا اقترح ان يكون عمله كالتالي :1- في جهة الكلاينت ان يقوم بعمل حساب جديد يوزر و باسورد
2- ان يكون هناك عملية تسجيل دخول
3- ان يكون هناك قائمة بالاعضاء الموجودين Online
4- ان يتم تحديد الشخص المراد ارسال الملف له ثم يتم تحديد الملف وارسالة request للعضو الاخر يطلب فيها قبول او رفض الملف .
هذا مبدئيا
التطويرات المستقبلة :
1- ان يكون هناك امكانية تحديد مجلد مشاركة عند كل عضو ويمكن الاطلاع علي ما بداخله عند الجميع .
2- ممكن تطوير امكانية محاثة نصية خفيفة بين الاعضاء .
هذا ما جاد به عقلي حتي هذه اللحظة
بما آني لم اجد مثال عن P2P زبون زبون والاخ عبد الحق غائب عنا لكي يوضح الامر اكثر وخوفا من توقف المشروع كالعادة
ساظع النقاط التاية وحسب اقتراح الاستاذ prof_1982
لمن يريد المشاركة سواء دلفي او سي شارب
ان يكون هناك عملية تسجيل دخول
-1 اظافة نافذة جدية في مشروع الزبون .
2- التحقق من كلمة السر تكون باظافة تابع webservice للخدة الويب GetUser مثلا حيث ترجع لنا هل الزبون مسجل او لا .
3- Active تحديث الحق الي true في حالت نجاح الاتصال
في جهة الكلاينت ان يقوم بعمل حساب جديد يوزر و باسورد
1-اظهاظافة فور التسجيل حث
2-نظيف تابع يقوم تسجيلالمعلماة في القاعدة webservice AddNewUser
المجام مفتوح للنقاش
تم تعديل هذه المشاركة بواسطة زكيري عبد العالي في 26 أغسطس 2011 في 17:05
السلام عليكم
اسف ان كنت سأخيب ضنك لكني لا استطيع الاكمال في المشروع لعدة ضروف ان شاء الله عندما اجد الوقت المناسب سأعيد احياءه اتوقع
ان تنهيه لوحدك ما شاء الله اخ زكيري
بالنسبة اذا كنت نجحت في تسجيل الاي بي في قاعدة البيانات و تسجيل الملف (اسم الملف)
الان عندما يريد عميل ما تحميل ملف كل ما عليه هو اخذ الاي بي و اسم الملف و طلب ارسال الملف
اعتقد ان حتى البرامج العالمية تعمل لطريقة P2p في نقل الملفات و هناك عدة دلائل على ذلك
بالتوفيق لك و للجميع
اخ زكيري انت اعتمدت على مكونات الاندي صح
على ما اعلم لا يمكن ارسال من client ل client بالعتماد على مكون IndyTCPClient
لذلك الحل ان تضع الاثنان معا IndyTCPClient و IndyTCPServer ....
اقتباساعتقد ان حتى البرامج العالمية تعمل لطريقة P2p في نقل الملفات و هناك عدة دلائل على ذلك
نعم لم اقل العكس حتى skyp المطور بالدلفي يعتمد على P2P لكن هناك محطة يمر بها الملف قبل الوصول المستقبل .
زكيري عبد العالي كتب:نعم لم اقل العكس حتى skyp المطور بالدلفي يعتمد على P2P لكن هناك محطة يمر بها الملف قبل الوصول المستقبل .
نعم جميع البرامج العالمية بداية كانت تستخدم طريقة p2p مثلا برنامج Msn قديما كان الارسال يتم مباشرة ثم تم تطويره و جعلت البرامج العالمية كل شيئ يمر على سيرفر
و ذلك بغية حماية المستخدم فمثلا في برنامج msn لم يعد بمقدورك الان الحصول على ip المتصل بك و ذلك كما قلت لغرض الحماية اسهل طريقة هي p2p كما قلت و هي الانفع للمشروع
بالرك الله فيك لكن لم اجد مثال توضيحي و لم يسبق لى ان استخدمت P2P هل لك ان تدلني على مصدر او مثال بسيط في الدلفي او لعة اخر الهم افهم القاعدة .
شكرا .
على شرط p2p CLIENT - CLIENT . و ليس CLIENT SERVER
شكرا
ارجوا ان تعود لنا بسعرة فاني اشعر بالممل لوحدي حتى استاذنا prof_1982 لم يشارك الى حد اللان
زكيري عبد العالي كتب:على شرط p2p CLIENT - CLIENT . و ليس CLIENT SERVER
client client صعبة
لان مكون الاندي tcpclient غير مجهز للتنصت و لذلك افضل حل كما قلت ان تجعل الاثنين معا مكون كلينت و مكون سيرفر
و بالتالي يكون البرنامج قادر على استقبال الاتصالات باستخدام مكون السيرفر و قادر على انشاء اتصال باستخدام مكون كلينت
لا ادري ان كان مكون الكلينت قد تم تطويره ليتعامل مع الـ thread المعلوم ان السيرفر يفعل ذلك في مكونات اندي 9 و 10 اعتقد ان الان مكونات الاندي تتعامل جميعا
مع الـ thread و هذا ما سيسهل العملية
اما عملية ارسال ملف فهي سهلة و يوجد العديد من الامثلة و الاكواد الجاهزة
المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية
جارٍ التحقق من المتواجدين…