How would someone go about creating a new cmd window and position it where ever from a win 32 program whenever .Also be able to get a handle to it to output text to the cmd window aswell.What call is required ?


Thanks

Recommended Answers

All 3 Replies

Execute a new cmd window, find the handle to that window (probably easiest using the FindWindow function), and use SetWindowPos to move the window. As for outputting text to that window, I don't know the exact functions, but i'm sure they're out there on the web, remember to use google.

Worked on that big time a few years back. What I specifically wanted to do was see if I could use printf from the msvcrt.dll in a GUI process. I expect WriteConsole would be easy, but I wanted printf, and that's trickier than h***. And to make matters worse, I wanted to do it in PowerBASIC. First I figured out how to do it in C, then I rewrote it in PowerBASIC. I'll include both programs. I don't expect you're interested in the PowerBASIC program (the 2nd), but that's where all the comments are. 1st the C++ program, as compilable in VC9...

#include <windows.h>
#include <stdio.h>          //contains _fdopen
#include <fcntl.h>          //contains equate _O_TEXT
#include <io.h>             //contains declare for _open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
#define  IDC_BUTTON  1500

long __stdcall fnWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) 
{ 
 HWND hButton;
 HINSTANCE hIns;
 int hCrt,iWeight;
 FILE *hf;	

 switch (msg)                                                            
 {                                                                       
  case WM_CREATE:
    hIns=((LPCREATESTRUCT)lParam)->hInstance;  
    hButton=CreateWindow("button","Show Console",WS_CHILD|WS_VISIBLE,110,65,200,25,hwnd,(HMENU)IDC_BUTTON,hIns,0);
    return 0;     
  case WM_COMMAND:
    if(LOWORD(wParam)==IDC_BUTTON)
    {
       AllocConsole();
       hCrt=_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
       hf = _fdopen( hCrt, "w" );
       _iob[1]=*hf;
       iWeight=210;
       printf("My Name Is Fred And I Weight %u Pounds!\n",iWeight);
    }
    return 0;
  case WM_CLOSE:
    DestroyWindow(hwnd);
    PostQuitMessage(WM_QUIT);
    return 0;                                      
 }                                                                       
                                                                         
 return DefWindowProc(hwnd,msg,wParam,lParam);                           
}


int __stdcall WinMain(HINSTANCE hIns,HINSTANCE hPrevIns,LPSTR lpszArgument,int iShow)
{                                   
 char szBuffer[64];       
 WNDCLASSEX wc;                    
 MSG messages;                     
 HWND hWnd;                        
 
 strcpy(szBuffer,"Console_Output");
 wc.lpszClassName=szBuffer   ;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=CS_DBLCLKS;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BACKGROUND;   wc.cbWndExtra=0;
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0; 
 RegisterClassEx(&wc);
 strcpy(szBuffer,"GUI Console Output With C Runtime Library From C!");  
 hWnd=CreateWindow("Console_Output",szBuffer,WS_OVERLAPPEDWINDOW,500,500,440,200,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
  TranslateMessage(&messages);
  DispatchMessage(&messages);
 }

 return messages.wParam;
}

...and here's the PowerBASIC program with comments..

'Program demonstrates how to restore standard output handle in C Runtime Library
'which is zeroed out by initialization of GUI process.
#Compile Exe
#Include "Win32api.inc"           'Translation of Windows.h for PowerBASIC
%IDC_BUTTON1 = 1250               'ctrl id of button
%O_TEXT      = &H4000             'from Fcntl.h

Type FILE      'From stdio.h      'When a GUI application is started the three standard OS handles
  pChar        As Asciiz Ptr      'STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, and STD_ERROR_HANDLE are all
  cnt          As Long            'zeroed out by the console initialization routines.  These three
  pBase        As Asciiz Ptr      'handles are replaced by valid values when a GUI application calls
  flag         As Long            'AllocConsole(). Therefore, once this is done, calling GetStdHandle()
  fil          As Long            'will always return valid handle values. The problem is that the
  charbuf      As Long            'CRT has already completed initialization before an application gets
  bufsize      As Long            'a chance to call AllocConsole(); the three low I/O handles 0, 1,
  TmpFileName  As Asciiz Ptr      'and 2 have already been set up to use the original zeroed out OS
End Type                          'handles, so all CRT I/O is sent to invalid OS handles and CRT output
                                  'does not appear in the console.

Declare Function GetConsoleWindow Lib "Kernel32.dll" Alias "GetConsoleWindow" () As Dword


