.386
.model flat, stdcall
option casemap :none   

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
 
WndProc  PROTO :DWORD,:DWORD,:DWORD,:DWORD   ;forward declare of used functions
EnumProc PROTO :DWORD,:DWORD
FindProc PROTO :HWND,:BOOL

Subtract MACRO first,second                      ;Macros need through out the code
    mov eax,first
        sub eax,second
            mov first,eax
ENDM
LOWORD MACRO bigword
    mov  eax,bigword
        and  eax,0FFFFh
ENDM
HIWORD MACRO bigword
    mov eax,bigword
        shr eax,16
ENDM     

.data
    dlgname     db "MAIN",0
    szProgman   db "Program Manager",0
    szAbout     db "Coded by: Betrayed",13,10
                db "Coded in: Asm(Masm)",13,10
                db "E-mail: odin77@hotmail.com",13,10
                db "Home page: http://betrayed.virtualave.net",0
    szPlease    db "Please select an item from the list box",0
    szMin       db "Window is minimized.",13,10
                db "Would you like to restore it?",0
    szNoWin     db "Specified Window could not be found.",13,10
                db "Refreshing Window list...",0
    szBadSize   db "Please Choose a non zero, numeric size.",0
    szTitle     db "Window Sizer",0

.data? 
    hInstance   dd ?
    hList       dd ?

.code
start:

    invoke GetModuleHandle, NULL
        mov hInstance, eax        
    invoke DialogBoxParam,hInstance,ADDR dlgname,0,ADDR WndProc,0
        invoke ExitProcess,eax

WndProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    .if uMsg == WM_INITDIALOG
        invoke LoadIcon,hInstance,100
            invoke SendMessage,hWin,WM_SETICON,1,eax
        invoke SetWindowPos,hWin,HWND_TOP+HWND_TOPMOST,NULL,NULL,NULL,NULL,SWP_NOMOVE+SWP_NOSIZE   ;window on top
        invoke GetDlgItem,hWin,1000                                     ;Get listbox
            mov hList,eax                                               ;save handle
        invoke EnumWindows,addr EnumProc,NULL                           ;enumerate the windows
        invoke SetFocus,hList                                           ;Set focus on the listbox
            xor eax,eax
                ret
    .elseif uMsg == WM_COMMAND
        LOWORD wParam                                                       ;loword returns the id code
            .if eax == 3002                                                 ;close button
                invoke SendMessage,hWin,WM_CLOSE,NULL,NULL                  ;Close it
            .elseif eax == 3001                                             ;about button
                invoke MessageBox,hWin,addr szAbout,addr szTitle,MB_OK+MB_ICONINFORMATION
            .elseif eax == 2003                                             ;Set button
                invoke FindProc,hWin,TRUE                                   ;call findprco with true so it knows to set a new size
            .elseif eax == 3000                                             ;Refresh button
                invoke SendMessage,hList,LB_RESETCONTENT,NULL,NULL          ;Clear listbox
                    invoke EnumWindows,addr EnumProc,NULL                   ;enumerate the windows
                        invoke SetFocus,hList                               ;set focus on the listbox
            .elseif eax == 1000                                             ;listbox
                HIWORD wParam                                               ;hiword shows the message sent  (fix from previous version)
                    .if eax ==  LBN_SELCHANGE                               ;if it is a change in the selection we want to know
                        invoke FindProc,hWin,FALSE                          ;Call findproc with false so we just update the sizebox
                    .endif
            .endif
                xor eax,eax
                    ret
    .elseif uMsg == WM_CLOSE
        invoke ShowWindow,hWin,SW_MINIMIZE      ;just a little bit of end eyecandy =P
            invoke EndDialog,hWin,0
                xor eax,eax
                    ret
    .endif
        xor eax,eax
            ret
WndProc endp

