December 11, 2024, 09:53:17 PM

News:

Own IWBasic 2.x ? -----> Get your free upgrade to 3.x now.........


mini Console

Started by Ionic Wind Support Team, December 04, 2006, 04:54:34 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Ionic Wind Support Team

Just something I was working on long ago.  Creates an emulated console using a regular window so you can have a console with a parent window.


mcOpen("Test2 of mini console")
mcCLS()
FOR x=1 to 160
mcPrint("X")
NEXT x
mcPrint("help me\n\n")
mcPrint("Thank\tyou\n")
mcPrint("Than\tyou\n")
mcPrint("Tha\tyou\n")
mcPrint("Th\tyou\n")

mcLocate(25,1)
mcColor(14,9)
mcPrint("Last line\tPress any key to close")

WAITUNTIL mcInkey$() <> ""
mcClose()
END


/*
the miniConsole code
********************
*/

WINDOW _mcwin

TYPE MCBUFFER
POINTER outbuf
POINTER inpbuf
UINT inppos
UINT readpos
ENDTYPE

TYPE MCCONSOLE
MCBUFFER buffer
UINT caretPos
UINT size:'size = width << 16 | height
UINT textsize: 'width and height of a character
UINT winWidth: 'width of the calculated window
INT fgColor
INT bgColor
UINT palette[16]
ENDTYPE


TYPEDEF LONG INT
TYPEDEF BCHAR CHAR
TYPEDEF BYTE CHAR

type TEXTMETRIC
    LONG tmHeight
    LONG tmAscent
    LONG tmDescent
    LONG tmInternalLeading
    LONG tmExternalLeading
    LONG tmAveCharWidth
    LONG tmMaxCharWidth
    LONG tmWeight
    LONG tmOverhang
    LONG tmDigitizedAspectX
    LONG tmDigitizedAspectY
    BCHAR tmFirstChar
    BCHAR tmLastChar
    BCHAR tmDefaultChar
    BCHAR tmBreakChar
    BYTE tmItalic
    BYTE tmUnderlined
    BYTE tmStruckOut
    BYTE tmPitchAndFamily
    BYTE tmCharSet
ENDTYPE

type MINMAXINFO
    POINT ptReserved
    POINT ptMaxSize
    POINT ptMaxPosition
    POINT ptMinTrackSize
    POINT ptMaxTrackSize
endtype

'a character in the buffer is a 32 bit quantity.
'its a packed bitfield
'00AAFBCC  00 = reserved, AA = attributes, F = foreground color, B = background color, CC = the ASCII character
TYPEDEF MCCHAR UINT
DECLARE IMPORT,AdjustWindowRectEx(pRect as WINRECT, Style as UINT, bMenu as INT, ExStyle as UINT)
DECLARE IMPORT,SetPropA(hwnd as UINT,lpString as STRING,hData as UINT),INT
DECLARE IMPORT,GetPropA(hwnd as UINT,lpString as STRING),UINT
DECLARE IMPORT,RemovePropA(hwnd as UINT,lpString as STRING),UINT
DECLARE IMPORT,GetDC(hwnd as UINT),UINT
DECLARE IMPORT,ReleaseDC(hwnd as UINT,hdc as UINT),INT
DECLARE IMPORT,GetDeviceCaps(hdc as UINT,nIndex as INT),UINT
DECLARE IMPORT,CreateCompatibleDC(hDC as UINT),UINT
DECLARE IMPORT,DeleteDC(hdc as UINT),INT
DECLARE IMPORT,SelectObject(hdc as UINT,object as UINT),UINT
DECLARE IMPORT,DeleteObject(hObject as UINT),INT
DECLARE IMPORT,CreateFontIndirectA(lf as LOGFONT),UINT
DECLARE IMPORT,lstrcpynA(dest as POINTER,source as POINTER,limit as INT),STRING
DECLARE IMPORT,MulDiv(nNumber as INT,nNumerator as INT,nDenominator as INT),INT
DECLARE IMPORT,ZeroMemory ALIAS RtlZeroMemory(pvoid as POINTER,length as INT),INT
DECLARE IMPORT,MoveMemory ALIAS RtlMoveMemory(pDest as POINTER,pSrc as POINTER,length as INT),INT
DECLARE IMPORT,GetTextMetricsA(hdc as UINT,LPTEXTMETRIC as TEXTMETRIC),INT
DECLARE IMPORT,TextOutA(hdc as UINT,x as INT,y as INT,LPCTSTR  as STRING,cbString as INT),INT
DECLARE IMPORT,SetTextAlign(hdc as UINT,fMode as UINT),INT
DECLARE IMPORT,GetSystemMetrics(nIndex as INT),INT
DECLARE IMPORT,SetBkColor(hdc as UINT,cBack as UINT),UINT
DECLARE IMPORT,SetTextColor(hdc as UINT,crColor as UINT),INT
'for multi threading
DECLARE IMPORT,CreateThread(lpThreadAttributes as POINTER,dwStackSize as UINT,_
lpStartAddress as UINT,lpParameter as POINTER,dwCreationFlags as UINT,lpThreadId as POINTER),UINT
DECLARE IMPORT,ExitThread(dwExitCode as UINT)
DECLARE IMPORT,CreateMutex(lpMutexAttributes as POINTER,bInitialOwner as INT,lpName as POINTER),UINT
DECLARE IMPORT,ReleaseMutex(hMutex as UINT),INT
DECLARE IMPORT,CloseHandle(handle as UINT),INT
DECLARE IMPORT,WaitForSingleObject(hHandle as UINT,dwTimeOut as UINT),UINT
'DECLARE ThreadProc(lpParameter as POINTER),UINT
CONST WAIT_TIMEOUT = 258
CONST WAIT_OBJECT_0 = 0
CONST INFINITE = 0xFFFFFFFF