Declare Function printf CDecl Lib "msvcrt.dll" Alias "printf" _   'printf from stdio.h
( _
  szFmtStr As Asciiz _
  [, _
     Byref lpVar1 As Any, _
     Byref lpVar2 As Any, _
     Byref lpVar3 As Any, _
     Byref lpVar4 As Any _
  ] _
) As Long


Declare Function Open_OSFileHandle CDecl Lib "msvcrt.dll" Alias "_open_osfhandle" _  'from IO.h
( _
  Byval hHandle As Long, _
  Byval iType   As Long _
) As Long


Declare Function FDOpen CDecl Lib "msvcrt.dll" Alias "_fdopen" _   'from stdio.h
( _
  Byval hHandle As Long, _
  ByRef pszStr As Asciiz _
) As Dword


Function WndProc(Byval hWnd As Long,Byval wMsg As Long,Byval wParam As Long,Byval lParam As Long) As Long
  Select Case wMsg
    Case %WM_CREATE
      Local hButton As Dword
      Local hIns As Dword
      hIns=GetModuleHandle(Byval 0)
      hButton=CreateWindow("button","Show Console!",%WS_CHILD Or %WS_VISIBLE,110,65,200,25,hWnd,%IDC_BUTTON1,hIns,Byval 0)
      WndProc=0
      Exit Function
    Case %WM_COMMAND
      If Lowrd(wParam)=%IDC_BUTTON1 And HiWrd(wParam)=%BN_CLICKED Then
         Local hStdOutput As Dword              'Standart Output Handle
         Local hf,ptrFile As FILE Ptr           'FILE *
         Local hDll,hCrt,dwWeight As Dword
         Local hSysMenu As Dword
         Register i As Long
         hDll=LoadLibrary("msvcrt.dll")         'Load/Increment Reference Count on msvcrt.dll
         If hDll Then                           'Get base address of exported symbol _iob from msvcrt.dll.  _iob is an
            ptrFile=GetProcAddress(hDll,"_iob") 'array of FILE structs that holds the stdin, stdout, and stderr handles.
            Call AllocConsole()                 'These handels are zeroed out at initialization of a GUI process, and
            hSysMenu=GetSystemMenu(GetConsoleWindow(),Byval 0)   'must be reset with valid operating system handles if
            Call DeleteMenu(hSysMenu,6,%MF_BYPOSITION)           'console output is desired in a GUI process.  With a
            hCrt=Open_OSFileHandle(GetStdHandle(%STD_OUTPUT_HANDLE),%O_TEXT)  'valid handel to stdout returned in hf, it
            hf=FDOpen(hCrt,"w")                 'is restored back in position 1 of the i/o buffer FILE array with
            @ptrFile[1]=@hf                     '@ptrFile=@hf. printf output using CRT in PowerBASIC!
            dwWeight=210
            For i=1 To 200                     '
              printf("%d" + Chr$(9) + "My Name Is Fred And I Weigh %u Pounds!"+$Cr+$Lf, Byval i, Byval dwWeight)
            Next i
            Call FreeLibrary(hDll)              'Free/decrement reference count on msvcrt.dll
         End If
      End If
      WndProc=0
      Exit Function
    Case %WM_DESTROY
      Call PostQuitMessage(0)
      WndProc=0
      Exit Function
  End Select

  WndProc=DefWindowProc(hWnd, wMsg, wParam, lParam)
End Function

Function WinMain(Byval hIns As Long, Byval hPrev As Long, Byval lpCL As Asciiz Ptr, Byval iShow As Long) As Long
  Local szBuffer As Asciiz * 64
  Local wc As WNDCLASSEX
  Local Msg As tagMsg
  Local hWnd As Dword

  szBuffer="Console_Output"                           : wc.lpszClAssName=Varptr(szBuffer)
  wc.lpfnWndProc=Codeptr(WndProc)                     : wc.cbSize=Sizeof(wc)
  wc.style=%CS_HREDRAW Or %CS_VREDRAW                 : wc.hInstance=hIns
  wc.cbClsExtra=0                                     : wc.cbWndExtra=0
  wc.hIcon=LoadIcon(%NULL, Byval %IDI_APPLICATION)    : wc.hCursor=LoadCursor(%NULL, Byval %IDC_ARROW)
  wc.hbrBackground=%COLOR_BTNFACE+1                   : wc.lpszMenuName=%NULL
  Call RegisterClAssEx(wc)
  szBuffer="GUI Console Output With C Runtime Library From PowerBASIC!"
  hWnd=CreateWindow("Console_Output",szBuffer,%WS_OVERLAPPEDWINDOW,500,550,440,200,0,0,hIns,Byval 0)
  Call ShowWindow(hWnd,iShow)
  Call UpdateWindow(hWnd)
  While GetMessage(Msg,%NULL,0,0)
    TranslateMessage Msg
    DispatchMessage Msg
  Wend

  Function=msg.wParam
