EuroAssembler Index Manual Download Source Macros


Sitemap Links Forum Tests Projects

dirswing.htm
Data
Data
Procedures
FindToBuffer
MainGui
PaintMarks
RenameButtons
WndCreate
WndPaint
WndProc
WndResize

This is a GUI module of EuroTool program EuroDirs for Windows.


     EUROASM CPU=X64, SIMD=Yes, Unicode=No, MaxInclusions=100, DumpWidth=36
dirswing PROGRAM Format=COFF,Width=64, MaxExpansions=90K
           %DROPMACRO *
           EXTERN BufferStore@RT, FileAssignW64@RT, FileNameParseW64@RT
           INCLUDEHEAD1 argument.htm
           INCLUDE1 winansi.htm,fastcall.htm,winabi.htm,winsgui.htm,winsdlg.htm,winf64.htm
           INCLUDE1 cpuext.htm,status32.htm,memory64.htm,string64.htm
           LINK ../objlib/winapi.lib
↑ Data
FIND_INDEX       STRUC     ; Structure saved in FindBuffer.
.LineNr            D DWORD ; Ordinal number of a line from the selected buffer. 1,2,3...MaxLineNr
.Offset            D DWORD ; 0,2,4,,,Offset of the found text from the start of line in bytes.
                 ENDSTRUC FIND_INDEX
CP_UTF8          = 65001
ScanDirBrowseId  = 0x8001
ScanDirEditId    = 0x8002
OlderSelectBtnId = 0x8005
OlderEditId      = 0x8006
NewerSelectBtnId = 0x8007
NewerEditId      = 0x8008
Btn1Id           = 0x8011
Btn2Id           = 0x8012
Btn3Id           = 0x8013
Btn4Id           = 0x8014
Btn5Id           = 0x8015
FindEditId       = 0x8021
FindBtnId        = 0x8022
ColorFind        = 0x0080EEEE
ColorCursor      = 0x00F0C0F0
ColorWhite       = 0x00FFFFFF
WheelPerLine     = 40      ; wParamHigh = 120 or -120 to scroll 3 rows up or down.
[.rodata]
;;NameEURODIRS         DU "EURODIRS",0
;;MainWindowName       DU "EuroDirs",0
ScanFilter           DU "Scan files",0,"*.scan",0,"All files",0,"*",0,0
[.bss]
FindIndex            DS FIND_INDEX
Msg                  DS MSG                  ; Window message.
WndClassEx           DS WNDCLASSEX ; Definition of the window class structure.
ScanDirFileDlg       DS OPENFILENAME
InpFileDlg           DS OPENFILENAME
OutFileDlg           DS OPENFILENAME
PaintStruct          DS PAINTSTRUCT
TextMetric           DS TEXTMETRICW
ScrollInfo           DS SCROLLINFO
MainWindowRect       DS RECT
DirWindowRect        DS RECT
ScanDirBrowseHandle  D QWORD
ScanDirEditHandle    D QWORD
OlderTitleHandle     D QWORD
OlderSelectBtnHandle D QWORD
OlderEditHandle      D QWORD
NewerTitleHandle     D QWORD
NewerSelectBtnHandle D QWORD
NewerEditHandle      D QWORD
FindBuffer           D QWORD
FindChars            D DWORD ; Number of unichars in FindText.
PenHandle            D QWORD
Handles:
Btn1Handle           D QWORD
Btn2Handle           D QWORD
Btn3Handle           D QWORD
Btn4Handle           D QWORD
Btn5Handle           D QWORD
FindTextHandle       D QWORD
FontHandle           D QWORD
MainWindowHandle     D QWORD ; Handle of the main window.
DirWindowHandle      D QWORD ; Handle of the window with volumes and dir names.
hDirDC               D QWORD ; Handle of device context used in painting DirWindow.
hMainDC              D QWORD ; Handle of device context used in painting MainWindow.
hBrushFind           D QWORD ; Handle of brush in Find window.
ClientY              D QWORD ; Y-coordinate of the client line (0,10,20,,ClientLines*10).
ClientLines          D DWORD ; Number of lines which will fit into client area.
ClientLinesMinus2    D DWORD
WindowWidth          D DWORD
WindowHeight         D DWORD
PreviousPos          D DWORD
SelectedLineNr       D DWORD   ; Number of line from [BufferSelected] (0..MaxLineNr::).
CursorLineNr         D DWORD   ; Line with a cursor (0..MaxLineNr::).
WheelCnt             D DWORD   ; Accumulated WheelPerLine value when mouse wheel is rolled.
ScanDir              D 260 * UNICHAR
FindText             D 260 * UNICHAR
[.text]
MainGui
This is the graphic entry procedure.
MainGui:: PROC
     CALL WndCreate               ; Initialize the main program window.
     CALL WndResize
     WinABI ShowWindow,[MainWindowHandle],SW_SHOW
     WinABI UpdateWindow,[MainWindowHandle]
     WinABI PostMessage,[MainWindowHandle],WM_COMMAND,Btn2Id,0
.MsgLoop:
     WinABI GetMessage, Msg,0,0,0
     TEST RAX
     JZ .MsgQuit:                                 ; ZF signalizes message WM_QUIT - request for program termination.
     WinABI TranslateMessage, Msg                 ; Remap character keys from national keyboards.
     WinABI DispatchMessage,  Msg                 ; Let Windows call our WndProc.
     JMP .MsgLoop:                                ; Wait for another message.
.MsgQuit:
     JMP MainCon.Terminate::
   ENDP MainGui
WndProc, hWnd, uMsg, wParam, lParam

This is a callback procedure which receives and handles messages for the MainWindow. Message parameters are by FastCall convention provided in registers RCX, RDX, R8, R9, we'll save them to shadow space with macro SaveToShadow . Thanks to this their contents will be available by formal names ( [%hWnd], [%uMsg], [%wParam], [%lParam]), too, in the entire WndProc body.

Messages obtained from Windows are dispatched by WndProc to their handlers.
Unhandled messages are passed to DefWindowProc.

