سؤال

أنا أفكر في إنشاء تطبيق WPF أو Silverlight يعمل تماما مثل نافذة الطرفية. إلا، لأنه في WPF / Silverlight، سيكون قادرا على "تعزيز" تجربة الطرفية مع الآثار والصور، إلخ.

أحاول معرفة أفضل طريقة لمحاكاة المحطة. أعرف كيفية التعامل مع محاكاة VT100 بقدر التحليل، وما إلى ذلك ولكن كيف تعرضها؟ كنت أعتبر استخدام RichTextBox وتحويل رموز Escape VT100 في RTF.

المشكلة التي أراها مع ذلك هو الأداء. قد تحصل المحطة على عدد قليل فقط من الأحرف في كل مرة، وأن تكون قادرا على تحميلها في مربع النص كما نذهب لأنني ستقوم باستمرار بإنشاء Textranges واستخدام الحمل () لتحميل RTF. أيضا، من أجل اكتمال كل "جلسة تحميل"، يجب أن تصف بالكامل RTF بالكامل. على سبيل المثال، إذا كان اللون الحالي أحمر، فستحتاج كل تحميل في مربع النص إلى رموز RTF لجعل النص أحمر، أو افترض أن RTB لن يتم تحميله باسم أحمر.

يبدو هذا زائدة جدا - ستكون وثيقة RTF الناتجة التي بنيت من المضاهاة فوضوي للغاية. أيضا، لا يبدو حركة Caret كما أنه سيتم التعامل مع RTB بشكل مثالي. أحتاج إلى شيء مخصص، methinks، ولكن هذا يخيفني!

على أمل سماع أفكار أو مؤشرات مشرقة للحلول الحالية. ربما هناك طريقة لتضمين محطة فعلية وتراكب على رأسها. الشيء الوحيد الذي وجدته هو عنصر تحكم قديم WinForms.

تحديث: معرفة كيفية فشل الحل المقترح بسبب Perf في إجابتي أدناه. :(

VT100 محاكاة المحطة في نظام التشغيل Windows WPF أو Silverlight

هل كانت مفيدة؟

المحلول

إذا حاولت تطبيق ذلك باستخدام RichTextBox و RTF، فسوف تعمل بسرعة في العديد من القيود وتجد نفسك تقضي المزيد من الوقت في العمل حول الاختلافات أكثر مما إذا قمت بتنفيذ الوظيفة بنفسك.

في الواقع، من السهل جدا تطبيق مضاهاة محطة VT100 باستخدام WPF. أعلم أنه الآن الآن قمت بتنفيذ محاكي VT100 الكامل تقريبا في ساعة أو نحو ذلك. أن تكون دقيقا، وأنا تعتبر كل شيء باستثناء:

  • إدخال لوحة المفاتيح،
  • مجموعات الأحرف البديلة،
  • عدد قليل من أوضاع VT100 الباطنية التي لم أرها أبدا،

الأجزاء الأكثر إثارة للاهتمام كانت:

  • أحرف العرض المزدوج / الطول المزدوج، الذي استخدمته rendertransform و rendertransformorigin
  • الوامض، الذي استخدمته الرسوم المتحركة على كائن مشترك حتى يغمض جميع الشخصيات معا
  • التسطير، الذي استخدمته شبكة ومستطيل حتى تبدو أكثر مثل عرض VT100
  • المؤشر والاختيار، الذي وضعت علامة على الخلايا نفسها واستخدام datatriggers لتغيير العرض
  • استخدام كل من صفيف أحادية الأبعاد ومجموعة متداخلة يشير إلى نفس الكائنات لجعل من السهل القيام بالتمرير والاختيار

هنا هو XAML:

giveacodicetagpre.

وهنا هو الرمز:

giveacodicetagpre.

لاحظ أنه إذا كنت لا تحب التصميم المرئي، ما عليك سوى تحديث Datatemplate TerminalCell. على سبيل المثال، يمكن أن يكون المؤشر مستطيلا وميض بدلا من واحد صلب.

كان هذا الرمز ممتعا للكتابة. نأمل أن يكون مفيدا لك. ربما يكون له خطأ أو اثنين (أو ثلاثة) منذ أن أعدم ذلك فعليا، لكنني أتوقع أن يتم مسح تلك بسهولة. أرحب بالتحرير إلى هذه الإجابة إذا قمت بإصلاح شيء ما.

نصائح أخرى

الطريقة الوحيدة لعرض النص بفعالية تستخدم النصوص. لقد قمت بتنفيذ عميل Telnet لألعاب آر بي جي القائمة على النصوص ويعمل بشكل جيد. يمكنك التحقق من المصادر على http://mudclient.codeplex.com

أنا لا أفهم لماذا تتخثر حول RTF الحصول على التوظيف.نعم.ولكن ليس عبءك للتعامل معها، فعل برنامج Microsoft قد حدث منذ فترة، فعليك كتابة التعليمات البرمجية لتقديم Colluted RTF.إنه يعمل بشكل جيد وهو مبهمة تماما لك.

نعم، لن يكون سريعا للغاية.ولكن ما هي مهلا، أنت تحاكي عرض 80x25 الذي اعتاد تشغيله عند 9600 باود.استبدال التحكم بالكامل في محاولة لجعلها الأمثل لا معنى لها وسوف تكون مهمة رئيسية.

حسنا، للإبلاغ عن حالتي، قررت أن هذا غير ممكن حقا مع WPF أو Silverlight .

المشكلة المتعلقة بالنهج المقترح هو أن هناك 80 * 24 TextBlocks بالإضافة إلى بعض العناصر الأخرى، مع ارتباطات متعددة للترانز، backcolor، إلخ. عندما تحتاج الشاشة إلى التمرير، يجب إعادة تقييم كل من هذه الارتباطات، و انها بطيئة جدا جدا. يستغرق تحديث الشاشة بأكملها بضع ثوان. في تطبيقي هذا غير مقبول، ستكون الشاشة تمرير باستمرار.

حاولت الكثير من الأشياء المختلفة لتحسينه. حاولت استخدام TextBlock واحد مع 80 يعمل كل صف لكل صف. حاولت خلع الإخطارات التغيير. حاولت أن أجعلها حدث "التمرير" محدثا يدويا كل TextBlock يدويا. لا شيء يساعد حقا - الجزء البطيء يقوم بتحديث واجهة المستخدم، وليس بالطريقة التي يتم بها.

شيء واحد كان من شأنه أن ساعده هو إذا ابتكرت آلية لا تحتوي على textblock أو تشغيلها لكل خلية، ولكن فقط تغيير TextBlocks عندما يتغير نمط النص. لذا فإن سلسلة نص نفس اللون على سبيل المثال سيكون فقط 1 textblock. ومع ذلك، سيكون ذلك معقدا للغاية، وفي النهاية، سيساعد سيناريوهات فقط التي لها اختلاف أسلوب صغير على الشاشة. سيكون تطبيقي الكثير من الألوان التي تطير من قبل (فكر في ANSI Art)، لذلك ستظل بطيئا في هذه الحالة.

شيء آخر اعتقدت أنه من شأنه أن يساعد هو إذا لم أقم بتحديث TextBlocks، ولكن قم بالتمرير بدلا من ذلك أثناء تمرير الشاشة. لذلك ستتحرك TextBlocks من الأعلى إلى الأسفل، ثم فقط من ستحتاج تلك الجديدة إلى التحديث. تمكنت من الحصول على هذا العمل باستخدام مجموعة يمكن ملاحظتها. ساعدت، لكنها لا تزال بطيئة للغاية!

حتى كنت تعتبر عنصر تحكم WPF مخصص باستخدام OnRender. قمت بإنشاء واحدة تستخدم DawingContext.rendertext بطرق مختلفة لمعرفة مدى السرعة التي يمكن أن تكون بها. ولكن حتى ذلك، يبطئ أيضا في التعامل مع تحديث الشاشة باستمرار.

لذلك هذا .. لقد استسلمت لهذا التصميم. أنا بدلا من ذلك ابحث في استخدام نافذة وحدة التحكم الفعلية كما هو موضح هنا:

لا يوجد إخراج إلى وحدة تحكم من تطبيق WPF؟

أنا لا أحب ذلك حقا نظرا لأن النافذة منفصلة عن النافذة الرئيسية، لذلك أبحث عن طريقة لتضمين نافذة وحدة التحكم في نافذة WPF، إذا كان ذلك ممكنا. سأطلب منك سؤال آخر على ذلك وسوف ربطه هنا عندما أفعل.

تحديث: تضمين نافذة وحدة التحكم فشلت أيضا، لأنه لا يتطلب منك إزالتها شريط عنوانها. لقد قمت بتنفيذها كوحدة تحكم WinForms اللوحة المنخفضة المستوى، وأستضيف ذلك في WPF. التي تعمل بشكل جميل وبعد بعض التحسينات، لها بسرعة كبيرة جدا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top