Different behaviour with console

Windows specific questions.
Posts: 342
Joined: Dec 28, 2012 13:31
Location: Paris - France

Different behaviour with console

Postby marpon » Mar 15, 2019 10:54

here you have a test to evaluate the different behaviour we can have with console.

Code: Select all

''   test_console.bas    by marpon  14 March 2019

' to test the 4 possible usages of console
'   1   compiled in console mode and launched by console prompt, so using the existing launching console
'   2   compiled in console mode and not lauched by console prompt, so use the own console
'   3   compiled in GUI mode and launched by console prompt, so using the existing launching console ( the sleep is not completly solved, and the restore mode not easy)
'   4   compiled in GUI mode and not launched by console prompt, so use a new created own console

 'what is interresting is the GUI compilation,  the prog will work normally without the console in the side
 '      but if a problem occurs it is possible to track it via console.

#include once "windows.bi"
#Include Once "win/psapi.bi"                     ' for process
#include once "win/tlhelp32.bi"                  ' for process
#include once "crt/stdio.bi"                     ' for printf

function GetWindowsFromProcessID(byval dwProcessID as DWORD, byref wclass as string = "") as HWND
    ' find all hWnds (vhWnds) associated with a process id (dwProcessID)
    dim as HWND hCurWnd = NULL
   dim as dword dwtemp
   dim as zstring ptr pwclass = strptr(wclass)
        hCurWnd = FindWindowEx(NULL, hCurWnd, pwclass, NULL)
        dwtemp = 0
        GetWindowThreadProcessId(hCurWnd, @dwtemp)
        if (dwtemp = dwProcessID) then return hCurWnd
    loop while (hCurWnd <> NULL)
   return NULL
end function

function  getParentPID(byval pid as DWORD) as DWORD
    dim as HANDLE h = NULL
    dim as PROCESSENTRY32 pe
    dim as DWORD ppid
    pe.dwSize = sizeof(PROCESSENTRY32)
    h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
    if Process32First(h, @pe)<> 0 then
            if pe.th32ProcessID = pid then
                ppid = pe.th32ParentProcessID
                exit do
            end if
        loop while( Process32Next(h, @pe)<> 0)
    end if
    return (ppid)
end function

function in_console(byval iset as long, byref stitle as string) as long
   static s__console as long                                 'warning a static var here to track AllocConsole()
   dim hwincons as handle
   if iset = 1 and s__console = 0 THEN
      hwincons = GetConsoleWindow()
      if hwincons = 0 THEN
         freopen( "CON", "r", stdin )
         freopen( "CON", "w", stdout )
         freopen( "CON", "w", stderr )
         hwincons = GetConsoleWindow()
         sleep 50
         if hwincons <> 0  THEN
            printf(!"\n\n\t==>  AllocConsole mode!\n\n")
            s__console = 1
            return 1
            return 0
         end if
         return 2
      END IF
   elseif iset = 0 and s__console = 1 THEN
      s__console = 0
      return 0
   return 0
END function

sub restore_true_console(byval ppid as DWORD)
   dim as hwnd h1 = GetWindowsFromProcessID(ppid, "ConsoleWindowClass")
    /' print "pid = " & ppid & "   hwnd = " & h1 '/
   if h1 THEN
      PostMessage(h1, WM_KEYDOWN, VK_RETURN, 0) 'to restore the normal prompt in cmd console
      'PostMessage(h1, WM_KEYUP, VK_RETURN, 0)
    /' else
      Keybd_event VK_RETURN , 0 , 0 , 0
      'Keybd_event VK_RETURN , 0 , KEYEVENTF_KEYUP , 0 '/
    END IF

function check_cmd()as long
   dim as DWORD darr(10)
   dim as DWORD dcons = GetConsoleProcessList( @darr(0), 10)
   return (cast(long,dcons))-1

dim as long cons_type = check_cmd()
if cons_type < 0 THEN                           'GUI mode
   messagebox 0, "No console yet", "info", 0
   dim as dword ppid = getParentPID(GetCurrentProcessId())
   if  ppid > 0  THEN
      if GetConsoleWindow() THEN                  'GUI mode :launched via prompt cmd
         freopen( "CON", "r", stdin )
         freopen( "CON", "w", stdout )
         freopen( "CON", "w", stderr )
         printf(!"\n\nGUI : Using the existing launching console\n")
         sleep 200
         printf(!"\ndoing someting here!\n")  'warning in that mode it is not possible to have easy interruption for sleep : have to be checked...
         sleep 400
         printf(!"\nLeaving now!\n")
      else                                 'GUI mode :launched without prompt cmd
         if in_console(1, "New console for GUI") then
            printf (!"GUI : Created new console, wait 4s  or press any key to stop\n")
            sleep 4000
            messagebox 0, "No console at all", "info", 0
         end if
        END IF
      messagebox 0, "Still No console", "info", 0
    END IF
elseif cons_type = 0 THEN                        'console mode :launched without prompt cmd
   printf !"\nIn 'real' console mode using own console, wait 4s  or press any key to stop " : print
   sleep 4000
else                                       'console mode :launched via prompt cmd
   printf !"\nIn 'real' console mode using the existing launching console, wait 4s  or press any key to stop " : print
   sleep 4000

compile with or without console mode, you will see 4 differents ways to always have a console when needed

that is very interresting if you want to track some events , debugg mode, error catching...
it is also helpful if you make libs or dlls, you can incorporate the console code on them to be sure you will always give a console,
even the global prog will be compiled on GUI mode.

as always do not hesitate to test and send your remarks...

by the way, give also some interresting functions you could have some use for.

Return to “Windows”

Who is online

Users browsing this forum: No registered users and 1 guest