📄 uinhelp.asm
字号:
DbChk FreeBuf2 ; release the HotSpot
; Check to see if the context is !B. If it is, then we should
; execute a HelpBack command instead of displaying the context
cmp WORD PTR b$Buf1,'B!' ; is it !B?
jne NotHelpBack ; no, go display it
cmp BYTE PTR b$Buf1+2,0 ; is it 0 terminated?
jne NotHelpBack ; no, go display it
DbAssertRel pwndAct,e,<OFFSET DGROUP:wndHelp>,UI,<SelectHotLink:Not in help window>
pop ax ; restore stack (param to
; DisplayHlpwndSz not used)
xor ax,ax ; move to (0,0) so we will
cCall MoveCursorPwndCur,<ax,ax> ; goto previous topic
DbChk FreeBuf1 ; incase HelpBack wants it
call HelpBack ; do the help back
jmp short ExitSuccess ; and exit
NotHelpBack:
cCall DisplayHlpWndSz ; display text
DbAssertRelB al,ne,HELP_NF,UI,<SelectHotLink:Returned hot link not found>
;ignore any errors
DbChk FreeBuf1 ; release context string
ExitSuccess:
xor ax,ax ; return value of success
; this way we will not put
; up an error box, then
; do something useful.
NoSelection:
cEnd
;Rewrote with [5]
;***
;FillContextNext - Fill the next buffer with the desired context information
;
;Purpose:
; Read a help context into the help buffer given the position that
; is previous to it. The information needed for the new context
; is obtained from the context given. This routine will read in
; as many contexts as desired.
;
; Note: this routine does not return any errors, as its caller
; does not check the error code (this is used to fill the buffer
; with topics after the current topic, so if we could not read
; in a topic for any reason, then we will just leave the buffer
; partially empty).
;
;Entry:
; BX = current buffer
; DI = number of context to read
;
;Exit:
; oLastBuf = Last valid buffer
; numBuf updated
;
;****
cProc FillContextNext,<NEAR>,<DI>
cBegin
DbAssertRelB fNoDelBufs,ne,0,UI,<FillContextNext:Caller did not set fNoDelBufs>
cEnd
;Added with [5]
;***
;GetHelpMsgNcFill - get a help message from a context number, fill in fields
;
;Purpose:
; Calls GetHelpMsgNc, and fills in all the fields of the buffer except
; for the first line number of the context.
;
;Entry:
; DX:AX = context number to be filled in
; BX = ptr to context
;Exit:
; if (AL = 0)
; BX = ptr to context
; all fields of context are filled in
; else
; AL = HELP_HANDLED.
;
;****
cProc GetHelpMsgNcFill,<NEAR>
cBegin
push bx ; We need to preserve BX
mov Word Ptr [bx].ContextNum,ax ; save Context Num in Buffer
mov Word Ptr [bx].ContextNum+2,dx
lea cx,[bx].bdlHelpText ; point to BLD
cCall GetHelpMsgNc,<dx,ax,cx> ; get message
; (AL = return code)
pop bx ; BX = *Buffer
Fill_Exit:
cEnd
;***
;GetHelpMsgSz - get a help message from a context string
;GetHelpMsgNc - get a help message from a context number
;
;Purpose:
; This routine calls the help engine to obtain the help text
; associated with a context string. The text is returned in a BDL.
; No buffering of the help context is performed.
;
; NOTE: Does not require oFirstBuf or oLastBuf to be set.
;
;Entry:
; szContext : pointer to context string
; BdlText : pointer to bdl owner structure.
;
;Exit:
; AL = HELP_OK (0) if success.
; AL = HELP_HANDLED, HELP_NF
;
;Uses:
; Per convention
;
;Exceptions:
;
;****
cProc GetHelpMsgSz,<NEAR,PUBLIC>
parmW szContext
parmW BdlText
cBegin
DbAssertTst HelpFlags,ne,HLP_GOTBUF,UI,<GetHelpMsgSz:HLP_GOTBUF false>
mov ax,szContext ; AX = context string
cCall CalcNc,<AX> ; DX:AX = nc for context string
jcxz GetHelpMsgSzExit ; return with error code (AL) if error
cCall GetHelpMsgNc,<DX,AX,BdlText> ; get message
GetHelpMsgSzExit:
cEnd
DbPub GetHelpMsgNc
cProc GetHelpMsgNc,<NEAR>,<SI,DI>
parmW ncHigh
parmW ncLow
parmW BdlText
cBegin
DbAssertTst HelpFlags,ne,HLP_GOTBUF,UI,<GetHelpMsgNc:HLP_GOTBUF false>
DbAssertRelB fHelpAlloc,ne,0,UI,<GetHelpMsgNc:fHelpAlloc not set>
mov di,ncHigh ;set DI:SI to context string
mov si,ncLow
and HelpFlags,NOT (HLP_FAILFNF OR HLP_FAILOOM) ; clear flags
cCall HelpNcCb,<DI,SI> ; AX = #bytes for decompressed topic
xchg ax,cx ; save size in CX
test HelpFlags,HLP_FAILFNF OR HLP_FAILOOM ; did we fail it?
mov al,HELP_HANDLED ; assume so
jnz GetHelpMsgNcExit_Near ; exit if error
mov bx,offset DGROUP:BdlTemp
cCall BdlAlloc,<BX,CX> ; alloc bdl for compressed data
or ax,ax ; OOM error?
jz GetHelpMsgOOM ; yes, go handle it
lea bx,[BdlTemp.BDL_seg] ; BX = handle to data segment
xor ax,ax ; offset 0
cCall HelpLook,<DI,SI,BX,AX> ; AX = # bytes uncompressed
xchg cx,ax ; CX = # bytes uncompressed
jcxz FreeExitError ; brif error -- release bdl & exit
inc fNoDelBufs ; don't delete buffers
mov bx,BdlText ; bx = *BDL owner
cCall BdlAlloc,<BX, CX> ; alloc BDL for uncompressed data
or ax,ax ; ZF ==> error
jnz DecompressHelp ; no error, go decompress help topic
cCall GiveHelpOOM ; generate OOM error
dec fNoDelBufs ; restore buffer flag
jmp short FreeExitError ; free Bdl and exit
GetHelpMsgOOM:
cCall GiveHelpOOM ; signal an OOM error
mov al,HELP_HANDLED
GetHelpMsgNcExit_Near:
jmp Short GetHelpMsgNcExit ; brif so -- give error and exit
DecompressHelp:
DbAssertTst HelpFlags,z,HLP_NOSHRINK,UI,<GetHelpMsgNc:NOSHRINK set>
or HelpFlags,HLP_NOSHRINK ; don't shrink during HelpDecomp
; otherwise it will fail.
mov bx,BdlText ; bx = *BDL owner (could have moved)
xor ax,ax ; offset 0
lea dx,[BX].BDL_seg ; DX = handle of destination seg
lea bx,[BdlTemp.BDL_seg] ; BX = handle of source segment
cCall HelpDecomp,<BX,AX,DX,AX,DI,SI>
; decompress help text
dec fNoDelBufs ; reset buffer delete flag
and HelpFlags,NOT HLP_NOSHRINK ; reenable shrinking.
or ax,ax ; did we get an error?
jz FreeExit ; no, free temp BDL and exit
mov ax,BdlText ; get pointer to bdl
cCall BdlFree,<AX> ; and deallocate it
test HelpFlags,HLP_FAILOOM or HLP_FAILFNF ; have we reported?
jnz FreeExitError ; yes, get return code
cCall GiveHelpOOM ; report the error.
FreeExitError:
mov al,HELP_HANDLED ; prepare to return error
FreeExit:
push ax ; save return code
mov ax,OFFSET DGROUP:BdlTemp
cCall BdlFree,<AX> ; release compressed data
pop ax ; AX = return code (NZ ==> success)
GetHelpMsgNcExit:
cEnd
subttl Display Text in the Help Window
;Rewrote with [5]
;***
;DisplayHlpWndSz - Display help in a window given a context string
;DisplayHlpWndNc - Display help in a window given a context number
;
;Purpose:
; Displays a context in the help window given either a context
; string (DisplayHlpWndSz) or a context number (DisplayHlpWndNc).
; This routine will open the help window if it is not already
; opened.
;
;Entry:
; szContext : pointer to a context string (DisplayHlpWndSz)
; or
; DX:AX : context number (DisplayHlpWndNc)
;
;Exit:
; AL = error code (HELP_OK, HELP_HANDLED, HELP_NF)
;
;Uses:
; Per Convention
;
;****
cProc DisplayHlpWndSz,<PUBLIC,NEAR>
parmW szContext
cBegin
DbAssertTst HelpFlags,ne,HLP_GOTBUF,UI,<DisplayHlpWndSz:HLP_GOTBUF false>
mov ax,szContext ;AX = context string
cCall CalcNc,<AX> ; DX:AX = nc for context string
jcxz HlpWndSzExit ; there was an error, exit
cCall DisplayHlpWndNc ;display help for this context number
HlpWndSzExit: ;AL = return code
cEnd
cProc DisplayHlpWndNc,<PUBLIC,NEAR>
cBegin
DbAssertTst HelpFlags,ne,HLP_GOTBUF,UI,<DisplayHlpWndNc:HLP_GOTBUF false>
cCall BufferNc ; BX = ptr to new context
or al,al ; was there an error?
jne DisplayFailure ; yes, exit with error code
push bx ; save buffer pointer
mov dx,Word Ptr [bx].ContextNum+2 ; Get context number into
mov ax,Word Ptr [bx].ContextNum ; DX:AX
cCall RecordHelpHistory ; record context number for Ctrl-F1
pop bx ; restore buffer pointer
lea ax,[bx].bdlHelpText
push ax ; save for call to GetHelpContextLen
cCall SizeHelpContext,<ax> ; get # lines in the help topic
; sets iFileSize
cCall GetHelpContextLen ; AX = get suggested size of wnd
cCall OpenHelpWindow ; go open the window (to size AX)
cCall DrawDebugScr ; force help title to be redrawn
xor ax,ax ; return 0 for no-errors
DisplayFailure:
cCall CloseCurHelpFile ; shut down current help file, if
; any opened. (preserves AX, DX)
cEnd
;***
;BufferNc - Given a context number, properly buffer in context
;
;Purpose:
; This routine will refill the help buffer so that Nc is
; present. If Nc did not exist, the buffer is flushed and
; refilled.
;
;Entry:
; DX:AX : Context number to be buffered
;
;Exit:
; if (successful)
; AL = HELP_OK (=0)
; BX = new buffer ptr
; numBuf updated
; oCurTopic = BX
; else
; AL = HELP_HANDLED
;
;****
cProc BufferNc,<PUBLIC,NEAR>,<DI>
cBegin
;See if the context number is already buffered
xor cx,cx
mov cl,numBuf ; scan numBuf contexts
jcxz DelNoBufs ; special case this...LOOP can't
mov bx,oFirstBuf ; Start at first context
CheckNext:
cmp ax,Word Ptr [bx].ContextNum ; check low word first
jne TryToLoop ; comparison failed, goto next one
cmp dx,Word Ptr [bx].ContextNum+2 ; check high word
jne TryToLoop ; comparison failed, goto next one
jmp FoundMatch ; we have the context already buffered
TryToLoop:
add bx,BUFSIZE ; move to next logical buffer
cmp bx,BUFFEREND ; did we go off the end?
jb Wrap5 ; no, continue
sub bx,BUFFERSIZE ; adjust back to begining
Wrap5:
loop CheckNext ; try the next context
NotBuffered:
; # buffers to free = # needed - # free
; = MAX_HELPBUFS / 2 - (MAX_HELPBUFS - numBufs)
; = numBufs - (MAX_HELPBUFS / 2)
mov cl,numBuf ; Calculate # buffers to delete
sub cl,MAX_HELPBUFS /2
ja DelSomeBufs ; brif a positive number
xor cl,cl ; delete 0 buffers (makes
DelSomeBufs: ; oCurTopic == oLastTopic)
xor ch,ch ; CBW for CX
push ax ; save the context number
push dx
call FlushBuffer ; delete CX current contexts
pop dx ; restores context number
pop ax
DelNoBufs:
DbAssertRelB numBuf,be,MAX_HELPBUFS,UI,<BufferNc: No buffers free after deleting some>
mov bx,oLastBuf ; Ptr to last buffer used
cmp numBuf,0 ; stupid special case?
jne UseoLastBuf ; no, index off of oLastBuf
mov oFirstBuf,bx ; oFirstBuf = oLastBuf
jmp short NoWrap6
UseoLastBuf:
add bx,BUFSIZE ; point to the next one
cmp bx,BUFFEREND ; did we go off the end?
jb NoWrap6
sub bx,BUFFERSIZE
NoWrap6:
cCall GetHelpMsgNcFill ; get the help topic
or al,al ; any errors?
jne BufferNc_Exit ; yes, exit with error code
inc numBuf ; indicate one more buf in use
;Fill the rest of the buffer with contexts after this one
inc fNoDelBufs ; do not delete buffers to get these
mov ax,MAX_HELPBUFS
sub al,numBuf ; AX = number of buffers free
push bx ; save it for exit
xchg di,ax ; set DI = number of free buffers
mov oLastBuf,bx ;set oLastBuf = last legal buffer
FillAnotherNext:
mov dx,Word Ptr [bx].ContextNum+2 ; DX:AX = current NC
mov ax,Word Ptr [bx].ContextNum
push bx
cCall GetNextNc
pop bx
je FillContextDone ; no more contexts
add bx,BUFSIZE ;Point BX at next buffer
cmp bx,BUFFEREND ; did we go off end of buffer?
jb NoWrap3 ;no, continue
sub bx,BUFFERSIZE ;wrap around to begining
NoWrap3:
cCall GetHelpMsgNcFill ;get message DX:AX into *(BX)
or al,al ; did an error occur
jne FillContextDone ; yes, stop filling in buffers
mov oLastBuf,bx ; set oLastBuf = last legal buffer
inc numBuf ;record that a buffer is now in uses
dec di ;one more context use
jne FillAnotherNext ;get another one if allowed
FillContextDone:
;Ignore any errors, we have at least one buffer
mov uierr,0 ; clear any errors
pop bx ; pointer to buffer with our context
dec fNoDelBufs ; reset buffer delete pointer
FoundMatch:
xor ax,ax ; ax = 0 (no errors)
mov oCurTopic,bx ; update current buffer ptr.
BufferNc_Exit:
cEnd
;Rewrote with [45]
;***
;OpenHelpWindow - Open the help window and ready it to print text
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -