1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
'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 _
[, _
Byval lpVar1 As Any, _
Byval lpVar2 As Any, _
Byval lpVar3 As Any, _
Byval 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,i,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
|