2013-03-10 2 views
3

프로세스의 일부 프로세스 ID (예 : firefox, 메모장 등)를 프로세스의 창을 스크롤하는 방법으로 보낼 수있는 프로그램을 만들려고합니다.Win32API를 사용하여 다른 프로세스에서 창을 스크롤하는 방법

저는 Pinvoke에서 찾은 GetScrollBarInfo 및 SetScrollPos를 사용해 보았습니다. 성공하지 못했습니다. 이것이 올바른지 아닌지 확실하지 않습니다. GetScrollBarInfo로 시작했는데 작동하지 않는 것 같습니다.

나는 http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx

임 확실하지에 따라, http://www.pinvoke.net/default.aspx/user32.getscrollbarinfo에서 발견 된 코드

[StructLayout(LayoutKind.Sequential)] 
public struct SCROLLBARINFO 
{ 
    public int cbSize; 
    public Rectangle rcScrollBar; 
    public int dxyLineButton; 
    public int xyThumbTop; 
    public int xyThumbBottom; 
    public int reserved; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] 
    public int[] rgstate; 
} 

private const uint OBJID_HSCROLL = 0xFFFFFFFA; 
private const uint OBJID_VSCROLL = 0xFFFFFFFB; 
private const uint OBJID_CLIENT = 0xFFFFFFFC; 

private int Scroll(int ProcessID) 
{ 
    IntPtr handle = Process.GetProcessById(ProcessID).MainWindowHandle; 
    SCROLLBARINFO psbi = new SCROLLBARINFO(); 
    psbi.cbSize = Marshal.SizeOf(psbi); 
    int nResult = GetScrollBarInfo(handle, OBJID_CLIENT, ref psbi); 
    if (nResult == 0) 
    { 
     int nLatError = Marshal.GetLastWin32Error(); 
    } 
} 

GetLastWin32Error는() "시스템 호출에 전달 된 데이터 영역이 너무 작습니다"를 의미 에러 코드 (122)를 반환 시도 내가 뭘 잘못했는지. 이 문제를 어떻게 해결할 수 있습니까?

답변

3

원하는 작업을 수행하기 위해 WM_MOUSEWHEEL 메시지를 보낼 수 있습니다. 예를 들어, C++를 사용하여 새 메모장 창에 한 번 아래로 스크롤 :

HWND hwnd = FindWindowEx(FindWindow(NULL, "Untitled - Notepad"), NULL, "Edit", NULL); 
RECT r; 
GetClientRect(hwnd, &r); 
SendMessage(hwnd, WM_MOUSEWHEEL, MAKEWPARAM(0, WHEEL_DELTA * -1), MAKELPARAM(r.right/2, r.bottom/2)); 

는 C#을 해당 적응하려면 이와 같은 뭔가를 할 수 : 사용할 수

[DllImport("user32.dll", CharSet = CharSet.Auto)] 
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, ref Point lParam); 

private void ScrollWindow(IntPtr hwnd, Point p, int scrolls = -1) 
{ 
    SendMessage(hwnd, WM_MOUSEWHEEL, (WHEEL_DELTA * scrolls) << 16, ref p); 
} 

가 아래로 스크롤 한 번이 같은 새 메모장 창에 : 메모장과 같은 다른 사람들이하지 않습니다 동안의 lParam이 필요합니다

//Imports 
[DllImport("user32.dll", SetLastError = true)] 
static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

[DllImport("user32.dll", SetLastError = true)] 
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 
... 
//Actual code 
IntPtr hwnd = FindWindowEx(FindWindow(null, "Untitled - Notepad"), IntPtr.Zero, "Edit", null); 
Point p = new Point(0, 0); 
ScrollWindow(hwnd, p); 

일부 프로그램은 스크롤 영역 위에 실제의 포인트로 보냈습니다.

+0

고마워. 나는 이것을 나중에 시험해 볼 것이다! :) –

+0

이것에 대한 정보를 찾는 것은 좀 어려운 것 같습니다. 당신의 모범은 그토록 위대한 일을했습니다. 당신이 내가 알고있는 몇 안되는 사람 중 하나 인 것 같아요.이 정보를 어디서 구합니까? 나는 이것을 더 일반화하고 싶다. 그래서 메모장 그 이상에서 작동한다. 어디서 "편집"이 오는지 확실하지 않습니다. 그게 뭐야? 다른 프로그램에 해당하는 것을 어떻게 찾을 수 있습니까? –

+0

"편집"은 스크롤을 보낼 필요가있는 메모장의 컨트롤입니다. 많은 브라우저가 컨트롤에 보내지 않아도됩니다. 예를 들어, FindWindow (null, "현재 페이지 이름 - Opera") 만 사용해 보았습니다. 그리고 스크롤은 잘 동작했다. 나는 과거에 WM_MOUSEWHEEL을 사용했으며, 저레벨 마우스 훅에서 사용하기 때문에 무엇이 필요한지 알고 있습니다. 다른 창에서 보낼 필요가있는 컨트롤을 얻으려면 EnumChildWindows를 살펴 보거나 WinSpy ++를 사용하십시오. 자세한 내용은 http://msdn.microsoft.com/en-us/library/windows/desktop/ms645617(v=vs.85).aspx – Jammerx2

2

다른 프로세스의 창을 스크롤하려는 경우 사실상 스크롤 막대 또는 키 누름에 대한 클릭을 시뮬레이트해야합니다. 가장 확실한 방법은 .NET과 네이티브 인터페이스가 모두있는 UI Automation을 사용하는 것입니다.

스크롤바 정보를 묻는 것으로 스크롤바가 표시되는 방법에 대한 정보를 얻는 것입니다. 그것은 당신에게 창 내용을 스크롤하는 방법을 제공하지 않을 것입니다. 사용자가 스크롤바를 조작하고 있다고 생각하게하여 대상 응용 프로그램을 가져 와서 내용을 스크롤해야합니다.

+0

이것은 일반적인 방법으로 들립니다. 확실히 들여다 볼 것입니다. 감사!! :) –

관련 문제