* source/rtl/gtwvt/gtwvt.c
- Removed HB_NOSTARTUPWINDOW link time GTWVT window
hiding option.
; For the same effect, but with the advantage that the
screen output won't slow the application at all, and
that behaviour is controllable from the command line
and/or at link time, please use gtgui.lib.
With GTGUI the application window is neither created
nor updated, while GTWVT will create the window,
update the window, but it will be fully invisible with
no way to unhide. Clipboard and sound generation works
in both cases.
For 100% similar end-user experience as the old hack:
- link gtgui.lib
- replace ANNOUNCE HB_NOSTARTUPWINDOW with
ANNOUNCE HB_GT_GUI_DEFAULT
- add REQUEST HB_GT_GUI
to your application.
* contrib/hbwhat32/whatutil.prg
* contrib/hbwhat32/wincomm.prg
* contrib/hbwhat32/wincore.prg
* contrib/hbwhat32/windebug.prg
* contrib/hbwhat32/winerror.prg
* contrib/hbwhat32/winini.prg
* contrib/hbwhat32/winrbar.prg
* contrib/hbwhat32/wintabs.prg
* contrib/hbwhat32/wintbar.prg
* Some .prg level code cleanup. (= operators,
if(), <> -> !=). No actual problem found.
620 lines
20 KiB
Plaintext
620 lines
20 KiB
Plaintext
/*
|
|
* $Id$
|
|
*/
|
|
|
|
|
|
// WHAT32 ErrorSys
|
|
// A.J. Wos 08/06/2002
|
|
// Scaled down and adapted for Harbour + What32.Lib
|
|
|
|
#include "common.ch"
|
|
|
|
#include "what32.ch"
|
|
#include "winuser.ch"
|
|
#include "error.ch"
|
|
#include "debug.ch"
|
|
|
|
#xtranslate NTRIM( <n> ) => lTrim( Str( <n> ) )
|
|
//#define LOGFILE error.log // don't use quotes
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
PROCEDURE ErrorSys( )
|
|
|
|
ErrorBlock( { | e | DefError( e ) } )
|
|
|
|
RETURN
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION DefError( e )
|
|
|
|
LOCAL cMessage, aOptions, nChoice
|
|
LOCAL cErr
|
|
LOCAL cProcStack := ''
|
|
LOCAL i
|
|
|
|
IF e:genCode == EG_PRINT
|
|
RETURN PrintError( )
|
|
ENDIF
|
|
IF ( e:genCode == EG_ZERODIV )
|
|
RETURN ( 0 )
|
|
ENDIF
|
|
IF ( e:genCode == EG_OPEN .AND. e:osCode == 32 .AND. e:canDefault )
|
|
NetErr( .T. )
|
|
RETURN ( .F. ) // NOTE
|
|
ENDIF
|
|
IF ( e:genCode == EG_APPENDLOCK .AND. e:canDefault )
|
|
NetErr( .T. )
|
|
RETURN ( .F. ) // NOTE
|
|
ENDIF
|
|
|
|
i := 2
|
|
DO WHILE ( ! Empty( ProcName( i ) ) )
|
|
cProcStack += ( CRLF + ProcFile( i ) + "->" + ProcName( i ) + "(" + NTRIM( ProcLine( i ++ ) ) + ")" )
|
|
IF ProcName( i ) == 'DEFERROR' // Oops, recursive arror, cannot continue !
|
|
OutputDebugString( "" )
|
|
OutputDebugString( "===============" + CRLF )
|
|
OutputDebugString( "RECURSIVE ERROR" + CRLF )
|
|
OutputDebugString( "===============" + CRLF )
|
|
OutputDebugString( e:description + CHR( 13 ) + "Procedure Stack Depth:" + ntrim( getprocstack( ) ) + CRLF )
|
|
OutputDebugString( cProcStack + CRLF )
|
|
PostQuitMessage( 0 )
|
|
Errorlevel( 1 )
|
|
// quit
|
|
RETURN( .F. )
|
|
ENDIF
|
|
ENDDO
|
|
|
|
//OutputDebugString( cProcStack + CRLF )
|
|
|
|
cErr := LogError( e, cProcStack )
|
|
OutputDebugString( cErr )
|
|
cMessage := ErrorMessage( e )
|
|
|
|
aOptions := { "Quit" }
|
|
IF ( e:canRetry )
|
|
aAdd( aOptions, "Retry" )
|
|
END
|
|
IF ( e:canDefault )
|
|
aAdd( aOptions, "Default" )
|
|
END
|
|
|
|
nChoice := 0
|
|
|
|
IF ( Empty( e:osCode ) )
|
|
nChoice := eAlert( cMessage, aOptions, cErr )
|
|
ELSE
|
|
nChoice := eAlert( cMessage + ;
|
|
";(OS Error " + NTRIM( e:osCode ) + ")", ;
|
|
aOptions, cErr )
|
|
END
|
|
|
|
IF ( ! Empty( nChoice ) )
|
|
|
|
// do as instructed
|
|
IF ( aOptions[ nChoice ] == "Break" )
|
|
SET DELETED ON
|
|
BREAK( e )
|
|
RETURN( .F. )
|
|
ELSEIF ( aOptions[ nChoice ] == "Retry" )
|
|
RETURN ( .T. )
|
|
ELSEIF ( aOptions[ nChoice ] == "Default" )
|
|
SET DELETED ON
|
|
RETURN ( .F. )
|
|
END
|
|
|
|
END
|
|
|
|
PostQuitMessage( 0 )
|
|
ErrorLevel( 1 )
|
|
Quit
|
|
//CLOSE ALL
|
|
//PGMEXIT()
|
|
|
|
RETURN ( .F. )
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION ErrorMessage( e )
|
|
|
|
LOCAL cMessage
|
|
|
|
// start error message
|
|
cMessage := iif( e:severity > ES_WARNING, "Error", "Warning" )
|
|
|
|
// add error description if available
|
|
IF ( ValType( e:description ) == "C" )
|
|
cMessage += ';' + e:description
|
|
END
|
|
|
|
// add either filename or operation
|
|
IF ( ! Empty( e:filename ) )
|
|
cMessage += ( ';' + e:filename )
|
|
ELSEIF ( ! Empty( e:operation ) )
|
|
cMessage += ( ';' + e:operation )
|
|
END
|
|
|
|
// add subsystem name if available
|
|
IF ( ValType( e:subsystem ) == "C" )
|
|
cMessage += ';ERROR: ' + e:subsystem( ) + ' '
|
|
ELSE
|
|
cMessage += ";ERROR: ??? "
|
|
END
|
|
|
|
// add subsystem's error code if available
|
|
IF ( ValType( e:subCode ) == "N" )
|
|
cMessage += ( NTRIM( e:subCode ) )
|
|
END
|
|
cMessage += ';Called from ' + ProcFile(3) + "->" + procname( 3 ) + ' (' + AllTrim( Str( procline( 3 ) ) ) + '), ' + ;
|
|
+ ProcFile(4) + "->" + procname( 4 ) + ' (' + AllTrim( Str( procline( 4 ) ) ) + ')'
|
|
cMessage += ';Error logged in file '+GetModuleFileName()+'\ERROR.LOG'
|
|
|
|
RETURN ( cMessage )
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION LogError( e, cProcStack )
|
|
|
|
LOCAL Args := convertargs( e:args )
|
|
LOCAL i := 3
|
|
LOCAL cErr := ''
|
|
LOCAL dVer
|
|
|
|
cErr += 'SYSTEM'
|
|
cErr += ( CRLF + '------' )
|
|
cErr += ( CRLF + 'Error date:' + dtoc( date( ) ) + ' time:' + time( ) )
|
|
cErr += ( CRLF + 'Application: ' + GetModuleFileName( ) )
|
|
cErr += ( CRLF + 'What32.Lib ver.' + WhatVersion( @dVer ) + ", " + DTOC( dVer ) )
|
|
|
|
// T.B.D.:
|
|
// add here Windows version, memory info, diskspace info, free resources info
|
|
// add computer name and operator name
|
|
|
|
cErr += ( CRLF )
|
|
cErr += ( CRLF + "ERROR INFORMATION" )
|
|
cErr += ( CRLF + "-----------------" )
|
|
cErr += ( CRLF + "Arguments " + Args )
|
|
cErr += ( CRLF + "Description " + e:description )
|
|
cErr += ( CRLF + "Filename " + IfEmpty( e:filename ) )
|
|
cErr += ( CRLF + "GenCode " + gencodetext( e:genCode ) )
|
|
cErr += ( CRLF + "Operation " + IfEmpty( e:operation ) )
|
|
cErr += ( CRLF + "Severity " + NTRIM( e:severity ) )
|
|
cErr += ( CRLF + "SubCode " + NTRIM( e:subCode ) )
|
|
cErr += ( CRLF + "SubSystem " + e:subSystem )
|
|
cErr += ( CRLF + "Tries " + NTRIM( e:tries ) )
|
|
cErr += ( CRLF + "Alias() " + IfEmpty( ALIAS( ) ) )
|
|
cErr += ( CRLF + "Open DBFs " + ntrim( GetAliasCount( ) ) )
|
|
cErr += ( CRLF + "DOS Error " + DosErrCode( e ) )
|
|
cErr += ( CRLF + "Windows Error " + NTRIM( GetLastError( ) ) )
|
|
cErr += ( CRLF )
|
|
cErr += ( CRLF )
|
|
cErr += ( CRLF + "PROCEDURE STACK" )
|
|
cErr += ( CRLF + "---------------" )
|
|
|
|
cErr += cProcStack
|
|
|
|
SET PRINTER TO "Error.Log" ADDITIVE
|
|
SET CONSOLE OFF
|
|
SET PRINTER ON
|
|
|
|
QOut( " Please mail or fax this error report to:" )
|
|
/*
|
|
? ' +---------------------------+'
|
|
? ' | YOUR BUSINESS NAME HERE |'
|
|
? ' | P.O.Box 123 |'
|
|
? ' |Some Prestigeous Town, 1234|'
|
|
? ' | Fax: (01) 1234 1234 |'
|
|
*/
|
|
QOut( " +---------------------------+" )
|
|
QOut( cErr )
|
|
|
|
QOut(Replicate( "=", 70 ))
|
|
|
|
EJECT
|
|
SET PRINTER OFF
|
|
SET PRINTER TO
|
|
SET CONSOLE ON
|
|
|
|
RETURN cErr
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION IfEmpty( Msg )
|
|
|
|
LOCAL Ret_Val := "<none>"
|
|
|
|
IF ! Empty( msg )
|
|
Ret_Val := Left( msg, 68 )
|
|
ENDIF
|
|
|
|
RETURN Ret_Val
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC PROCEDURE PrintError
|
|
|
|
BREAK
|
|
|
|
// RETURN
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION ConvertArgs( a )
|
|
|
|
LOCAL Ret_Val
|
|
LOCAL x, cType
|
|
LOCAL NumArgs := iif( ValType( a ) == "A", Len( a ) , iif( ValType( a ) == "C", ( a := { a } , 1 ) , 0 ) )
|
|
|
|
IF NumArgs > 0
|
|
Ret_Val := '{ '
|
|
FOR x := 1 TO NumArgs
|
|
cType := ValType( a[ x ] )
|
|
DO CASE
|
|
CASE cType == "C"
|
|
Ret_Val += a[ x ]
|
|
CASE cType == "N"
|
|
Ret_Val += NTRIM( a[ x ] )
|
|
CASE cType == "D"
|
|
Ret_Val += dtoc( a[ x ] )
|
|
CASE cType == "L"
|
|
Ret_Val += iif( a[ x ] , ".T.", ".F." )
|
|
CASE cType == "O"
|
|
Ret_Val += a[ x ] :className + " Object"
|
|
CASE cType == "U"
|
|
Ret_Val += "NIL"
|
|
ENDCASE
|
|
//ÄÄÄÄÄ Next block added 1/8/92 To separate arguments
|
|
IF x < NumArgs
|
|
Ret_Val += ', '
|
|
ENDIF
|
|
NEXT
|
|
Ret_Val += ' }'
|
|
ENDIF
|
|
|
|
RETURN ifempty( Ret_Val )
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION GetAliasCount( )
|
|
|
|
LOCAL Counter := 0
|
|
LOCAL nCounter := 0
|
|
|
|
FOR Counter := 1 TO 255
|
|
IF ! Empty( alias( Counter ) )
|
|
nCounter ++
|
|
ENDIF
|
|
NEXT
|
|
|
|
RETURN( nCounter )
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION getprocstack( )
|
|
|
|
LOCAL i := 2
|
|
|
|
DO WHILE ! Empty( procname( i ) )
|
|
i ++
|
|
ENDDO
|
|
|
|
RETURN( i - 3 )
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION DosErrCode( e )
|
|
|
|
LOCAL Msg
|
|
|
|
IF e:osCode > 0
|
|
Msg := NTRIM( e:osCode ) + ": " + Left( DosErrText( e:osCode ) , 37 )
|
|
ELSE
|
|
Msg := "(not an operating system error)"
|
|
ENDIF
|
|
|
|
RETURN Msg
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
/*
|
|
Function: DosErrText( )
|
|
Author: Craig Yellick
|
|
Purpose: Provide full description of DOS error code ( see table D - 1
|
|
in the Clipper 5.0 "Programming & Utilities Guide" )
|
|
Returns: character string
|
|
*/
|
|
|
|
STATIC FUNCTION DosErrText( n )
|
|
|
|
LOCAL desc_ := { "Invalid function number" , ; // 1
|
|
"File not found" , ; // 2
|
|
"Path not found" , ; // 3
|
|
"Too many files open (no handles left)" , ; // 4
|
|
"Access denied" , ; // 5
|
|
"Invalid handle" , ; // 6
|
|
"Memory control blocks destroyed (oh, my)", ; // 7
|
|
"Insufficient memory" , ; // 8
|
|
"Invalid memory block address" , ; // 9
|
|
"Invalid environment" , ; // 10
|
|
"Invalid format" , ; // 11
|
|
"Invalid access code" , ; // 12
|
|
"Invalid data" , ; // 13
|
|
, ; // 14
|
|
"Invalid drive was specified" , ; // 15
|
|
"Attempt to remove the current directory" , ; // 16
|
|
"Not same device" , ; // 17
|
|
"No more files" , ; // 18
|
|
"Attempt to write on write-protected diskette", ; // 19
|
|
"Unknown unit" , ; // 20
|
|
"Drive not ready" , ; // 21
|
|
"Unknown command" , ; // 22
|
|
"Data error (CRC)" , ; // 23
|
|
"Bad request structure length" , ; // 24
|
|
"Seek error" , ; // 25
|
|
"Unknown media type" , ; // 26
|
|
"Sector not found" , ; // 27
|
|
"Printer out of paper" , ; // 28
|
|
"Write fault" , ; // 29
|
|
"Read fault" , ; // 30
|
|
"General failure" , ; // 31
|
|
"Sharing violation" , ; // 32
|
|
"Lock violation" , ; // 33
|
|
"Invalid disk change" , ; // 34
|
|
"FCB unavailable" , ; // 35
|
|
"Sharing buffer overflow" , ; // 36
|
|
, , , , , , , , , , , , , ; // 37-49
|
|
"Network request not supported" , ; // 50
|
|
"Remote computer not listening" , ; // 51
|
|
"Duplicate name on network" , ; // 52
|
|
"Network name not found" , ; // 53
|
|
"Network busy" , ; // 54
|
|
"Network device no longer exists" , ; // 55
|
|
"Network BIOS command limit exceeded" , ; // 56
|
|
"Network adapter hardware error" , ; // 57
|
|
"Incorrect response from network" , ; // 58
|
|
"Unexpected network error" , ; // 59
|
|
"Incompatible remote adapter" , ; // 60
|
|
"Print queue full" , ; // 61
|
|
"Not enough space for print file" , ; // 62
|
|
"Print file deleted (not enough space)" , ; // 63
|
|
"Network name deleted" , ; // 64
|
|
"Access denied" , ; // 65
|
|
"Network device type incorrect" , ; // 66
|
|
"Network name not found" , ; // 67
|
|
"Network name limit exceeded" , ; // 68
|
|
"Network BIOS session limit exceeded" , ; // 69
|
|
"Temporarily paused" , ; // 70
|
|
"Network request not accepted" , ; // 71
|
|
"Print or disk redirection paused" , ; // 72
|
|
, , , , , , , ; // 73-79
|
|
"File already exists" , ; // 80
|
|
, ; // 81
|
|
"Cannot make directory entry" , ; // 82
|
|
"Fail on INT 24h" , ; // 83
|
|
"Too many redirections" , ; // 84
|
|
"Duplicate redirection" , ; // 85
|
|
"Invalid password" , ; // 86
|
|
"Invalid parameter" , ; // 87
|
|
"Network device fault" , ; // 88
|
|
;
|
|
"Undefined or reserved error code!" ; // +1
|
|
}
|
|
|
|
/*
|
|
Check that code number is within known upper limit,
|
|
AND that a description is available For it.
|
|
*/
|
|
/*
|
|
IF ( n > ( Len( desc_ ) - 1 ) ) .OR. ( desc_[ n ] == NIL )
|
|
n := Len( desc_ )
|
|
ENDIF
|
|
*/
|
|
IF ( ( n < 1 ) .OR. n > ( Len( desc_ ) - 1 ) ) .OR. ( desc_[ n ] == NIL )
|
|
n := Len( desc_ )
|
|
ENDIF
|
|
|
|
RETURN desc_[ n ]
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION GenCodeText( n )
|
|
|
|
LOCAL desc_ := { "EG_ARG", ; // 1
|
|
"EG_BOUND" , ; // 2
|
|
"EG_STROVERFLOW" , ; // 3
|
|
"EG_NUMOVERFLOW" , ; // 4
|
|
"EG_ZERODIV" , ; // 5
|
|
"EG_NUMERR" , ; // 6
|
|
"EG_SYNTAX" , ; // 7
|
|
"EG_COMPLEXITY" , ; // 8
|
|
, , ; // 9-10
|
|
"EG_MEM" , ; // 11
|
|
"EG_NOFUNC" , ; // 12
|
|
"EG_NOMETHOD" , ; // 13
|
|
"EG_NOVAR" , ; // 14
|
|
"EG_NOALIAS" , ; // 15
|
|
"EG_NOVARMETHOD" , ; // 16
|
|
"EG_BADALIAS" , ; // 17 (new w/ 5.01a)
|
|
"EG_DUPALIAS" , ; // 18 (new w/ 5.01a)
|
|
, ; // 19
|
|
"EG_CREATE" , ; // 20
|
|
"EG_OPEN" , ; // 21
|
|
"EG_CLOSE" , ; // 22
|
|
"EG_READ" , ; // 23
|
|
"EG_WRITE" , ; // 24
|
|
"EG_PRINT" , ; // 25
|
|
, , , , ; // 26-29
|
|
"EG_UNSUPPORTED" , ; // 30
|
|
"EG_LIMIT" , ; // 31
|
|
"EG_CORRUPTION" , ; // 32
|
|
"EG_DATATYPE" , ; // 33
|
|
"EG_DATAWIDTH" , ; // 34
|
|
"EG_NOTABLE" , ; // 35
|
|
"EG_NOORDER" , ; // 36
|
|
"EG_SHARED" , ; // 37
|
|
"EG_UNLOCKED" , ; // 38
|
|
"EG_READONLY" , ; // 39
|
|
"EG_APPENDLOCK" , ; // 40
|
|
;
|
|
"Unknown or reserved" ; // +1
|
|
}
|
|
|
|
/*
|
|
Check that code number is within known upper limit,
|
|
AND that a description is available For it.
|
|
*/
|
|
/*
|
|
IF ( n > ( Len( desc_ ) - 1 ) ) .OR. ( desc_[ n ] == NIL )
|
|
n := Len( desc_ )
|
|
ENDIF
|
|
*/
|
|
IF ( ( n < 1 ) .OR. n > ( Len( desc_ ) - 1 ) ) .OR. ( desc_[ n ] == NIL )
|
|
n := Len( desc_ )
|
|
ENDIF
|
|
|
|
|
|
RETURN NTRIM( n ) + ": " + desc_[ n ]
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION eAlert( cMsg, aChoices, cDetail )
|
|
|
|
LOCAL aDlg, i, n, aChoose, aMsg
|
|
LOCAL hWnd, hDC
|
|
LOCAL lErr := .F., w , h, t := 0, cTitle, Msgh, ButWidth
|
|
LOCAL crPos := 0, txth := 0, atm := { }
|
|
LOCAL isDetail := .F.
|
|
|
|
IF !ISCHARACTER( cMsg )
|
|
cMsg := asString( cMsg )
|
|
ENDIF
|
|
cTitle := 'Alert'
|
|
|
|
IF aChoices == NIL
|
|
aChoices := { "&Ok" }
|
|
ENDIF
|
|
|
|
aAdd( achoices, "&Details >>" )
|
|
|
|
cMsg := StrTran( cMsg, ";", CR )
|
|
|
|
IF ( crPos := at( CR, cMsg ) ) > 0
|
|
cTitle := Left( cMsg, crPos - 1 )
|
|
cMsg := SubStr( cMsg, crPos + 1 )
|
|
ENDIF
|
|
|
|
hWnd := GetDesktopWindow( ) // default parent
|
|
hDC := GetDC( hWnd )
|
|
|
|
//------------- total width without buttons
|
|
|
|
w := GetTextExtentPoint32( hDC, AllTrim( cTitle ) ) [ 1 ]
|
|
aMsg := str2a( cMsg, CR )
|
|
AEVAL( aMsg, { | x | w := Max( w, GetTextExtentPoint32( hDC, AllTrim( x ) ) [ 1 ] ) } )
|
|
w += 20
|
|
|
|
//--------- total width of choices, also add "&" to the choices (if needed)
|
|
|
|
n := Len( aChoices )
|
|
aChoose := array( n )
|
|
|
|
txth := 8 //ATM[TM_Height]
|
|
Msgh := Len( aMsg ) * txth
|
|
FOR i := 1 TO n
|
|
ButWidth := Max( 20, GetTextExtentpoint32( hDC, aChoices[ i ] ) [ 1 ] + 6 )
|
|
t := Max( t, ButWidth )
|
|
aChoose[ i ] := iif( at( "&", aChoices[ i ] ) == 0, "&" + aChoices[ i ] , aChoices[ i ] )
|
|
NEXT i
|
|
|
|
ReleaseDC( , hDC )
|
|
|
|
ButWidth := t / 2
|
|
t *= ( n + 1 )
|
|
w := Max( Max( w, t ) + 40, 500 ) // minimum dlg width
|
|
h := Msgh + 33
|
|
w /= 2
|
|
|
|
//----------- create dialog
|
|
|
|
aDlg := MakeDlgTemplate( cTitle, ;
|
|
WS_CAPTION + DS_MODALFRAME + WS_VISIBLE + 4 + WS_POPUP + DS_SETFONT , ;
|
|
0, 0, w, h, 8, 'MS Sans Serif' )
|
|
|
|
FOR i := 1 TO n
|
|
aDlg := AddDlgItem( aDlg, i, "BUTTON", ;
|
|
BS_PUSHBUTTON + WS_TABSTOP + WS_CHILD + WS_VISIBLE, ;
|
|
w - ( n - i ) * ( ButWidth + 5 ) - ButWidth - 5, h - 18, ButWidth, 14, ;
|
|
aChoose[ i ] )
|
|
NEXT i
|
|
|
|
aDlg := AddDlgItem( aDlg, - 1, "STATIC", ;
|
|
SS_CENTER + WS_CHILD + WS_VISIBLE, ;
|
|
10, 8, w - 20, Msgh, ;
|
|
cMsg )
|
|
|
|
aDlg := AddDlgItem( aDlg, - 1, "BUTTON", ;
|
|
BS_GROUPBOX + WS_CHILD + WS_VISIBLE, ;
|
|
5, 1, w - 10, Msgh + 10, ;
|
|
"" )
|
|
|
|
aDlg := AddDlgItem( aDlg, 101, "EDIT", ;
|
|
WS_CHILD + WS_VISIBLE + WS_BORDER + ES_MULTILINE + ES_READONLY + WS_VSCROLL + WS_TABSTOP, ;
|
|
5, h + 1, w - 10, 115, ;
|
|
cDetail )
|
|
|
|
MessageBeep( MB_ICONHAND )
|
|
i := DialogBox( , aDlg, hWnd, { | hDlg, nMsg, nwParam, nlParam | ;
|
|
eAlertProc( hDlg, nMsg, nwParam, nlParam, @isDetail, hWnd, n ) } )
|
|
SetFocus( hWnd )
|
|
|
|
RETURN i
|
|
|
|
|
|
*------------------------------------------------------------------------------*
|
|
|
|
STATIC FUNCTION eAlertProc( hDlg, nMsg, nwParam, nlParam, isDetail, hWnd, n )
|
|
|
|
LOCAL aRect
|
|
|
|
HB_SYMBOL_UNUSED( nlParam )
|
|
|
|
DO CASE
|
|
CASE nMsg == WM_INITDIALOG
|
|
CenterWindow( hDlg, , , hWnd )
|
|
SetOnTop( hDlg, HWND_TOPMOST )
|
|
RETURN( 1 )
|
|
|
|
CASE nMsg == WM_COMMAND
|
|
IF 'Detail' $ GetDlgItemText( hDlg, nwParam )
|
|
aRect := getwindowrect( hDlg )
|
|
IF isDetail
|
|
SetDlgItemText( hDlg, nwParam, '&Detail >>' )
|
|
MoveWindow( hDlg, aRect[ 1 ] , aRect[ 2 ] , aRect[ 3 ] - aRect[ 1 ] , aRect[ 4 ] - aRect[ 2 ] - 200, .T. )
|
|
isDetail := .F.
|
|
ELSE
|
|
SetDlgItemText( hDlg, nwParam, '<< &Detail' )
|
|
MoveWindow( hDlg, aRect[ 1 ] , aRect[ 2 ] , aRect[ 3 ] - aRect[ 1 ] , aRect[ 4 ] - aRect[ 2 ] + 200, .T. )
|
|
isDetail := .T.
|
|
ENDIF
|
|
ELSE
|
|
IF nwParam > 0 .AND. nwParam < n
|
|
EndDialog( hDlg, nwParam )
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDCASE
|
|
|
|
RETURN 0
|