05-24-2014, 01:35 PM
Macro QM-console
Function MakeExe_Console
Function ConsoleOut
Function ConsoleIn
Tested: printf and _cputs also work, but _cgets fails.
;/exe
;Run this to test MakeExe_Console, ConsoleOut and ConsoleIn.
ConsoleOut "Type something and press Enter"
str s
ConsoleIn s
ConsoleOut F"s=''{s}''"
1
;BEGIN PROJECT
;exe_file $my qm$\QM-console.exe
;on_after MakeExe_Console
;flags 6
;END PROJECT
;Converts QM-created exe from GUI to console.
;Use this function in 'Make exe' dialog, 'After' field.
;Example: <open>QM-console</open>.
str exe=_command
if(exe.endi(".qmm")) out "Function MakeExe_Console cannot be used with .qmm, must be .exe."; ret
_s="[3]" ;;IMAGE_OPTIONAL_HEADER::Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI
_s.setfile(exe 0x16c 1)
ret 1
;/
function $s [flags] ;;flags: 1 stderr, 2 no newline
;In exe shows text in console window of this or parent process.
;s - the text.
;REMARKS
;Writes to the standard output buffer or error buffer (flag 1).
;Exe must be created as console. For it you need function MakeExe_Console. Put its name in 'Make exe' dialog, 'After' field.
;If exe runs from cmd.exe, can use its console. Else exe creates own console window when starting.
;If called in QM (not in exe), this function just calls out().
;Example: <open>QM-console</open>.
#if !EXE
out s
#else
int+ g_stdout g_stderr
if !g_stdout
,g_stdout=GetStdHandle(STD_OUTPUT_HANDLE)
,g_stderr=GetStdHandle(STD_ERROR_HANDLE)
int h=iif(flags&1 g_stderr g_stdout)
if(flags&2=0) s=_s.from(s "[]")
_s.unicode(s) ;;also need to set console font that supports Unicode characters, eg Lucida Console
WriteConsoleW h _s _s.len/2 &_i 0
;/
function str&s
;In exe waits and reads user input text from console window.
;s - variable that receives the text (1 line).
;REMARKS
;Exe must be created as console. For it you need function MakeExe_Console. Put its name in 'Make exe' dialog, 'After' field.
;If exe runs from cmd.exe, can use its console. Else exe creates own console window when starting.
;If called in QM (not in exe), this function just calls inp().
;This function waits for Enter. While waiting, cannot process Windows messages and COM events. The thread should not have dialogs etc.
;Example: <open>QM-console</open>.
s.all
#if !EXE
if(!inp(s)) end "ConsoleIn failed, Cancel"
#else
int+ g_stdin
if !g_stdin
,g_stdin=GetStdHandle(STD_INPUT_HANDLE)
_s.all(16*1024 2)
if(!ReadConsole(g_stdin _s _s.len &_i 0)) end "ConsoleIn failed" 16
_s.fix(_i); _s.trim("[]")
if(_unicode) _s.ConvertEncoding(GetConsoleCP _unicode)
s=_s
#endif
;tested: _cgets fails.
Tested: printf and _cputs also work, but _cgets fails.