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

📄 uinhelp.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	TITLE	uinhelp.asm - utilities for new help engine.
;***
;uinhelp.asm
;
;	Copyright <C> 1985-1988, Microsoft Corporation
;
;Purpose:
;	Utilities for the new help system.
;
;
;*******************************************************************************

	.xlist
	include	version.inc
	.list
	UINHELP_ASM = ON


	include cw/version.inc
	include cw/windows.inc
	include cw/edityp.inc

	IncludeOnce architec
	IncludeOnce heap
	Include     help.inc
	IncludeOnce parser
	IncludeOnce prstab
	IncludeOnce rtps
	IncludeOnce qbimsgs
	IncludeOnce ui
	IncludeOnce uiint
	IncludeOnce uimenu		
	IncludeOnce uinhelp		

assumes DS,DATA
assumes ES,DATA
assumes SS,DATA

	subttl	DATA segment definitions.
	page

sBegin	DATA
	externW	iMsgStatusLine		; current status line message
	externW iHelpId 		

; GetHelpMessage and MapLineToContext return codes

	globalB fHelpAlloc,0		; Non-zero if help system is doing
					; a far heap allocation
	BdlTemp	BDL	<>		; temporary BDL owner
	externB	bdlHelp			; BDL for keyword help (def in UIHELP.C)
	externW	szDialogHelpContext	; *sz context of current dialog help


	externB b$Buf1			; FILNAML-sized buffer
	externB b$Buf2			; 16-byte buffer
	HtSpot	EQU	b$Buf2		; Static HotSpot structure

	globalB HelpFlags,0,1		;status of the help system
	globalB HelpFlags2,0,1		;more help system state


;BUFFERING:
;
;   The Help system uses a circular buffer of buffers to hold the
;   text of help messages (called contexts) so that scrolling up
;   and down in a file does not have to be continuously hitting the
;   disk.  The buffers are organized as follows:
;
;	HelpBuffer  : Slot 1 : Slot 2 : Slot 3 : ... : Slot MAX_HELPBUFS :
;
;   Each active slot in the Static HelpBuffer is of type HelpBufType.  The
;   entries in HelpBuffer are organized as a circular list so that they
;   may grow on either end without moving the existing entries.  Each
;   active entry in HelpBuffer represents one context that is currently
;   stored in memory.
;

	staticW oFirstBuf,,1		;Offset of first logical buffer
	staticW oLastBuf,,1		;Offset of last logical buffer
	staticB numBuf,0,1		;number of active buffers in HelpBuffer
	staticB fNoDelBufs,0,1		; are we allowed to delete the
					; buffers during a ShrinkHelp?


	MAX_HELPBUFS	= 9		; Number of entries in HelpBuffer
	BUFSIZE 	= SIZE HelpBufType;The size of the entries in HelpBuffer

	BUFFERSIZE	= MAX_HELPBUFS * BUFSIZE ; Size of HelpBuffer
	staticB	HelpBuffer,0,BUFFERSIZE
	BUFFEREND	EQU (OFFSET DGROUP:HelpBuffer) + (BUFFERSIZE)

	DbPub	HelpBuffer

	globalW iCurRequestLine,UNDEFINED,1 ; line # to get attributes for,
					; or UNDEFINED if no attributes
					; available
	globalW oCurTopic,0,1		; offset to the current topic
					; (0 if no current topic)

	globalW iFileSize,0,1		; Size of current help topic
	externW iStaticHelpTopic	; High word of NC during searches

	externW WndHelp 		; Help Window structure
	externW efHelp			; Editmgr structure for Help Wnd.

;QUEUE MANAGEMENT
;
;  In order to support help history (Ctrl-F1), we keep a LIFO queue
;  of the last 20 items that we requested help on.  The items are stored
;  as a circular list, with a pointer to the next item to be filled in
;  and a count of the number of items that exist.
;
;
;  This list (of type HelpHistEntry) is contained in a BDL, with the first
;  few bytes of the BDL containg a header (type HelpHistHeader) of useful
;  information
;

	BdlHelpHist BDL <>		; BDL for help backup (^F1) list

	ncInitial DD 0			

	HelpHistEntry STRUC
	    HH_HiWord	DW ?
	    HH_LoWord	DW ?
	HelpHistEntry ENDS

	HelpHistHeader STRUC		
	    HH_Used	DW ?		; number of history items in use
	    HH_First	DW ?		; offset into seg of next free item
	HelpHistHeader ENDS		

	NUM_HISTORY	= 20		; number of items that can be saved
	HELPHIST_BEGIN = Size HelpHistHeader  ; offset of first item in segment
	HELPHIST_END   = HELPHIST_BEGIN + NUM_HISTORY * SIZE HelpHistEntry
					; end of the last item

