سؤال

هل هناك طريقة يمكنني وضع تطبيق وحدة التحكم في علبة النظام عند التقليل؟

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

المحلول

وحدة التحكم لا تحتوي على نافذة لتقليلها بحد ذاتها. يعمل في نافذة موجه الأوامر. قد توغل رسائل النافذة وإخفاء النافذة على التقليل. في التطبيق الخاص بك، من الممكن إضافة أيقونة صينية تماما كما تفعل ذلك في تطبيق Windows. حسنا، بطريقة ما هذا رائحة كريهة...

لكن: لست متأكدا من السبب في أن تريد القيام بذلك. تطبيق وحدة التحكم عن طريق التصميم المختلفة إلى تطبيق Windows. وبالتالي، ربما يكون خيارا لتغيير التطبيق لتكون تطبيق نموذج Windows؟

نصائح أخرى

نعم، يمكنك أن تفعل هذا. إنشاء تطبيق نماذج Windows وإضافة مكون notifyicon.

ثم استخدم الطرق التالية (وجدت على MSDN.) تخصيص وعرض وحدة التحكم

[DllImport("kernel32.dll")]
public static extern Boolean AllocConsole();

[DllImport("kernel32.dll")]
public static extern Boolean FreeConsole();

[DllImport("kernel32.dll")]
public static extern Boolean AttachConsole(Int32 ProcessId);

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

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

// Find window by Caption only. Note you must pass IntPtr.Zero as the first parameter.
// Also consider whether you're being lazy or not.
[DllImport("user32.dll", EntryPoint="FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

تأكد من استدعاء FreeConsole كلما كنت على استعداد لإغلاق التطبيق.

using System.Windows.Forms;
using System.Drawing;

static NotifyIcon notifyIcon = new NotifyIcon();
static bool Visible = true;
static void Main(string[] args)
{
    notifyIcon.DoubleClick += (s, e) =>
    {
        Visible = !Visible;
        SetConsoleWindowVisibility(Visible);
    };
    notifyIcon.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
    notifyIcon.Visible = true;
    notifyIcon.Text = Application.ProductName;

    var contextMenu = new ContextMenuStrip();
    contextMenu.Items.Add("Exit", null, (s, e) => { Application.Exit(); });
    notifyIcon.ContextMenuStrip = contextMenu;

    Console.WriteLine("Running!");

    // Standard message loop to catch click-events on notify icon
    // Code after this method will be running only after Application.Exit()
    Application.Run(); 

    notifyIcon.Visible = false;
}

[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
public static void SetConsoleWindowVisibility(bool visible)
{
    IntPtr hWnd = FindWindow(null, Console.Title);
    if (hWnd != IntPtr.Zero)
    {
        if (visible) ShowWindow(hWnd, 1); //1 = SW_SHOWNORMAL           
        else ShowWindow(hWnd, 0); //0 = SW_HIDE               
    }
}

أنا أستعمل trayrunner. لهذا الغرض بالضبط. في الأساس، يلتف تطبيق وحدة التحكم في التقاط جميع الإخراج. ولكن عند التقليل من ذلك، فإنه يقلل من علبة النظام بدلا من شريط المهام. يمكنك حتى تخصيص أيقونة العرض عند التقليل. يمكنني استخدامها لأشياء مثل Tomcat أو Apache لتحرير المساحة على شريط المهام الخاص بي دون تشغيلها كخدمات Windows.

[DllImport("user32.dll")]
internal static extern bool SendMessage(IntPtr hWnd, Int32 msg, Int32 wParam, Int32 lParam);
static Int32 WM_SYSCOMMAND = 0x0112;
static Int32 SC_MINIMIZE = 0x0F020;

static void Main(string[] args)
{
    SendMessage(Process.GetCurrentProcess().MainWindowHandle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
}

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

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