PDA

View Full Version : C# Selecting/Detecting Runescape window



n3ss3s
01-06-2011, 09:47 PM
I need to do what SCAR/Simba does when you drag the crosshair over scape, except for without the crosshair and the dragging, so basically I need to get the RS window coords, or some kind of a handle n shit

tips ples :sasmokin:

Cazax
01-06-2011, 09:59 PM
What I have in Delphi...

procedure TForm1.BitBtn3MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
tp : tpoint;
Begin
GetCursorPos(TP);
RS_Handle := WindowFromPoint(TP);
End;
what I found on google about C# WindowFromPoint:

[DllImport("user32.dll")]
public static extern IntPtr WindowFromPoint(Point lpPoint);

[DllImport("user32.dll")]
public static extern bool GetCursorPos(out Point lpPoint);

public static IntPtr GetWindowUnderCursor()
{
Point ptCursor = new Point();

if (!(PInvoke.GetCursorPos(out ptCursor)))
return IntPtr.Zero;

return WindowFromPoint(ptCursor);
}ยก
Hope that helps :p

n3ss3s
01-06-2011, 10:00 PM
I'm almost a 100% sure that will get the whole window (e.g FireFox, not just the RuneScape applet) :(

mastaraymond
01-06-2011, 11:00 PM
Simba is open source

n3ss3s
01-06-2011, 11:23 PM
Simba is open source

But Simba is pascal isn't it?

Frement
01-07-2011, 01:29 AM
Heres what I have done, could be ported to C#.
library FremPlugin;

{$R *.res}

uses
ShareMem, Windows, Messages, SysUtils, Variants, Classes, Controls,
Forms,Graphics, Dialogs, StdCtrls, StrUtils, ComCtrls;

type
TForm1 = class( TForm )
end;

type
PWindows = ^TWindows;
TWindows = Record
WindowHandle: HWND;
WindowText: String;
end;

var AWindows: PWindows;
InFrame, InCanvas, InCanvas2: Boolean;
Mode: Integer;
Return: HWND;

function FindWindowByTitle( WindowTitle: String ): HWND; stdcall; export;
var
NextHandle: Hwnd;
NextTitle: Array[0..260] Of Char;
begin
NextHandle := GetWindow( Application.Handle, GW_HWNDFIRST );
while ( NextHandle > 0 ) do
begin
GetWindowText( NextHandle, NextTitle, 255 );

if ( AnsiContainsText( NextTitle, WindowTitle ) ) then begin
if ( AnsiContainsText( NextTitle, 'Opera' ) ) then begin
Mode := 1;
end else begin
Mode := 0;
end;
Result := NextHandle;
Exit;
end else begin
NextHandle := GetWindow( NextHandle, GW_HWNDNEXT );
end;

end;
Result := 0;
end;

function EnumChildWindowsProc( Wnd: HWnd ): Boolean; stdcall; export;
var
Buffer: Array[0..99] Of Char;
hWindowText: Array[0..260] Of char;
begin
GetWindowText( Wnd, Buffer, 100 );
RealGetWindowClass( Wnd, hWindowText, 255 );

if ( StrPas( hWindowText ) = '' ) then begin
hWindowText := 'Empty';
end;

if ( StrPas( Buffer ) = '' ) then begin
Buffer := 'Empty';
end;

new(AWindows);

with AWindows^ do
begin
WindowHandle := Wnd;
WindowText := StrPas( Buffer );
end;

if ( Mode = 1 ) then begin
if ( InCanvas2 ) then begin
//ShowMessage( 'RS Canvas: ' + IntToStr( Wnd ) );
Return := Wnd;
Result := True;
InFrame := False;
InCanvas := False;
InCanvas2 := False;
Exit;
end;

if ( InCanvas ) and ( StrPas(hWindowText) = 'SunAwtCanvas' ) then begin
InCanvas2 := True;
end;
end;

if ( Mode = 0 ) then begin
if ( InCanvas ) then begin
//ShowMessage( 'RS Canvas: ' + IntToStr( Wnd ) );
Return := Wnd;
Result := True;
InFrame := False;
InCanvas := False;
InCanvas2 := False;
Exit;
end;
end;