Handler input
RCX=[%hWnd] is the main window handle (the same as static [MainWindowHandle] obtained by WndCreate).
RDX=[%uMsg] is message identifier,
R8=[%wParam] is message w-parameter,
R9=[%lParam] is message l-parameter.
Handler output
RAX=0 if the message was completely processed by the handler. Otherwise the message is processed by WinAPI DefWindowProc and RAX outputs its return value.
Scratch registers RCX,RDX,R8..R11 may be destroyed in the handlers.
Callee-save registers RBX,RSI,RDI,R12..R15 must be restored, if used in the handlers. This provides macro Uses.
Invoked by
WinAPI DispatchMessage.
WndProc Procedure hWnd, uMsg, wParam, lParam ; These parameters are provided in RCX,RDX,R8,R9.
    SaveToShadow
    Uses RBX,RBP,RSI,RDI ; It's only necessary if some of callee-save registers was used in this fastcalled procedure.
    ; Fork message uMsg=RDX to its handler using macro Dispatch:
     Dispatch EDX, WM_CREATE, WM_PAINT, WM_SIZE, WM_VSCROLL, \
              WM_MOUSEWHEEL, WM_KEYDOWN, WM_SYSKEYDOWN, WM_COMMAND, WM_DESTROY,  \
              WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_RBUTTONUP ;;;;;;;;;;;;;;, WM_CTLCOLOREDIT
.Def:WinABI DefWindowProc,[%hWnd],[%uMsg],[%wParam],[%lParam]  ; Pass ignored event to DefWindowProc with unchanged arguments.
     JMP .Ret:  ; Go to EndProcedure with result value RAX as returned from DefWindowProc.
     ; All message handlers terminate with a jump to label .Def: or .Ret0:.
.WM_CREATE: ; MainWindow is created.
   WinABI GetClientRect,[MainWindowHandle],MainWindowRect
   MOV EDX,[MainWindowRect.right]
   MOV ECX,[MainWindowRect.bottom]
   MOV [WindowWidth],EDX
   MOV [WindowHeight],ECX
   WinABI GetDC,[MainWindowHandle]
   MOV [hDirDC],RAX
   WinABI GetTextMetrics,RAX,TextMetric
   WinABI ReleaseDC,[MainWindowHandle],[hDirDC]
   JMP .Ret0:
.WM_PAINT:  ; Window needs to repaint its contents. Use procedure WndPaint.
     CALL WndPaint
     JMP .Ret0:
.WM_SIZE:
     CALL WndResize
     JMP .Ret0:
.WM_LBUTTONDOWN:        ; Mouse button will move line-cursor in DirWindow.
.WM_RBUTTONDOWN:
     SHR R9,16
     MOVZX RAX,R9W      ; RAX is y-coordinate.
     XOR EDX,EDX
     MOV EDI,[TextMetric.tmHeight]
     DIV RDI
     ADD EAX,[SelectedLineNr]
     MOV [CursorLineNr],EAX
     WinABI InvalidateRect,[DirWindowHandle],0,-1 ; Repaint DirWindow.
     JMP .Ret:
.WM_RBUTTONUP:          ; When the right mouse button is released, it starts a new window
      MOV EBX,[CursorLineNr]  ; with the directory selected by line-cursor.
      CALL OneLine2Dir::
      MOV RDI,RSI
      MOV AX,' '
      REPNE SCASW
      JNE .Ret0:
      WinABI ShellExecuteW,[DirWindowHandle],0,RDI,0,0,SW_SHOWNORMAL
      JMP .Ret:
.WM_KEYDOWN:   ; Non-character hot key R8D=wParam was pressed.
     MOV EAX,[SelectedLineNr]    ; Prepare EAX and ECX for the cursor keys.
     MOV ECX,[MaxLineNr::]
     SUB ECX,[ClientLinesMinus2] ; Maximal position of the selected line.
     JGE .10:
     XOR ECX,ECX
.10: Dispatch R8D, VK_UP,VK_DOWN,VK_NEXT,VK_PRIOR,VK_HOME,VK_END,VK_ESCAPE, \ Dispatch the cursor keys.
              'B','S','E','F','1','2','3','4','5','a','b','c','d','e'
     JMP .Def: ; Pass unhandled keys to WinABI DefWindowProc.
.WM_SYSKEYDOWN:     ; A key pressed together with Alt.
   Dispatch R8W,'B','S','E','F','1','2','3','4','5','a','b','c','d','e'
   JMP .Def:
.Saturate: ; SelectedLineNr in EAX will be saturated to the range 0..ECX=MaxLineNr-ClientLinesMinus2.
     TEST EAX
     JNS .20:
     XOR EAX,EAX
.20: CMP EAX,ECX
     JB .30:
     MOV EAX,ECX
.30: MOV [SelectedLineNr],EAX
     MOV [ScrollInfo.nPos],EAX
     MOV [PreviousPos],EAX
     WinABI SetScrollInfo,[DirWindowHandle],SB_VERT,ScrollInfo,-1
     WinABI InvalidateRect,[DirWindowHandle],0,0
     JMP .Ret0:
.SB_LINEUP:
.VK_UP:
     DEC EAX
     JMP .Saturate:
.SB_LINEDOWN:
.VK_DOWN:
     INC EAX
     JMP .Saturate:
.SB_PAGEDOWN:
.VK_NEXT:
     ADD EAX,[ClientLinesMinus2]
     JMP .Saturate:
.SB_PAGEUP:
.VK_PRIOR:
     SUB EAX,[ClientLinesMinus2]
     JMP .Saturate:
.SB_TOP:
.VK_HOME:
     XOR EAX,EAX
     JMP .Saturate:
.SB_BOTTOM:
.VK_END:
     MOV EAX,ECX
     JMP .Saturate:
.WM_VSCROLL:     ; LOWORD R8 is nScrollCode (SB_TOP,SB_BOTTOM, SB_LINEUP etc).
     MOV [ScrollInfo.cbSize],SIZE# SCROLLINFO
     MOV [ScrollInfo.fMask],SIF_ALL
     WinABI GetScrollInfo,[DirWindowHandle],SB_VERT,ScrollInfo
     MOV EAX,[ScrollInfo.nPos]
     MOV [PreviousPos],EAX
     MOV ECX,[MaxLineNr::]
     MOV EAX,[SelectedLineNr]    ; Prepare EAX and ECX for the cursor keys.
     SUB ECX,[ClientLinesMinus2]
     JGE .40:
     XOR ECX,ECX
