3

I’m trying to use the SendMessage function of a hotkey utility (or NirCMD, etc.) to get a hidden window to pop up. I can for example get windows to close by sending 0x0010 (WM_CLOSE), but when I try sending 0x0018 (WM_SHOWWINDOW) with a wParam of 1 and an lParam of 0, nothing happens.

I’ve looked around, and the few places where someone complained that WM_SHOWWINDOW did not work, they happily took the suggestion to use ShowWindow() instead.

However I don’t have ShowWindow() available; I can only send Windows messages. But ShowWindow() is not magic, surely it works by SendMessage-ing a WM_SHOWWINDOW or something under the covers.

How can I get a window to display itself by sending it a message?

Thanks.

Synetech
  • 9,643
  • 9
  • 64
  • 96
  • Why isn't ShowWindow() available? If you can call SendMessage() you clearly can build a program using Win32 API. Why not call ShowWindow()? – Andreas Magnusson Sep 03 '10 at 11:17
  • 1
    Because like I said, the hotkey program/nircmd/etc. only provide an interface to send/post a message (it is like scripting, not compilation with headers and such). – Synetech Sep 03 '10 at 18:18

3 Answers3

4

Try these two messages:

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

Or if using 3rd party apps is ok, try cmdow

Anders
  • 97,548
  • 12
  • 110
  • 164
  • Well something happens (the window flashes up and then goes away). I think the problem is that it is not just a minimized window, it is hidden, so this doesn’t quite work. I actually do have a copy of cmdow (and other similar apps). I was hoping to only send a message, but if that just won’t work out, I may have to resort to running an external app. – Synetech Sep 03 '10 at 18:30
2

WM_SHOWWINDOW is a notification, not a command. From MSDN:

The WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown.

I don't believe there is any message that you can use to make a window show itself. Actually, the very idea seems a little strange to me. The window manager is the system component responsible for showing and hiding windows. To show a window, you must use one of the window manager APIs.

Peter Ruderman
  • 12,241
  • 1
  • 36
  • 58
  • See, that’s what I thought was causing it to not work ‘as expected’. The quote you mentioned is exactly what I was thinking about yesterday when I was checking the `WM_SHOWWINDOW` page. However I don’t see why the idea should seem strange to you since you can send a WM_CLOSE to a window and it will close. You can send a WM_SIZE to resize a window. So why should it be unusualy to send a WM_SHOWWINDOW to un-hide a window? – Synetech Sep 03 '10 at 18:27
  • It would. Most window messages (with some exceptions) are notifications, not commands (WM_SIZE is a notification; WM_CLOSE is a command). Also keep in mind that sending *any* window message to an unknown window is risky. You can't be sure that the window will ever receive the message, and you certainly can't be sure what the window will do when it receives it. There's no guarantee that a window will close in response to WM_CLOSE, for example (though well behaved windows do). – Peter Ruderman Sep 04 '10 at 00:02
0

I think there is no way to achieve that with SendMessage (WM_SYSCOMMAND didn't work for me). I tried actually in C#. You click the button, the window will be minimized via ShowWindow() and then you can see what messages are sent:

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);
        }
    }
}   
Bitterblue
  • 13,162
  • 17
  • 86
  • 124