⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uinhelp.asm

📁 Microsoft MS-DOS6.0 完整源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	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 + -