.40: MOVZX EDX,R8W
     Dispatch EDX,SB_TOP,SB_BOTTOM,SB_LINEUP,SB_LINEDOWN,SB_PAGEUP,SB_PAGEDOWN,SB_THUMBTRACK
     JMP .Def:
.SB_THUMBTRACK:
     MOV EAX,[ScrollInfo.nTrackPos]
     MOV [ScrollInfo.nPos],EAX
     MOV [SelectedLineNr],EAX
     MOV [ScrollInfo.fMask],SIF_POS
     WinABI SetScrollInfo,[DirWindowHandle],SB_VERT,ScrollInfo,-1
     WinABI GetScrollInfo,[DirWindowHandle],SB_VERT,ScrollInfo
     MOV EDX,[PreviousPos]
     SUB EDX,[ScrollInfo.nPos]
     JZ .Ret0:
     MOV EAX,[TextMetric.tmHeight]
     IMUL RDX
     WinABI ScrollWindow,[DirWindowHandle],0,RAX,0,0
     WinABI UpdateWindow,[DirWindowHandle]
     JMP .Ret0:
.WM_MOUSEWHEEL:
     SAR R8D,16              ; R8D is now +120 or -120 on mouse-wheel roll.
     ADD [WheelCnt],R8D      ; Accumulate scroll requests.
     MOV R9D,[WheelCnt]
 .RollUp:
     CMP R9D,WheelPerLine
     JL  .RollDown:
     SUB R9D,WheelPerLine
     MOV [WheelCnt],R9D
     WinABI SendMessage,[DirWindowHandle],WM_VSCROLL,SB_LINEUP,0
     JMP .RollUp:
 .RollDown:
     CMP R9D,0
     JGE .Ret0:
     ADD R9D,WheelPerLine
     MOV [WheelCnt],R9D
     WinABI SendMessage,[DirWindowHandle],WM_VSCROLL,SB_LINEDOWN,0
     JMP .RollDown:
.WM_COMMAND:: ; id=LOWORD R8
     MOVZX EDX,R8W
     Dispatch EDX, Btn1Id,Btn2Id,Btn3Id,Btn4Id,Btn5Id,                     \
             ScanDirBrowseId,ScanDirEditId,OlderSelectBtnId,OlderEditId,   \
             NewerSelectBtnId,NewerEditId,FindEditId,FindBtnId
     JMP .Def:               ; Let other commands handle by DefWindowProc().
.F:
.FindBtnId:
    LEA RCX,[FindText]
    WinABI GetWindowTextW,[FindTextHandle],RCX,260
    MOV [FindChars],EAX
    WinABI InvalidateRect,[DirWindowHandle],0,-1
    WinABI SetFocus,[MainWindowHandle]
    JMP .Ret0:
.FindEditId:   ; An character was added/subtracted to the edit field FindText.
    LEA RCX,[FindText]
    WinABI GetWindowTextW,[FindTextHandle],RCX,SIZE# FindText /2
    MOV [FindChars],EAX
    CALL FindToBuffer
    CALL PaintMarks
    ; Invalidate marks on the right side.
    LEA RBX,[MainWindowRect]
    WinABI GetClientRect,[MainWindowHandle],RBX
    MOV EAX,[RBX+RECT.right]
    SUB EAX,10
    MOV [RBX+RECT.left],EAX
    WinABI InvalidateRect,[MainWindowHandle],RBX,-1
    WinABI InvalidateRect,[DirWindowHandle],0,-1
    JMP .Ret0:
.1:
.a:
.Btn1Id:
     MOV AL,1
     JMP .50:
.2:
.b:
.Btn2Id:
     MOV AL,2
     JMP .50:
.3:
.c:
.Btn3Id:
     MOV AL,3
     JMP .50:
.4:
.d:
.Btn4Id:
     MOV AL,4
     JMP .50:
.5:
.e:
.Btn5Id:
     MOV AL,5
.50: MOVZX EAX,AL
     MOV [ArgViewDirs::],EAX
     LEA RBX,[8*RAX-8+Buffers::]
     MOV [BufferSelected::],RBX
     BufferRetrieve RBX
     SHR ECX,4
     MOV [MaxLineNr],ECX
     MOVD [CursorLineNr],-1
     MOV EAX,ECX
     SUB EAX,[ClientLinesMinus2]
     JS .60:
     JAE .70:
.60: XOR EAX,EAX
.70: MOV [SelectedLineNr],EAX ; When the ViewDirs has changed, position the DirWindow to the bottom.
     WinABI PostMessage,[Btn1Handle],BM_SETSTATE,0,0 ; Unpush all five buttons first.
     WinABI PostMessage,[Btn2Handle],BM_SETSTATE,0,0
     WinABI PostMessage,[Btn3Handle],BM_SETSTATE,0,0
     WinABI PostMessage,[Btn4Handle],BM_SETSTATE,0,0
     WinABI PostMessage,[Btn5Handle],BM_SETSTATE,0,0
     MOV EAX,[ArgViewDirs::]
     MOV RBX,[Handles+8*RAX-8]                    ; RBX is now the handle of the selected button.
     WinABI PostMessage,RBX,BM_SETSTATE,-1,0      ; Make it pushed.
     WinABI InvalidateRect,[MainWindowHandle],0,-1
     WinABI SetFocus,[MainWindowHandle]
     CALL FindToBuffer
     CALL PaintMarks
     CALL WndResize
     JMP .Ret0:
 .B:                     ; Hotkey 'B' pressed.
.ScanDirBrowseId:        ; Button [Browse] pressed.
     WinABI GetOpenFileNameW,ScanDirFileDlg
     TEST RAX
     JZ .Ret0:
     MOV RSI,[ScanDirFileDlg.lpstrFile]
     MOVZXW ECX,[ScanDirFileDlg.nFileOffset]
     LEA RDI,[ScanDirUTF16::]
     MOV RDX,RDI
     REP MOVSW
     XOR EAX,EAX
     STOSW
     MOV RSI,RDX
     WinABI SetWindowTextW,[ScanDirEditHandle],RSI
     LEA RDI,[ArgScanDir::]
     WinABI WideCharToMultiByte,CP_UTF8,0,RSI,-1,RDI,264,0,0
     JMP .Ret0
