• Console Window - subclassing (capturing WM_PAINT) : How ?

    From R.Wieser@21:1/5 to All on Sat Sep 17 13:49:11 2022
    Hello all,

    I'm trying to draw some simple graphics (dots, lines) into a windowed
    console.

    Although grabbing its DC and use that to draw on works, any updating of the screen by the running program (partially) causes havoc - from the drawing
    being partially erased to it fully disappearing.

    So, I'm looking for a way to subclass a console window so I can intercept
    its WM_PAINT message, and redraw my stuff after an update of the window
    occurs.

    The problem is that although I have a hWnd to the console, a 'SetWindowSubclass' fails (incorrect parameter), and a GetWindowLong GWL_WINPROC returns Zero (whut ?).

    This morning I've been searching the intarnetz for information on how to intercept WM_* messages of a console window, but I've not been able to find anything in that direction. :-\

    Anyone knows how to do it and wants to share ?

    Target OS: XPsp3

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul N@21:1/5 to R.Wieser on Sat Sep 17 09:47:20 2022
    On Saturday, September 17, 2022 at 12:49:20 PM UTC+1, R.Wieser wrote:
    Hello all,

    I'm trying to draw some simple graphics (dots, lines) into a windowed console.

    Although grabbing its DC and use that to draw on works, any updating of the screen by the running program (partially) causes havoc - from the drawing being partially erased to it fully disappearing.

    So, I'm looking for a way to subclass a console window so I can intercept its WM_PAINT message, and redraw my stuff after an update of the window occurs.

    The problem is that although I have a hWnd to the console, a 'SetWindowSubclass' fails (incorrect parameter), and a GetWindowLong GWL_WINPROC returns Zero (whut ?).

    This morning I've been searching the intarnetz for information on how to intercept WM_* messages of a console window, but I've not been able to find anything in that direction. :-\

    Anyone knows how to do it and wants to share ?

    Target OS: XPsp3

    I thought the basic idea of a console was that you weren't going to do that sort of thing?

    I don't know how to do what you want to do, and I'm not even sure if it's possible. A possible way round things though - why don't you have a normal window, with a big multi-line edit box covering some or all of it, and "print" text by adding it to the
    text in the box?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sun Sep 18 09:00:26 2022
    Paul,

    I thought the basic idea of a console was that you weren't going to do
    that sort of thing?

    Well ... I've been using graphics in a console windows for years thru QBASIC (and INT 0x10). Yep, I'm working with/looking at DOS programs there. :-)

    The problem is that one of my 'puters has a /very/ basic video card, which
    just causes the puter to lockup (needing a hard reset) whenever I now try.
    :-(

    So, I'm looking for something to keep everything in textmode, but add the graphics as an "overlay".

    I don't know how to do what you want to do, and I'm not even sure if
    it's possible.

    I'm not sure either. But I'm trying different things to see if something
    works better than directly drawing to the windows DC (which does work, just badly).

    A possible way round things though - why don't you have a normal window,
    with a big multi-line edit box covering some or all of it, and "print"
    text by adding it to the text in the box?

    That would work if I could redirect all the text output to code I control. Alas, old DOS programs sometimes (often?) write directly to the text memory (0xB800 IIRC), which is rather hard to intercept. The above-mentioned
    QBASIC program is one of them.

    Thanks for the suggestion though.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Sun Sep 18 13:40:07 2022
    On Sat, 17 Sep 2022 13:49:11 +0200, R.Wieser wrote:
    Hello all,

    I'm trying to draw some simple graphics (dots, lines) into a windowed console.

    Although grabbing its DC and use that to draw on works, any updating of the screen by the running program (partially) causes havoc - from the drawing being partially erased to it fully disappearing.

    So, I'm looking for a way to subclass a console window so I can intercept
    its WM_PAINT message, and redraw my stuff after an update of the window occurs.

    The problem is that although I have a hWnd to the console, a 'SetWindowSubclass' fails (incorrect parameter), and a GetWindowLong GWL_WINPROC returns Zero (whut ?).

    This morning I've been searching the intarnetz for information on how to intercept WM_* messages of a console window, but I've not been able to find anything in that direction. :-\

    Anyone knows how to do it and wants to share ?

    Target OS: XPsp3

    Regards,
    Rudy Wieser

    Have you tried using `SetWindowLong()` or `SetClassLong()` instead?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sun Sep 18 15:47:52 2022
    JJ,

    Have you tried using `SetWindowLong()` or `SetClassLong()` instead?

    Neither. The first because reading the GWLWNDPROC returned zero, and the second because only want to affect a specific console window, not all of
    them.

    But you're right, I could at least try to see what happens.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Sun Sep 18 16:14:41 2022
    JJ,

    [quote=me]
    But you're right, I could at least try to see what happens.
    [/quote]

    Alas, changing either/both doesn't give any kind of different result. No intercepted messages, nothing throwing a hissy fit either. Its as if I've
    done nothing at all.

    Worse: changing both GWL_WNDPROC and CWL_WNDPROC and checking them later
    shows the same values as before I made the change. IOW, its as if setting
    them is ignored.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Mon Sep 19 15:16:53 2022
    On Sun, 18 Sep 2022 16:14:41 +0200, R.Wieser wrote:

    Alas, changing either/both doesn't give any kind of different result. No intercepted messages, nothing throwing a hissy fit either. Its as if I've done nothing at all.

    Worse: changing both GWL_WNDPROC and CWL_WNDPROC and checking them later shows the same values as before I made the change. IOW, its as if setting them is ignored.

    I think the system has an unconditional hardcoded protection for console
    window message handler, since GetWindowLong returns zero with an access
    denied error code when the console application is run using the SYSTEM
    account. Weirdly, if the console application is not run using the SYSTEM account, GetWindowLong returns a kernel-space pointer (e.g. 0xFFFF0501) with
    a success error code.

    This conclusion is based on the fact that, an application run using the
    SYSTEM account can terminate CSRSS.EXE and BSOD-ed the system. So, if it
    can't subclass the console window, it should mean that, the system has prevented it unconditionally - regardless of user credentials and
    privileges. Because IMO, it's unbelievable to think that a console window message handler is more crucial than CSRSS.EXE.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Mon Sep 19 11:52:36 2022
    JJ,

    GetWindowLong returns a kernel-space pointer (e.g. 0xFFFF0501)

    Hmmm.. In my case (XPsp3) GetWindowLong returned Zero, and getClassLong returned a kernel-space pointer. I must say that I didn't try to check for
    an error though (didn't realize that the standard GWL_* GCL_* indices could throw them).

    This conclusion is based on the fact that, an application run using
    the SYSTEM account can terminate CSRSS.EXE and BSOD-ed the system.
    So, if it can't subclass the console window, it should mean that,
    the system has prevented it unconditionally - regardless of user
    credentials and privileges.

    My focus is userland, so I again didn't even think of trying it under
    different accounts. But thank you for the testing (and posting it :-) ).

    Because IMO, it's unbelievable to think that a console window
    message handler is more crucial than CSRSS.EXE.

    Hmmmm... I'm allowed to tinker around with most all GUI windows, but am not allowed to do the same with a console one. I'm not so sure I understand
    that distinction.

    But, as doing anything with a console window is either not allowed or is
    iffy I'm already looking in another direction (creating a GUI window and sending the graphical data to it).

    By the way, I also tried to use VESA, but that locked up the 'puter as well. :-\ I knew (was warned about it that) the NVIDIA GT 730 video card is a simple one, but *that* simple ?...

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Tue Sep 20 15:21:48 2022
    On Mon, 19 Sep 2022 11:52:36 +0200, R.Wieser wrote:

    My focus is userland, so I again didn't even think of trying it under different accounts. But thank you for the testing (and posting it :-) ).

    That was a userland test, but using the SYSTEM account rather than an
    account member of the Administrator group.

    Hmmmm... I'm allowed to tinker around with most all GUI windows, but am not allowed to do the same with a console one. I'm not so sure I understand that distinction.

    To my understanding, console window is a protected window. Since Vista, it's even more protected, by separating the handler in a separate CONHOST.EXE process which is spawned by CSRSS.EXE for each console window. Perhaps the contents of the console window is rendered in a special way, which I
    suspect, is handled directly from kernel-space. Because that would explain
    the blazingly fast rendering of a console window content. If we try to
    create our own "console" window class using our own renderer, it will never
    be as fast as the real console.

    By the way, I also tried to use VESA, but that locked up the 'puter as well.
    :-\ I knew (was warned about it that) the NVIDIA GT 730 video card is a
    simple one, but *that* simple ?...

    What do you mean "use VESA"? AFAIK, Windows doesn't expose any of the
    display adapter's VESA API.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Tue Sep 20 10:47:24 2022
    JJ,

    What do you mean "use VESA"? AFAIK, Windows doesn't expose any of
    the display adapter's VESA API.

    My problem started with a DOS program (QBASIC) locking up when I tried to switch sceen modus ("screen 13", 640x640, 256 color graphics).

    I stayed in DOS and checked INT 0x10, AH=0x00 to see if it would make a difference. It didn't. Than I also tried VESA (INT 0x10, AH=0x4E) with a modus returned by the card itself(?) (INT 0x10 AX=4E00). No workie either.

    And before you ask: I'm using the BOP method to transfer data from the DOS environment to the Windows one : http://sta.c64.org/blog/dosvddaccess.html

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to R.Wieser on Tue Sep 27 11:02:46 2022
    "R.Wieser" <address@not.available> wrote in message news:tg4c7r$148$1@gioia.aioe.org...
    Hello all,

    I'm trying to draw some simple graphics (dots, lines) into a windowed console.
    ...
    Anyone knows how to do it and wants to share ?

    I found some almost decade-old code that does it here :

    http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/

    Although there are a number of restrictions, it shows that you can indeed
    use the console window for graphics output. :-)

    Alas, as it doesn't draw the graphics over the already existing text (and
    only works in a windowed console) its not really usefull toward my own goal. :-\

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Wed Sep 28 18:51:18 2022
    On Tue, 27 Sep 2022 11:02:46 +0200, R.Wieser wrote:

    I found some almost decade-old code that does it here :

    http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/

    Although there are a number of restrictions, it shows that you can indeed
    use the console window for graphics output. :-)

    That's interresting. I forgot that, console was designed to be able to
    present graphic content from DOS based programs while still being windowed.

    You can only create graphics buffers on 32-bit versions of Windows [4].

    Kind of expected that, since 64-bit Windows no longer support 16-bit
    programs. But... FUUU!!

    Alas, as it doesn't draw the graphics over the already existing text (and only works in a windowed console) its not really usefull toward my own goal.
    :-\

    That may be worked around by hooking the drawing function and if necessary,
    use an off-screen console graphic buffer, but I suspect that the code which
    use the function is in kernel space.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to Having on Wed Sep 28 14:56:16 2022
    JJ,

    You can only create graphics buffers on 32-bit versions of Windows [4].

    Kind of expected that, since 64-bit Windows no longer support 16-bit programs. But... FUUU!!

    I'm not so sure it has anything to do with 16-bit programs : In the example
    the console buffer itself is 32 bits, as is the program feeding it.

    Having said that, I've got no idea what actually prohibits it.

    Alas, as it doesn't draw the graphics over the already existing text
    (and only works in a windowed console) its not really usefull toward
    my own goal. :-\

    That may be worked around by hooking the drawing function

    :-) That was what I was looking for, but have not been able to find.

    I /could/ do it the other way around I suppose : grab a copy of the target window(s graphics), draw my own stuff over it and present that as the new
    data. But again, no synchronisation between the two.

    And I got caught out by the example : I implemented that code and got zero result from it. ...Until I realized that I was running the code in a fullscreen 80x25 console, and not from a windowed one. After I switched
    over the image did indeed appear. :-)


    By the way : I got something to work with that BOP method, but ultimatily decided against it - the intermediate DLL needs to be registered *and unregistered* in the DOS program. Fail to unregister it and the next usage doesn't give the desired result. :-|

    As switching to a DOS graphics mode isn't possible (on that one machine) and
    as such I'm forced to use a windowed console anyway I thought of just using
    a standard Windows dialog and communicate with it (from within the DOS
    program) thru a 'named pipe' (which I can just "print" to). Seems to work alright.

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JJ@21:1/5 to R.Wieser on Thu Sep 29 23:58:43 2022
    On Wed, 28 Sep 2022 14:56:16 +0200, R.Wieser wrote:

    I'm not so sure it has anything to do with 16-bit programs : In the example the console buffer itself is 32 bits, as is the program feeding it.

    Having said that, I've got no idea what actually prohibits it.

    I wasn't referring to the graphic console buffer's bitmap bit depth.

    Graphic content in windowed console only exist for supporting real mode or
    V86 mode programs which may use graphic video mode. 64-bit Windows no longer has 16-bit subsystem. There's no longer need to have graphic cosole buffer
    in 64-bit Windows, since there's nothing which runs in real or V86 mode.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From R.Wieser@21:1/5 to All on Thu Sep 29 20:47:29 2022
    JJ,

    Having said that, I've got no idea what actually prohibits it.

    I wasn't referring to the graphic console buffer's bitmap bit depth.

    I didn't think you where. I was just putting forward that both the screen buffer as well as the code are 32 bit, and should be no problem for a 64-bit environment.

    There's no longer need to have graphic cosole buffer in 64-bit Windows,
    since there's nothing which runs in real or V86 mode.

    As it seems that the calls / code runs fine without either real or V86 mode*
    it doesn't quite look as if thats the reason.

    * I just checked, running that code doesn't activate/use NTVDM.

    It might just be the reason why we are not allowed to tap into the message
    loop of a console window : security. Being able to control (override) what
    is shown in a console window might be considered a problem.

    Than again, who knows. :-)

    Regards,
    Rudy Wieser

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)