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

📄 uimain.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;  to discard module(s).
;  If any module has been modified since last saved, a dialog box asks
;     the user if the module(s) are to be saved.
;     If user selects Yes,
;        CmdFileSaveAll is invoked
;        If any errors occur during CmdFileSaveAll, an error code is returned.
;        else the function returns 0.
;     If user selects Cancel,
;        it returns MSG_GoDirect, which is not trappable,
;        and eventually gets us back into user interface, which does not
;        report this special MSG_GoDirect runtime error.
;     If user selects No,
;        the function returns -2.
;  Else if no modules need to be saved,
;     it just returns -1.
;
;  NotSavedInc just does this for INCLUDE mrs's with the prompt:
;   "Modified $INCLUDE files must be saved before running. Save them now?"
;
;  NotSavedIncSav just does this for INCLUDE mrs's with the prompt:
;   "Save modified $INCLUDE files first?"
;
; Entry:
;  none
;
; Exit:
;  returns 0 if all modified files were saved without error,
;  returns -1 if no files were modified (and thus not saved)
;  returns -2 if user responded NO to the prompt
;  returns MSG_GoDirect if user responded CANCEL to the prompt
;  returns error code in ax if an I/O error occurred while trying to save.
;
;*********************************************************************
PUBLIC	NotSaved, NotSavedInc, NotSavedIncSav
NotSavedIncSav PROC FAR
	mov	al,2
	SKIP2_PSW			;skip following mov al,1 instruction
NotSavedIncSav ENDP
NotSavedInc PROC FAR
	mov	al,1
	SKIP2_PSW			;skip following mov al,0 instruction
NotSavedInc ENDP
NotSaved PROC FAR
	mov	al,0

;Common entry for NotSaved, NotSavedInc
	push	si			;save caller's si,di
	push	di
	cbw				;ax = fInclude
	xchg	di,ax			;di = fInclude

	mov	[uierr],0		;need to init uierr, because it
					; could be non-zero if user selected
					; File/Exit with dirty line in editor.
	call	EnStaticStructs		;activate static prsCur, mrsCur, txdCur
					;cx = 0 if no action taken
	push	ax			;remember if we need to call DisStatic..
	push	WORD PTR([grs.GRS_fDirect])
	push	[grs.GRS_oRsCur]	;save caller's oRs (for UiRsActivate)

	mov	si,UNDEFINED
	.erre	IDCANCEL - UNDEFINED	; (it will be tested below)
	.erre	IDNO - UNDEFINED	; (it will be tested below)
	.erre	IDYES - UNDEFINED	; (it will be tested below)

	;pass UNDEFINED to UiRsActivate so no mrs is active
	cCall	UiRsActivate,<si>	
NsLoop:
	call	NextMrsFile_All		; activate next mrs that has a FILE
					; NextMrsFile doesn't pick up an
					; empty <Untitled> module.
	inc	ax			;test for UNDEFINED
	je	NsDone			;brif done with all mrs's
	test	[mrsCur.MRS_flags2],FM2_Modified
	je	NsLoop			;brif module is unchanged
	or	di,di
	je	SaveIt			;brif saving ALL files, not just INCLUDE
	test	[mrsCur.MRS_flags2],FM2_Include
	je	NsLoop			;brif this isn't an INCLUDE file

SaveIt: ;Got at least 1 module which needs to be saved - ask user
	PUSHI	ax,MB_YESNOCANCEL
	mov	ax,MSG_NotSavedAll
	.errnz MSG_NotSavedInc - MSG_NotSavedAll - 1
	.errnz MSG_NotSavedIncSav - MSG_NotSavedAll - 2
	add	ax,di			;bump to MSG_NotSavedInc if fInclude
	push	ax
	call	MsgBoxStd		;al = reply
	cmp	al,IDYES
	xchg	si,ax			;save user's response in si
	jne	NsNoSave		;brif NO or CANCEL reply

	xor	ax,ax			; no title for subsequent dialog
	xchg	ax,szDialogTitle	; boxes (save all)
	push	ax			; save current dialog box title title
	cCall	CmdFileSaveAll,<di>	;save all modified modules
	pop	szDialogTitle		; restore current dialog box title

	or	ax,ax
	jne	NsNoSave		;brif user didn't select CANCEL in
					; Save dialog, and no I/O errors
	mov	si,IDCANCEL
NsNoSave:
;At this point, si = UNDEFINED if no files needed to be saved,
;		     IDNO if user chose to not save unsaved files,
;		     IDCANCEL if user wants to back out of current operation,
;		     IDYES if all files were saved,
;	                (uierr = non-zero if any errors occurred while saving)
;	
NsDone:
	call	UiRsActivate		;activate stacked register set.
	pop	ax			;ax = saved value of grs.fDirect
	mov	[grs.GRS_fDirect],al	;restore it
	pop	cx			;cx=0 if static structs were already
	jcxz	NsStatic		; enabled when NotSaved was called
	call	DisStaticStructs	;ensure static structs deactivated
NsStatic:
	;If CANCEL button was pressed, return untrappable runtime error
	;which will get us back into user interface if we were in the
	;middle of CHAIN/RUN <file>
	
	mov	ax,[uierr]
	or	ax,ax
	jne	NsExit			;brif I/O error during save

	mov	al,MSG_GoDirect
	cmp	si,IDCANCEL
	je	NsExit			;brif user responded CANCEL

	sub	ax,ax			;ax = 0
	cmp	si,IDYES
	je	NsExit			;return 0 if any/all files saved
	dec	ax			;ax = -1
	inc	si			;test for UNDEFINED
	je	NsExit			;return -1 if no files need to be saved
	dec	ax			;if user said NO, return -2
NsExit:
	pop	di			;restore caller's si,di
	pop	si
	or	ax,ax			;set condition codes for caller
	ret
NotSaved ENDP

;**************************************************************************
; UiGrabSpace
; Purpose:
;	Don't let user enter such a long program that he can't even execute
;	a SYSTEM, CLEAR, or SETMEM statement.
;	VERY IMPORTANT: Every call to UiGrabSpace MUST be balanced by
;	a subsequent call to UiReleaseSpace.  Make sure the code in
;	between can't take pathological branches (RtError) or non-pathological
;	branches around the UiReleaseSpace call.
;
;	The goal of user-interface tight-memory-management is to never
;	let the user get so low on memory that they get locked up
;	(i.e. so tight they can't even delete some text or unload a module
;	or execute a direct-mode clear/setmem statement).  If they
;	get locked up to the point where they can't save their file,
;	it is as bad as crashing.
;	  Part of the strategy involves reserving memory whenever the
;	user could potentially be making long-term memory commitments
;	(i.e. loading a new module or inserting a new line of text)
;	  Another part of it is having UiGrabSpace release any
;	"discretionary memory" it can when we run out of memory.
;
;**************************************************************************
cProc	UiGrabSpace,<PUBLIC,NEAR>
cBegin
	inc	[cGrab]
	call	GrabSpace
	or	ax,ax
	jne	GotSpace		;brif got space

	;We're very low on memory
	;Release any discretionary info we can to give us the space we need.
	call	AlphaORsFree		;release sorted alphabetised list
					; of modules/procedures - we build
					; it whenever we need it.
	extrn	FreeCmdHistory:near
	call	FreeCmdHistory		;release command window's history
	call	GrabSpace		;should never fail.
GotSpace:
cEnd

;**************************************************************************
; UiReleaseSpace
; Purpose:
;	We're not in an area where we could make long-term memory commitments
;	that would prevent us from doing a SYSTEM, CLEAR, or SETMEM statement.
;	Unlike ReleaseSpace(), this function doesn't release the space
;	unless all nested callers of UiGrabSpace have released their hold.
;
;**************************************************************************
cProc	UiReleaseSpace,<PUBLIC,NEAR>
cBegin
	DbAssertRelB [cGrab],ne,0,UI,<UiReleaseSpace: cGrab=0>
	dec	[cGrab]
	jne	NotDone			;brif not everyone that called
	call	ReleaseSpace		; UiGrabSpace has called UiReleaseSpace
NotDone:
cEnd

;**************************************************************************
; UiAlphaORsBuild
; Purpose:
;	Since AlphaORsBuild allocates a heap entry, we need to make sure
;	it doesn't encroach upon the minimum heap the user interface needs.
; Exit:
;	ax = 0 if out-of-memory
;
;**************************************************************************
cProc	UiAlphaORsBuild,<PUBLIC,NEAR>
cBegin
	call	AlphaBuildORs		
cEnd


;**************************************************************************

;**************************************************************************
;EnMenuCall
;Purpose:
;	Makes a far call to EnableMenuItem.
;Entry:
;	AL = Menu Item Name
;	DI = Enable / Disable item
;Exit:
;	None
;Usage:
;	Saves AX,BX,CX,DX.
;**************************************************************************
cProc	EnMenuCall,<NEAR>,<AX,BX,CX,DX>
cBegin
	xor	ah,ah			; AX = MenuItemName
	cCall	EnableMenuItem,<ax,di>
cEnd

;*************************************************************************
;ChMenuCall
;Purpose:
;	Makes a far call to CheckMenuItem
;Entry:
;	AL = Menu Item Name
;	DI = Enable / Disable item
;Exit:
;	None
;Usage:
;	Per Convention
;*************************************************************************
cProc	ChMenuCall,<NEAR>		
cBegin
	xor	ah,ah			; AX = MenuItemName
	cCall	CheckMenuItem,<ax,di>
cEnd


;**************************************************************************
; MenuEnable - rewritten in assembler from c code in uictl.c
; Purpose:
;	Enables Display in Main Window.
; Entry:
;	None
; Exit:
;	None
; Uses:
;	PerConvention
;
;**************************************************************************
cProc	MenuEnable,<PUBLIC,FAR>,<DI,SI>
cBegin
	cCall	UiRsActivateWnd     ; Tell context manager to activate
				    ; active window's register set

	; The Edit Field Structure is updated by every cursor movement
	; indicating system's current state, in terms of options available.
	; For example at the begining of qb sesbx on with blank screen, i.e.
	; no files loaded, you would not have any 'Edit' options available.
	; the moment you type anything 'Undo' becomes available. Further
	; until you select and 'cut', 'paste' would not be availble.

	mov	bx,pwndAct	    ; bx  = pointer to active window's reg set
	mov	bx,[bx.pefExtra]    ; bx  = * to edit field structure

	push	bx		     ; Save for later use
	mov	bl,[bx.EF_fSelection]
	xor	bh,bh		     ; BX = fSelection from edit field structure

	xor	cx,cx		    ; if pwndAct != wndCmd then ListWnd=False
	cmp	pwndAct,DATAOFFSET wndCmd;		       else ListWnd=True
	je	fIsListWndSet	    ; CX = ListWnd Status
	dec	cx
fIsListWndSet:

	xor	dx,dx			    ; So no changes like cut, paste
	cmp	pwndAct,DATAOFFSET wndHelp  ; are allowed. fChangeable flag
	je	fChangeableSet		    ; specifies if user is in Help.
	dec	dx			
fChangeableSet: 		    ; DX = fChangeable
	mov	si,dx			;SI = fChangeable


	mov	di,bx		    ; DI = fSelection
	mov	al,midEditCopy	    ; Set up Edit/Copy
	cCall	EnMenuCall	

	and	di,si		    ; DI = fSelection AND fChangeable
	mov	al,midEditCut	    ; Setup Edit/Cut
	call	EnMenuCall	
	mov	al,midEditClear     ; Set up Edit/Clear
	cCall	EnMenuCall	

	mov	al,fPasteOk	
	cbw			
	xchg	di,ax		    ; DI = Paste Command availability status
	and	di,si		    ; DI = fPasteOK AND fChangeable
	mov	al,midEditPaste     ; Set up Edit/Paste
	cCall	EnMenuCall	

	mov	di,cx		    ; DI = ListWindow Status
	mov	al,midSearchFind    ; Set up Search/Find
	cCall	EnMenuCall	
	mov	al,midSearchNext    ; Set up Search/Next
	cCall	EnMenuCall	

	and	di,si		    ; DI = ListWnd AND fChangeable
	mov	al,midSearchChange  ; Set up Search/Change
	cCall	EnMenuCall	
				    ; bx  was save way above.
	pop	bx		    ; Restore bx  = * Edit Field Structure

	mov	al,fSyntaxCheck
	cbw			    ; AX = Syntax Check options Selected?
	xchg	di,ax		    ; DI = Syntax Check options
	mov	al,midOptnsSyntax   ; in Options of menus
	cCall	ChMenuCall

	xor	cx,cx
	xor	ah,ah			
	mov	al,[mrsCur].MRS_flags2	;get mrs file flags
	and	al,FM2_Include+FM2_NoPcode ;is this a pcoded window?
	jnz	SetFalse	    ; brif not
	dec	cx		
SetFalse:
	mov	dx,si			; DX = fChangable
	and	dx,cx			; fIsCodeWnd = Pcode & Changeable
					; DX = fIsCodeWnd, CX = fPcode


	mov	di,dx		    ; DI = IsCodeWnd
	mov	al,midEditNewSub    ; Setup Edit/New Sub
	cCall	EnMenuCall	
	mov	al,midEditNewFunc   ; Setup Edit/New Function
	cCall	EnMenuCall	
	mov	al,midDebugToggleBp ; Set up Debug/Toggle BreakPoint
	cCall	EnMenuCall	
	mov	al,midGoUntilCursor
	cCall	EnMenuCall	

	mov	di,fIsProgram		; DI = TRUE if prog, FALSE if doc

	mov	al,midViewSubs		; Setup View/Subs
	cCall	EnMenuCall	    	
	mov	al,midRunStart		; Setup Run/Start
	cCall	EnMenuCall	    	
	mov	al,midRunRestart	; Setup Run/Retart
	cCall	EnMenuCall	    	
	mov	al,midRunContinue	; Setup Run/Continue
	cCall	EnMenuCall	    	
	mov	al,midStep		; Setup Debug/Step
	cCall	EnMenuCall	    	
	mov	al,midPStep		; Setup Debug/PStep
	cCall	EnMenuCall	    	
	mov	al,midDebugClearAllBp	; Setup Debug/Clear all Bp
	cCall	EnMenuCall	    	
	mov	al,midDebugTraceOn 	; Setup Debug/Trace On
	cCall	EnMenuCall	    	


	mov	di,dx			; di = fIsCodeWnd
	or	di,di			; is this a code window?
	je	NotCodeWnd		; brif not
	cCall	fCanContUI	    ; returns AX = Execution State
	xchg	ax,di		    ; False if Not in Code Window
NotCodeWnd:				
	mov	al,midDebugSetNextStmt; Set up Set Next Stmt command
	cCall	EnMenuCall	    ;	in debug options of menus

	mov	al,fTraceOn	
	cbw			
	xchg	di,ax		    ; di = Trace On Flag
	mov	al,midDebugTraceOn  ; Setup Debug/Trace On
	cCall	ChMenuCall	

cEnd


sEnd	UI

end

⌨️ 快捷键说明

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