.S:                     ; Hotkey 'S' pressed.
.OlderSelectBtnId:      ; Button [Select] older scan file pressed.
     WinABI GetOpenFileNameW,InpFileDlg
     TEST RAX
     JZ .Ret0:
     MOV RSI,[InpFileDlg.lpstrFile]
     LEA RDI,[InputFileNameUTF16::]
     MOV RDX,RDI
.73: LODSW
     STOSW
     TEST AX
     JNZ .73:
     MOV RSI,RDX
     WinABI SetWindowTextW,[OlderEditHandle],RSI
     LEA RDI,[ArgInputFile::]
     WinABI WideCharToMultiByte,CP_UTF8,0,RSI,-1,RDI,264,0,0
     FileAssign File_scanOlder::,RSI, Unicode=yes
     CALL LoadAndCompareScans::
     CALL RenameButtons
     BufferClear [FindBuffer]
     WinABI SetFocus,[DirWindowHandle]
     WinABI InvalidateRect,[DirWindowHandle],0,-1
     WinABI PostMessage,[DirWindowHandle],WM_COMMAND,Btn2Id,0
     JMP .Ret0
.E:                     ; Hotkey 'E' pressed.
.NewerSelectBtnId:      ; Button [Select] newer scan file pressed.
     WinABI GetOpenFileNameW,OutFileDlg
     TEST RAX
     JZ .Ret0:
     MOV RSI,[OutFileDlg.lpstrFile]
     LEA RDI,[OutputFileNameUTF16::]
     MOV RDX,RDI
.76: LODSW
     STOSW
     TEST AX
     JNZ .76:
     MOV RSI,RDX
     WinABI SetWindowTextW,[NewerEditHandle],RSI
     LEA RDI,[ArgOutputFile::]
     WinABI WideCharToMultiByte,CP_UTF8,0,RSI,-1,RDI,264,0,0
     FileAssign File_scanNewer::,RSI, Unicode=yes
     CALL LoadAndCompareScans::
     CALL RenameButtons
     BufferClear [FindBuffer]
     WinABI InvalidateRect,[DirWindowHandle],0,-1
     WinABI PostMessage,[DirWindowHandle],WM_COMMAND,Btn2Id,0
     JMP .Ret0:
.ScanDirEditId
.OlderEditId:
.NewerEditId
     JMP .Def:
.VK_ESCAPE:                       ; Terminate program.
.WM_DESTROY:                      ; Program terminates.
     WinABI PostQuitMessage,0     ; Tell Windows to quit this program with errorlevel 0.
.Ret0:XOR EAX,EAX                 ; RAX=0 signalizes that the message was processed here.
.Ret:EndProcedure WndProc
RenameButtons
This procedure is called when a view has been changed by pressing one of five buttons.
It changes titles of those five buttons to reflect new selected pair of scan files.
Called by
WndProc (private calling convention).
RenameButtons PROC
     LEA RDI,[Dir::]
     Concat$ RDI,=U"Inserted ",Number1W::,=U" new directories (&1)",Size=100, Unicode=yes
     WinABI SetWindowTextW,[Btn1Handle],RDI
     Concat$ RDI,=U"Increased ",Number2W::,=U" directories (&2)",Size=100, Unicode=yes
     WinABI SetWindowTextW,[Btn2Handle],RDI
     Concat$ RDI,=U"Unchanged ",Number3W::,=U" directories (&3)",Size=100, Unicode=yes
     WinABI SetWindowTextW,[Btn3Handle],RDI
     Concat$ RDI,=U"Decreased ",Number4W::,=U" directories (&4)",Size=100, Unicode=yes
     WinABI SetWindowTextW,[Btn4Handle],RDI
     Concat$ RDI,=U"Deleted ",Number5W::,=U" old directories (&5)",Size=100, Unicode=yes
     WinABI SetWindowTextW,[Btn5Handle],RDI
     MOVD [ArgViewDirs::],ArgViewDirsInc
     WinABI SendMessage,[Btn1Handle],BM_SETSTATE,0,0
     WinABI SendMessage,[Btn2Handle],BM_SETSTATE,-1,0
     WinABI SendMessage,[Btn3Handle],BM_SETSTATE,0,0
     WinABI SendMessage,[Btn4Handle],BM_SETSTATE,0,0
     WinABI SendMessage,[Btn5Handle],BM_SETSTATE,0,0
     WinABI InvalidateRect,[DirWindowHandle],0,-1
     RET
    ENDP RenameButtons
WndCreate
Register window class and create all windows.
Called by
MainGui
WndCreate:: PROC
    PUSH RBX,RSI,RDI
    BufferCreate FindBuffer,Size=2M
    MOV [FindBuffer],RAX
    ; Register WndClassEx for the main window.
    MOV [WndClassEx.cbSize],SIZE# WndClassEx
    MOV [WndClassEx.lpszClassName],EuroDirs
    MOV [WndClassEx.style],CS_HREDRAW|CS_VREDRAW
    MOV [WndClassEx.lpfnWndProc],WndProc
    WinABI GetModuleHandle,0
    MOV [WndClassEx.hInstance],RAX
    WinABI LoadIcon,RAX,1             ; The 1st and only icon from [.rsrc] section.
    MOV [WndClassEx.hIcon],RAX
    WinABI GetStockObject,WHITE_BRUSH ; Default window background colour.
    MOV [WndClassEx.hbrBackground],RAX
    WinABI RegisterClassEx, WndClassEx
    ; Create the main window.
    LEA RSI,[EuroDirs::]
    WinABI CreateWindowEx, WS_EX_CLIENTEDGE,        \
           RSI, RSI, WS_OVERLAPPEDWINDOW, \
           CW_USEDEFAULT,CW_USEDEFAULT,1100,600,    \
           0, 0, [WndClassEx.hInstance], 0
    MOV [MainWindowHandle],RAX
   ; Initialize ScanDirExplore dialogue.
    MOV [ScanDirFileDlg.lStructSize],SIZE# OPENFILENAME
    MOV RAX,[MainWindowHandle]
    MOV [ScanDirFileDlg.hwndOwner],RAX
    MOV [ScanDirFileDlg.lpstrTitle],=U"Choose any file and click 'Open'"
    LEA RSI,[ScanDirUTF16::]
    LEA RDI,[ScanDir]
    MOV [ScanDirFileDlg.lpstrFile],RDI
    MOV [ScanDirFileDlg.nMaxFile],260
    MOV [ScanDirFileDlg.lpstrFilter],ScanFilter
.10:LODSW
    TEST AX
    JZ .20:
    STOSW
    JMP .10:
.20:MOV AX,'\'
    CMP [RDI-2],AX
    JE .30:
    STOSW
.30:MOV EAX,'*'
    STOSD
 ; Initialize OlderExplore dialogue.
    MOV [InpFileDlg.lStructSize],SIZE# OPENFILENAME
    MOV RAX,[MainWindowHandle]
    MOV [InpFileDlg.hwndOwner],RAX
    MOV [InpFileDlg.lpstrTitle],=U"Select an older scan"
    LEA RAX,[InputFileNameUTF16::]
    MOV [InpFileDlg.lpstrFile],RAX
    MOV [InpFileDlg.nMaxFile],260
    MOV [InpFileDlg.lpstrFilter],ScanFilter
    MOV [InpFileDlg.Flags],OFN_FILEMUSTEXIST+OFN_PATHMUSTEXIST
 ; Initialize NewerExplore dialogue.
    MOV [OutFileDlg.lStructSize],SIZE# OPENFILENAME
    MOV RAX,[MainWindowHandle]
    MOV [OutFileDlg.hwndOwner],RAX
    MOV [OutFileDlg.lpstrTitle],=U"Select a newer scan"
    LEA RAX,[OutputFileNameUTF16::]
    MOV [OutFileDlg.lpstrFile],RAX
    MOV [OutFileDlg.nMaxFile],260
    MOV [OutFileDlg.lpstrFilter],ScanFilter
    MOV [OutFileDlg.Flags],OFN_FILEMUSTEXIST+OFN_PATHMUSTEXIST
    ; EuroDirs icon.
    WinABI CreateWindowEx,0,="STATIC",="#1",WS_CHILD+WS_VISIBLE+SS_ICON,\
           12,0,16,16,[MainWindowHandle],0,[WndClassEx.hInstance],0
    WinABI SendMessage,RAX,STM_SETICON,[WndClassEx.hIcon],0
   ; Title EuroDirs version.
    WinABI CreateWindowExA,0,=B"STATIC", Version::,\
           WS_CHILD+WS_VISIBLE,50,10,180,20,[MainWindowHandle],0,[WndClassEx.hInstance],0
    ; Title of ScanDirExplore dialogue.
    WinABI CreateWindowExA,0,=B"STATIC", =B"A folder with scan files:",\
           WS_CHILD+WS_VISIBLE,\
           240,10,156,20,[MainWindowHandle],0,[WndClassEx.hInstance],0
    ; Edit field of ScanDirExplore.
    MOV EDX,[WindowWidth]
    SUB EDX,331
    WinABI CreateWindowExW,0,=U'EDIT',ScanDirUTF16::,WS_CHILD+WS_VISIBLE+WS_BORDER, \
           300,10,RDX,20,[MainWindowHandle],ScanDirEditId,[WndClassEx.hInstance],0
    MOV [ScanDirEditHandle],RAX
   ; Output ScanDirExplore button.
    MOV EDX,[WindowWidth]
    SUB EDX,100
    WinABI CreateWindowExA,0,=B'BUTTON',=B"&Browse",WS_CHILD+WS_VISIBLE+BS_DEFPUSHBUTTON,\
           RDX,10,90,20,[MainWindowHandle],ScanDirBrowseId,[WndClassEx.hInstance],0
    MOV [ScanDirBrowseHandle],RAX
    MOV ECX,[WindowWidth]
    SUB ECX,5*10+2*90
    SHR ECX,1
    WinABI CreateWindowExA,0,=B"STATIC",=B" Select an older scan file",WS_CHILD+WS_VISIBLE ,\
          10,40,RCX,20,[MainWindowHandle],0,[WndClassEx.hInstance],0
    MOV [OlderTitleHandle],RAX
    ; Input OlderExplore button.
    MOV EDX,[WindowWidth] ; MainWindows width.
    SUB EDX,5*10+2*90
    SHR EDX,1
    ADD EDX,2*10
    WinABI CreateWindowExA,0,=B'BUTTON',=B"&Select",WS_CHILD+WS_VISIBLE+BS_DEFPUSHBUTTON,\
           RDX,40,90,20,[MainWindowHandle],OlderSelectBtnId,[WndClassEx.hInstance],0
    MOV [OlderSelectBtnHandle],RAX
    ; Title NewerExplore dialogue.
    MOV EDX,[WindowWidth]
    MOV ECX,EDX
    SUB EDX,5*10+2*90
    SHR EDX,1
    MOV ECX,EDX
    ADD EDX,3*10+90
    WinABI CreateWindowExA,0,=B"STATIC",=B" and compare it with a newer scan file",WS_CHILD+WS_VISIBLE ,\
         RDX,40,RCX,20,[MainWindowHandle],0,[WndClassEx.hInstance],0
    MOV [NewerTitleHandle],RAX
   ; Output NewerExplore button.
    MOV EDX,[WindowWidth]
    SUB EDX,10+90
    WinABI CreateWindowExA,0,=B'BUTTON',=B"S&elect",WS_CHILD+WS_VISIBLE+BS_DEFPUSHBUTTON,\
           RDX,40,90,20,[MainWindowHandle],NewerSelectBtnId,[WndClassEx.hInstance],0
    MOV [NewerSelectBtnHandle],RAX
   ; Edit OlderExplore file name.
    MOV ECX,[WindowWidth]
    SUB ECX,3*10
    SHR ECX,1
    WinABI CreateWindowExW,0,=U'EDIT',File_scanOlder.Name::,WS_CHILD+WS_VISIBLE+WS_BORDER+ES_AUTOHSCROLL, \
           10,64,RCX,24,[MainWindowHandle],OlderEditId,[WndClassEx.hInstance],0
    MOV [OlderEditHandle],RAX
    ; Edit NewerExplore file name
    MOV EDX,[WindowWidth]
    SUB EDX,3*10
    SHR EDX,1
    MOV ECX,EDX
    ADD EDX,2*10
    WinABI CreateWindowExW,0,=U'EDIT',File_scanNewer.Name::,WS_CHILD+WS_VISIBLE+WS_BORDER+ES_AUTOHSCROLL, \
           RDX,64,RCX,24,[MainWindowHandle],NewerEditId,[WndClassEx.hInstance],0
    MOV [NewerEditHandle],RAX
    ; Buttons /ViewDirs=
    MOV EAX,[WindowWidth]
    SUB EAX,6*10
    XOR EDX,EDX
    MOV ECX,5
    DIV RCX
    MOV R12,RAX
    LEA RDI,[Dir::]
   ; Output Button1 - Inserted.
    Concat$ RDI,=U"Inserted ",Number1W::,=U" new directories (&1)",Size=100,Unicode=yes
    WinABI CreateWindowExW,0,=U'BUTTON',RDI,WS_CHILD+WS_VISIBLE+BS_PUSHBUTTON+BS_LEFT,\
           10,98,R12,20,[MainWindowHandle],Btn1Id,[WndClassEx.hInstance],0
    MOV [Btn1Handle],RAX
   ; Output Button2 - Incremented.
    Concat$ RDI,=U"Increased ",Number2W::,=U" directories (&2)",Size=100,Unicode=yes
    LEA RDX,[R12+2*10]
    WinABI CreateWindowExW,0,=U'BUTTON',RDI,WS_CHILD+WS_VISIBLE+BS_PUSHBUTTON+BS_LEFT,\
           RDX, 98,R12,20,[MainWindowHandle],Btn2Id,[WndClassEx.hInstance],0
    MOV [Btn2Handle],RAX
   ; Output Button3 - Unchanged.
    Concat$ RDI,=U"Unchanged ",Number3W::,=U" directories (&3)",Size=100,Unicode=yes
    LEA RDX,[R12+R12+3*10]
    WinABI CreateWindowExW,0,=U'BUTTON',RDI,WS_CHILD+WS_VISIBLE+BS_PUSHBUTTON+BS_LEFT,\
           RDX, 98,R12,20,[MainWindowHandle],Btn3Id,[WndClassEx.hInstance],0
    MOV [Btn3Handle],RAX
   ; Output Button4 - Decremented.
    Concat$ RDI,=U"Decreased ",Number4W::,=U" directories (&4)",Size=100,Unicode=yes
    LEA RDX,[R12+2*R12+4*10]
    WinABI CreateWindowExW,0,=U'BUTTON',RDI,WS_CHILD+WS_VISIBLE+BS_PUSHBUTTON+BS_LEFT,\
           RDX, 98,R12,20,[MainWindowHandle],Btn4Id,[WndClassEx.hInstance],0
    MOV [Btn4Handle],RAX
   ; Output Button5 - Deleted.
    Concat$ RDI,=U"Deleted ",Number5W::,=U" old directories (&5)",Size=100,Unicode=yes
    LEA RDX,[4*R12+5*10]
    WinABI CreateWindowExW,0,=U'BUTTON',RDI,WS_CHILD+WS_VISIBLE+BS_PUSHBUTTON+BS_LEFT,\
           RDX, 98,R12,20,[MainWindowHandle],Btn5Id,[WndClassEx.hInstance],0
    MOV [Btn5Handle],RAX
   ; Create Find static text.
    WinABI CreateWindowExA,0,=B"STATIC", =B"Find this text:",WS_CHILD+WS_VISIBLE,\
           10,127,94,20,[MainWindowHandle],0,[WndClassEx.hInstance],0
   ; Create FindText edit window.
    MOV EDX,[WindowWidth]
    SUB EDX,134
    WinABI CreateWindowExW,0,=U'EDIT',0,WS_CHILD+WS_VISIBLE +WS_BORDER, \
           114,127,RDX,20,[MainWindowHandle],FindEditId,[WndClassEx.hInstance],0
    MOV [FindTextHandle],RAX
   ; Create brush for Find window.
   WinABI CreateSolidBrush, ColorFind
   MOV [hBrushFind],RAX
   ; Create DirWindow for displaying of directories.
    MOV EDX,[WindowWidth]
    SUB EDX,22
    MOV ECX,[WindowHeight]
    SUB ECX,168
    LEA RSI,[EuroDirs::]
    WinABI CreateWindowExA, WS_EX_CLIENTEDGE,       \
           RSI, 0, WS_CHILD+WS_VISIBLE+WS_BORDER+WS_VSCROLL, \
           10,158,RDX,RCX,[MainWindowHandle], 0, [WndClassEx.hInstance], 0
    MOV [DirWindowHandle],RAX
    POP RDI,RSI,RBX
    RET
   ENDP WndCreate
