发送CTRL-S消息到窗口 [英] Sending CTRL-S message to a window

查看:253
本文介绍了发送CTRL-S消息到窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用C#代码保存TextPad窗口;我可以找出窗口的句柄,但不知道如何发送CTRL - S到该窗口。我想使用的P / Invoke API来实现这一目标。同样,TextPad窗口将处于非活动状态,因为我的应用程序会在那个时候活跃。

I want to save a TextPad window using C# code; I can find out the handle of the window but not sure how to send CTRL - S to that window. I want to use P/Invoke API to achieve this. Also, that TextPad window will be inactive, because my application will be active at that time.

[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hwnd, int msg, int wParam, int lParam);

发送Ctrl +向上的窗口

我看着这个讨论是非常相似,我的问题。我明白在逻辑上,我必须做4派低于

I looked at this discussion which is very similar to my problem. I understand logically that I have to do 4 send messages like below


  • 的KeyDown CTRL键

  • 的KeyDown样的消息S键

  • 的KeyUp S键

  • 的KeyUp CTRL键

  • KeyDown CTRL key
  • KeyDown S key
  • KeyUp S key
  • KeyUp CTRL key

我不知道如何正确的参数发送给SendMessage函数。要关闭我使用窗口

I am not sure how to send the right parameters to the SendMessage. To close the window I use

SendMessage(hWnd, 0x0010, 0, 0);



我得到这个从MSDN库。

I got this from MSDN library.

你能告诉我一些链接,告诉我的十六进制的键盘按键并解释了最后两个参数代表

Can you please direct me to some link which tells me the hexadecimal for keys in the keyboard and explains what the last two parameters represent?

更新 - ?1

使用间谍++我觉得产生这些事件与我按CTRL-S在记事本窗口

UPDATE - 1
Using spy++ I find these events generated with I press CTRL-S on Notepad window


1. WM_KEYDOWN nVirtKey:VK_Control, 
2. WM_KEYDOWN nVirtKey:'S' .. some other messates ..
3. WM_KEYUP nVirtKey:VK_Control. 
4. WM_KEYUP nVirtKey:'S'. 



更新 - 2


       private IntPtr startnotepad() {
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = @"notepad.exe";
            String fileName = baseDirectory + textbox1.Text;
            psi.Arguments = @"""" + fileName + @"""";
            psi.WindowStyle = ProcessWindowStyle.Minimized;
            Process p = Process.Start(psi); 
            return p.MainWindowHandle;
        }

        private void SaveNotepad(IntPtr handle)
        {
            IntPtr handle = GetWindow(handle, 5); // get the keyboard focus handle
            // verified the handle with Spy ++.
            SendMessage(handle, 0x0100, 0x11, 0); // keydown ctrl
            SendMessage(handle, 0x0100, 0x53, 0); // keydown S
            //SendMessage(handle, 0x0101, 0x11, 0); --- I tried keeping "Keyup Ctrl" here as well.
            SendMessage(handle, 0x0101, 0x53, 0); // keyup s
            SendMessage(handle, 0x0101, 0x11, 0); // keyup ctrl            
        }

这代码不工作(保存它的一部分),甚至虽然我能看到WM_KEYDOWN - CTRL .. WM_KEYDOWN - 'S'.. KEYUP'S'和KEYUP CTRL被送到右侧窗口中的间谍++。任何人都可以发表评论什么是错的代码?或者有什么建议,如果我做一些非常愚蠢的。

This code does not work (save part of it) even though I am able to see the WM_KEYDOWN - CTRL .. WM_KEYDOWN - 'S' .. KEYUP 'S' and KEYUP CTRL being sent to the right window in spy++. Can anyone comment what is wrong with this code? Or any suggestions if I am doing something really stupid.

更新3

作为@Hans在他的评论暗示我应该使用PostMessage的,而不是SendMessage函数。

I should be using PostMessage instead of SendMessage as @Hans suggested in his comments.


 [DllImport("user32.dll")]
 public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);  

        private void Save(IntPtr mainWindowHandle)
        {               
            IntPtr handle = GetWindow(mainWindowHandle, 5); // getChild window
            IntPtr CTRL_KEY = new IntPtr(0x11);
            uint KEY_DOWN = 0x0100;
            uint KEY_UP = 0x0101;
            IntPtr S_KEY = new IntPtr(0x53);

            //SetForegroundWindow(p.MainWindowHandle);
            PostMessage(handle, KEY_DOWN, CTRL_KEY, IntPtr.Zero);
            PostMessage(handle, KEY_DOWN, S_KEY, IntPtr.Zero);
            PostMessage(handle, KEY_UP, S_KEY, IntPtr.Zero);
            PostMessage(handle, KEY_UP, CTRL_KEY, IntPtr.Zero);                      
        } 



上面的代码,而不是CTRL + S发送CTRL和S到记事本窗口。所以,我可以看到两个S在记事本中被抛出。纵观当我们按下CTRL + S产生真正的消息时,我看到我的PostMessage的的最后一个参数是错误的。它应该像(重点UP Ctrl键C01F0001)

The above code instead of CTRL+S sends CTRL and S to Notepad window. So, I can see two "S" being thrown at Notepad. Looking at the real message generated when we press CTRL+S, I see that last parameter of my Postmessage is wrong. It should be something like (for KEY UP CTRL key "C01F0001")

能否请你告诉我怎么通过这个十六进制的PostMessage的的最后一个参数?

Can you please tell me how to pass this hexadecimal as last parameter of postmessage?


// does not work
PostMessage(handle, KEY_UP, CTRL_KEY, new IntPtr(0xC01F0001);


更新4:我想我们无法发送热键消息。以最小化窗口使用Post消息



这下面的代码可与SendInput:但它会弹出窗口,这样的擦伤目的。不管怎么说,只是想更新这个帖子。

Update 4 : I think we cannot send "hot key" messages to a minimized window. using Post Message.
This below code works with SendInput: but it will pop up the window, which kind a mar the purpose. Anyways, just wanted to update this thread.


 private void Save_Notepad(IntPtr mainWindowHandle) {
            //SetActiveWindow(mainWindowHandle);
            //SetFocus(GetWindow(mainWindowHandle, 5));
            ShowWindow(mainWindowHandle, 1); // show window 
            SetForegroundWindow(mainWindowHandle);
            //SetActiveWindow(mainWindowHandle);
            //SetFocus(GetWindow(mainWindowHandle, 5));
            //IntPtr returnvalue = SetFocus(mainWindowHandle);
            uint intReturn;
            INPUT structInput;
            structInput = new INPUT();
            structInput.type = 1;// keyboard input
            // key down
            structInput.ki.wScan = 0x1D;
            structInput.ki.time = 0;
            structInput.ki.dwFlags = 0;
            // key down Ctrl
            structInput.ki.wVk = 0x11;  //0x1D; //
            intReturn = SendInput(1, ref structInput, Marshal.SizeOf(new INPUT()));
            // key down S
            structInput.ki.wScan = 0x1F;
            structInput.ki.wVk = 0x53; //0x41;//0x53;  //0x1F;//
            intReturn = SendInput(1, ref structInput, Marshal.SizeOf(new INPUT()));
            // key up 
            structInput.ki.dwFlags = 0x0002; // key up
            // key up S
            intReturn = SendInput(1, ref structInput, Marshal.SizeOf(typeof(INPUT)));
            // key up CTRL
            structInput.ki.wVk = 0x11;  //0x1D; //
            intReturn = SendInput(1, ref structInput, Marshal.SizeOf(new INPUT()));
            //ShowWindow(mainWindowHandle, 2); // minimize it again 
        }

在CTRL + SI可以最小化窗口,但随后将创建一个闪光灯。
任何人都可以提出,如果我可以不带FLASH实现这一功能(至少)?



更新5:使用WM_SYSCOMMAND

After CTRL + S I can minimize the window but then it will create a flash. Can anyone suggest if I can achieve this functionality without the "FLASH" (at least)?
UPDATE 5 : using WM_SYSCOMMAND


IntPtr handle = GetWindow(mainWindowHandle, 5);
// send Alt F message to Notepad.
// http://msdn.microsoft.com/en-us/library/ms646360(v=VS.85).aspx
// I can see this is working.
PostMessage(handle, 0x0112, 0xF100, 'f');  // send WM_SYSCOMMAND
// how to send s on this window ??
// I have tried things which I have learned so far. 



我只需要发送S消息记录到文件菜单,会弹出WM_SYSCOMMAND的结果。任何人都可以点我到一个文档,该怎么办?

I just need to send S messages to file menu which will pop up as a result of WM_SYSCOMMAND. Can anyone point me to a documentation to how to do that?


PostMessage(handle, KEY_DOWN, S_KEY, 0x1F0001); // POST does not work
// tried with mainwindowhandle as well
PostMessage(handle, 0x111, 'S', 0); // WM_COMMAND does not work
PostMessage(handle, 0x0112, 0xF100, 's');  // WM_SYSCOMMAND does not work (and does not make sence either)



最后更新

我无法发送,2S消息,最小化窗口。我使用的SendKeys(^ S)每2-3秒的时候,重点是一个编辑器。

I was not able to send ^S message to a minimized window. I am using sendkeys(^s) every 2-3 seconds when the focus is on an editor.

- Karephul

-- Karephul

推荐答案

您不能使用SendMessage函数(或PostMessage的时,正确的),以模拟修饰键的状态,如CTRL。您必须使用SendInput()。

You cannot use SendMessage (or PostMessage, the correct one) to simulate the state of the modifiers keys, like CTRL. You must use SendInput().

如Ctrl + S击键不untypically翻译成WM_COMMAND消息。使用间谍工具++时看到你手工输入Ctrl + S会发生什么。如果你看到WM_COMMAND那么你的黄金,你的可以的使用的SendMessage()发送该消息。当然,这只会在特定的工作过程。

A keystroke like Ctrl+S is not untypically translated into a WM_COMMAND message. Use the Spy++ tool to see what happens when you type Ctrl+S by hand. If you see WM_COMMAND then you're golden, you can use SendMessage() to send that message. This will of course only work on a specific process.

这篇关于发送CTRL-S消息到窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