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
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
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;
}
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.