WndResize
Dimensions of the MainWindow changed.
Called from
WndProc.WM_SIZE.
WndResize:: PROC
    PUSH RBX,RSI,RDI,R12
    LEA RBX,[MainWindowRect]
    WinABI GetClientRect,[MainWindowHandle],RBX
    MOV ECX,[RBX+RECT.right]
    MOV EAX,[RBX+RECT.bottom]
    MOV [WindowWidth],ECX
    MOV [WindowHeight],EAX
    CMP EAX,190                      ; Minimal height.
    JA .20:
    WinABI GetWindowRect,[MainWindowHandle],RBX
    MOV EDX,[RBX+RECT.left]
    MOV ECX,[RBX+RECT.top]
    MOV EBX,[RBX+RECT.right]
    SUB EBX,EDX
    WinABI MoveWindow,[MainWindowHandle],RDX,RCX,RBX,230,-1
    JMP .80:                         ; Do not let the height of MainWindow drop under 190 px.
.20:SUB EAX,129                      ; Fixed height of common dialogues and buttons above DirWindow.
    MOV ECX,[TextMetric.tmHeight]
    XOR EDX,EDX
    DIV RCX
    MOV [ClientLines],EAX
    ; Set vertical scroll info.
    DEC EAX,EAX
    MOV [ClientLinesMinus2],EAX
    MOV [ScrollInfo.nPage],EAX
    MOV [ScrollInfo.cbSize],SIZE# SCROLLINFO
    MOV [ScrollInfo.fMask],SIF_RANGE | SIF_PAGE | SIF_POS
    MOV [ScrollInfo.nMin],0
    MOV EAX,[MaxLineNr::]
    MOV [ScrollInfo.nMax],EAX
    MOV EAX,[SelectedLineNr]
    MOV [ScrollInfo.nPos],EAX
    WinABI SetScrollInfo,[DirWindowHandle],SB_VERT,ScrollInfo,-1
    ; ScanDirExplore edit.
    MOV EDX,[WindowWidth]
    SUB EDX,411+  102
    WinABI MoveWindow,[ScanDirEditHandle],400,10,RDX,20,1
    ; ScanDirExplore button.
    MOV EDX,[WindowWidth]
    SUB EDX,90+10
    WinABI MoveWindow,[ScanDirBrowseHandle],RDX,10,90,20,1
    ; Title of OlderExplore dialogue.
    MOV ECX,[WindowWidth]
    SUB ECX,5*10+2*90
    SHR ECX,1
    WinABI MoveWindow,[OlderTitleHandle],10,40,RCX,20,1
    ; Input OlderExplore button.
    MOV EDX,[WindowWidth]
    SUB EDX,5*10+2*90
    SHR EDX,1
    ADD EDX,2*10
    WinABI MoveWindow,[OlderSelectBtnHandle],RDX,40,90,20,1
    ; Title NewerExplore dialogue.
    MOV EDX,[WindowWidth]
    MOV ECX,EDX
    SUB EDX,5*10+2*90
    SHR EDX,1
    MOV ECX,EDX
    ADD EDX,3*10+90
    WinABI MoveWindow,[NewerTitleHandle],RDX,40,RCX,20,1
    ; Output NewerExplore button.
    MOV EDX,[WindowWidth]
    SUB EDX,5*10+2*90
    ADD EDX,4*10+1*90
    WinABI MoveWindow,[NewerSelectBtnHandle],RDX,40,90,20,1
    ; Edit OlderExplore file name.
    MOV ECX,[WindowWidth]
    SUB ECX,3*10
    SHR ECX,1
    WinABI MoveWindow,[OlderEditHandle],10,64,RCX,24,1
    ; Edit NewerExplore file name
    MOV EDX,[WindowWidth]
    SUB EDX,3*10
    SHR EDX,1
    MOV ECX,EDX
    ADD EDX,2*10
    WinABI MoveWindow,[NewerEditHandle],RDX,64,RCX,24,1
   ; Five buttons /ViewDirs=
    MOV EAX,[WindowWidth]
    SUB EAX,6*10
    XOR EDX,EDX
    MOV ECX,5
    DIV RCX
    MOV R12,RAX
    ; Output insButton.
    WinABI MoveWindow,[Btn1Handle],10, 98,R12,20,1
    ; Output incButton.
    LEA RDX,[R12+2*10]
    WinABI MoveWindow,[Btn2Handle],RDX, 98,R12,20,1
    ; Output unchButton.
    LEA RDX,[R12+R12+3*10]
    WinABI MoveWindow,[Btn3Handle],RDX, 98,R12,20,1
    ; Output decButton.
    LEA RDX,[R12+2*R12+4*10]
    WinABI MoveWindow,[Btn4Handle],RDX, 98,R12,20,1
    ; Output delButton.
    LEA RDX,[4*R12+5*10]
    WinABI MoveWindow,[Btn5Handle],RDX, 98,R12,20,1
    ; Find text edit window.
    MOV EDX,[WindowWidth]
    SUB EDX,124
    WinABI MoveWindow,[FindTextHandle],114,127,RDX,20,1
    ; DirWindow.
    MOV EDX,[WindowWidth]
    SUB EDX,22
    MOV ECX,[WindowHeight]
    SUB ECX,128+10+20+9
    WinABI MoveWindow,[DirWindowHandle],10,128+30,RDX,RCX,1
