使用C#和WIN32实现滚动记事本

4

我正在尝试使用C#应用程序滚动Notepad窗口。以下是相关的代码块,调用移动/大小窗口的函数可以工作,所以我知道句柄是有效的。

请您看一下我漏掉了什么,因为运行时没有任何反应。

    [Flags]
    public enum SetWindowPosFlags : uint
    {
        SWP_ASYNCWINDOWPOS = 0x4000,
        SWP_DEFERERASE = 0x2000,
        SWP_DRAWFRAME = 0x0020,
        SWP_FRAMECHANGED = 0x0020,
        SWP_HIDEWINDOW = 0x0080,
        SWP_NOACTIVATE = 0x0010,
        SWP_NOCOPYBITS = 0x0100,
        SWP_NOMOVE = 0x0002,
        SWP_NOOWNERZORDER = 0x0200,
        SWP_NOREDRAW = 0x0008,
        SWP_NOREPOSITION = 0x0200,
        SWP_NOSENDCHANGING = 0x0400,
        SWP_NOSIZE = 0x0001,
        SWP_NOZORDER = 0x0004,
        SWP_SHOWWINDOW = 0x0040,
    }


    private const int WM_SCROLL = 276; // Horizontal scroll
    private const int WM_VSCROLL = 277; // Vertical scroll
    private const int SB_LINEUP = 0; // Scrolls one line up
    private const int SB_LINELEFT = 0;// Scrolls one cell left
    private const int SB_LINEDOWN = 1; // Scrolls one line down
    private const int SB_LINERIGHT = 1;// Scrolls one cell right
    private const int SB_PAGEUP = 2; // Scrolls one page up
    private const int SB_PAGELEFT = 2;// Scrolls one page left
    private const int SB_PAGEDOWN = 3; // Scrolls one page down
    private const int SB_PAGERIGTH = 3; // Scrolls one page right
    private const int SB_PAGETOP = 6; // Scrolls to the upper left
    private const int SB_LEFT = 6; // Scrolls to the left
    private const int SB_PAGEBOTTOM = 7; // Scrolls to the upper right
    private const int SB_RIGHT = 7; // Scrolls to the right
    private const int SB_ENDSCROLL = 8; // Ends scroll


    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);



    public void scroll()
    {


        IntPtr handle = IntPtr.Zero;

        Process[] processes = Process.GetProcessesByName("Notepad");

        foreach (Process p in processes)
        {
            handle = p.MainWindowHandle;

            Console.WriteLine("Got Handle: " + p.MainWindowTitle);

            break;
        }

        //this is to test I have a valid handle
        SetWindowPos(handle, new IntPtr(0), 10, 10, 1024, 350, SetWindowPosFlags.SWP_DRAWFRAME);


        SendMessage(handle, WM_VSCROLL,  (IntPtr)SB_LINEDOWN, IntPtr.Zero);
        SendMessage(handle, WM_VSCROLL, (IntPtr)SB_PAGEDOWN, IntPtr.Zero);

    }

只是好奇,为什么你想从C#应用程序控制记事本? - jrummell
"什么也没发生": 这意味着您没有收到“已获取句柄:x”的消息,窗口也没有成功移动。 - Kieren Johnstone
1个回答

4
这个失败是因为你将WM_VSCROLL消息发送到了主窗口。你需要将消息发送到记事本的编辑控件,也就是带有滚动条的窗口。
你可以使用EnumChildWindows枚举记事本的子窗口。具有“Edit”类的子窗口是你想要的窗口。

谢谢,Notepad很好用,有没有关于Outlook 2010消息窗口的想法?我已经遍历了所有子元素,但是没有一个可以将消息向下滚动的? - Tekhoi
@Tekhoi:使用spy++来调查Outlook的UI是如何构建的(我自己没有Outlook,所以无法查看)。 - arx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接