if ( StrPas( hWindowText ) = 'SunAwtFrame' ) then begin
InFrame := True;
end;

if ( InFrame ) and ( StrPas(hWindowText) = 'SunAwtCanvas' ) then begin
InCanvas := True;
end;

if ( GetWindow(Wnd, GW_CHILD) <> 0 ) then
begin
if not ( Result ) then begin
Enumchildwindows(Wnd, @EnumChildWindowsProc, 0);
end;
end;

Result := True;
end;

function GetRSHandle: HWND;
var H: HWND;
begin
H := FindWindowByTitle( 'RuneScape -' );
InFrame := False;
InCanvas := False;
InCanvas2 := False;
EnumChildWindows( H, @EnumChildWindowsProc, 0 );
Result := Return;
end;

function GetFunctionCount(): Integer; stdcall; export;
begin
Result := 3;
end;

function GetFunctionInfo(x: Integer; var ProcAddr: Pointer; var ProcDef: PChar): Integer; stdcall; export;
begin
case x of
0:
begin
ProcAddr := @FindWindowByTitle;
StrPCopy(ProcDef, 'function FindWindowByTitle( WindowTitle: String ): HWND;');
end;
1:
begin
ProcAddr := @EnumChildWindowsProc;
StrPCopy(ProcDef, 'function EnumChildWindowsProc( Wnd: HWnd ): Boolean;');
end;
2:
begin
ProcAddr := @GetRSHandle;
StrPCopy(ProcDef, 'function GetRSHandle: HWND;');
end;
else
x := -1;
end;
Result := x;
end;

exports GetFunctionCount;
exports GetFunctionInfo;

end.

EDIT: And heres the thread where I discussed this: http://villavu.com/forum/showthread.php?t=54922

n3ss3s
01-07-2011, 02:23 AM
Looks good, I'll try porting it although I'm a complete noob to .NET and all of that :)



(No FindWindowBySize isn't a cool solution).

loled irl

Frement
01-07-2011, 03:39 AM
I would love to hear where you are going to use this, and maybe see the ported version?

You can add me on MSN if you want: frement@windowslive.com

Jos muistan oikein ni olit suomalainen? ;)

n3ss3s
01-07-2011, 04:02 AM
Olen suomalainen, I live in the US nowadays so I'm rarely on at the same time as GMTers, I'm actually trying to make an utility that some people here will propably hate on, a pin logger that is...

Frement
01-07-2011, 04:05 AM
A "pin logger", like you log the bank pins? To what purpose if I may ask?

3Garrett3
01-07-2011, 04:28 PM
A "pin logger", like you log the bank pins? To what purpose if I may ask?

Judging from his post, malicious purposes? If we'd hate on it :p

Cazax
01-07-2011, 04:36 PM
Good luck reading the numbers on the pin screen :p

n3ss3s
01-07-2011, 08:04 PM
Good luck reading the numbers on the pin screen


Problem?




EDIT: Well well well, if it isnt Mr SunAwtCanvas

http://i51.tinypic.com/29c77kp.jpg

Posting code later today, not quite finished


EDIT: YES!!! THERE IS A GOD! Found out my bitmap copying was flawed and spent hours probind the DC shit for nothing lol


As I promised: (If this is any use for anyone, esp. if the problem with grabbing the canvas still persists feel free to use this if its any use)


/*
* Created by SharpDevelop.
* User: admin
* Date: 4.1.2011
* Time: 18:56
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Net.Mail;
using System.Runtime.InteropServices;
using System.Threading;
using System.Text;
using System.Diagnostics;

namespace PinLogger
{
class Program
{

internal delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
internal delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);


class GDI32
{
[DllImport("GDI32.dll")]
public static extern bool BitBlt(int hdcDest,int nXDest,int nYDest,int nWidth,int nHeight,int hdcSrc,int nXSrc,int nYSrc,int dwRop);
[DllImport("GDI32.dll")]
public static extern int CreateCompatibleBitmap(int hdc,int nWidth, int nHeight);[DllImport("GDI32.dll")]
public static extern int CreateCompatibleDC(int hdc);
[DllImport("GDI32.dll")]
public static extern bool DeleteDC(int hdc);
[DllImport("GDI32.dll")]
public static extern bool DeleteObject(int hObject);
[DllImport("GDI32.dll")]
public static extern int GetDeviceCaps(int hdc,int nIndex);
[DllImport("GDI32.dll")]
public static extern int SelectObject(int hdc,int hgdiobj);
}

class User32
{
[DllImport("User32.dll")]
public static extern int GetDesktopWindow();
[DllImport("User32.dll")]
public static extern int GetWindowDC(int hWnd);
[DllImport("User32.dll")]
public static extern int ReleaseDC(int hWnd,int hDC);
[DllImport("user32.dll") ]
public static extern int GetWindowText(int hWnd, StringBuilder text, int count);
[DllImport("user32.dll")]
public static extern int GetWindow(int hWnd, GW uCmd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
public static extern uint RealGetWindowClass(IntPtr hwnd, [Out] StringBuilder pszType, uint cchType);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetWindowRect(HandleRef hwnd, out RECT lpRect);
}

public enum GW : int
{
HWNDFIRST = 0,
HWNDLAST = 1,
HWNDNEXT = 2,
HWNDPREV = 3,
OWNER = 4,
CHILD = 5,
}


public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}

private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
}
list.Add(handle);
return true;
}

public String GetWindowCaption(int Hwnd)
{
const int nChars = 256;
StringBuilder builder = new StringBuilder(nChars);
String result = "";
if (User32.GetWindowText(Hwnd, builder, nChars) > 0 )
result = builder.ToString();
return result;
}

public IntPtr FindWindowByTitle(String WindowTitle)
{
Process[] p = Process.GetProcesses();
IntPtr hWnd;
foreach(Process proc in p)
{
if ((hWnd = proc.MainWindowHandle) != IntPtr.Zero)
{
if (GetWindowCaption(hWnd.ToInt32()).Contains(WindowT itle))
return hWnd;
}
}
return IntPtr.Zero;
}

public IntPtr[] GetChildWindows(IntPtr Parent)
{
List<IntPtr> children = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(children);
try
{
EnumWindowsProc childProc = new EnumWindowsProc(EnumWindow);
User32.EnumChildWindows(Parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return children.ToArray();
}

public String GetWindowC(IntPtr hWnd)
{
StringBuilder s = new StringBuilder();
User32.RealGetWindowClass(hWnd, s, 255);
return s.ToString();
}

public IntPtr SearchChildWindows(IntPtr[] ChildWindows, String caption)
{
foreach(IntPtr i in ChildWindows)
{
if (i != IntPtr.Zero)
{System.Console.WriteLine(GetWindowC(i));
if (GetWindowC(i).Contains(caption)) {
System.Console.WriteLine(";;;"+GetWindowC(i));
IntPtr x = new IntPtr(User32.GetWindow(i.ToInt32(), GW.CHILD));
while (User32.GetWindow(x.ToInt32(), GW.CHILD) != 0)
{
x = new IntPtr(User32.GetWindow(x.ToInt32(), GW.CHILD));
}
return x;
}
}
}
return IntPtr.Zero;
}

public IntPtr FindChildWindow(String parent, String childtext)
{
return SearchChildWindows(GetChildWindows(FindWindowByTit le(parent)), childtext);
}

public void CaptureScreen(string fileName,ImageFormat imageFormat)
{
RECT r;
User32.GetWindowRect(new HandleRef(this, FindChildWindow("RuneScape", "SunAwtCanvas")), out r);
int w = r.right-r.left;
int h = r.bottom-r.top;
IntPtr hWnd = FindChildWindow("RuneScape", "SunAwtCanvas");
int hdcSrc = User32.GetWindowDC(hWnd.ToInt32()),
hdcDest = GDI32.CreateCompatibleDC(hdcSrc),
hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, w, h);
User32.GetWindowRect(new HandleRef(this, FindChildWindow("RuneScape", "SunAwtCanvas")), out r);
System.Console.WriteLine("Width :" + (r.right-r.left) + " Height: "+(r.bottom-r.top));
GDI32.SelectObject(hdcDest,hBitmap);
GDI32.BitBlt(hdcDest,0,0,w,
h,hdcSrc,0,0,0x00CC0020);
SaveImageAs(hBitmap,fileName,imageFormat);
Cleanup(hBitmap,hdcSrc, hWnd, hdcDest);
}

private void Cleanup(int hBitmap,int hdcSrc, IntPtr hWnd, int hdcDest)
{
User32.ReleaseDC(hWnd.ToInt32(), hdcSrc);
GDI32.DeleteDC(hdcDest);
GDI32.DeleteObject(hBitmap);
}

private void SaveImageAs(int hBitmap,string fileName,ImageFormat imageFormat)
{

Bitmap image = new Bitmap(Image.FromHbitmap(new IntPtr(hBitmap)),
Image.FromHbitmap(new IntPtr(hBitmap)).Width,
Image.FromHbitmap(new IntPtr(hBitmap)).Height);
image.Save(fileName,imageFormat);
}

public static void Main(string[] args)
{
Program d = new Program();
d.CaptureScreen("C:/Users/Admin/RS.Png", ImageFormat.Png);
Thread.Sleep(10000);
}
}

}



Also, not going to take shit for not shortening code by 2 lines at some possible places, first time with C#

Freddy1990
01-09-2011, 10:58 PM
I'm almost a 100% sure that will get the whole window (e.g FireFox, not just the RuneScape applet) :(

I'm almost 100% sure it won't get the whole window... GetCursorPos + WindowFromPoint for the handle, GetWindowRect to get the window position to calculate relative coordinates :)

Only thing you rly need to dig into the client for is sending keys :)

mastaraymond
01-09-2011, 11:26 PM
But Simba is pascal isn't it?
Yes.. And you are capable of reading pascal, so what was your point again ;)

Frement
01-09-2011, 11:27 PM
Yes.. And you are capable of reading pascal, so what was your point again ;)

He just wanted to be spoon fed.

mastaraymond
01-09-2011, 11:31 PM
He just wanted to be spoon fed.
There is no spoon

n3ss3s
01-11-2011, 10:26 PM
I'm almost 100% sure it won't get the whole window... GetCursorPos + WindowFromPoint for the handle, GetWindowRect to get the window position to calculate relative coordinates

No, that's how you get the firefox window, you have to loop into the sun canvas... Posted the source above so no flame m8... Got everything working fine but now I'm getting a System.ArgumentException it a context that has a notorious reputation for random exceptions :mad:


Also above answers the


He just wanted to be spoon fed.



EDIT: managed to fix the shitface, was somehow caused by 2 pretty much consecutive calls of the method that uses getpixel, idk why but now its done..

Freddy1990
01-12-2011, 12:32 AM
No, that's how you get the firefox window, you have to loop into the sun canvas... Posted the source above so no flame m8... Got everything working fine but now I'm getting a System.ArgumentException it a context that has a notorious reputation for random exceptions :mad:

I don't see how that was flaming, but ok... Here's proof: http://freddy1990.com/files/ClientSel.rar
Open RS in firefox, drag the crosshair over it, see where ur cursor hits 0,0 on the app.

(Srr the app isn't pretty, but I hate using a touchpad xD )

n3ss3s
01-12-2011, 01:04 AM
Hmm, well to be honest I didn't actually try the mouse method as somehow at the time it seemed it would return the same handle as GetDesktopWindow... Also I didn't really mean that you were flaming me ;)

Freddy1990
01-12-2011, 01:52 AM
Yea, np, basically, you get other windows when you select the desktop because you can't actually see the desktop window, it's overlapped by a bunch of other windows that make up the desktop. For example, aside from the taskbar, you have a big empty space with your icons and background, you might think that would be the desktop window, but it's basically a big listview. :)

n3ss3s
01-13-2011, 02:24 AM
Woops sorry I meant GetForegroundWindow but yea...