عقدة دلفي مع html
#1
السلام عليكم
كيف يمكنني عرض صفحة html في دلفي من دون مشاكل
جربت كل من المكوننين المرفقان مع دلفي لكن دون جدوى
أشعر أن هناك شيء ما ينقصني أو حيلة
الرد
#2
وعليكم السلام ورحمة الله

لعرض صفحات HTML في تطبيقات دلفي بشكل حديث، مستقر، وخالٍ من مشاكل التوافق مع معايير HTML5/CSS3/JavaScript، أنصح بشدة باستخدام TWebView2 بدلاً من TWebBrowser التقليدي (المبني على Internet Explorer). TWebView2 هو المكون الرسمي المدعوم من إيمباركاديرو ومايكروسوفت، ويعتمد على محرك Edge (Chromium).
إليك الدليل العملي خطوة بخطوة:

? 1. المتطلبات الأساسية
دلفي 10.4 Sydney أو أحدث (الأفضل 11.x أو 12.x).
نظام تشغيل: Windows 10 أو 11 (يدعم 7/8 عبر حزمة WebView2 Runtime، لكن غير موصى به للمشاريع الجديدة).
مكتبة WebView2 مثبتة مع دلفي (تظهر تلقائياً في Tool Palette تحت تبويب Microsoft).
? 2. إضافة واستخدام TWebView2
اسحب المكون TWebView2 إلى الفورم.
في وقت التشغيل، استخدم الدالة Navigate لعرض الصفحة:

كود :
uses
  System.IOUtils, Winapi.Windows;

procedure TForm1.FormCreate(Sender: TObject);
var
  LocalHTMLPath: string;