;MAGIC EDIT MANAGER Variables
;
;   The following magic locations in the edit manager are used:
;
;	EfHelp.EF_ipCur_ob     = Current column in help window
;	EfHelp.EF_ipCur_oln    = Current line in help window
;	EfHelp.EF_pdCur_olnTop = Top line of help window
;	EfHelp.EF_pdCur_obleft = Leftmost column of help window
;
;	WndHelp.arcClipping.ayBottomArc, WndHelp.arcClipping.ayTopArc
;		specify the top and bottom of the window.  I believe
;		that they are in screen coordinates.
;
;	One thing to note:  The Edit Manager uses 0 relative coordinates
;	while the helpengine (and variable help) use 1 relative coordinates.
;	Thus, you have to be careful in converting from one to another.
;
;	There are only 2 places that a line or column number is stored:
;	  - Bookmarks (0 relative, as the HelpEngine is not involved)
;	  - iCurRequestLine (1 relative, because it is a HelpEngine line#)
;


;HELP System ENTRY/EXIT conditions
;
;  Anytime that code for the help system is executing, we must have the
;  following conditions met:
;
;	1.)  As close as possible to the point where we could display a
;	     dialog box or message box receiveing ANY input from the user
;	     we must have HLP_INHELP set to prevent recursively entering the
;	     help system.  Currently, this occurs in 2 places:
;		- Displaying "Help File Not Found"
;		- Displaying "INsufficient memory for help system"
;
;	2.)  The help system must be active to the level that is needed to
;	     implement the desired functionality.  There are three levels:
;
;	     a.) Help Engine shut down - No functionality at all possible.
;
;	     b.) Help Engine Active, no current topic.
;		  HLP_GOTBUF is true, but oCurTopic = 0.
;
;	     c.) Help Engine Active, Current topic available.
;
;
;	     The following assumptions and conditions are used in checking
;	     entry conditions:
;
;	     - If the help window is open, we must be at level C.
;	     - If the help window is closed, we may be at A or B.
;	     - If we get a message from the help window, it must be open (C).
;	     - If StartHelp returns 0, you are in either B or C.
;
;	3.)  Any allocation could end up causing CompressHelp to be called.
;	     Thus, there has to be flag set ANYTIME we are in the help system
;	     so that CompressHelp will not yank the help system out from
;	     underneeth itself.  Currenly, there are only 2 entry points
;	     for help:
;		- Help()
;		- HelpWndProc()


sEnd	DATA

	externFP B$IFOUT		; Convert number to string
	externFP HelpOpen		; Misc Help engine routines
	externFP HelpNc
	externFP HelpNcCb
	externFP HelpLook
	externFP HelpDecomp
	externFP HelpXRef
	externFP HelpGetLine
	externFP HelpHlNext
	externFP HelpNcNext
	externFP HelpSzContext
	externFP HelpClose		
	externFP HelpShrink		
	externFP _atoi			; CONSIDE: use runtime call for this
	externFP fEditorActive		
	externFP fQhelpActive



sBegin	UI
assumes CS,UI

	staticB szHelpFileEdit,<"EDIT.HLP",0>	; main help file name
	staticB szHelpFileQhelp,<"HELP.HLP",0>	; qhelp help file name
	staticB szHelpFileInterp,<"QBASIC.HLP",0> ; second help file name

	externNP MoveCursorPwndCur	; Move cursor of current window
	externNP MoveCursorPwnd 	; Move cursor of specified window
	externNP WndHelpOpen		; Open help window to a given size
	externNP WndHelpClose		; Close the help window
	externNP SetHelpKeyword		; put keyword into help syntax menu

	externNP HelpBack		

	subttl	Main Help EntryPoints
	page


;***
;KeywordHelp : Display help for a keyword
;
;Purpose:
;	This routine implements SHIFT-F1.  If the cursor is on a keyword
;	in a window, then display help for this keyword in the help window
;	(opening it if needed). If there is no text selected, or it is
;	not a keyword, then return a non-zero value to indicate that F1
;	should be done.
;
;Entry:
;	None.
;
;Exit:
;	None
;
;Uses:
;	AX,BX,CX,DX
;
;****

cProc	KeywordHelp,<NEAR,PUBLIC>,<SI>	
cBegin
	cCall	StartHelp		; make sure we have the help system
	or	ax,ax			; did we succeed?
	jne	KeywordHelpExit 	; no, just return

	cCall	KeywordHelpLookup	; AX = length of current keyword
					; (text placed in bufStdMsg)
	or	ax,ax			; is there a current keyword?
	jne	CurKeyword		; brif so
Moo:
	cCall	CowMoo			; -- beep speaker & return
	jmp	short KeywordHelpExit	
CurKeyword:

	DbChk	HoldBuf1		; grab B$Buf1

	mov	ax,offset dgroup:bufStdMsg ; where the topic was placed
	mov	bx,offset dgroup:B$Buf1 ; new home for the topic string
	push	bx			; param to DisplayHlpWndSz

	cCall	fstrcpy2,<DS,bx,DS,ax>	


	cCall	DisplayHlpWndSz 	; try to display the help

	DbChk	FreeBuf1		; release the buffer

	or	al,al			; Did we succeed with engine hlp
	je	KeywordHelpExit_Ok	; yes, exit.

	test	al,HELP_HANDLED 	; have we displayed anything to
					; the user?
	jnz	KeywordHelpExit 	; yes, just exit
	jmp	short Moo		; otherwise tell user about it