.80:POP R12,RDI,RSI,RBX
    RET
ENDP WndResize
WndPaint

This is a procedure which repaints the client area of DirWindow.

Input
[BufferSelected] is BUFFER with INDEXes.
SelectedLineNr is the topmost 0-based line number in client area.
Output
-
Called by
WndProc.WM_PAINT
WndPaint:: PROC
   PUSH RBX,RSI,RDI,R12
    WinABI BeginPaint, [DirWindowHandle], PaintStruct
    MOV [hDirDC],RAX
    WinABI CreateFont,0,0,0,0,0,0,0,0,DEFAULT_CHARSET, \  Create an unproportional font.
           OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DRAFT_QUALITY,FIXED_PITCH|FF_DONTCARE,0
    MOV [FontHandle],RAX
    WinABI SelectObject,[hDirDC],RAX
    WinABI GetTextMetrics,[hDirDC],TextMetric
    BufferRetrieve [BufferSelected::]
    SHR ECX,4
    MOV [MaxLineNr::],ECX
    MOV ECX,[TextMetric.tmHeight]
    MOV EAX,[WindowHeight]
    SUB EAX,129+27
    JNA .90:
    XOR EDX,EDX
    DIV RCX
    MOV [ClientLines],EAX    ; EAX=number of visible lines of text.
    SUB EAX,2
    MOV [ClientLinesMinus2],EAX
    MOV ECX,[TextMetric.tmAveCharWidth]
    MOV EAX,[WindowWidth]
    XOR EDX,EDX
    DIV RCX                  ; EAX=Number of columns per client width. Complete with spaces.
    MOV R12,RAX              ; R12 is the number of chars in client window.
    XOR EAX,EAX
    MOV [ClientY],RAX        ; Start painting with pixel line 0.
    MOV ECX,[ClientLines]
    MOV EBX,[SelectedLineNr] ; EBX specifies the line from the selected buffer (1,2,3,,,MaxLineNr::).
.20:PUSH RCX                 ; This loop displays [ClientLines] of text in the client area.
      CALL OneLine2Dir::     ; Dir (RSI) is filled with RCX bytes of WIDE text. Or RCX=0 when out of buffer.
      MOV R8,RSI             ; R8 points at the beginning of the line text.
      LEA R9,[RSI+RCX]       ; R9 points at the end of the line text.
      SHR ECX,1              ; Convert bytes to characters.
      MOV EAX,ColorCursor
      CMP EBX,[CursorLineNr]
      JE .25:
      MOV EAX,ColorWhite
.25:  WinABI SetBkColor,[hDirDC],RAX,Fastmode=no
      MOV R10,R12
      SUB R10,RCX            ; R10 is the required number of spaces.
      JA .30:
      MOV R10,RCX