EnumProc proc eHandle:DWORD,y:DWORD
LOCAL buffer[1024]:BYTE

    invoke IsWindowVisible,eHandle      ;see if it is visble
        .if eax                             ;If it is go on
            invoke GetWindowText,eHandle,addr buffer,sizeof buffer   ;get the text
                .if eax                                              ;make sure it has text
                    invoke lstrcmp,addr szProgman,addr buffer        ;compare it to the program manager
                        push eax                                   ;save result
                    invoke lstrcmp,addr szTitle,addr buffer          ;compare it to our title
                        mov edx,eax
                        pop eax
                            .if !(edx == 0 || eax == 0)                   ;If neither match go on
                                invoke SendMessage,hList,LB_ADDSTRING,NULL,addr buffer  ;and add it to the list box
                            .endif
                .endif
        .endif
            mov eax,eHandle                 ;enumerate until the handle is zero
                ret
EnumProc endp

FindProc proc hWnd:HWND,which:BOOL
LOCAL buffer2[1024]:BYTE
LOCAL IndexItem:DWORD
LOCAL handle:HWND
LOCAL rectWin:RECT

    invoke SendMessage,hList,LB_GETCURSEL,0,0       ;get the selection position
        mov IndexItem,eax                           ;save it
            .if eax != LB_ERR                       ;make sure something is selected
                invoke SendMessage,hList,LB_GETTEXT,IndexItem,ADDR buffer2  ;get the selected text
                    invoke FindWindow,NULL,addr buffer2                     ;use it to find the window
                        mov handle,eax                                      ;save the handle
                            .if eax != NULL                                 ;make sure we have a handle
                                .if which == TRUE                           ;see what we want to do with this function
                                    invoke IsIconic,handle                  ;since it was true we want to resize and we need to know if it is minimized
                                        .if !eax                            ;if it is not go on 
                                            invoke GetDlgItemInt,hWnd,2000,NULL,0   ;get width we want to resize to
                                               push eax                       ;save it
                                            invoke GetDlgItemInt,hWnd,2001,NULL,0   ;get the height to resize to
                                               mov edx,eax;
                                               pop eax                       ;save it
                                                    .if !(eax==0 || edx==0)         ;make sure neither is zero
                                                        invoke SetWindowPos,handle,NULL,0, 0, eax, edx, SWP_NOMOVE + SWP_NOZORDER ;resize the window
                                                    .else
                                                        invoke MessageBox,hWnd,addr szBadSize,addr szTitle,MB_OK+MB_ICONSTOP ;if zero let the user know about it
                                                    .endif
                                        .else
                                            invoke MessageBox,hWnd,addr szMin,addr szTitle,MB_YESNO+MB_ICONSTOP ;it is minimized
                                                .if eax == IDYES
                                                    invoke ShowWindow,handle,SW_RESTORE                         ;asked the user what to do if they chose restore 
                                                    invoke SendMessage,hWnd,WM_COMMAND,2003,NULL                ;and set the size again
                                                .endif
                                        .endif
                                .else                                                          ;which was false
                                    invoke GetWindowRect,handle,addr rectWin                   ;get the window rectangle   
                                        Subtract rectWin.right,rectWin.left                    ;Call the macro to subtract
                                        Subtract rectWin.bottom,rectWin.top                    ;Call the macro to subtract
                                            invoke SetDlgItemInt,hWnd,2000,rectWin.right,0     ;Set the size in the width box
                                            invoke SetDlgItemInt,hWnd,2001,rectWin.bottom,0    ;Set the size in the height box
                                .endif
                            .else
                                invoke MessageBox,hWnd,addr szNoWin,addr szTitle,MB_OK+MB_ICONEXCLAMATION   ;Window could not be found
                                    invoke SendMessage,hWnd,WM_COMMAND,3000,NULL                                ;Refresh the list
                            .endif
        .else
            invoke MessageBox,hWnd,addr szPlease,addr szTitle,MB_OK+MB_ICONSTOP ;Nothing selected in the listbox
        .endif
            xor eax,eax
                ret
FindProc endp
end start


