📄 sorting.asm
字号:
;-----------------------------------------------------------------------------------------
; Prototypes.
;-----------------------------------------------------------------------------------------
PaintElements PROTO :DWORD, :DWORD, :DWORD
StartSorting PROTO
CancelSorting PROTO
SortingThread PROTO :DWORD
InitSortInfoStruct PROTO :DWORD
StartAlgorithm PROTO :DWORD
.code
AddErrorString MACRO
lea eax, localBuffer
.IF SortInfo.errorId != ERROR_SUCCESS
invoke szCopy, OFFSET LVI_Error, ADDR localBuffer
lea eax, localBuffer
add eax, SIZEOF LVI_Error - 1
.ENDIF
ENDM
;-----------------------------------------------------------------------------------------
; Display- and delay-macros.
;-----------------------------------------------------------------------------------------
RefreshElement MACRO element:REQ, hDC:=<NULL>
LOCAL Return
;---------------------------------------------------------------------------------------
;-- Paint the elements only if the graphic dialog is shown.
cmp SortInfo.fGraphic, 0
jz Return
pushad
invoke PaintElements, element, hDC, FALSE
popad
Return:
ENDM
IncCMPCounter MACRO
LOCAL Return
;---------------------------------------------------------------------------------------
;-- Increment the comparison counter.
add DWORD PTR [SortInfo.cmpCounter + 4], 1
;---------------------------------------------------------------------------------------
;-- Note: JNC + INC is measurable faster (at least on a Pentium IV)
jnc Return
inc DWORD PTR [SortInfo.cmpCounter]
Return:
ENDM
IncMOVCounter MACRO
LOCAL Return
;---------------------------------------------------------------------------------------
;-- Increment the exchange counter.
add DWORD PTR [SortInfo.movCounter + 4], 1
;---------------------------------------------------------------------------------------
;-- Note: JNC + INC is measurable faster (at least on a Pentium IV)
jnc Return
inc DWORD PTR [SortInfo.movCounter]
Return:
ENDM
WaitDelay MACRO
LOCAL Label1
;-------------------------------------------------------------------------------------
;-- Get the current tick count.
invoke GetTickCount
mov edx, SortInfo.delay
sub eax, edx
;-------------------------------------------------------------------------------------
;-- Is the selected delay elapsed?
cmp eax, SortInfo.lastTickCount
ja Label1
;-------------------------------------------------------------------------------------
;-- No, sleep the rest of the time.
push eax
push edx
sub eax, SortInfo.lastTickCount
neg eax
push eax
invoke Sleep, eax
pop ebx
pop edx
pop eax
add eax, ebx
add eax, edx
;---------------------------------------------------------------------------------------
;-- Save the current tick count.
Label1:
mov SortInfo.lastTickCount, eax
ENDM
DelayAfterPass MACRO
LOCAL Return
;---------------------------------------------------------------------------------------
;-- If no delay is selected return.
cmp SortInfo.delay, 0
jz Return
;---------------------------------------------------------------------------------------
;-- If the delay position is not 'after each pass' return.
cmp SortInfo.fDelayPosition, DELAY_AFTER_PASS
jne Return
pushad
;-------------------------------------------------------------------------------------
;-- Ensure that the selected delay is elapsed.
WaitDelay
popad
Return:
ENDM
DelayAfterComparison MACRO element1:REQ, element2
LOCAL Return
;---------------------------------------------------------------------------------------
;-- If no delay is selected return.
cmp SortInfo.delay, 0
jz Return
;---------------------------------------------------------------------------------------
;-- If the delay position is not 'after each comparison' return.
cmp SortInfo.fDelayPosition, DELAY_AFTER_COMPARISON
jne Return
pushad
mov Element1, element1
IFDEF element2
mov Element2, element2
ELSE
mov Element2, -1
ENDIF
;-------------------------------------------------------------------------------------
;-- Paint these elements with a special color.
invoke PaintElements, Element1, 0, TRUE
IFDEF element2
invoke PaintElements, Element2, 0, TRUE
ENDIF
;-------------------------------------------------------------------------------------
;-- Ensure that the selected delay is elapsed.
WaitDelay
;-------------------------------------------------------------------------------------
;-- Paint these elements with the normal color.
invoke PaintElements, Element1, 0, FALSE
mov Element1, -1
IFDEF element2
invoke PaintElements, Element2, 0, FALSE
mov Element2, -1
ENDIF
popad
Return:
ENDM
DelayAfterExchange MACRO
LOCAL Return
;---------------------------------------------------------------------------------------
;-- If no delay is selected return.
cmp SortInfo.delay, 0
jz Return
;---------------------------------------------------------------------------------------
;-- If the delay position is not 'after each exchange' return.
cmp SortInfo.fDelayPosition, DELAY_AFTER_EXCHANGE
jne Return
pushad
;-------------------------------------------------------------------------------------
;-- Ensure that the selected delay is elapsed.
WaitDelay
popad
Return:
ENDM
;-----------------------------------------------------------------------------------------
; Purpose: Displays the values of each element of an array (the pointer to this array
; is SortInfo.lpElements) by drawing lines with different lengths.
;
; Inputs: element - index of the element that shall be painted; if -1, then all
; elements are painted
; hDC - handle of a display device context (can be NULL)
; fSpecialColor - if TRUE the element will be painted with a special color
;
; Outputs: none
;
; Notes: For displaying the values the display window of the graphic dialog is used.
;-----------------------------------------------------------------------------------------
PaintElements PROC element:DWORD, hDC:DWORD, fSpecialColor:DWORD
LOCAL hBrushOld :DWORD
LOCAL hPenOld :DWORD
LOCAL fReleaseDC :BYTE
mov fReleaseDC, FALSE
.IF (hDC == NULL) || fSpecialColor
@@:
mov fReleaseDC, TRUE
;-----------------------------------------------------------------------------------
;-- Get a handle of a display device context for the display window and save it.
invoke GetDC, hGraphicDialog_S_Display
mov hDC, eax
;-----------------------------------------------------------------------------------
;-- If the handle is invalid return.
test eax, eax
jz @Return
.ENDIF
.IF element == -1
;-----------------------------------------------------------------------------------
;-- Paint all elements.
;-----------------------------------------------------------------------------------
;-- Paint the background.
invoke SelectObject, hDC, hBrush_Background
mov hBrushOld, eax
invoke SelectObject, hDC, hPen_BackgroundFrame
mov hPenOld, eax
invoke Rectangle, hDC, 0, 0, Display_Right, Display_Bottom
;-----------------------------------------------------------------------------------
;-- Now display the values.
mov ebx, Display_Right
inc ebx
shr ebx, 1
mov edx, Display_Bottom
inc edx
shr edx, 1
mov eax, SortInfo.numElements
.IF fDisplayLines
;-------------------------------------------------------------------------------
;-- Display lines.
lea eax, [eax*2]
sub ebx, eax
.ELSE
;-------------------------------------------------------------------------------
;-- Display points.
shl eax, 1
sub ebx, eax
shr eax, 2
add edx, eax
.ENDIF
xor ecx, ecx
@Loop1:
;---------------------------------------------------------------------------------
;-- Get the value of the current element.
mov esi, SortInfo.lpElements
mov eax, DWORD PTR [esi + ecx*4]
;---------------------------------------------------------------------------------
;-- Select the proper color for this value.
push eax
push ebx
push ecx
push edx
invoke SelectObject, hDC, DWORD PTR [OFFSET hPens_Array + eax*4]
pop edx
pop ecx
pop ebx
pop eax
.IF fDisplayLines
;-----------------------------------------------------------------------------
;-- Display lines.
;-----------------------------------------------------------------------------
;-- Divide the value by 2.
shr eax, 1
push eax
push ebx
push ecx
push edx
;---------------------------------------------------------------------------
;-- Calculate the start coordinates of the line.
lea ecx, [ecx*4 + ebx]
sub edx, eax
;---------------------------------------------------------------------------
;-- Move to the calculated position.
invoke MoveToEx, hDC, ecx, edx, 0
pop edx
pop ecx
pop ebx
pop eax
push ebx
push ecx
push edx
;---------------------------------------------------------------------------
;-- Calculate the end coordinates of the line.
lea ecx, [ecx*4 + ebx]
lea edx, [edx + eax + 1]
;---------------------------------------------------------------------------
;-- Draw the line.
invoke LineTo, hDC, ecx, edx
pop edx
pop ecx
pop ebx
.ELSE
;-----------------------------------------------------------------------------
;-- Display points.
push eax
push ebx
push ecx
push edx
;---------------------------------------------------------------------------
;-- Calculate the start coordinates of the line.
lea ebx, [ebx + ecx*4]
sub edx, eax
;---------------------------------------------------------------------------
;-- Move to the calculated position and draw the line.
push ebx
push edx
invoke MoveToEx, hDC, ebx, edx, 0
pop edx
pop ebx
inc edx
invoke LineTo, hDC, ebx, edx
pop edx
pop ecx
pop ebx
pop eax
.ENDIF
;---------------------------------------------------------------------------------
;-- Have all elements been drawn?
inc ecx
cmp ecx, SortInfo.numElements
jb @Loop1
;-----------------------------------------------------------------------------------
;-- Yes. Restore the old brush.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -