#c# #.net #windows #winapi #maximize
#c# #.net #Windows #winapi #развернуть
Вопрос:
Я использовал мьютекс для запуска программы с одним экземпляром, и теперь я хочу, чтобы окно стало максимальным, если оно в данный момент свернуто, когда пользователь повторно открывает приложение.
Вот код, который у меня сейчас есть в файле Program.cs:
static class Program
{
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool Ok = true;
string ProductName = Application.ProductName;
Mutex m = new Mutex(true, ProductName, out Ok);
if (!Ok)
{
System.Diagnostics.Process[] p = System.Diagnostics.Process.GetProcessesByName(ProductName);
SetForegroundWindow(p[0].MainWindowHandle);
}
else
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
Комментарии:
1. Могу ли я предположить, что восстановление окна (то есть не-минимизация) имеет больше смысла, чем его максимизация .
2. @romkyns: Согласен, определенно.
SW_SHOW
это способ сделать это, как я упоминал в нижней части моего ответа. Это вернет окно в его предыдущее состояние перед сворачиванием, независимо от того, было ли это стандартное окно или развернутое окно.
Ответ №1:
Вы ищете ShowWindow
функцию и SW_MAXIMIZE
флаг.
В C # объявление P / Invoke выглядело бы следующим образом:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_MAXIMIZE = 3;
Добавьте это в свой код здесь:
if (!Ok)
{
Process[] p = Process.GetProcessesByName(ProductName);
SetForegroundWindow(p[0].MainWindowHandle);
ShowWindow(p[0].MainWindowHandle, SW_MAXIMIZE);
}
Если вы действительно хотите сначала проверить, свернуто ли окно, прежде чем его развернуть, вы можете использовать IsIconic
функцию старой школы:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsIconic(IntPtr hWnd);
// [...]
if (!Ok)
{
Process[] p = Process.GetProcessesByName(ProductName);
IntPtr hwndMain= p[0].MainWindowHandle;
SetForegroundWindow(hwndMain);
if (IsIconic(hwndMain))
{
ShowWindow(hwndMain, SW_MAXIMIZE);
}
}
Если вы просто хотите активировать окно (а не разворачивать его), используйте SW_SHOW
значение ( 5
) вместо SW_MAXIMIZE
. Это вернет его в предыдущее состояние, до того, как оно было свернуто.
Комментарии:
1. отлично, это работает. просто исправьте это в своем ответе [DllImport («user32.dll «, кодировка = CharSet.Auto)]
2. @moslem: Хорошо, готово. Все время от времени забывают закрывающую фигурную скобку. Можете ли вы сказать, что я привык писать код в IDE?
3. У меня не работаетSW_SHOW или value (5) — с свернутым окном ничего не происходит (протестировано на Win XP SP3 и Win 7 SP1 ). SW_RESTORE или value (9) сработали для меня, и, на мой взгляд, это правильный выбор в соответствии с описанием MSDN
4. @bairog Это правильно. Вы должны выбрать правильный флаг для того, что вы хотите сделать.
SW_SHOW
не восстановит или не развернет свернутое окно. Для этого вам нуженSW_RESTORE
orSW_MAXIMIZE
. Документация — хорошее место для просмотра, этот ответ только поможет вам начать. Это было составлено специально для первоначального задаваемого вопроса.
Ответ №2:
Я хотел бы предложить решение, которое является чисто .NET (т. Е. без зависимости от операционной системы).
Program.cs
static class Program
{
private static volatile bool _exitProcess;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
bool createdNew;
var showMeEventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "MyApp.ShowMe", out createdNew);
if (createdNew)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form1();
new Thread(() =>
{
while (!_exitProcess)
{
showMeEventHandle.WaitOne(-1);
if (!_exitProcess)
{
if (form.InvokeRequired)
{
form.BeginInvoke((MethodInvoker)form.BringFormToFront);
}
else
{
form.BringFormToFront();
}
}
}
}).Start();
Application.Run(form);
}
_exitProcess = true;
showMeEventHandle.Set();
showMeEventHandle.Close();
}
}
ExtMethods.cs
public static class ExtMethods
{
public static void BringFormToFront(this Form form)
{
form.WindowState = FormWindowState.Normal;
form.ShowInTaskbar = true;
form.Show();
form.Activate();
}
}
Form1.cs
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
{
this.BringFormToFront();
}
private void button1_Click(object sender, EventArgs e)
{
WindowState = FormWindowState.Minimized;
ShowInTaskbar = false;
Hide();
}
}
Комментарии:
1. Абсолютно блестяще и намного лучше, чем решение с DLL.