begin
  // مثال: عرض ملف محلي من مجلد البرنامج
  LocalHTMLPath := TPath.Combine(TPath.GetDirectoryName(ParamStr(0)), 'index.html');
 
  // تحويل المسار إلى صيغة URL صحيحة
  LocalHTMLPath := 'file:///' + StringReplace(LocalHTMLPath, '\', '/', [rfReplaceAll]);
 
  WebView21.Navigate(LocalHTMLPath);
 
  // أو لعرض رابط إنترنت:
  // WebView21.Navigate('https://example.com');
end;

? 3. توزيع WebView2 Runtime على أجهزة المستخدمين
في ويندوز 10/11 الحديث: مثبت مسبقاً تلقائياً عبر Windows Update.
إذا أردت ضمان العمل على جميع الأجهزة أو الأنظمة القديمة:
حمّل WebView2 Bootstrapper من موقع مايكروسوفت وأرفقه مع برنامج التثبيت الخاص بك.
أو استخدم النسخة الثابتة Fixed Version إذا كنت تريد عزل التطبيق عن تحديثات النظام.


? 5. نصائح ذهبية لتجنب المشاكل الشائعة
✅ للملفات المحلية: استخدم دائماً بادئة file:/// وتأكد من صلاحيات القراءة.
✅ تفاعل Delphi ↔ JavaScript: استخدم WebView21.ExecuteScript() وحدث WebMessageReceived لتبادل البيانات بأمان.
✅ معالجة الأخطاء: اربط حدث NavigationCompleted للتحقق من IsSuccess قبل افتراض تحميل الصفحة.
✅ الخصوصية والأمان: عطّل الميزات غير الضرورية مثل AreDefaultScriptDialogsEnabled أو AreHostObjectsAllowed إذا لم تحتاجها.
✅ التخزين المؤقت: TWebView2 يدير الكاش تلقائياً، لكن يمكنك مسحه برمجياً عبر CoreWebView2.Profile.ClearBrowsingDataAsync عند الحاجة.


? مثال سريع للتواصل بين Delphi و JavaScript

كود :
// إرسال قيمة من Delphi إلى الصفحة
WebView21.ExecuteScript('document.getElementById("msg").textContent = "مرحباً من دلفي!";');

// استقبال رسالة من JavaScript
procedure TForm1.WebView21WebMessageReceived(Sender: TObject;
  const Args: TWebMessageReceivedEventArgs);
var
  JsonMsg: string;
begin
  JsonMsg := Args.WebMessageAsJson;
  ShowMessage('استلمت من JS: ' + JsonMsg);
end;

وفي كود HTML:


كود :
<button onclick="chrome.webview.postMessage('تم النقر!')">أرسل إلى دلفي</button>
إذا رأيت منتجاً مجانياً فأعلم بأنك أنت السّلعة
[-] كل من 2 users say قال شكرا ل الفجر الابيض على المشاركة المفيدة
  • rm31, mo7ammed
الرد
#3
شكرا على سرعة الرد
بارك الله فيك، جاري التجربة
الرد
#4
الاخ الفجر الابيض اذا امكن مثال لربط قاعدة بيانات مع HTML في الديلفي ولك جزيل الشكر
وقل ربي زدني علماً
الرد
#5
ربط قاعدة بيانات مع HTML داخل تطبيق Delphi يعتمد على الغرض من التطبيق. إذا كنت تبني تطبيق سطح مكتب تريد واجهته بلغة HTML/CSS/JS، فإن أحدث وأسهل طريقة هي استخدام مكون TEdgeBrowser (المبني على Edge WebView2) مع FireDAC للاتصال بقاعدة البيانات.
إليك مثال عملي كامل وجاهز للتشغيل:
? المتطلبات المسبقة
Delphi 10.4.2 أو أحدث (لدعم TEdgeBrowser)
تثبيت WebView2 Runtime على جهاز التطوير (مرفق عادة مع ويندوز 10/11 أو يمكن تحميله من مايكروسوفت)
مكتبة FireDAC (مدمجة افتراضياً مع دلفي)

تصميم الواجهة (Form)

كود :
unit MainForm;

interface

uses
  Winapi.Windows, System.SysUtils, System.Classes, Vcl.Forms, Vcl.StdCtrls,
  Vcl.Edge, FireDAC.Comp.Client, FireDAC.Phys.SQLite, FireDAC.Stan.Intf,
  System.JSON;

type
  TForm1 = class(TForm)
    FDConnection1: TFDConnection;
    FDQuery1: TFDQuery;
    EdgeBrowser1: TEdgeBrowser;
    BtnLoadData: TButton;
    procedure FormCreate(Sender: TObject);
    procedure BtnLoadDataClick(Sender: TObject);
    procedure EdgeBrowser1WebMessageReceived(Sender: TObject;
      const Args: TWebMessageReceivedEventArgs);
  private
    procedure CreateDemoDatabase;
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  CreateDemoDatabase;

  FDConnection1.DriverName := 'SQLite';
  FDConnection1.Params.Values['Database'] := ExtractFilePath(ParamStr(0)) + 'demo.db';
  FDConnection1.LoginPrompt := False;

  try
    FDConnection1.Connected := True;
  except
    on E: Exception do
      ShowMessage('خطأ في الاتصال: ' + E.Message);
  end;
end;

procedure TForm1.CreateDemoDatabase;
var
  DBPath: string;
begin
  DBPath := ExtractFilePath(ParamStr(0)) + 'demo.db';
  if not FileExists(DBPath) then
  begin
    FDConnection1.DriverName := 'SQLite';
    FDConnection1.Params.Values['Database'] := DBPath;
    FDConnection1.Connected := True;
    FDConnection1.ExecSQL('CREATE TABLE Employees (ID INTEGER PRIMARY KEY, Name TEXT, Dept TEXT)');
    FDConnection1.ExecSQL('INSERT INTO Employees VALUES (1, "أحمد محمد", "تقنية المعلومات")');
    FDConnection1.ExecSQL('INSERT INTO Employees VALUES (2, "سارة علي", "الموارد البشرية")');
    FDConnection1.ExecSQL('INSERT INTO Employees VALUES (3, "خالد حسن", "المحاسبة")');
    FDConnection1.Connected := False;
  end;
end;

procedure TForm1.BtnLoadDataClick(Sender: TObject);
var
  HTML: string;
  RowHTML: string;
  ID, Name, Dept: string;
begin
  FDQuery1.Close;
  FDQuery1.SQL.Text := 'SELECT ID, Name, Dept FROM Employees ORDER BY ID';
  FDQuery1.Open;

  HTML := '<!DOCTYPE html>' +
          '<html lang="ar" dir="rtl">' +
          '<head><meta charset="UTF-8"><title>بيانات الموظفين</title>' +
          '<style>body{font-family:Segoe UI,sans-serif;padding:20px;background:#f5f7fa;}' +
          'table{width:100%;border-collapse:collapse;background:#fff;box-shadow:0 2px 8px rgba(0,0,0,0.1);}' +
          'th,td{padding:12px;border:1px solid #ddd;text-align:center;}' +
          'th{background:#4a90e2;color:#fff;}tr:hover{background:#f0f4f8;}' +
          'button{padding:10px 20px;margin-top:20px;cursor:pointer;background:#27ae60;color:#fff;border:none;border-radius:6px;}' +
          '</style></head><body>' +
          '<h2>? جدول الموظفين</h2>' +
          '<table><tr><th>المعرف</th><th>الاسم</th><th>القسم</th></tr>';

  while not FDQuery1.Eof do
  begin
    ID   := FDQuery1.FieldByName('ID').AsString;
    Name := FDQuery1.FieldByName('Name').AsString;
    Dept := FDQuery1.FieldByName('Dept').AsString;

    // حماية بسيطة من حقن HTML
    Name := StringReplace(Name, '<', '&lt;', [rfReplaceAll]);
    Dept := StringReplace(Dept, '<', '&lt;', [rfReplaceAll]);

    RowHTML := Format('<tr><td>%s</td><td>%s</td><td>%s</td></tr>', [ID, Name, Dept]);
    HTML := HTML + RowHTML;
    FDQuery1.Next;
  end;

  HTML := HTML + '</table>' +
          '<button onclick="window.chrome.webview.postMessage(''refresh'')">? تحديث البيانات</button>' +
          '<script>function addLog(m){window.chrome.webview.postMessage(m);}</script>' +
          '</body></html>';

  EdgeBrowser1.NavigateToString(HTML);
end;

procedure TForm1.EdgeBrowser1WebMessageReceived(Sender: TObject;
  const Args: TWebMessageReceivedEventArgs);
var
  Msg: string;
begin
  if Args.TryGetWebMessageAsString(Msg) then
  begin
    if Msg = 'refresh' then
      BtnLoadDataClick(Sender);
  end;
end;

end.


FireDAC + SQLite
اتصال خفيف لا يحتاج تثبيت خادم قواعد بيانات منفصل
NavigateToString
يعرض كود HTML مباشرة دون الحاجة لخادم ويب أو ملفات خارجية
window.chrome.webview.postMessage
قناة آمنة لإرسال رسائل من JavaScript إلى Delphi
OnWebMessageReceived
يستقبل الرسائل وينفذ إجراءات دلفي (مثل التحديث)
StringReplace لحماية من XSS
يمنع إدخال وسوم HTML خبيثة عبر بيانات القاعدة


ملاحظات إنتاجية هامة
استخدم Parameterized Queries بدلاً من SQL.Text := ... لمنع SQL Injection في المشاريع الحقيقية.
لتشفير قواعد بيانات SQLite، فعّل FDQuery1.Params.Values['SQLiteDriverID'] := 'SQLite'; واستخدم Password=yourkey.
إذا كنت تستخدم قواعد أخرى (MySQL, SQL Server, PostgreSQL)، غيّر DriverName وأضف مكتبة FireDAC.Phys.MySQL أو المماثل، وعدّل Params فقط.
إذا رأيت منتجاً مجانياً فأعلم بأنك أنت السّلعة
[-] كل من 2 users say قال شكرا ل الفجر الابيض على المشاركة المفيدة
  • أبو معاذ, bouh25
الرد


التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم