News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

SetConsoleDisplayMode not defined in MASM32

Started by Brannagan, September 15, 2014, 06:29:51 AM

Previous topic - Next topic

Brannagan

I am trying to use the SetConsoleDisplayMode function, but when I compile it MASM complains that it is undefined.



   LOCAL bufferSize:COORD

    invoke SetConsoleDisplayMode, hStdOut, 2, DWORD PTR bufferSize



error A2006: undefined symbol : SetConsoleDisplayMode

Is there other includes I need to add in addition to  \masm32\include\masm32rt.inc?


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

Vortex

Hi Brannagan,

Could you try the attached kernel32.lib ? It's rebuilt to include SetConsoleDisplayMode. Also, don't forget to specify the prototype in your source code :

SetConsoleDisplayMode PROTO :DWORD,:DWORD,:DWORD

Brannagan

Thanks Vortex, it now compiles, but when it encounters the SetConsoleDisplayMode invoke, it crashes the exe. :(

After some further research, I think I do not need SetConsoleDisplayMode after all. What I am trying to do is programmatically change the size of my Console Window, so the user can set it to either the default 80x25 mode, or 80x50 mode. I have it almost working now that I adjust the buffer size before adjusting the console size, and the only detail I was not able to accomplish is maximizing the Console to the full 80x50 size. It does make the maximum Window size 80x50, but it's actual Size is still 80x25, with the addition of the scrollbar on the right side allowing me to scroll down to see the additional 25 lines.  In order to see all 50 lines, I must click on the "Maximize" button in the upper right, but I want it this size programmatically.

I thought I could do this using ShowWindow, but it had no effect.



    LOCAL windowSize:SMALL_RECT
    LOCAL bufferSize:COORD

    mov windowSize.Left, 0
    mov windowSize.Right, 0
    mov windowSize.Top, 79
    mov windowSize.Bottom, 24   

    mov bufferSize.x, 80
    mov bufferSize.y, 25
   
    invoke GetStdHandle, STD_OUTPUT_HANDLE
    mov hStdOut,eax
   
    invoke SetConsoleWindowInfo, hStdOut, TRUE, ADDR windowSize
    invoke SetConsoleScreenBufferSize, hStdOut, DWORD PTR bufferSize
    invoke ShowWindow, hStdOut, SW_MAXIMIZE



Any ideas?

jj2007

See How To Obtain a Console Window Handle

include \masm32\include\masm32rt.inc

.data?
buffer   db 1000 dup(?)

.code
start:   print "Hello World", 13, 10
   mov esi, offset buffer
   invoke GetConsoleTitle, esi, sizeof buffer
   invoke FindWindow, 0, esi
   push SW_MAXIMIZE
   push eax
   print str$(eax), " is the handle"
   call ShowWindow
   exit
end start

Brannagan

Hi JJ,

I see that by your example, a Console Window handle is not the same as the consoles STD_OUTPUT_HANDLE.
I will have to give some thought to how I can change my application to use a unique title, since there could be multiple copies of my application running at the same time I would want to make sure the right one is selected.

Perhaps I'm better off solving this another way, such as simulating a mouse click on the maximize button. I will do some more research.

dedndave

the attached program works

however, it's odd that the function appears in kernl32p.inc/lib but not kernel32.inc/lib   :P

EDIT: sorry - fixed a couple typos

adeyblue

Quote from: Brannagan on September 15, 2014, 09:07:00 AM
I will have to give some thought to how I can change my application to use a unique title, since there could be multiple copies of my application running at the same time I would want to make sure the right one is selected.

Use
invoke GetConsoleWindow
instead. It was (probably) invented to circumvent this problem.

hutch--

If its simple console you are after, there are a number of macros that help here.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
                    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    print "Cannon to right of us",13,10
    fn SetConsoleTitle,"New Window Title"
    inkey "next ..."

    print "Cannon to left of us",13,10
    fn SetConsoleTitle,"Title Number 2"
    inkey "next ..."

    print "Cannon in front of us",13,10
    fn SetConsoleTitle,"Third Title"
    inkey "next ..."

    print "Volleyed and thundered",13,10
    fn SetConsoleTitle,"Fourth Title"
    inkey "next ..."

    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start

Adamanteus

As I know, resolution of console screen could change user by window menu, so documented API for it is absent - could be counted as Windows conception. But if is much outputing, possible adjust console buffer size  :biggrin:

Neil

Place this at the start of the cde section :-

SetSmallRect proc ps_r:DWORD,left:DWORD,top:DWORD,right:DWORD,bottom:DWORD

    mov edx,ps_r
    mov eax,left
    mov [edx].SMALL_RECT.Left,ax
    mov eax,top
    mov [edx].SMALL_RECT.Top,ax
    mov eax,right
    mov [edx].SMALL_RECT.Right,ax
    mov eax,bottom
    mov [edx].SMALL_RECT.Bottom,ax
   
    invoke SetConsoleWindowInfo,hConsoleOutput,TRUE,ADDR small_rect
    ret
   

Call it from within your program with this :-

invoke SetSmallRect,ADDR small_rect,0,0,79,49

This will display a console window with 80 columns & 50 rows.  Don't forget row & column counts start at zero.

Neil

Forgot to say that that in the .data? section put this:-

small_rect     SMALL_RECT <>

Neil

i Think i'm getting a bit forgetful in my old age, of course this is required also in the .data? section:-

SMALL_RECT STRUCT
    Left         WORD      ?
    Top         WORD      ?
    Right       WORD      ?
    Bottom    WORD      ?
SMALL_RECT ENDS

Brannagan

#12
Thanks everyone!

adeyblue: Nice, by using GetConsoleWindow, I won't need to set a unique title and use FindWindow :)
This appeared to solve things at first, until I realized that my console was not being sized correctly. It seems that the way I'm accessing the SMALL_RECT structure was bad...

dedndave: I'll go back to giving SetConsoleDisplayMode another try, but from what I have read it seems that what should be needed is a combination of SetConsoleWindowInfo and SetConsoleScreenBufferSize as demonstrated here:

http://www.cplusplus.com/forum/windows/10731/

and here is a version redskull ported which also has the SMALL_RECT structure broken:

http://www.masmforum.com/board/index.php?topic=14129.0


Neil, I think you may be on the right track with your example, but when I made it into the following program, it does not change the console to 80x50 as it should have.. Did I overlook anything?


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
  include \masm32\include\masm32rt.inc

   .data
   
   small_rect SMALL_RECT <>
   hStdOut  dd 0

   .data?

SMALL_RECT STRUCT
    Left     WORD      ?
    Top      WORD      ?
    Right    WORD      ?
    Bottom   WORD      ?
SMALL_RECT ENDS

   .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

SetSmallRect proc ps_r:DWORD,left:DWORD,top:DWORD,right:DWORD,bottom:DWORD

    mov edx,ps_r
    mov eax,left
    mov [edx].SMALL_RECT.Left,ax
    mov eax,top
    mov [edx].SMALL_RECT.Top,ax
    mov eax,right
    mov [edx].SMALL_RECT.Right,ax
    mov eax,bottom
    mov [edx].SMALL_RECT.Bottom,ax
   
    invoke SetConsoleWindowInfo,hStdOut,TRUE,ADDR small_rect
    ret

SetSmallRect endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    invoke GetStdHandle, STD_OUTPUT_HANDLE
    mov hStdOut,eax

    invoke SetSmallRect,ADDR small_rect,0,0,79,49
   
    print "The Console should now be 80x50",13,10
    ret

main endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start

jj2007

include \masm32\include\masm32rt.inc
.code
start:   print "Hello World", 13, 10
   xchg ebx, rv(GetConsoleWindow)
   invoke MoveWindow, ebx, 100, 100, 600, 300, 1
   inkey str$(ebx), " is the handle"
   exit
end start

Neil

it's been a few years since I wrote a console program, I've given it some thoughyt & think that the console buffer has to be as large or greater than the console display itsel. So add this to The .data? section :-

csbi            CONSOLE_SCREEN_BUFFER_INFO <>

Put this in the code section before changing console window size :-

    mov ax,50
    shl eax,16
    mov ax,csbi.dwSize.x
    invoke SetConsoleScreenBufferSize,hConsoleOutput,eax

This works for me, by the way small_rect      SMALL_RECT <> should be in the .data? section.