HI! I am new to this forum and mostly newb on MASM. I have few programs programmed by it. So, now I wanted to program a file viewer myself. I 'ripped' some code from one tut, added mine, but it wasn't good. Maybe someone could help me fixing the errors? The code is below. Please help me :)
.386
.model flat,stdcall
option casemap:none
include C:\masm32\include\windows.inc
include C:\masm32\include\kernel32.inc
include C:\masm32\include\user32.inc
include C:\masm32\include\comctl32.inc
includelib C:\masm32\lib\comctl32.lib
includelib C:\masm32\lib\kernel32.lib
includelib C:\masm32\lib\user32.lib
includelib C:\masm32\lib\shell32.lib
include C:\masm32\include\shell32.inc
MainWindow proto :DWORD
ViewFile proto :DWORD, :DWORD
RunFile proto :BYTE
.data
classname db "ListViewWinClass",0
windowname db "FileBrowser",0
ListViewName db "SysListView32",0
Filename db "*.*",0
Header db "File name",0
DefaultPath db "C:\",0
EditName db "edit",0
ButClass db "button",0
ButName db "Gooo!",0
.data?
hInstance HINSTANCE ?
hList dd ?
hEdit dd ?
hButton dd ?
buffer db 256 dup (?)
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke MainWindow, hInstance
invoke ExitProcess, 0
invoke InitCommonControls
MainWindow proc
LOCAL message:MSG
LOCAL hWindow:HWND
LOCAL WC:WNDCLASSEX
mov WC.cbSize,SIZEOF WNDCLASSEX
mov WC.style, NULL
mov WC.IpfnWndProc, OFFSET WindowProc
mov WC.cbClsExtra, NULL
mov WC.cbWndExtra, NULL
push hInstance
pop WC.hInstance
invoke LoadIcon, NULL, IDI_APPLICATION
mov WC.hIcon, eax
mov WC.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov WC.hCursor, eax
mov WC.hbrBackground, COLOR_WINDOW+1
mov WC.IpszMenuName, NULL
mov WC.IpszClassName, OFFSET classname
invoke RegisterClassEx, addr WC
invoke CreateWindowEx, NULL, addr classname, addr windowname,\
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,\
CW_USEDEFAULT, CW_USEDEFAULT, NULL,
NULL, hInstance, NULL
mov hWindow, eax
invoke ShowWindow, hWindow, SW_SHOWDEFAULT
.While TRUE
invoke GetMessage, addr message, NULL, 0, 0
.BREAK .IF (!eax)
invoke TranslateMessage, addr message
invoke DispatchMessage, addr message
.endw
MainWindow endp
WindowProc proc hWnd:HWND, WinMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if WinMsg==WM_DESTROY
invoke PostQuitMessage, NULL
ret
.elseif WinMsg==WM_CREATE
invoke CreateWindowEx,0,addr EditName,0,\
WS_DLGFRAME+WS_CHILD+ES_AUTOHSCROLL,
0,0,710,25,\
hWnd,0,hInstance,0
mov hEdit, eax
invoke ShowWindow,hEdit,SW_SHOWDEFAULT
invoke SendMessage,hEdit,WM_SETTEXT,0,Addr writepath
invoke SendMessage,hEdit,EM_SETSEL,0,-1
invoke CreateWindowEx,0 , addr ButClass, addr ButName,
WS_CHILD+BS_DEFPUSHBUTTON+BS_TEXT+BS_VCENTER,
710,0,50,25,hInstance,0
mov hButton, eax
invoke ShowWindow,hButton,SW_SHOW
invoke CreateWindowEx, NULL, addr ListViewName, NULL,\
WS_CHILD+LVS_REPORT+LVS_ALIGNLEFT+LVS_SORTASCENDING,\
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,\
CW_USEDEFAULT, hWnd, NULL, hInstance, NULL
mov hList, eax
invoke ShowWindow, hList, SW_SHOW
call InsertColumn
invoke SetCurrentDirectory, addr DefaultPath
call ShowAll
.ElseIf WinMsg==WM_COMMAND
mov eax,wparam
shr eax,16
.IF eax==BN_CLICKED
mov eax,lParam
.If eax==hButton
invoke RunFile,1
.endif
.endif
.ElseIf WinMsg==WM_SIZE
mov eax,lParam
mov edx,eax
and eax,0FFFFH
shr edx,16
push eax
invoke MoveWindow,hList, 0, 0, eax,edx,TRUE
pop eax
sub eax,50
push eax
Invoke MoveWindow,hEdit,0,0,eax,25,TRUE
pop eax
invoke MoveWindow,hButton,eax,0,50,25,TRUE
.ElseIF WinMsg==WM_NOTIFY
mov edi,lParam
assume edi:ptr NMHDR
mov eax,[edi].hwndFrom
.if eax==hList
.if [edi].code==NM_DBLCLK
Invoke RunFile,0
.ElseIf [edi].code==NM_RETURN
Invoke RunFile,0
.endif
.endif
assume edi:nothing
.else
invoke DefWindowProc, hWnd, WinMsg, wParam, lParam
ret
.endif
xor eax,eax
ret
InsertColumn proc
LOCAL lvc:LV_COLUMN
mov lvc.imask,LVCF_FMT+LVCF_WIDTH+LVCF_TEXT
mov lvc.fmt,LVCFMT_LEFT
mov lvc.lx,100
mov lvc.pszText, OFFSET Header
invoke SendMessage, hList, LVM_INSERTCOLUMN, 0, addr lvc
ret
InsertColumn endp
ShowAll proc, WinFind:DWORD
uses edi
LOCAL WinFind:WIN32_FIND_DATA
LOCAL FHandle:DWORD
invoke FindFirstFile, addr FileName, addr WinFind
.if eax!=INVALID_HANDLE_VALUE
mov FHandle, eax
xor edi, edi
.while eax!=0
invoke ViewFile, edi, addr WinFind
inc edi
invoke FindNextFile, FHandle, addr WinFind
.endw
invoke FindClose, FHandle
.endif
ret
ShowAll endp
ViewFile proc, eilute:DWORD, WinFind:DWORD
uses edi
LOCAL LVI:LV_ITEM
mov edi, WinFind
assume edi:ptr WIN32_FIND_DATA
mov LVI.imask,LVIF_TEXT
push eilute
pop LVI.iItem
mov LVI.iSubItem, 0
lea eax,[edi].cFileName
mov LVI.pszText,eax
push eilute
pop LVI.lParam
invoke SendMessage, hList, LVM_INSERTITEM, 0, addr lvi
assume edi:nothing
ret
ViewFile endp
RunFile proc EorL:BYTE
LOCAL lvi:LV_ITEM
.If EorL==1
invoke SendMessage,hEdit,WM_GETTEXT,256,addr buffer
.Else
invoke SendMessage,hList,LVM_GETNEXTITEM, -1, LVNI_FOCUSED
mov lvi.iItem,eax
mov lvi.imask,LVIF_TEXT
lea eax,buffer
mov lvi.pszText,eax
mov lvi.iSubItem,0
mov lvi.cchTextMax,256
invoke SendMessage, hList, LVM_GETITEM, 0, addr lvi
.EndIf
invoke GetFileAttributes, addr buffer
and eax,10h ;FILE_ATTRIBUTE_DIRECTORY=10h, LOL...
.If eax!=0
invoke SendMessage, hList, LVM_DELETEALLITEMS, 0, 0
invoke SetCurrentDirectory, addr buffer
call FillList
.else
invoke ShellExecuteA,0,0,addr buffer,0,0,SW_SHOWDEFAULT
.endif
ret
RunFile endp
end start
Welcome!
Quick notes:
1) When you post long code, I would say it's better to attach it to the message
2) You are calling MainWindow with a argument, but the proc is defined without any arguments, so, probably, the stack is debalanced.
[edit]
or, better yet, forget about that argument. You are saving the module handle in a global variable, then you are passing it using the stack to a function. There's no need for that. Just change
MainWindow proto :DWORD
in
MainWindow proto
and
invoke MainWindow, hInstance
in
invoke MainWindow
[/edit]
I will take a closer look in a while. :)
Regards,
Nick
I think you should change
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke MainWindow
invoke ExitProcess, 0
invoke InitCommonControls
to
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke InitCommonControls
invoke MainWindow
invoke ExitProcess, 0
Paul
@Nick, next time I will and thanks for your help.
@Paul, I changed that. Thanks.
Wow guys, thanks. I still get errors, but less then previous time :) Here are my errors:
D:\RadASM\File Viewer.asm(94) : error A2006: undefined symbol : writepath
D:\RadASM\File Viewer.asm(94) : error A2114: INVOKE argument type mismatch : argument : 4
D:\RadASM\File Viewer.asm(96) : error A2137: too few arguments to INVOKE
D:\RadASM\File Viewer.asm(154) : error A2144: cannot nest procedures
D:\RadASM\File Viewer.asm(156) : error A2012: PROC, MACRO, or macro repeat directive must precede LOCAL
D:\RadASM\File Viewer.asm(161) : error A2006: undefined symbol : lvc
D:\RadASM\File Viewer.asm(161) : error A2114: INVOKE argument type mismatch : argument : 4
D:\RadASM\File Viewer.asm(166) : error A2144: cannot nest procedures
D:\RadASM\File Viewer.asm(167) : error A2008: syntax error : edi
D:\RadASM\File Viewer.asm(169) : error A2012: PROC, MACRO, or macro repeat directive must precede LOCAL
D:\RadASM\File Viewer.asm(170) : error A2012: PROC, MACRO, or macro repeat directive must precede LOCAL
D:\RadASM\File Viewer.asm(171) : error A2006: undefined symbol : FileName
D:\RadASM\File Viewer.asm(171) : error A2114: INVOKE argument type mismatch : argument : 1
D:\RadASM\File Viewer.asm(178) : error A2006: undefined symbol : FHandle
D:\RadASM\File Viewer.asm(178) : error A2114: INVOKE argument type mismatch : argument : 1
D:\RadASM\File Viewer.asm(180) : error A2006: undefined symbol : FHandle
D:\RadASM\File Viewer.asm(180) : error A2114: INVOKE argument type mismatch : argument : 1
D:\RadASM\File Viewer.asm(187) : error A2144: cannot nest procedures
D:\RadASM\File Viewer.asm(188) : error A2008: syntax error : edi
D:\RadASM\File Viewer.asm(189) : error A2012: PROC, MACRO, or macro repeat directive must precede LOCAL
D:\RadASM\File Viewer.asm(200) : error A2006: undefined symbol : lvi
D:\RadASM\File Viewer.asm(200) : error A2114: INVOKE argument type mismatch : argument : 4
D:\RadASM\File Viewer.asm(207) : error A2144: cannot nest procedures
D:\RadASM\File Viewer.asm(209) : error A2012: PROC, MACRO, or macro repeat directive must precede LOCAL
D:\RadASM\File Viewer.asm(221) : error A2006: undefined symbol : lvi
D:\RadASM\File Viewer.asm(221) : error A2114: INVOKE argument type mismatch : argument : 4
D:\RadASM\File Viewer.asm(236) : fatal error A1010: unmatched block nesting : WindowProc
I attached that file. And edited first post, there was error in there. I am looking forward to your replies, guys. :)
Luke
[attachment deleted by admin]
He, he! Some months ago my error list was longer than the file itself, too! :green2
Some tips:
- the error message gives you important information:
File Viewer.asm(94) - file and line number wher the error was found
for first error:
QuoteD:\RadASM\File Viewer.asm(94) : error A2006: undefined symbol : writepath
line 94 say:
invoke SendMessage,hEdit,WM_SETTEXT,0,Addr writepath
but there is no
writepath in the entire file... so, the symbol
writepath is undefined
- to split a line, use the backslash:
invoke CreateWindowEx,0 , addr ButClass, addr ButName, \
WS_CHILD+BS_DEFPUSHBUTTON+BS_TEXT+BS_VCENTER,\
710,0,50,25,hInstance,0
- any
WindowProc proc
should have a coresponding
WindowProc endp
because, if it hasn't, you will have a bounch of errors for next lines :)
Fix this and the list will be a lot smaller.
[edit]
just noticed that you used this:
WS_CHILD+BS_DEFPUSHBUTTON+BS_TEXT+BS_VCENTER
to tell the style of a window. the flags should be OR'ed, not added
WS_CHILD or BS_DEFPUSHBUTTON or BS_TEXT or BS_VCENTER
[/edit]
Nick
Code ripping is a very bad habit ! However, I made your prog working.
[attachment deleted by admin]
OMG guys, I love both of you :bg Thanks Nick for pointing my mistakes :P And ramguru, you too. Really thank you. And I ripped some of that code from journal, so I had to type everything AND it was meant to be compiled, it was a tutorial.
Luke
:U :bg
Quote from: PBrennick on December 28, 2006, 02:59:53 PM
I think you should change
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke MainWindow
invoke ExitProcess, 0
invoke InitCommonControls
to
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke InitCommonControls
invoke MainWindow
invoke ExitProcess, 0
Paul
Now, THERE is a question I've been meaning to ask for....well a bloody long time. Why is it that InitCommonControls/InitCommonControlsEx goes at the END of the startup code? Been driving me crazy for ages....
Ehtyar.
Actually it doesn't need to be moved as I said. I am just a purist. It is included in the code to force the DLL to load but at run time it does not need to be executed hence he put it after ExitProcess.
Paul
So why for InitCommonControlsEx do we set the class of controls to be loaded if the API itself is never executed?
Ehtyar.
Quote from: Ehtyar on January 01, 2007, 10:57:59 PM
So why for InitCommonControlsEx do we set the class of controls to be loaded if the API itself is never executed?
Presumably for improved load time (ie. only load the classes you need). Though it will give an error if one of the specified classes could not be loaded (if it's an older version of comctl32) so you can't arbitrarily load all the classes all at once (this is based on one experience with it, correct me if I'm wrong).
AFAIK, InitCommonControlsEx does need to execute before you create any windows of a common control class, but I haven't tried it. InitCommonControls is obsolete and was used only to ensure that the linker didn't discard the reference.
Cheers,
Zooba :U
At least under Windows 2000 there is no need to actually call InitCommonControlsEx. In my crude tests the difference in load time was much smaller than the run to run variation. The average over several hundred runs showed the version that called InitCommonControlsEx to be slightly slower than the version that did not, but even so, IMO it is silly to not call InitCommonControlsEx, considering that the call must be coded, and that the call may be necessary on some systems.
Still based on my one experience with this, I found the call to InitCommonControlsEx was required under Windows XP with no manifest (MSDN says it's not needed when you have a manifest but I didn't check) and the call had to succeed. Some control classes failed to load in which case none of them were usable.
In any case, Microsoft have documented that the call is required. Maybe it is, maybe it isn't, as developers we aren't to question that. If one day (Vista?) they make it necessary to call InitCommonControlsEx and your program breaks because you don't, they've covered themselves by documenting it.
Bottom line, call InitCommonControlsEx, call it properly and test the return value.
Cheers,
Zooba :U
Believe it or not I had the same question to myself yesterday and founded this thread...
http://www.masm32.com/board/index.php?topic=3408.0
Quotebut it's still included in the import table, and the dll get's loaded during the startup
Hi again! :bg First of all, happy new year :thumbu I have some questions about ramguru's fixed code.
1. Why when I launch any application it is ok, but when I want to change directory, it doesn't show anything.
2. Why "Gooo" button shows up only when you press on space where it should be, but isn't showing when you don't push it.
Luke
Quote from: BRONiUS on January 10, 2007, 02:42:21 PM
1. Why when I launch any application it is ok, but when I want to change directory, it doesn't show anything.
Because I've commented function that doesn't exist in your file (which supposedly does that job)
.If eax!=0
invoke SendMessage, hList, LVM_DELETEALLITEMS, 0, 0
invoke SetCurrentDirectory, addr buffer
;call FillList
.else
Quote from: BRONiUS on January 10, 2007, 02:42:21 PM
2. Why "Gooo" button shows up only when you press on space where it should be, but isn't showing when you don't push it.
It's because of this code
.ElseIf WinMsg==WM_SIZE
mov eax,lParam
mov edx,eax
and eax,0FFFFH
shr edx,16
push eax
invoke MoveWindow,hList, 0, 0, eax,edx,TRUE
pop eax
sub eax,50
push eax
Invoke MoveWindow,hEdit,0,0,eax,25,TRUE
pop eax
invoke MoveWindow,hButton,eax,0,50,25,TRUE
Windows just overlap
I think you should give more efforts, try to understand what you're doing, etc.