CONST cBLACK = 0
CONST cBLUE = 0x007F0000
CONST cGREEN = 0x00007F00
CONST cCYAN = 0x007F7F00
CONST cRED = 0x0000007F
CONST cMAGENTA = 0x007F007F
CONST cBROWN = 0x00007F7F
CONST cWHITE = 0x00EFEFEF
CONST cGRAY = 0x007F7F7F
CONST cLTBLUE = 0x00FF0000
CONST cLTGREEN = 0x0000FF00
CONST cLTCYAN = 0x00FFFF00
CONST cLTRED = 0x000000FF
CONST cLTMAGENTA = 0x00FF00FF
CONST cYELLOW = 0x0000FFFF
CONST cHIWHITE = 0x00FFFFFF

CONST defWidth = 80
CONST defHeight = 25
CONST defFontPoints = 10
CONST defTabWidth = 8
CONST input_buffer_size = 256

CONST WM_GETMINMAXINFO = 0x24

SUB mcOpen(title as STRING,OPT parent=NULL as POINTER)
DEF width,height as INT
DEF tm as TEXTMETRIC
DEF rc as WINRECT
DEF pConsole as POINTER
DEF hdc,hdcScreen,font,oldfont AS UINT
'Get a device context we can use to determine font sizes
hdc = GetDC(NULL)
hdcScreen = CreateCompatibleDC(hdc)
ReleaseDC(NULL,hdc)
'calculate the client size needed based on the font
LOGFONT lf
ZeroMemory(lf,LEN(LOGFONT))
lstrcpynA(lf.lfFaceName,"Terminal",32)
lf.lfHeight = -MulDiv(defFontPoints,GetDeviceCaps(hdcScreen,90 /*LOGPIXELSY*/),72)
lf.lfWeight = 400
lf.lfQuality = 1 /*DRAFT_QUALITY*/
lf.lfPitchAndFamily = 0 /*DRAFT_PITCH*/
lf.lfCharSet = 0x00FF /*OEM charset */
font = CreateFontIndirectA(lf)
oldfont = SelectObject(hdcScreen,font)
GetTextMetricsA(hdcScreen,tm)
IF(oldfont)
SelectObject(hdcScreen,oldfont)
ENDIF
DeleteObject(font)
DeleteDC(hdcScreen)
'whew...all of that just to get the sizes of a font before opening a window!
width = defWidth * tm.tmMaxCharWidth
height = defHeight * tm.tmHeight
rc.left = 0
rc.right = width
rc.top = 0
rc.bottom = height
'now figure out what our client size will be
AdjustWindowRectEx(rc,@SIZE|@CAPTION|@BORDER,FALSE,@EXWINDOWEDGE)
'AdjustWindowRectEx doesn't account for scrollbars
rc.right += GetSystemMetrics(2) /*SM_CXVSCROLL = 2*/
'and finally create the mcConsole window
IF _mcwin.hwnd = NULL
OPENWINDOW _mcwin,0,0,(rc.right-rc.left),(rc.bottom-rc.top),@SIZE|@VSCROLL|@NOAUTODRAW|@MINBOX|@MAXBOX,parent,title,&mcHandler
SETWINDOWCOLOR _mcwin,cBLACK
FRONTPEN _mcwin, cLTGREEN
BACKPEN _mcwin, cBLACK
DRAWMODE _mcwin,@OPAQUE
SETFONT _mcwin,"Terminal",defFontPoints,400,0x00FF0000
'create the consoles data structures
pConsole = NEW( MCCONSOLE,1)
SETTYPE pConsole,MCCONSOLE
'allocate an extral line for overflows
#pConsole.buffer.outbuf = NEW(MCCHAR,defWidth*defHeight+defWidth)
#pConsole.buffer.inpbuf = NEW(CHAR,input_buffer_size)
#pConsole.size = defWidth << 16 | defHeight
#pConsole.textsize = tm.tmMaxCharWidth << 16 | tm.tmHeight
#pConsole.winWidth = (rc.right-rc.left)
#pConsole.fgColor = 10
#pConsole.bgColor = 0
#pConsole.palette = cBLACK,cBLUE,cGREEN,cCYAN,cRED,cMAGENTA,cBROWN,_
cWHITE,cGRAY,cLTBLUE,cLTGREEN,cLTCYAN,cLTRED,cLTMAGENTA,cYELLOW,cHIWHITE
SetPropA(_mcwin.hwnd,"MCCONSOLE",pConsole)
ENDIF
RETURN
ENDSUB

SUB mcSize(w as INT,h as INT)
RETURN
ENDSUB

SUB mcClose()
POINTER pConsole
IF _mcwin.hwnd <> NULL
pConsole = GetPropA(_mcwin.hwnd,"MCCONSOLE")
DELETE #<MCCONSOLE>pConsole.buffer.outbuf
DELETE #<MCCONSOLE>pConsole.buffer.inpbuf
RemovePropA(_mcwin.hwnd,"MCCONSOLE")
CLOSEWINDOW _mcwin
ENDIF
RETURN
ENDSUB

SUB mcLocate(y as INT,x as INT)
POINTER pConsole
INT width,height
IF _mcwin.hwnd
x--
y--
if(x < 0) THEN x = 0
if(y < 0) THEN y = 0
pConsole = GetPropA(_mcwin.hwnd,"MCCONSOLE")
SETTYPE pConsole,MCCONSOLE
width = #pConsole.size >> 16
height = #pConsole.size & 0xFFFF
if x >= width THEN x=0
if y >= height THEN y=height-1
#pConsole.caretpos = x << 16 | y
ENDIF
RETURN
ENDSUB

SUB mcColor(fg as INT,bg as INT)
POINTER pConsole
IF(_mcwin.hwnd)
IF fg > 15 THEN fg = 15
IF fg < 0 THEN fg = 0
IF bg > 15 THEN bg = 15
IF bg < 0 THEN bg = 0
pConsole = GetPropA(_mcwin.hwnd,"MCCONSOLE")
#<MCCONSOLE>pConsole.bgColor = bg
#<MCCONSOLE>pConsole.fgColor = fg
ENDIF
RETURN
ENDSUB

SUB mcPrintAt(y as INT,x as INT,text as STRING)
mcLocate(y,x)
mcPrint(text)
RETURN
ENDSUB

SUB mcPrint(text as STRING)
POINTER pConsole
INT x,y,lin,col,width,height,pos,tabpos
UINT current_color
IF _mcwin.hwnd <> NULL
pConsole = GetPropA(_mcwin.hwnd,"MCCONSOLE")
SETTYPE pConsole,MCCONSOLE
lin = #pConsole.caretPos & 0xFFFF
col = #pConsole.caretPos >> 16
width = #pConsole.size >> 16
height = #pConsole.size & 0xFFFF
pos = col + (lin * width)
current_color = ((#pConsole.fgColor << 4 | #pConsole.bgColor) << 8)
FOR x = 0 TO LEN(text)-1
SELECT text[x]
CASE 0x0D
lin++
CASE 0x0A
col = 0
CASE ASC("\t")
'calculate the nearest tab stop
tabpos = defTabWidth - (col % defTabWidth)
FOR y = 0 TO tabpos-1
#pConsole.buffer.#<MCCHAR>outbuf[pos+y] = 0x20 | current_color
NEXT y
col+=tabpos
IF col >= width
col -= width
lin++
ENDIF
DEFAULT
#pConsole.buffer.#<MCCHAR>outbuf[pos] = text[x] | current_color
col++
ENDSELECT
IF col >= width
col = 0
lin++
ENDIF
pos = col + (lin * width)
NEXT x
#pConsole.caretPos = col << 16 | lin
ENDIF
RETURN
ENDSUB

SUB mcInkey$(),CHAR
CHAR cReturn:cReturn = NULL
POINTER pConsole
IF _mcwin.hwnd <> NULL
pConsole = GetPropA(_mcwin.hwnd,"MCCONSOLE")
SETTYPE pConsole,MCCONSOLE
if #pconsole.buffer.readpos <> #pconsole.buffer.inppos
cReturn = #pConsole.buffer.#<CHAR>inpbuf[#pconsole.buffer.readpos]
#pconsole.buffer.readpos++
else
#pconsole.buffer.readpos = 0
#pconsole.buffer.inppos = 0
endif
ENDIF
RETURN cReturn
ENDSUB

SUB mcCLS()
POINTER pConsole
INT length
IF _mcwin.hwnd <> NULL
pConsole = GetPropA(_mcwin.hwnd,"MCCONSOLE")
SETTYPE pConsole,MCCONSOLE
length = (#pConsole.size >> 16) * (#pConsole.size & 0xFFFF) * 4
ZeroMemory(#pConsole.buffer.outbuf,length)
#pConsole.caretpos = 0
ENDIF
RETURN
ENDSUB

'the console window handler
SUB mcHandler
POINTER pConsole
pConsole = GetPropA(_mcwin.hwnd,"MCCONSOLE")
SETTYPE pConsole,MCCONSOLE
SELECT @MESSAGE
CASE WM_GETMINMAXINFO
'prevent the window from sizing larger than the width
if(pConsole <> NULL)
*<MINMAXINFO>@LPARAM.ptMaxSize.x = #<MCCONSOLE>pConsole.winWidth
*<MINMAXINFO>@LPARAM.ptMaxTrackSize.x = #<MCCONSOLE>pConsole.winWidth
endif
CASE @IDCLOSEWINDOW
'mcClose()
'END
CASE @IDSIZE
CASE @IDCHAR
if(pConsole <> NULL)
if #<MCCONSOLE>pConsole.buffer.inppos < 256
#<MCCONSOLE>pConsole.buffer.#<CHAR>inpbuf[#<MCCONSOLE>pConsole.buffer.inppos] = @CODE
#<MCCONSOLE>pConsole.buffer.inppos++
endif
endif
CASE @IDPAINT
mcHandlePaint()
ENDSELECT
RETURN
ENDSUB

SUB mcHandlePaint()
POINTER pConsole
ISTRING co[2]
INT x,y,width,height,textwidth,textheight
UINT hdc
co[1] = NULL
MCCHAR c
pConsole = GetPropA(_mcwin.hwnd,"MCCONSOLE")
SETTYPE pConsole,MCCONSOLE
IF pConsole <> NULL
hdc = GetHDC(_mcwin)
SetTextAlign(hdc,0)
width = #pConsole.size >> 16
height = #pConsole.size & 0xFFFF
textwidth = #pConsole.textsize >> 16
textheight = #pConsole.textsize & 0xFFFF
FOR y=0 to height-1
FOR x = 0 to width-1
c = #pConsole.buffer.#<MCCHAR>outbuf[x + (y * width)]
IF(c & 0xFF)
co[0] = c & 0xFF
SetBkColor(hdc,#pConsole.palette[(c >> 8) & 0x0F])
SetTextColor(hdc,#pConsole.palette[(c >> 12) & 0x0F])
TextOutA(hdc,textwidth * x,textheight * y,co,1)
ENDIF
NEXT x
NEXT y
ReleaseHDC(_mcwin,hdc)
ENDIF
RETURN
ENDSUB
Ionic Wind Support Team

Parker

I believe I still have the code for this from the original post on the Pyxia forums. I like the idea, and for anyone wanting to learn windows programming, you may want to try improving this console emulator.

ExMember001

Great works ;)
thx for sharing.

Zen

he he I still have this from IBasic Pro too :P

Lewis

Ionic Wind Support Team

Since the original is gone I thought I would post it here.  Don't know how many got it from back then ;)
Ionic Wind Support Team

Haim

All new to me.
Lots of good stuff there too.
Thanks,

Haim.\