C# - كيف يمكنني إعادة تسمية نافذة العملية التي بدأتها؟

StackOverflow https://stackoverflow.com/questions/1016823

  •  06-07-2019
  •  | 
  •  

سؤال

هل هناك أي طريقة يمكنني من خلالها إعادة تسمية شريط عنوان النافذة لأحد التطبيقات التي قمت بتشغيلها؟أي.إذا قمت بتشغيل Notepad.exe، فيمكنني إعادة تسمية شريط العنوان الخاص به من "بدون عنوان - المفكرة" إلى "اسم المفكرة الجديد".

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

المحلول

ويمكنك القيام بذلك باستخدام P / استدعاء:

[DllImport("user32.dll")]
static extern int SetWindowText(IntPtr hWnd, string text);



private void StartMyNotepad()
{
    Process p = Process.Start("notepad.exe");
    Thread.Sleep(100);  // <-- ugly hack
    SetWindowText(p.MainWindowHandle, "My Notepad");
}

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

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

نصائح أخرى

في الواقع، أنا فرز بنفسي وأنها تعمل تماما. على أي حال شكرا.

[DllImport("user32.dll")]
static extern SetWindowText(IntPtr hWnd, string windowName);

IntPtr handle = p.MainWindowHandle;
SetWindowText(handle, "This is my new title");

لا يمكنك القيام بذلك في C#، ولكن يمكنك القيام بذلك باستخدام واجهة برمجة التطبيقات ذات المستوى المنخفض.أدخل خيطًا في العملية، اتصل سيتWindowText() منه

وكما يعتقدFredrik مورك، والمشكلة هي أن هناك حاجة إلى الانتظار لنافذة يمكنك استلام رسائل لتحديد عنوانه. يمكن انتظار 100 مللي ثانية كسر بير رسالة داخلية من البرنامج وانها مجرد الحل. للحصول على رسالة، يجب أن يكون نافذة مقبض التي تستخدم للالرجوع إلى هذا الإطار، وبالتالي يمكنك ببساطة انتظر مقبض النافذة، والتي في بدء التشغيل يجب IntPtr.Zero (مقبض فارغة).

وهنا مثال لهذا النهج:

Process p = Process.Start("notepad.exe");
while (p.MainWindowHandle == IntPtr.Zero)
    Application.DoEvents();
SetWindowText(p.MainWindowHandle, "My Notepad");

وعن طريق Application.DoEvents() البرنامج سوف تستمر في تلقي الرسائل ونظام عملية، لذلك لن تمنع (ولا تعطل)، على الرغم من أنها ليست غير المتزامن.

ويمكنك أيضا أن نفكر لتجنب النفقات العامة وحدة المعالجة المركزية عن طريق استبدال بيان while مع دعوة SpinWait.SpinUntil (حتى، ستحتاج إلى استيراد System.Threading):

Process p = Process.Start("notepad.exe");
SpinWait.SpinUntil(delegate
{
    return p.MainWindowHandle != IntPtr.Zero;
});
SetWindowText(p.MainWindowHandle, "My Notepad");

لا.

قد يتطلب هذا أن يسمح التطبيق المستهدف بتعديل عنوان النافذة على الإطلاق.تستخدم العديد من البرامج عناوينها لإظهار معلومات مفيدة (مثل اسم الملف المفتوح للتحرير في برنامج "المفكرة"، أو ملف <TITLE> لمستند HTML المفتوح في Firefox).

الحالة الوحيدة التي أعرفها والتي تتيح للمستخدم تعيين نص العنوان مع بعض القيود هي CMD.EXE الذي يعمل في نافذة وحدة التحكم.يدعم CMD TITLE أمر مدمج يقوم بتعيين عنوان النافذة بناءً على وسيطاتها.ولكن لا يمكن القيام بذلك من خلال نافذة ثانية دون إدخال ضغطات المفاتيح في نافذة وحدة التحكم المحددة، وهو أمر غير مستحسن بشكل عام.

يحرر:

منذ الفكرة تطفو على ذلك SetWindowText() سأفعل هذا من أجلك، دعني أوضح ذلك.

تعمل وظيفة API هذه بالفعل على تغيير شريط العنوان لنافذة المستوى الأعلى.إنها في الواقع المكالمة التي من المحتمل أن يستخدمها تطبيق مثل Notepad لتعيين عنوانه الخاص في أي وقت يعتقد فيه أن العنوان قد تغير.

السبب في أنني أدعي أن هذا هو لا الحل هو أن برنامج Notepad يقوم بالفعل بتغيير العنوان عندما يريد ذلك.سيكون لدى التطبيق الذي يدعم التغييرات التعسفية على عنوانه آلية من نوع ما لتذكر أنه تم تغيير العنوان وعدم استعادة سلسلة العنوان المفضلة بشكل تعسفي.

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