I will focus mostly on making interactive menus *without* using a server, as it is significantly simpler and possibly good enough.
I am using an image (img\123.bmp) that is in the cmdgfx archive, so it should be possible to run these scripts straight from the cmdgfx folder if you create them there.
Example 1:
Code: Select all
@echo off
setlocal
cmdwiz setfont 2 & cls & mode 41,50
set /a size=1
set text=_The_menu:\n\n1._Option_A\n2._Option_B\n3._Option_C\n\c0Esc._\rCancel
:rep
set /a size+=1
if %size% gtr 40 set /a size=1
set /a xp=20-size/2, yp=20-size/2
cmdgfx_VT "fbox 7 0 20 & image img/123.bmp 0 0 0 -1 %xp%,%yp% 0 0 %size%,%size% & text 7 0 0 %text% 15,41" k
set /a key=%errorlevel%
if %key% == 27 set /a choice=0, stop=1
if %key% geq 49 if %key% leq 51 set /a choice=%key%-48, stop=1
if not defined stop goto rep
cls & echo Your choice was %choice%
cmdwiz getch
endlocal
This creates the following menu, with an animated image (by size):
Ok, what to say about this script?
1. I force a fixed size of the console window and set a specific font (raster font 2). Especially the latter part is not at all necessary. However the first part, forcing a size and removing scroll bars, typically makes things easier to deal with
2. I prepare a text which is used to print the menu by the "text" operation. _ must be used instead of spaces, \n means new line, \c0 means use foreground color c(12), background color 0, \r means use previous color
3. In the loop, we calculate the size of the image and where we should put it, then call cmdgfx_VT with the "k" flag, which means it should return a key code if a key press was made
4. "fbox" is used to clear the buffer, then "image" is used with resizing to draw the image, and finally "text" prints the text we prepared earlier
5. If we pressed escape (key code 27), then exit with choice 0, if we pressed key 1-3 exit with choice 1-3. How to get these key codes? There are basically two ways: Either run "getchloop.bat" in the cmdgfx folder, start pressing keys of interest and note down their numbers, OR look up "decimal Ascii table" on google (however, for special keys like cursor keys etc you will still need to run getchloop.bat)
6. Finally we print the choice
Example 2: a variant of the previous script where we use cursor keys and Return to select a choice.
Code: Select all
@echo off
setlocal
cmdwiz setfont 2 & cls & mode 41,50
set /a size=1, pos=0, nofchoice=3
set text=The_menu:\n\nOption_A\nOption_B\nOption_C\n\n\c0Esc=Cancel
:rep
set /a size+=1
if %size% gtr 40 set /a size=1
set /a xp=20-size/2, yp=20-size/2, barpos=pos+43
cmdgfx_VT "fbox 7 0 20 & image img/123.bmp 0 0 0 -1 %xp%,%yp% 0 0 %size%,%size% & text 7 0 0 %text% 16,41 & line f 9 ? 14,%barpos%,25,%barpos%" k
set /a key=%errorlevel%
if %key% == 27 set /a choice=0, stop=1
if %key% == 328 set /a pos-=1
if %key% == 336 set /a pos+=1
if %key% == 13 set /a choice=pos+1, stop=1
if %pos% lss 0 set /a pos=%nofchoice%-1
if %pos% geq %nofchoice% set /a pos=0
set /a key=0
if not defined stop goto rep
cls & echo Your choice was %choice%
cmdwiz getch
endlocal
There actually isn't that much to say about it as it is quite similar, but we use a little trick to draw the "selected" choice: line f 9 ? 14,%barpos%,25,%barpos% . Here we draw a line with white text color and blue background, but use ? to mean that whatever text is currently in the buffer should not be changed, only the colors.
Example 3: As example 1, but this is just to show that we can mix the output of cmdgfx_VT with text previously put in the buffer. In this case we must specify the position/size of the cmdgfx buffer, as it normally uses the entire cmd window buffer (even the parts off-sceen, hence why it's good to have a fixed console size and no scrollbars)
Code: Select all
@echo off
setlocal
cmdwiz setfont 2 & cls & mode 41,50
set /a size=1
cmdwiz setcursorpos 0 41
echo My menu: & echo. & echo 1. Option A & echo 2. Option B & echo 3. Option C & echo Esc. Cancel
:rep
set /a size+=1
if %size% gtr 40 set /a size=1
set /a xp=20-size/2, yp=20-size/2
cmdgfx_VT "fbox 7 0 20 & image img/123.bmp 0 0 0 -1 %xp%,%yp% 0 0 %size%,%size%" kf:0,0,41,41
set /a key=%errorlevel%
if %key% == 27 set /a choice=0, stop=1
if %key% geq 49 if %key% leq 51 set /a choice=%key%-48, stop=1
if not defined stop goto rep
cls & echo Your choice was %choice%
cmdwiz getch
endlocal
Notable things:
1. we start by using normal echo commands to put the menu text on screen without cmdgfx
2. In the call to cmdgfx, we specify flag "f:0,0,41,41" to say that the buffer should be put as position 0,0 with width 41 and height 41 (leaving lines 42-50 free for our previously echoed text)
Finally, example 4, which is like example 2, except it runs cmdgfx as server:
Code: Select all
@echo off
setlocal
if not defined _ (
cmdwiz setfont 2 & cls & mode 41,50
set _=.
cmdgfx_input.exe knW20 | call %0 %* | cmdgfx_VT "" S
set _=
)
if not defined _ set /p choice=<tempFile
if not defined _ cls & echo Your choice was %choice% & cmdwiz getch & goto :eof
set /a size=1, pos=0
set text=The_menu:\n\nOption_A\nOption_B\nOption_C\n\n\c0Esc=Cancel
:rep
set /a size+=1
if %size% gtr 40 set /a size=1
set /a xp=20-size/2, yp=20-size/2, barpos=pos+43
echo "cmdgfx: fbox 7 0 20 & image img/123.bmp 0 0 0 -1 %xp%,%yp% 0 0 %size%,%size% & text 7 0 0 %text% 16,41 & line f 9 ? 14,%barpos%,25,%barpos%" F
set /p input=
for /f "tokens=1,2,4,6" %%a in ("%input%") do ( set ev_base=%%a & set /a key=%%d )
if %key% == 27 set /a choice=0, stop=1
if %key% == 328 set /a pos-=1
if %key% == 336 set /a pos+=1
if %key% == 13 set /a choice=pos+1, stop=1
if %pos% lss 0 set /a pos=2
if %pos% geq 3 set /a pos=0
set /a key=0
if not defined stop goto rep
echo "cmdgfx: quit"
title input:Q
echo %choice% >tempFile
endlocal
The structure is similar to the minimal server example in my previous post.
Notable:
Since we call the script a second time from the pipe chain, we can't get the user's choice through a variable once we return. Instead, I write the choice to a temporary file which is then read by the calling script.
In all these examples we can replace cmdgfx_VT with cmdgfx_RGB for faster output. In this case we also need to specify f2 as a flag in the call, or else cmdgfx_RGB will use its default, raster font 6.
In the (last) server example, this will work fine.
In the non-server examples though, we get a pretty horrible flicker (unless running a legacy console). Why? Because as I mentioned in my previous post, Windows 10 clears any bitmaps from the console after a command finishes! However when we run as server, cmdgfx does not quit until the entire script finishes.
For simplicity, I didn't use delayed expansion in these examples, and I used a standard goto for the loop. To speed things up, most of the cmdgfx example scripts actually typically have this loop structure instead:
Code: Select all
setlocal EnableDelayedExpansion
:REP
for /l %%1 in (1,1,300) do if not defined STOP (
...code using delayed expansion
)
if not defined STOP goto REP
instead of simply:
:REP
...code not using delayed expansion
if not defined STOP goto REP