End Function

Here's another version of the C++ code. I've got piles of versions of this. One of these days I might even find a use for this stuff. Actually, this is the one I tried in VC9. I think the 1st was VC6 or Dev C++ or something...

//AllocateConsole.h
#define       IDC_BUTTON  1500

typedef struct    WindowsEventArguments               
{
 HWND             hWnd;                               
 WPARAM           wParam;                             
 LPARAM           lParam;                             
 HINSTANCE        hIns;                               
}WndEventArgs,    *lpWndEventArgs;


struct EVENTHANDLER
{
 unsigned int    Code;
 long            (*fnPtr)(lpWndEventArgs);
};
//Main.cpp
#include      <windows.h>
#include      <tchar.h>
#include      <stdio.h>
#include      <stdlib.h>
#include      <fcntl.h>
#include      <io.h>
#include      "AllocateConsole.h"
EVENTHANDLER  EventHandler[3];


long fnWndProc_OnCreate(lpWndEventArgs Wea)
{
 HWND hButton;
	
 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;  
 hButton=CreateWindow(_T("button"),_T("Execute"),WS_CHILD|WS_VISIBLE,70,70,141,30,Wea->hWnd,(HMENU)IDC_BUTTON,Wea->hIns,0);
 return 0;                                             
}


long fnWndProc_OnCommand(lpWndEventArgs Wea)
{
 HMENU hSysMenu;
 unsigned int i;
 int hCrt;
 FILE *hf;
 
 if(LOWORD(Wea->wParam)==IDC_BUTTON)
 {
    AllocConsole();
    hSysMenu=GetSystemMenu(GetConsoleWindow(),0);
    DeleteMenu(hSysMenu,6,MF_BYPOSITION);         
    hCrt=_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE),_O_TEXT);
    hf=_tfdopen(hCrt,_T("w"));
    *stdout=*hf;
    i=setvbuf(stdout,NULL,_IONBF,0);
    for(i=0;i<10;i++)
        _tprintf(_T("%u\t%s\n"),i,_T("Some Of The More Wicked Code I've Ever Written!"));
 }

 return 0;
}


long fnWndProc_OnClose(lpWndEventArgs Wea)  //This function handles the WM_CLOSE message
{                                           //sent when the 'x' button is clicked.
 if(MessageBox(Wea->hWnd,_T("Do You Wish To Exit This App?"),_T("Exit Check?"),MB_YESNO)==IDYES)
 {
    DestroyWindow(Wea->hWnd);
    PostQuitMessage(WM_QUIT);
 }

 return 0;
}


void AttachEventHandlers(void)  
{
 EventHandler[0].Code=WM_CREATE,    EventHandler[0].fnPtr=fnWndProc_OnCreate;         
 EventHandler[1].Code=WM_COMMAND,   EventHandler[1].fnPtr=fnWndProc_OnCommand; 
 EventHandler[2].Code=WM_CLOSE,     EventHandler[2].fnPtr=fnWndProc_OnClose; 
}


long __stdcall fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam,LPARAM lParam)
{
 WndEventArgs Wea;
   
 for(unsigned int i=0;i<3 ;i++)
 {
     if(EventHandler[i].Code==msg)
     {
        Wea.hWnd=hwnd,Wea.lParam=lParam,Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(&Wea);
     }
 } 

 return (DefWindowProc(hwnd,msg,wParam,lParam));
}



int __stdcall WinMain(HINSTANCE hIns,HINSTANCE hPrevIns,LPSTR lpszArgument,int iShow)
{                                   
 TCHAR szClassName[]=_T("AllocateConsole");  
 WNDCLASSEX wc;                     
 MSG messages;                     
 HWND hWnd;  
                      
 AttachEventHandlers();                                    
 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=CS_DBLCLKS;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=0;
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0; 
 RegisterClassEx(&wc);
 hWnd=CreateWindow(szClassName,_T("Allocate Console"),WS_OVERLAPPEDWINDOW,200,100,300,250,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
  TranslateMessage(&messages);
  DispatchMessage(&messages);
 }

 return messages.wParam;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.