.30:  MOV AX,' '
      MOV R11,RCX            ; Temporary save RCX=number of chars in line.
      MOV RCX,R12
      MOV RDI,R9
      REP STOSW
      MOV R9,RDI             ; R9 points now at the end of client columns.
      MOV RCX,R11            ; Restore RCX=number of characters in line.
      MOV EDX,[FindChars]    ; Size of FindText in characters.
.40:  MOV EAX,10
      MOV RDI,R8
      TEST EDX
      JZ .60:                ; Do not search when the size of FindText is 0.
      CMP EBX,[CursorLineNr]
      JE .60:                ; Do not search when the current line is CursorLineNr.
      LEA R11,[RDX-1]        ; R11 is FindSize-1.
      CMP EDX,ECX
      JA  .60:
      MOV RDI,RSI            ; Start searching here.
      LEA RSI,[FindText]
      LODSW                  ; Load AX with the first character of FoundText.
      XOR EDX,EDX
.50:  REPNE SCASW
      JNE .40:
      PUSH RCX,RSI,RDI
        MOV RCX,R11
        REPE CMPSW
      POP RDI,RSI,RCX
      JNE .50:                 ; Continue search for the first character.
      MOV EDX,[FindChars]
      ; FindText was found. Display RDI-2-R8 white chars,
      ;   then RDX yellow, then the rest in white again.
      SUB RDI,R8
      SHR EDI,1
      DEC EDI
      WinABI TextOutW,[hDirDC],10,[ClientY],R8,RDI,Fastmode=No
      WinABI SetBkColor,[hDirDC],ColorFind,Fastmode=no
      LEA RSI,[R8+2*RDI]
      MOV EAX,[TextMetric.tmAveCharWidth]
      MUL RDI
      ADD EAX,10
      MOV EDX,[FindChars]
      LEA RDI,[RSI+2*RDX]
      WinABI TextOutW,[hDirDC],RAX,[ClientY],RSI,RDX,Fastmode=No
      WinABI SetBkColor,[hDirDC],0x00FFFFFF
      MOV EAX,[TextMetric.tmAveCharWidth]
      MOV RCX,RDI
      SUB RCX,R8
      SHR ECX,1
      MUL RCX
      ADD EAX,10
.60:  SUB R9,RDI
      SHR R9,1
      WinABI TextOutW,[hDirDC],RAX,[ClientY],RDI,R9,Fastmode=No
    POP RCX
    MOV EAX,[TextMetric.tmHeight]
    ADD [ClientY],RAX
    INC EBX                  ; Next line.
    DEC ECX
    JNZ .20:
.90:WinABI DeleteObject,[FontHandle]
    WinABI EndPaint,  [DirWindowHandle], PaintStruct
    CALL PaintMarks
   POP R12,RDI,RSI,RBX
   RET
  ENDP WndPaint
FindToBuffer

For each line from BufferSelected it will store FIND_INDEX record to FindBuffer.

Input
[BufferSelected] is BUFFER with INDEXes.
SelectedLineNr is the topmost 0-based line number in client area.
Output
-
Calls
OneLine2Dir::.
Called by
WndProc.WM_PAINT
FindToBuffer PROC
    BufferClear [FindBuffer]
    JC .90:
    CMPD [FindChars],0
    JZ .90:
    SUB EBX,EBX
.10:INC EBX
    CALL OneLine2Dir::  ; RSI=Dir is filled with RCX bytes of WIDE text. Or RCX=0 when out of buffer.
    JRCXZ .90:
    MOV R8,RSI
    MOV RDI,RSI
    LEA RSI,[FindText]
    XOR EAX,EAX
    LODSW
    SHR ECX,1
.20:REPNE SCASW          ; Search for the first UNICHAR of the FindText string in Dir.
    JNE .10:
    PUSH RCX,RSI,RDI
      MOV ECX,[FindChars]
      DEC ECX
      CMP ESI,EDI   ; Set ZF=0.
      REPE CMPSW
    POP RDI,RSI,RCX
    JNE .20:
    MOV [FindIndex.LineNr],EBX  ; FindText was found in this line.
    SUB RDI,2
    SUB RDI,R8
    MOV [FindIndex.Offset],EDI
    BufferStore [FindBuffer],FindIndex,SIZE# FIND_INDEX
    JMP .10:        ; Read the next line.
.90:RET
   ENDP FindToBuffer
PaintMarks

Paint little yellow marks on the right side of the main window.
It relies on BufferFind filled by FindToBuffer.

Called by
WndProc.WM_PAINT
PaintMarks PROC
    WinABI BeginPaint,[MainWindowHandle],PaintStruct
    MOV [hMainDC],RAX
    LEA RDI,[MainWindowRect]
    WinABI GetClientRect,[MainWindowHandle],RDI
    LEA RSI,[DirWindowRect]
    WinABI GetClientRect,[DirWindowHandle],RSI
    MOV EAX,[RDI+RECT.right]
    SUB EAX,[RSI+RECT.right]
    CMP EAX,30                 ; 40 if vertical scrollbar exists, 24 otherwise.
    JNA .80:                   ; Do not paint marks when the scrollbar is not visible.
    BufferRetrieve [FindBuffer]
    JNA .80:
    PUSH RCX
     WinABI CreatePen,PS_SOLID,3,ColorFind
     MOV [PenHandle],RAX
     WinABI SelectObject,[hMainDC],RAX
     MOV EDI,[DirWindowRect.bottom]
     SUB EDI,2*17
    POP RCX
    SHR ECX,3
.20:PUSH RCX
     MOV EAX,[RSI+FIND_INDEX.LineNr]
     MUL RDI
     MOV ECX,[MaxLineNr::]
     DIV RCX  ; RAX is now vertical coordinate of the mark, related to DirWindowRect.top.
     LEA EBX,[EAX+175]
     MOV ECX,[DirWindowRect.right]
     ADD ECX,35
     WinABI MoveToEx,[hMainDC],RCX,RBX,0
     ADD ECX,5
     WinABI LineTo,[hMainDC],RCX,RBX
     ADD RSI,SIZE# FIND_INDEX
    POP RCX
    DEC ECX
    JNZ .20:
    WinABI DeleteObject,[PenHandle]
.80:WinABI EndPaint,[MainWindowHandle],PaintStruct
    RET
    ENDP PaintMarks
  ENDPROGRAM dirswing

▲Back to the top▲