AutoHotkey Community

It is currently May 27th, 2012, 11:23 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: July 11th, 2009, 8:08 pm 
I'm trying to create a custom console, but I'm having issues with the cloning, for starters, the console is not accepting an Enter. `n creates a new line, ControlSend, {Enter} doesn't work either. It works if I enter the command in the console myself. I have to FreeConsole/AttachConsole each time too, which is not good. Anybody know how to solve this? And better, how to do the same, but with a console in the gui window, like demonstrated by Lexicos?

I want to be able to simulate keystrokes, mouseclicks/moves, setcursor and have a streaming update in the Gui version of the console.

Code:
#SingleInstance force


Gui, Color, , Black
Gui, Add, Edit, x0 y0 w600 h400 cFFFFFF vRepConsole,
Gui, Color

Gui, Add, Edit, x0 y400 w520 h20 cFFFFFF vConsoleInput, cls
Gui, Add, Button, x528 y400 w60 h20 gNewConsoleInput, Enter

Gui, Show, , ConsoleTest


Run, %ComSpec% /k dir, %A_WinDir%,, cmdPid
WinWait, ahk_pid %cmdPid%, , 3
if ErrorLevel
{
  MsgBox, WinWait timed out.
  ExitApp
}

AttachConsole(cmdPid)
Sleep 500 ; is needed because otherwise the timer fails
SetTimer, UpdateGui, 50


Return

Write(txt) {

  ; do I really need to do it this way?
  global cmdPid
 
  FileAppend, % txt, CONOUT$
 

  DllCall("CloseHandle", "uint", hConIn)
  DllCall("CloseHandle", "uint", hConOut)
  DllCall("FreeConsole")
 
  Sleep 500
  ControlSend, , {Enter}, ahk_class ConsoleWindowClass
  Sleep 500
  AttachConsole(cmdPid)

}


NewConsoleInput:

  Gui, Submit, NoHide
  SetTimer, UpdateGui, Off
 
  Write(ConsoleInput)
  ;ConsoleSend(ConsoleInput, cmdPid)
 
  Sleep 500
  SetTimer, UpdateGui, On

Return

UpdateGui:
  ; do really I need a timer, or is there an OnMessage option?
  text := GetConsoleText()
  If text = %prevText%
    Return
  GuiControl, , RepConsole, % text
  prevText := text
Return

GuiClose:
DllCall("FreeConsole")
WinClose, ahk_pid %cmdPid%
ExitApp


; -----------------------------------

AttachConsole(pid)
{
  global hConOut, hConIn

  if !DllCall("AttachConsole","uint",pid)
      {
      MsgBox AttachConsole failed - error %A_LastError%.
      ExitApp
      }

  ; If it succeeded, console functions now operate on the target console window.
  ; Use CreateFile to retrieve a handle to the active console screen buffer.
  hConOut:=DllCall("CreateFile","str","CONOUT$","uint",0xC0000000
                      ,"uint",7,"uint",0,"uint",3,"uint",0,"uint",0)
  if hConOut = -1 ; INVALID_HANDLE_VALUE
      {
      MsgBox CreateFile failed - error %A_LastError%.
      ExitApp
      }
     
  hConIn := DllCall("CreateFile", "str", "CONIN$", "uint", 0xC0000000
                , "uint", 0x3, "uint", 0, "uint", 0x3, "uint", 0, "uint", 0)
  if hConIn = -1
      {
      MsgBox CreateFile failed - error %A_LastError%.
      ExitApp
      }
}


GetConsoleText()
{
  global hConOut
  ; Allocate memory for a CONSOLE_SCREEN_BUFFER_INFO structure.
  VarSetCapacity(info, 24, 0)
  ; Get info about the active console screen buffer.
  if !DllCall("GetConsoleScreenBufferInfo","uint",hConOut,"uint",&info)
      {
      MsgBox GetConsoleScreenBufferInfo failed - error %A_LastError%.
      ExitApp
      }

  ; Determine which section of the buffer is on display.
  ConWinLeft := NumGet(info, 10, "Short")     ; info.srWindow.Left
  ConWinTop := NumGet(info, 12, "Short")      ; info.srWindow.Top
  ConWinRight := NumGet(info, 14, "Short")    ; info.srWindow.Right
  ConWinBottom := NumGet(info, 16, "Short")   ; info.srWindow.Bottom
  ConWinWidth := ConWinRight-ConWinLeft+1
  ConWinHeight := ConWinBottom-ConWinTop+1
  ; Allocate memory to read into.
  VarSetCapacity(text, ConWinWidth*ConWinHeight, 0)
  ; Read text.

  if !DllCall("ReadConsoleOutputCharacter","uint",hConOut,"str",text
              ,"uint",ConWinWidth*ConWinHeight,"uint",0,"uint*",numCharsRead)
      {
      MsgBox ReadConsoleOutputCharacter failed - error %A_LastError%.
      ExitApp
      }

  /* Alternate, slower method:
      ; Allocate memory to read into.
      VarSetCapacity(buf, ConWinWidth*ConWinHeight*4, 0)
      ; Read an array of CHAR_INFO structures, containing text and attributes.
      ; Note: &info+10 is the address of a SMALL_RECT containing the coords we
      ; wish to read from. On success, it will receive the actual coords used.
      if !DllCall("ReadConsoleOutput","uint",hConOut,"uint",&buf
                      ,"uint",ConWinWidth|ConWinHeight<<16,"uint",0
                      ,"uint",&info+10)
          {
          MsgBox ReadConsoleOutput failed - error %A_LastError%.
          ExitApp
          }

      ; buf should now contain an array of CHAR_INFO structures.
      ; We must decode this to retrieve readable text.
      VarSetCapacity(text, ConWinWidth*ConWinHeight)
      Loop % ConWinWidth*ConWinHeight
          text .= Chr(NumGet(buf, 4*(A_Index-1), "Char"))
  */

  ; Optional: insert line breaks every %ConWinWidth% characters.
  text := RegExReplace(text, "`a).{" ConWinWidth "}(?=.)", "$0`n")
  ; Finally, display the text.
  Return text
}


; http://www.autohotkey.com/forum/topic27854.html

; ConsoleSend("Hooray, it works!", "ahk_class ConsoleWindowClass")

; Sends text to a console's input stream. WinTitle may specify any window in
; the target process. Since each process may be attached to only one console,
; ConsoleSend fails if the script is already attached to a console.
ConsoleSend(text, ConsoleID) ;WinTitle="", WinText="", ExcludeTitle="", ExcludeText="")
{
   
    ;pid := ConsoleID
       
    ;WinGet, pid, PID, %WinTitle%, %WinText%, %ExcludeTitle%, %ExcludeText%
   
   
    /*
    if !pid
        return false, ErrorLevel:="window"
    ; Attach to the console belonging to %WinTitle%'s process.
    if !DllCall("AttachConsole", "uint", pid)
        return false, ErrorLevel:="AttachConsole"
       
       
       
    hConIn := DllCall("CreateFile", "str", "CONIN$", "uint", 0xC0000000
                , "uint", 0x3, "uint", 0, "uint", 0x3, "uint", 0, "uint", 0)
    if hConIn = -1
        return false, ErrorLevel:="CreateFile"
   
    */
   
   
    Global hConIn ; moved to AttachConsole()
   
    VarSetCapacity(ir, 24, 0)       ; ir := new INPUT_RECORD
    NumPut(1, ir, 0, "UShort")      ; ir.EventType := KEY_EVENT
    NumPut(1, ir, 8, "UShort")      ; ir.KeyEvent.wRepeatCount := 1
    ; wVirtualKeyCode, wVirtualScanCode and dwControlKeyState are not needed,
    ; so are left at the default value of zero.
   
    Loop, Parse, text ; for each character in text
    {
        NumPut(Asc(A_LoopField), ir, 14, "UShort")
       
        NumPut(true, ir, 4, "Int")  ; ir.KeyEvent.bKeyDown := true
        gosub ConsoleSendWrite
       
        NumPut(false, ir, 4, "Int") ; ir.KeyEvent.bKeyDown := false
        gosub ConsoleSendWrite
    }
    gosub ConsoleSendCleanup
    return true
   
    ConsoleSendWrite:
        if ! DllCall("WriteConsoleInput", "uint", hconin, "uint", &ir, "uint", 1, "uint*", 0)
        {
            gosub ConsoleSendCleanup
            return false, ErrorLevel:="WriteConsoleInput"
        }
    return
   
    ConsoleSendCleanup:
   
        if (hConIn!="" && hConIn!=-1)
            DllCall("CloseHandle", "uint", hConIn)
        ; Detach from %WinTitle%'s console.
        DllCall("FreeConsole")
    return
}




Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: July 12th, 2009, 11:54 am 
Bump. Is it really not possible to clone a console window? So that everything is exactly mirrored?

Halp...

:?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: July 20th, 2009, 2:09 pm 
Ok, I got a little bit further with this.

Issues I still have are with results greater than the screenbuffer size, and auto-scrolling to the bottom of the result (the last console line).

If the result of the console command is larger than the 80x25 buffer, for example if I use the "dir" command on a large folder, the script will not show all output. Any way of changing this?

Code:
#NoEnv
#SingleInstance force
SetBatchLines -1
SendMode Input
SetWorkingDir %A_ScriptDir%

OnExit, DoExit


  Run %comspec% /k , , , pid
  WinWait, ahk_pid %pid%, , 3
  AttachConsole(pid)
  if ErrorLevel
  {
      MsgBox, WinWait timed out.
      ExitApp
    }

    Gui, Font, s10, Lucida Console
  Gui, Color, Default, 000000
  Gui, Add, Edit, x0 y0 w662 h300 cFFFFFF hwndRepHwnd vRepConsole,
  Gui, Add, Edit, x0 y320 w540 h20 cFFFFFF vSendToConsole, ping 127.0.0.1
  Gui, Font
  Gui, Add, Button, x550 y320 w40 h20 gDoSend, Go
  Gui, Show, w662 h340, AttachConsole by Lexicos
 
  SetTimer, UpdateGui, 50
 
  Gosub DoSend
 
Return

DoSend:
    Gui, Submit, NoHide
    ConsoleSend(pid, SendToConsole)
Return

UpdateGui:
    text := GetConsoleText()
    If text = %prevText%
        Return
    GuiControl, , RepConsole, % text

    ; 0x115 is WM_VSCROLL, 7 is SB_BOTTOM
    SendMessage, 0x115, 7, 0, , ahk_id %RepHwnd%

    prevText := text
Return

AttachConsole(pid)
{
  global hConOut
  ; AttachConsole accepts a process ID.
  if !DllCall("AttachConsole","uint",pid)
  {
      MsgBox AttachConsole failed - error %A_LastError%.
      ExitApp
  }
  ; If it succeeded, console functions now operate on the target console window.
  ; Use CreateFile to retrieve a handle to the active console screen buffer.
  hConOut:=DllCall("CreateFile","str","CONOUT$","uint",0xC0000000
                      ,"uint",7,"uint",0,"uint",3,"uint",0,"uint",0)
  if hConOut = -1 ; INVALID_HANDLE_VALUE
  {
      MsgBox CreateFile failed - error %A_LastError%.
      ExitApp
  }
}

GetConsoleText()
{
  global hConOut
  ; Allocate memory for a CONSOLE_SCREEN_BUFFER_INFO structure.
  VarSetCapacity(info, 24, 0)
  ; Get info about the active console screen buffer.
  if !DllCall("GetConsoleScreenBufferInfo","uint",hConOut,"uint",&info)
  {
      MsgBox GetConsoleScreenBufferInfo failed - error %A_LastError%.
      ExitApp
  }
  ; Determine which section of the buffer is on display.
  ConWinLeft := NumGet(info, 10, "Short")     ; info.srWindow.Left
  ConWinTop := NumGet(info, 12, "Short")      ; info.srWindow.Top
  ConWinRight := NumGet(info, 14, "Short")    ; info.srWindow.Right
  ConWinBottom := NumGet(info, 16, "Short")   ; info.srWindow.Bottom
  ConWinWidth := ConWinRight-ConWinLeft+1
  ConWinHeight := ConWinBottom-ConWinTop+1
  ; Allocate memory to read into.
  VarSetCapacity(text, ConWinWidth*ConWinHeight, 0)
  ; Read text.
  ;/*
  if !DllCall("ReadConsoleOutputCharacter","uint",hConOut,"str",text
              ,"uint",ConWinWidth*ConWinHeight,"uint",0,"uint*",numCharsRead)
  {
      MsgBox ReadConsoleOutputCharacter failed - error %A_LastError%.
      ExitApp
  }
  ;*/
  /* Alternate, slower method:
      ; Allocate memory to read into.
      VarSetCapacity(buf, ConWinWidth*ConWinHeight*4, 0)
      ; Read an array of CHAR_INFO structures, containing text and attributes.
      ; Note: &info+10 is the address of a SMALL_RECT containing the coords we
      ; wish to read from. On success, it will receive the actual coords used.
      if !DllCall("ReadConsoleOutput","uint",hConOut,"uint",&buf
                      ,"uint",ConWinWidth|ConWinHeight<<16,"uint",0
                      ,"uint",&info+10)
      {
          MsgBox ReadConsoleOutput failed - error %A_LastError%.
          ExitApp
      }
      ; buf should now contain an array of CHAR_INFO structures.
      ; We must decode this to retrieve readable text.
      VarSetCapacity(text, ConWinWidth*ConWinHeight)
      Loop % ConWinWidth*ConWinHeight
          text .= Chr(NumGet(buf, 4*(A_Index-1), "Char"))
  */
  ; Optional: insert line breaks every %ConWinWidth% characters.
  text := RegExReplace(text, "`a).{" ConWinWidth "}(?=.)", "$0`n")
  ; Finally, display the text.
  Return text
}

; Sends text to a console's input stream. WinTitle may specify any window in
; the target process. Since each process may be attached to only one console,
; ConsoleSend fails if the script is already attached to a console.
ConsoleSend(pid, text) ; (text, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="")
{
   
    text .= "`r`n" ; new line/return in console
   
    ;WinGet, pid, PID, %WinTitle%, %WinText%, %ExcludeTitle%, %ExcludeText%
    if !pid
        return false, ErrorLevel:="window"
    ; Attach to the console belonging to %WinTitle%'s process.
    ;if !DllCall("AttachConsole", "uint", pid)
    ;    return false, ErrorLevel:="AttachConsole"
    hConIn := DllCall("CreateFile", "str", "CONIN$", "uint", 0xC0000000
                , "uint", 0x3, "uint", 0, "uint", 0x3, "uint", 0, "uint", 0)
    if hConIn = -1
        return false, ErrorLevel:="CreateFile"
   
    VarSetCapacity(ir, 24, 0)       ; ir := new INPUT_RECORD
    NumPut(1, ir, 0, "UShort")      ; ir.EventType := KEY_EVENT
    NumPut(1, ir, 8, "UShort")      ; ir.KeyEvent.wRepeatCount := 1
    ; wVirtualKeyCode, wVirtualScanCode and dwControlKeyState are not needed,
    ; so are left at the default value of zero.
   
    Loop, Parse, text ; for each character in text
    {
        NumPut(Asc(A_LoopField), ir, 14, "UShort")
       
        NumPut(true, ir, 4, "Int")  ; ir.KeyEvent.bKeyDown := true
        gosub ConsoleSendWrite
       
        NumPut(false, ir, 4, "Int") ; ir.KeyEvent.bKeyDown := false
        gosub ConsoleSendWrite
    }
    ;gosub ConsoleSendCleanup
    return true
   
    ConsoleSendWrite:
        if ! DllCall("WriteConsoleInput", "uint", hconin, "uint", &ir, "uint", 1, "uint*", 0)
        {
            ;gosub ConsoleSendCleanup
            return false, ErrorLevel:="WriteConsoleInput"
        }
    return
   
    ;ConsoleSendCleanup:
        ;if (hConIn!="" && hConIn!=-1)
         ;   DllCall("CloseHandle", "uint", hConIn)
        ; Detach from %WinTitle%'s console.
        ;DllCall("FreeConsole")
    ;return
}


DoExit:
GuiClose:
  WinClose ahk_pid %pid%
  ExitApp


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: July 20th, 2009, 10:13 pm 
Ok, got it working so far, so good. If you are interested, here it is. Remove the Hide in the Run line to show the original console

Code:
#NoEnv
#SingleInstance force
SetBatchLines -1
SetWinDelay, 0
DetectHiddenWindows on
SendMode Input

OnExit, DoExit

currWD := A_ScriptDir
prevWD := currWD

  Run %comspec% /k , %currWD%, Hide, pid
  WinWait, ahk_pid %pid%, , 3
  AttachConsole(pid)
  if ErrorLevel
  {
      MsgBox, WinWait timed out.
      ExitApp
    }

    Gui, Font, s10, Lucida Console
  Gui, Color, Default, 000000
  Gui, Add, Edit, x0 y0 w662 h20 cFFFFFF vSendToConsole,
  Gui, Add, Edit, x0 y20 w662 h20 cFFFFFF vWorkingDir, %currWD%

  Gui, Add, Edit, x0 y40 w662 h300 cFFFFFF hwndRepHwnd vRepConsole,
 
  Gui, Font
  Gui, Add, Button, x550 y320 w40 h20 Hide +Default gDoSend vGoButton, Go
  Gui, Show, w662 h340, Alternative Console
 
 
    isRunning := 0
  SetTimer, UpdateGui, 50
 
  GuiControl, Focus, SendToConsole
 
Return

  ; 1252   windows-1252   ANSI Latin 1; Western European (Windows)
  ;MsgBox % DllCall("GetConsoleCP")

DoSend:

    If isRunning
        Return

    Gui, Submit, NoHide
   
    ; commands to filter
    StringGetPos, firstSpace, SendToConsole, %A_Space%
    If (firstSpace = -1)
        commandBeingSent := SendToConsole
    Else
        StringLeft, commandBeingSent, SendToConsole, %firstSpace%
   
    ; cmd, telnet
    If commandBeingSent in cmd,telnet
    {
        MsgBox Don't use %commandBeingSent%!
        Return
    }

    isRunning := 1

    ConsoleSend(pid, SendToConsole)
Return


StrTail(k,str) {  ; Return the last k lines of str
   Loop Parse, str, `n
      i := Mod(A_Index,k), L%i% := A_LoopField
   Loop % k
      i := Mod(i+1,k), L .= L%i% "`n"
    StringTrimRight, L, L, 1
   Return L
}


UpdateGui:

    ; get text
    newText := GetConsoleText()
   
    ; if no change, do nothing, return
    If (newText = prevText)
        Return
   
    ; empty input
    GuiControl, , SendToConsole,

    ; autotrim removes trailing tabs/spaces when used like this
    newText2 = %newText%
   
    ; replace wrong showing chars
    StringReplace, newText2, newText2, �, ΓΌ, All
   
    ; add line breaks (from function)
    newText2 := RegExReplace(newText2, "`a).{" 80 "}(?=.)", "$0`n")
   
    ; get last line
    lastline := strtail(1,newText2)
   
    ; is done?
    If RegExMatch(lastline, "^.*:\\(.*)>") ; is prompt?
    {
        If !InStr(lastline, prevWD . ">" . SendToConsole) ; is not input?
        {
            ; assume is done
           
            ; extract working dir
            StringGetPos, promptPos, lastline, >
            StringLeft, currWD, lastline, %promptPos% 
            GuiControl, , WorkingDir, % currWD
           
            prevWD := currWD
            isRunning := 0
       
            GuiControl, Enable, SendToConsole ; enable input
        }
    }

    ; update edit
    GuiControl, , RepConsole, % newText2

    ; scroll to bottom of edit, 0x115 is WM_VSCROLL, 7 is SB_BOTTOM
    SendMessage, 0x115, 7, 0, , ahk_id %RepHwnd%

    prevText := newText
Return

AttachConsole(pid)
{
  global hConOut
  ; AttachConsole accepts a process ID.
  if !DllCall("AttachConsole","uint",pid)
  {
      MsgBox AttachConsole failed - error %A_LastError%.
      ExitApp
  }
  ; If it succeeded, console functions now operate on the target console window.
  ; Use CreateFile to retrieve a handle to the active console screen buffer.
  hConOut:=DllCall("CreateFile","str","CONOUT$","uint",0xC0000000
                      ,"uint",7,"uint",0,"uint",3,"uint",0,"uint",0)
  if hConOut = -1 ; INVALID_HANDLE_VALUE
  {
      MsgBox CreateFile failed - error %A_LastError%.
      ExitApp
  }
}

GetConsoleText()
{
  global hConOut
  ; Allocate memory for a CONSOLE_SCREEN_BUFFER_INFO structure.
  VarSetCapacity(info, 24, 0)
  ; Get info about the active console screen buffer.
  if !DllCall("GetConsoleScreenBufferInfo","uint",hConOut,"uint",&info)
  {
      MsgBox GetConsoleScreenBufferInfo failed - error %A_LastError%.
      ExitApp
  }
  ; Determine which section of the buffer is on display.
  ConWinLeft := NumGet(info, 10, "Short")     ; info.srWindow.Left
  ConWinTop := NumGet(info, 12, "Short")      ; info.srWindow.Top
  ConWinRight := NumGet(info, 14, "Short")    ; info.srWindow.Right
  ConWinBottom := NumGet(info, 16, "Short")   ; info.srWindow.Bottom
  ConWinWidth := ConWinRight-ConWinLeft+1
  ConWinHeight := ConWinBottom-ConWinTop+1
  ; Allocate memory to read into.
 
  ; bigger buffer
  ConWinHeight := 4 * 80
 
  VarSetCapacity(text, ConWinWidth*ConWinHeight, 0)
  ; Read text.
  ;/*
  if !DllCall("ReadConsoleOutputCharacter","uint",hConOut,"str",text
              ,"uint",ConWinWidth*ConWinHeight,"uint",0,"uint*",numCharsRead)
  {
      MsgBox ReadConsoleOutputCharacter failed - error %A_LastError%.
      ExitApp
  }

  ; Optional: insert line breaks every %ConWinWidth% characters.
  ;text := RegExReplace(text, "`a).{" ConWinWidth "}(?=.)", "$0`n")
 
  ; Finally, display the text.
  Return text
}

; Sends text to a console's input stream. WinTitle may specify any window in
; the target process. Since each process may be attached to only one console,
; ConsoleSend fails if the script is already attached to a console.
ConsoleSend(pid, text) ; (text, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="")
{
   
    text .= "`r`n" ; new line/return in console
   
    ;WinGet, pid, PID, %WinTitle%, %WinText%, %ExcludeTitle%, %ExcludeText%
    if !pid
        return false, ErrorLevel:="window"
    ; Attach to the console belonging to %WinTitle%'s process.
    ;if !DllCall("AttachConsole", "uint", pid)
    ;    return false, ErrorLevel:="AttachConsole"
    hConIn := DllCall("CreateFile", "str", "CONIN$", "uint", 0xC0000000
                , "uint", 0x3, "uint", 0, "uint", 0x3, "uint", 0, "uint", 0)
    if hConIn = -1
        return false, ErrorLevel:="CreateFile"
   
    VarSetCapacity(ir, 24, 0)       ; ir := new INPUT_RECORD
    NumPut(1, ir, 0, "UShort")      ; ir.EventType := KEY_EVENT
    NumPut(1, ir, 8, "UShort")      ; ir.KeyEvent.wRepeatCount := 1
    ; wVirtualKeyCode, wVirtualScanCode and dwControlKeyState are not needed,
    ; so are left at the default value of zero.
   
    Loop, Parse, text ; for each character in text
    {
        NumPut(Asc(A_LoopField), ir, 14, "UShort")
       
        NumPut(true, ir, 4, "Int")  ; ir.KeyEvent.bKeyDown := true
        gosub ConsoleSendWrite
       
        NumPut(false, ir, 4, "Int") ; ir.KeyEvent.bKeyDown := false
        gosub ConsoleSendWrite
    }
    ;gosub ConsoleSendCleanup
    return true
   
    ConsoleSendWrite:
        if ! DllCall("WriteConsoleInput", "uint", hconin, "uint", &ir, "uint", 1, "uint*", 0)
        {
            ;gosub ConsoleSendCleanup
            return false, ErrorLevel:="WriteConsoleInput"
        }
    return
   
    ;ConsoleSendCleanup:
        ;if (hConIn!="" && hConIn!=-1)
         ;   DllCall("CloseHandle", "uint", hConIn)
        ; Detach from %WinTitle%'s console.
        ;DllCall("FreeConsole")
    ;return
}


^!r::Reload

DoExit:
GuiClose:

  WinClose ahk_pid %pid%
  ExitApp


8)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: July 20th, 2009, 11:47 pm 
Some of you might know Console2.

I just found out it doesn't use an attached console, but it reads from the console's memory. This way it can use multiple consoles (tabs), which cannot be done with AttachConsole. It also handles telnet.

Anybody any clue how to read the screenbuffer from memory with AutoHotkey like Console2 does?


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: September 7th, 2009, 5:55 am 
i am not sure if its a bug or is it because the scroll bar is turned off


Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 20 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group