KeywordHelpExit_Ok:
	mov	[uierr],0		; clear any leftover errors
KeywordHelpExit:
cEnd

;***
;KeywordHelpLookup : Find help for a keyword
;
;Purpose:
;	Added with revision [5].
;
;	Looks up the keyword, enables/disables the HelpSyntax menu item, and
;	puts the keyword into the HelpSyntax menu item.
;
;Entry:
;	None.
;
;Exit:
;	AX : =0 if no keyword was found
;	    length of keyword (NZ) if keyword was found
;Uses:
;	AX,BX,CX,DX
;
;****

cProc	KeywordHelpLookup,<NEAR,PUBLIC>
cBegin

	mov	ax,offset dgroup:bufStdMsg
	mov	bx,10			; maximum length of word  (10 is magic)
	mov	cx,GEW_HELPMASK 	; do not include . or ! in search
	cCall	GetEditWordMask,<ax,bx,cx> ; AX = length of word retrieved
	push	ax			; save for return value

	; enable/disable help syntax menu item based on AX (0 ==> disable)
	or	ax,ax			; if NZ, set low bit for stupid-ass
	jz	disableit		; COW C function
	mov	al,1
disableit:
	mov	bx,midHelpSyntax
	cCall	EnableMenuItem,<bx,ax>

	; copy current topic name into help syntax menu buffer
	mov	ax,offset dgroup:bufStdMsg
	cCall	SetHelpKeyword,<ax>

	pop	ax			; return AX = length of keyword
cEnd



;***
;SelectHotLink - Go to the hot link that is specified in the window coords
;
;Purpose:
;	Look in the help file given by the line number and column
;	number.  If there is a hot link at this position, go to the item
;	that it links to.  Otherwise, just returns.
;
;Entry:
;	(rx,ry) - virtual line coordinates of the location of a
;		  supposive hot spot.
;	beep	- TRUE if we are suspose to beep when we don't find anything
;
;Exit:
;	AX = 0 (FALSE) if a hot link was selected
;
;Uses:
;	Per Convention
;****

cProc	SelectHotLink,<PUBLIC,NEAR>,<SI,DI>
parmW	rx
parmW	ry
parmB	GiveBeep
cBegin

	;Since we got a keyboard message from the help window, it must be
	;open, therefor we must be initialized.

	DbAssertTst HelpFlags,ne,HLP_GOTBUF,UI,<SelectHotLink:Buffers Not Initialized>


	DbChk	HoldBuf2		; lock down the HotSpot
	DbChk	HoldBuf1		; for composed hotlink names

	mov	bx,oCurTopic		; get ptr to topic
	lea	bx,[bx].bdlHelpText.BDL_seg ; BX = handle to data seg
	mov	cx,rx
	inc	cx			; make column 1 relative
	mov	HtSpot.colHS,cx 	
	mov	cx,ry			; get line number
	inc	cx			; make it 1 relative
	mov	HtSpot.lineHS,cx	; and stick in HotSpot structure
	mov	ax,OFFSET DGROUP:HtSpot
	xor	cx,cx
	and	HelpFlags,NOT (HLP_FAILFNF OR HLP_FAILOOM) ; clear errors
	cCall	HelpXRef,<BX,CX,DS,AX>	;Get context string for topic
	or	ax,ax			; did we get a topic
	jnz	GotSelection		; yes, go display it
	test	HelpFlags,HLP_FAILFNF OR HLP_FAILOOM ; is error handled?
	jnz	NoBeep			; yes, do not beep
SelectHotLink_Beep:
	cmp	GiveBeep,0		; should we give a beep?
	je	NoBeep			; no, just exit with error code
	cCall	CowMoo			; beep cow's speaker
NoBeep:
	mov	ax,sp			; return with non-zero value
	DbChk	FreeBuf2		; release the HotSpot
	DbChk	FreeBuf1		;  and our other buffer
	jmp	short NoSelection	; and exit

GotSelection:
	;Copy context string into free part of Buf2 and display it in a help
	;window. The source string is in HtSpot.pXrefHS and is 0 terminated
	;We can not use the source directly, as it points into a BDL, and
	;we are not guarenteing a locked heap.

	push	ds				; set ES = DS = DGROUP
	pop	es				
	mov	di,offset dgroup:b$buf1 	; ES:DI = destination
	push	di				; parm for DislplayHlpWnd
	lds	si,DWord Ptr HtSpot.pXrefHS	; DS:SI = source

CopyLoop:
	lodsb					; copy the byte
	stosb					
	or	al,al				; is it the 0 termiantor
	jne	CopyLoop			; no, do next byte
	lodsw					; Copy next word
	stosw					; incase it was local

	push	es				; restore DGROUP
	pop	ds				

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -