Using WriteConsoleA from a Clarion application


#1

Today I was inspired to respond to a StackOverflow question and pulled this example together from pieces I found on the newsgroup :slight_smile:

Compile the program, run it from a command line and mash the button!

image

  PROGRAM

HANDLE    EQUATE(UNSIGNED)
DWORD     EQUATE(ULONG)
BOOL      EQUATE(BYTE)
VOID      EQUATE(LONG)
LPVOID    EQUATE(ULONG)
LPDWORD   EQUATE(ULONG)
ATTACH_PARENT_PROCESS EQUATE(-1)
STD_OUTPUT_HANDLE EQUATE(-11)

  MAP
    MODULE('API')
      AttachConsole(DWORD dwProcessId),BYTE,PASCAL,RAW
      FreeConsole(),BYTE,PROC,PASCAL,RAW
      GetStdHandle(DWORD nStdHandle),LONG,PASCAL,RAW
      WriteConsoleA( |
        HANDLE  hConsoleOutput, |
        VOID    lpBuffer, |
        DWORD   nNumberOfCharsToWrite, |
        *LPDWORD lpNumberOfCharsWritten, |
        LPVOID  lpReserved),BYTE,PASCAL,RAW,PROC
    END
WriteLine PROCEDURE(STRING pMessage)
  END

Window    WINDOW('Test WriteConsole'),AT(,,101,43),GRAY,FONT('Microsoft Sans Serif',8)
            BUTTON('Write To Stdout'),AT(17,12),USE(?ButtonTest)
          END
  CODE

  Open(Window)
  
  ACCEPT
    IF Event() = EVENT:Accepted AND Accepted() = ?ButtonTest
      WriteLine('Hi!')
    END
  END
  
WriteLine PROCEDURE(STRING pMessage)
conHandle   HANDLE
outLen      LPDWORD
bufferStr   &CSTRING
  CODE
  bufferStr &= New(CSTRING(Len(pMessage)+2))
  bufferStr = pMessage & '<10><0>'
  IF AttachConsole(ATTACH_PARENT_PROCESS)
    conHandle = GetStdHandle(STD_OUTPUT_HANDLE)
    WriteConsoleA(conHandle,Address(bufferStr),LEN(bufferStr),outLen,0)
    FreeConsole()
  END
  Dispose(bufferStr)
  RETURN

#2

Hi Brahn,

Interesting, note you don’t need the string reference with it’s new and dispose you can just use LEN to create a cstring of the required length, as in …

WriteLine           PROCEDURE(STRING pMessage)
conHandle               HANDLE
outLen                  LPDWORD
bufferStr               CSTRING(LEN(pMessage)+2)
	CODE
		  bufferStr = pMessage & '<10><0>'
		  IF AttachConsole(ATTACH_PARENT_PROCESS)
		         	conHandle = GetStdHandle(STD_OUTPUT_HANDLE)
			        WriteConsoleA(conHandle,Address(bufferStr),LEN(bufferStr),outLen,0)
			        FreeConsole()
		  END
		  RETURN

#3

Oh neat, I forgot about that!
I’m not sure how necessary the FreeConsole() is either but I was trying it out.