Page 2 of 2 FirstFirst 12
Results 11 to 15 of 15
  1. #11
    Join Date
    Oct 2002
    Location
    Leicester, UK
    Posts
    3,335
    You could use FindWindowEx() to search for the window handle for the menu - using the menu class. Unfortunately I couldn't find the name given to a menu class.

    Or you could use GetSystemMenu() to get the system menu and then GetSubMenu() to get the Edit menu. GetMenuItemInfo() to get the ID of the "Select All" and "Copy" menu items and then send them via WM_COMMAND messages.

    Alternatively, you could use EnumWindows() or EnumChildWindows() and examine each enumerated window to see which one contains the text of the menu. IsMenu() would help.

    WindowFromPoint() might be another solution to find the handle for the menu.

    I don't understand why the console functions won't work. The screenshot you posted shows "cmd.exe" in the title bar.
    Last edited by keithathaide; 03-27-2006 at 08:40 PM.
    Forget the username, call me Keith

  2. #12
    Join Date
    Dec 2004
    Location
    Wisconsin
    Posts
    1,422
    Quote Originally Posted by keithathaide
    I don't understand why the console functions won't work. The screenshot you posted shows "cmd.exe" in the title bar.
    I just realized what you meant be console functions - looked it up, and found (to my dismay) a really simple answer to me problem - but I'm still not sure about how to use it.

    ReadConsoleOutput() has five parameters:

    HANDLE hConsoleOutput
    A handle which I can get from FindActiveWindow(), yea?

    PCHAR_INFO lpBuffer
    I'm assuming I need to creating this, and it holds what the console's text, right?

    COORD dwBufferSize
    This is the size of the area (rows and coloums) that is held in the console, correct? If so, how do I find out the size?

    COORD dwBufferCoord
    I'm not sure what this means, is it the position from which to start reading data?

    PSMALL_RECT lpReadRegion
    This is a rectangle on the console from which to read the data - but how would I specify all of it? Just pass NULL?


    Also - it seems as though Char_Info is just a one character buffer. If that is true, then I am very confused as to this bit of code from MSDN
    Code:
        //fSuccess is a bool
        fSuccess = ReadConsoleOutput( 
           hStdout,        // screen buffer to read from 
           chiBuffer,      // buffer to copy into 
           coordBufSize,   // col-row size of chiBuffer 
           coordBufCoord,  // top left dest. cell in chiBuffer 
           &srctReadRect); // screen buffer source rectangle

    Any help is much appreciated

  3. #13
    Join Date
    Oct 2002
    Location
    Leicester, UK
    Posts
    3,335
    Here's a simple example (C++):

    Code:
    CHAR_INFO buffer[20];
    COORD bufferSize = {5, 4};
    COORD bufferCoord = {0, 0};
    SMALL_RECT readRegion = {0, 0, 100, 100};
    
    AttachConsole(processId);
    
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    ReadConsoleOutput(hConsole, buffer, bufferSize, bufferCoord, &readRegion);
    FreeConsole();
    This example assumes the process identifier has been obtained either by enumerating processes or by a call to GetWindowThreadProcessId(). This is the process identifier of the application from which the characters will be read.

    A program is not allowed to have two consoles, so if your own program has a console, call FreeConsole() before the snippet above.

    lpBuffer does store the text. dwBufferSize specifies the area you want. If you wish to get a 4x5 block as above, then set Y to 4 and X to 5. Yes, dwBufferCoord is the origin of the block (zero-based values). In the example above, I started reading from the top left corner. lpReadRegion is the region you want - the values are clamped to what is specified in dwBufferSize.

    To give an analogy, say you want to copy a portion of your screen (the console) to a bitmap in memory (lpBuffer). To do this, you need the bitmap in memory, the size of the bitmap in memory (dwBufferSize) and the dimensions and location of the area of the screen you wish to copy (lpReadRegion). Now suppose you were taking different areas of the screen and copying them to the same bitmap in different locations - in this case the location at which to start copying to the in-memory bitmap is required (dwBufferCoord). Sort of like a BitBlt().

    If you don't need all the attribute information, and only need to read one line of characters at a time (not a block), you can use ReadConsoleOutputCharacter(). Example:

    Code:
    TCHAR buffer[20];
    COORD coord = {0, 0};
    DWORD nRead;
    
    AttachConsole(processId);
    
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    ReadConsoleOutputCharacter(hConsole, buffer, 19, coord, &nRead);
    FreeConsole();
    Forget the username, call me Keith

  4. #14
    Join Date
    Mar 2004
    Posts
    0
    ok man, i wrote up a quick little API for you to use in C# called "ConsoleHacker". you can use it to get the text you want. there is also a sample app included to show you how to use it.

    basicly, just use the static class ConsoleHacker to enumerate all running procs on your system by calling the "RunningProcs" property. this will give you an array of a class caled ProcInfos which contains the proc's name and its ID in IntPtr form. use this to find the proc you want, then call ConsoleHacker's 'AttachTo' method with the ID of the proc you want. Then call the 'ReadOutput' function on ConsoleHacker which needs the starting point of where to copy, and the size of the rect you want to copy (for example, if you want to copy the first 75 chars of the first five lines starting at the second line, you would pass in (0, 2) for startPoint and (75, 5) for the sizeOf). the size of the returned array's size is sizeOf.Width * sizeOf.Height.
    the returned array is of CharInfo structs which contain the char, and an 'attribute' enum which has all the color information about the cell in the console.
    you will have to manualy seperate the text into lines, but all you have to do (in the case of the example above) is insert line breaks every 75 charecters.

    then, when you are done, call ConsoleHacker's RemoveFrom() method to detach from the console.


    also, a side note, if you try to attach and retrive console output from a non console application, you will have to restart the ConsoleHacker app before you can reatach to a console app. if someone can tell me how to make sure a proc is a console app, it would be aprechated.

    anyway, here ya go!
    Attached Files Attached Files

  5. #15
    Join Date
    Dec 2004
    Location
    Wisconsin
    Posts
    1,422
    DUDE! That was awesome, exactly what I needed - I actually was working on some very similar code, which not surprisingly wasn't working very well

    Thanks a bunch!



    Off-topic... check out this pic.. maybe a vbBulletin bug? Kinda strange.. do you have a timemachine you are hiding from us MH?
    Last edited by ChadStout; 04-03-2006 at 06:25 PM.

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •