📄 uinhelp.asm
字号:
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
;
;Purpose:
; This routine will not only open the help window to the correct
; size, but will adjust the size of the window to account
; for the existance/non existance of the scroll bar.
;
;Entry:
; ax = Size of window
;
;Exit:
; None.
;****
DbPub OpenHelpWindow
cProc OpenHelpWindow,<NEAR>
cBegin
cmp pwndAct,OFFSET DGROUP:WndHelp ; in help window?
je InHelpWindow ; no, do not resize
inc ax ; add a line for scroll bar
InHelpWindow:
cCall WndHelpOpen,<AX> ; AX = actual size of window
; We must always move the cursor to (0,0), otherwise the edit
; manager may not realize that this is a new topic and would not
; position it so that the first line is visible.
xor bx,bx ; cursor position is 0,0
mov ax,OFFSET DGROUP:wndHelp; window to receive the message
push ax ; save for second call
cCall MoveCursorPwnd,<AX,BX,BX> ; goto 0,0 in window
cCall GetInitialPos ; get initial position on screen
cCall MoveCursorPwnd,<DX,AX> ; goto hot link spot
cEnd
;***
;GetInitialPos - Calculate the initial cursor position in the help window
;
;Purpose:
; Returns the initial cursor position in the help window. This is
; the (0 relative) coordinates of the first hot link (if it exists
; and is visible), or (0,0).
;
;Entry:
; None
;
;Exit:
; (DX,AX) - initial Row/Column of the screen (0,0) or first hot spot
;
;Uses:
; Per C Convention.
;****
cProc GetInitialPos,<PUBLIC,NEAR>
cBegin
DbChk HoldBuf2 ; lock down the hotspot
test HelpFlags,HLP_VARHELP ; are we in var help?
jnz Use00 ; yes, there are no hotlinks
mov ax,1 ; current row/column position
mov HtSpot.ColHS,ax
mov HtSpot.lineHS,ax
DbAssertRel oCurTopic,ne,0,UI,<GetInitialPos:oCurTopic invalid>
mov bx,oCurTopic
lea bx,[bx].bdlHelpText.BDL_seg
mov cx,OFFSET DGROUP:HtSpot
dec ax ; ax = 0
cCall HelpHlNext,<AX,BX,AX,DS,CX>
or ax,ax ; did we get a hot link?
je Use00 ; no, use (0,0) as position
mov ax,HtSpot.ColHS ; get position of hotlink
mov dx,HtSpot.lineHS
dec dx ; make position 0 relative
dec ax
; Make sure the hot link is visible.
mov cl,WndHelp.arcClipping.ayBottomArc
sub cl,WndHelp.arcClipping.ayTopArc ; CX = size of help window
cmp cl,dl ; within visible range?
jae GetInitialPos_Exit ; no, ignore the hotlink
Use00:
xor dx,dx
xor ax,ax
GetInitialPos_Exit:
DbChk FreeBuf2 ; release HotSpot
cEnd
subttl Edit Manager Support Routines
page
;Extracted and modified with revision [29].
;***
;GetHelpTitleStr - Returns the title for a given help topic
;
;Purpose:
; Calculates the title, and returns it in bufStdMsg.
; All titles are prefixed by "HELP: ".
;
; Uses the ":n" information if the help file, if it exists.
; Otherwise, returns the current context string.
;
;Entry:
; pHelpBdl = *bdl containing decompressed help topic.
; cbMaxSize = max title length allowed
;
; If window help, curNc is the help context #
; If dialog box help, szDialogHelpContext points to the current szContext
;
;Exit:
; AX = number of characters in title
; bufStdMsg = contains title.
;
;Uses:
; Per Convention
;
;****
cProc GetHelpTitleStr,<NEAR,PUBLIC>,<SI,DI>
parmW pHelpBdl
parmW cbMaxSize
cBegin
DbAssertTst HelpFlags,nz,HLP_GOTBUF,UI,<GetHelpTitleStr:HLP_GOTBUF false>
inc fNoDelBufs ; do not delete buffers, we have
; a generic ptr to a buffer
; Setting fNoDelBufs is probably not needed as currently
; pHelpBdl points to either oCurTopic or to a static
; Bdl used by dialog help. However, I doubt that we do any
; allocs in this code, and I can not guarentee that pHelpBdl
; is safe.
mov ax,MSG_HelpTitleQH ; first part of title ("MS-DOS Help: ")
test cmdSwitches,CMD_SW_QHELP ; /QHELP viewer?
jnz ghts1 ; YES, got title
mov ax,MSG_HelpTitle ; first part of title ("HELP: ")
ghts1:
cCall ListStdMsg,<AX> ; put in bufStdMsg
push ax ; save length of static portion
add ax,OFFSET DGROUP:bufStdMsg ; ds:di = useful buffer
xchg di,ax
mov al,'n' ; look for ":nTITLE"
cCall GetHelpControlInfo,<pHelpBdl,cbMaxSize,ax> ; SI = *embedded title, if any
or si,si ; title found?
jnz AppendTitle ; brif so
mov si,szDialogHelpContext ; use current context string as title
; for dialog box help
cmp pHelpBdl,offset DGROUP:bdlHelp ; title for dialog box help?
je AppendTitle ; brif so -- append string to title
mov bx,oCurTopic ; ptr to current topic data
or bx,bx ; is it valid?
je GetHelpTitleStr_Fail ; no, use MSG_HelpTitle for now
push ds ;push far address to load szContext
push di
push Word Ptr [bx].ContextNum+2 ; push context number
push Word Ptr [bx].ContextNum
cCall HelpSzContext ;Get text
or ax,ax ; did we succeed?
je GetHelpTitleStr_Fail ; no, exit with error
;Strip off the filename at the begining of the context
cCall szSrchExcl,<di> ; search for '!' in *di
DbAssertRel ax,ne,0,UI,<GetHelpTitleStr: Illegal string from HelpSzContext>
inc ax ; point to chr beyond '!'
xchg si,ax ;di = *buffer, si = *szContext
AppendTitle: ; append title to bufStdMsg
; DS:SI= *title
; DS:DI= where to put it
pop bx ; BX = length of static portion
push ds ; ES = DS for string ops
pop es
AnotherChar:
lodsb ; append szTitle to "HELP:" in
stosb ; bufStdMsg
inc bx ; seen another char
or al,al ; more chars to do?
jnz AnotherChar ; brif so
dec bx ; don't include NULL in count
cmp bx,cbMaxSize ; is it larger than we want to return
jbe GetHelpTitleStr_Exit ; no, exit
mov bx,cbMaxSize-1 ; return maximum size (without NULL)
mov byte ptr [bufstdMsg+bx+1],al ; truncate the string
GetHelpTitleStr_Exit:
xchg ax,bx ; return count in AX
SKIP1_PSW ; skip the pop ax
GetHelpTitleStr_Fail:
pop ax ; get length in case of error
dec fNoDelBufs ; reenable buffer deletes.
DbAssertRel ax,be,cbMaxSize,UI,<GetHelpTitleStr: title too big>
cEnd
;Added with revision [29].
;***
;GetHelpContextLen - Returns the length to use for a given help topic
;
;Purpose:
; Returns the suggested # lines to use to display a topic.
; Uses ":lLENGTH" if it exists. Otherwise, returns the total # lines
; in the topic.
;
;Entry:
; pHelpBdl = *bdl containing decompressed help topic.
;
;Exit:
; AX = number of lines to use
;
;Uses:
; Per Convention
;
;****
cProc GetHelpContextLen,<NEAR,PUBLIC>,<SI,DI>
parmW pHelpBdl
cBegin
inc fNoDelBufs ; do not delete buffers, we have
; a generic ptr to a buffer
; Setting fNoDelBufs is probably not needed as currently
; pHelpBdl points to either oCurTopic or to a static
; Bdl used by dialog help. However, I doubt that we do any
; allocs in this code, and I can not guarentee that pHelpBdl
; is safe.
mov di,OFFSET DGROUP:bufStdMsg ; ds:di = useful buffer
mov cx,6 ; max len we care about
mov al,'l' ; look for ":l<LENGTH>"
cCall GetHelpControlInfo,<pHelpBdl,cx,ax> ; SI = *embedded len,
or si,si ; length found?
jz GetTotalLines ; brif not -- get the line count
push si ; arg on stack
call _atoi ; AX = result
pop bx ; clean stack (C calling conventions)
jmp SHORT GetHelpContextLen_Exit
GetTotalLines:
cCall SizeHelpContext,<pHelpBdl> ;AX = # lines in context
; sets iFileSize
GetHelpContextLen_Exit:
dec fNoDelBufs ; reenable buffer deletes.
cEnd
;Extracted and modified with revision [29].
;***
;GetHelpControlInfo
;
;Purpose:
; Returns the control information in a given help context, if any.
;
;Entry:
; pHelpBdl = * bdl containing decompressed help topic
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -