📄 sorting.asm
字号:
invoke SelectObject, hDC, hBrushOld
.ELSE
;-----------------------------------------------------------------------------------
;-- Paint one element.
;-----------------------------------------------------------------------------------
;-- Select the pen with the right color and save the old pen.
.IF fSpecialColor
;-------------------------------------------------------------------------------
;-- This element shall be painted as a compared element.
mov eax, hPen_ComparedElement
.ELSE
;-------------------------------------------------------------------------------
;-- This element shall be painted with the normal color.
mov eax, hPen_Background
.ENDIF
invoke SelectObject, hDC, eax
mov hPenOld, eax
;-----------------------------------------------------------------------------------
;-- Calculate the x coordinate (in EBX) where the line/point has to be drawn.
mov ecx, element ;-- ECX = offset of the element
sub ecx, SortInfo.lpElements
shr ecx, 2 ;-- ECX now contains the index of the element
;-- that shall be drawn.
mov ebx, Display_Right ;-- EBX = ((width of the display window - 1)
inc ebx ;-- + 1)
shr ebx, 1 ;-- / 2
mov eax, SortInfo.numElements ;-- EAX = (number of elements
.IF fDisplayLines
;-------------------------------------------------------------------------------
;-- Display lines.
shr eax, 1 ;-- / 2
sub eax, ecx ;-- - index of the element)
lea eax, [eax*4] ;-- * 4
sub ebx, eax ;-- EBX = EBX - EAX
;-- -> EBX now contains the x coordinate
.ELSE
;-------------------------------------------------------------------------------
;-- Display points.
shl eax, 1
sub ebx, eax
lea ebx, [ebx + ecx*4]
.ENDIF
;-----------------------------------------------------------------------------------
;-- Repaint the old line/point with the background color.
push ebx
push ecx
push ebx
invoke MoveToEx, hDC, ebx, 0, 0
pop ebx
push ebx
invoke LineTo, hDC, ebx, Display_Bottom
pop ebx
.IF fSpecialColor
dec ebx
push ebx
invoke MoveToEx, hDC, ebx, 0, 0
pop ebx
invoke LineTo, hDC, ebx, Display_Bottom
.ENDIF
pop ecx
pop ebx
;-----------------------------------------------------------------------------------
;-- Get the value of the element.
mov esi, SortInfo.lpElements
mov eax, DWORD PTR [esi + ecx*4]
;-----------------------------------------------------------------------------------
;-- Select the proper color for this value.
push eax
push ebx
invoke SelectObject, hDC, DWORD PTR [OFFSET hPens_Array + eax*4]
pop ebx
pop eax
.IF fDisplayLines
;-------------------------------------------------------------------------------
;-- Display lines.
;-------------------------------------------------------------------------------
;-- Divide the value of the element by 2.
shr eax, 1
;-------------------------------------------------------------------------------
;-- Calculate the vertical middle of the display window.
mov edx, Display_Bottom ;-- EDX = (height of the display window
inc edx ;-- + 1)
shr edx, 1 ;-- / 2
;-------------------------------------------------------------------------------
;-- Calculate the start coordinates of the line and move to this coordinates.
push eax
push ebx
push edx
sub edx, eax ;-- EDX = half of the display window height
;-- - half of the value
;-- EDX now contains the upper y coordinate
;-- of the line.
invoke MoveToEx, hDC, ebx, edx, 0
pop edx
pop ebx
pop eax
;-------------------------------------------------------------------------------
;-- Calculate the end coordinates of the line.
lea edx, [edx + eax + 1] ;-- EDX = half of the display window height
;-- + half of the value + 1
;-- EDX now contains the lower y coordinate
;-- of the line.
.ELSE
;-----------------------------------------------------------------------------
;-- Display points.
;-----------------------------------------------------------------------------
;-- Calculate the y coordinate where the point has to be drawn.
mov edx, Display_Bottom
add edx, SortInfo.numElements
inc edx
shr edx, 1
sub edx, eax
;---------------------------------------------------------------------------
;-- Move to the calculated position and draw the line (it will look like
;-- a point).
push ebx
push edx
invoke MoveToEx, hDC, ebx, edx, 0
pop edx
pop ebx
inc edx
.ENDIF
;-----------------------------------------------------------------------------------
;-- Paint the line.
invoke LineTo, hDC, ebx, edx
.ENDIF
;---------------------------------------------------------------------------------------
;-- Restore the old pen.
invoke SelectObject, hDC, hPenOld
;---------------------------------------------------------------------------------------
;-- Release the display device context if no one was specified.
.IF fReleaseDC
invoke ReleaseDC, hGraphicDialog_S_Display, hDC
.ENDIF
@Return:
ret
PaintElements ENDP
;-----------------------------------------------------------------------------------------
; Purpose: Creates a thread that runs the sorting algorithm(s).
;
; Inputs: none
;
; Outputs: none
;
; Notes: none
;-----------------------------------------------------------------------------------------
StartSorting PROC
LOCAL threadId :DWORD
;---------------------------------------------------------------------------------------
;-- Create a new thread that runs the sorting algorithm(s).
invoke CreateThread, 0, 0, ADDR SortingThread, TRUE, 0, ADDR threadId
mov SortInfo.hThread, eax
@Return:
ret
StartSorting ENDP
;-----------------------------------------------------------------------------------------
; Purpose: Terminates the sorting process and induces the clean up.
;
; Inputs: none
;
; Outputs: none
;
; Notes: none
;-----------------------------------------------------------------------------------------
CancelSorting PROC
;---------------------------------------------------------------------------------------
;-- Terminate the sorting thread.
invoke TerminateThread, SortInfo.hThread, -1
;---------------------------------------------------------------------------------------
;-- If the sorting algorithm has allocated memory free it.
mov eax, SortInfo.hMemory
.IF eax
invoke SysFreeString, eax
.ENDIF
;---------------------------------------------------------------------------------------
;-- Kill the timer.
invoke KillTimer, hCurrentDialog, IDEvent_TIMER
;---------------------------------------------------------------------------------------
;-- Clean up (restore the texts and free allocated memory if the SortingThread procedure
;-- has allocated any).
invoke SortingThread, FALSE
ret
CancelSorting ENDP
;-----------------------------------------------------------------------------------------
; Purpose: Initializes the SortInfo-structure.
;
; Inputs: fStarting - flags whether a sorting algorithm starts or ends
;
; Outputs: some members of the SortInfo-structure
;
; Notes: none
;-----------------------------------------------------------------------------------------
InitSortInfoStruct PROC fStarting:DWORD
.IF fStarting
;-----------------------------------------------------------------------------------
;-- The sorting algorithm starts.
mov SortInfo.fSorting, TRUE
;-----------------------------------------------------------------------------------
;-- Set the counters to 0.
mov DWORD PTR [SortInfo.cmpCounter], 0
mov DWORD PTR [SortInfo.cmpCounter + 4], 0
mov DWORD PTR [SortInfo.movCounter], 0
mov DWORD PTR [SortInfo.movCounter + 4], 0
;-----------------------------------------------------------------------------------
;-- Set the time values to 0.
mov SortInfo.elapsedTime, 0
mov SortInfo.lastTickCount, 0
;-----------------------------------------------------------------------------------
;-- Set the useMemory member to 0.
mov SortInfo.usedMemory, NULL
;-----------------------------------------------------------------------------------
;-- Set the hMemory member to 0.
mov SortInfo.hMemory, NULL
;-----------------------------------------------------------------------------------
;-- Set the insufficientMemory member to 0.
mov SortInfo.errorId, ERROR_SUCCESS
.ELSE
;-----------------------------------------------------------------------------------
;-- The sorting process ends.
mov SortInfo.fSorting, FALSE
;-----------------------------------------------------------------------------------
;-- Close the thread handle.
invoke CloseHandle, SortInfo.hThread
mov SortInfo.hThread, NULL
;-----------------------------------------------------------------------------------
;-- Set the hMemory member to 0.
mov SortInfo.hMemory, NULL
;-----------------------------------------------------------------------------------
;-- Set the insufficientMemory member to 0.
mov SortInfo.errorId, ERROR_SUCCESS
.ENDIF
ret
InitSortInfoStruct ENDP
;-----------------------------------------------------------------------------------------
; Purpose: Runs a sorting algorithm.
;
; Inputs: lpAlgorithmProc - offset of the sorting algorithm procedure
;
; Outputs: some members of the SortInfo-structure
;
; Notes: none
;-----------------------------------------------------------------------------------------
StartAlgorithm PROC lpAlgorithmProc:DWORD
LOCAL time :DWORD
LOCAL localBuffer[256] :BYTE
;---------------------------------------------------------------------------------------
;-- Update the status bar values.
invoke SendMessage, hCurrentDialog, WM_APP, NULL, NULL
;---------------------------------------------------------------------------------------
;-- Set the timer.
invoke SetTimer, hCurrentDialog, IDEvent_TIMER, TimerInterval, NULL
;---------------------------------------------------------------------------------------
;-- Save the current tick count.
invoke GetTickCount
mov time, eax
mov SortInfo.lastTickCount, eax
;---------------------------------------------------------------------------------------
;-- Save the current tick count.
ASSUME fs:nothing
push OFFSET ExceptionHandler
push fs:[0]
mov SEH.OrgEsp, esp
mov SEH.OrgEbp, ebp
mov SEH.SaveEip, OFFSET @SafePlace
mov fs:[0], esp
;-------------------------------------------------------------------------------------
;-- Call the sorting algorithm procedure.
push SortInfo.numElements
push SortInfo.lpElements
call lpAlgorithmProc
@SafePlace:
pop fs:[0]
add esp, 4
;---------------------------------------------------------------------------------------
;-- Save the current tick count and compute the elapsed time.
invoke GetTickCount
sub eax, time
mov SortInfo.elapsedTime, eax
;---------------------------------------------------------------------------------------
;-- Kill the timer.
invoke KillTimer, hCurrentDialog, IDEvent_TIMER
;---------------------------------------------------------------------------------------
;-- Update the status bar values.
invoke SendMessage, hCurrentDialog, WM_APP, NULL, NULL
;---------------------------------------------------------------------------------------
;-- Display a message box if an error occured.
.IF SortInfo.errorId != ERROR_SUCCESS
mov ebx, hTableDialog_SB
.IF SortInfo.fGraphic
mov ebx, hGraphicDialog_SB
.ENDIF
invoke SendMessage, ebx, SB_GETTEXT, SB_PART_ALGORITHM, ADDR localBuffer
and eax, 0FFFFh
lea ebx, localBuffer
add eax, ebx
.IF SortInfo.errorId == ERROR_STACK_OVERFLOW
mov ebx, lpSTR_ERR_STACKOVERFLOW
.ELSEIF SortInfo.errorId == ERROR_NOT_ENOUGH_MEMORY
mov ebx, lpSTR_ERR_NOTENOUGHMEMORY
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -