Использование WM_SHOWWINDOW для отображения окна вместо ShowWindow()

Я пытаюсь использовать функцию SendMessage утилиты горячих клавиш (или NirCMD и т. д.), чтобы вызвать всплывающее скрытое окно. Я могу, например, закрыть окна, отправив 0x0010 (WM_CLOSE), но когда я пытаюсь отправить 0x0018 (WM_SHOWWINDOW) с wParam, равным 1, и lParam, равным 0, ничего не происходит.

Я осмотрелся, и в тех немногих местах, где кто-то жаловался, что WM_SHOWWINDOW не работает, они с радостью восприняли предложение использовать вместо него ShowWindow().

Однако у меня нет ShowWindow(); Я могу только отправлять сообщения Windows. Но ShowWindow() не волшебство, конечно, оно работает, отправляя сообщение WM_SHOWWINDOW или что-то в этом роде.

Как я могу заставить окно отображать себя, отправив ему сообщение?

Спасибо.


person Synetech    schedule 02.09.2010    source источник
comment
Почему ShowWindow() недоступен? Если вы можете вызвать SendMessage(), вы, несомненно, сможете создать программу с использованием Win32 API. Почему бы не вызвать ShowWindow()?   -  person Andreas Magnusson    schedule 03.09.2010
comment
Потому что, как я уже сказал, программа горячих клавиш /nircmd/etc. только предоставить интерфейс для отправки/публикации сообщения (это похоже на сценарий, а не на компиляцию с заголовками и тому подобное).   -  person Synetech    schedule 03.09.2010


Ответы (3)


Попробуйте эти два сообщения:

SendMessage(h,WM_SYSCOMMAND,SC_MINIMIZE,0);
SendMessage(h,WM_SYSCOMMAND,SC_RESTORE,0);

Или, если можно использовать сторонние приложения, попробуйте cmdow.

person Anders    schedule 03.09.2010
comment
Что-то происходит (окно вспыхивает, а затем исчезает). Я думаю, проблема в том, что это не просто свернутое окно, оно скрыто, поэтому это не совсем работает. На самом деле у меня есть копия cmdow (и других подобных приложений). Я надеялся отправить только сообщение, но если это просто не сработает, мне, возможно, придется прибегнуть к запуску внешнего приложения. - person Synetech; 03.09.2010

WM_SHOWWINDOW — это уведомление, а не команда. Из MSDN:

Сообщение WM_SHOWWINDOW посылается окну, когда окно должно быть скрыто или показано.

Я не верю, что есть какое-либо сообщение, которое вы можете использовать, чтобы заставить окно показывать себя. На самом деле, сама идея кажется мне немного странной. Оконный менеджер — это системный компонент, отвечающий за отображение и скрытие окон. Чтобы отобразить окно, вы должны использовать один из API оконного менеджера.

person Peter Ruderman    schedule 02.09.2010
comment
Видите ли, именно это, как я думал, заставляет его работать «не так, как ожидалось». Упомянутая вами цитата — это именно то, о чем я думал вчера, когда проверял WM_SHOWWINDOW страницу. Однако я не понимаю, почему эта идея должна показаться вам странной, ведь вы можете отправить WM_CLOSE окну, и оно закроется. Вы можете отправить WM_SIZE, чтобы изменить размер окна. Так почему же должно быть необычно отправлять WM_SHOWWINDOW, чтобы показать окно? - person Synetech; 03.09.2010
comment
Это было бы. Большинство оконных сообщений (за некоторыми исключениями) являются уведомлениями, а не командами (WM_SIZE — уведомление, WM_CLOSE — команда). Также имейте в виду, что отправка любого оконного сообщения неизвестному окну сопряжена с риском. Вы не можете быть уверены, что окно когда-либо получит сообщение, и вы, конечно, не можете быть уверены, что окно сделает, когда оно его получит. Нет никакой гарантии, что окно закроется, например, в ответ на WM_CLOSE (хотя окна с хорошим поведением закроются). - person Peter Ruderman; 04.09.2010

Я думаю, что нет способа добиться этого с помощью SendMessage (WM_SYSCOMMAND у меня не сработал). Я пробовал на самом деле в С#. Вы нажимаете кнопку, окно сворачивается через ShowWindow() и тогда вы можете видеть, какие сообщения отправляются:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public class Form1: Form
    {
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool ShowWindow(IntPtr window, int showCommand);

        private const int SW_MINIMIZE = 6;
        private bool print = false;

        public Form1()
        {
            Button button = new Button();
            button.Click += onButtonsClick;
            Controls.Add(button);
        }

        private void onButtonsClick(object sender, EventArgs e)
        {
            print = true;
            ShowWindow(Handle, SW_MINIMIZE);
            print = false;
        }

        protected override void WndProc(ref Message m)
        {
            if (print)
                Console.WriteLine(m.Msg.ToString() + "\t0x" + m.Msg.ToString("x4") + "\t" + m.WParam + "\t" + m.LParam);
            base.WndProc(ref m);
        }
    }
}   
person Bitterblue    schedule 20.05.2014