Hi All,

I need your help. I stuck with Icz tutorial #31 Listview Control:



//Iczelion's tutorial #31: Listview Control
program aListView;

#include("w.hhf")
#include("comctl32.hhf")

readonly
ClassName : string := "ListViewWinClass";
AppName : string := "Testing a ListView Control";
ListViewClassName : string := "SysListView32";
FileNamePattern : string := "*.*";
template : string := "%lu";
Heading1 : string := "Filename";
Heading2 : string := "Size";

static
hInstance : dword;
FileNameSortOrder : dword := 0;
SizeSortOrder : dword := 0;
hMenu : dword;
hList : dword;
wsprintf : procedure(p0:dword;p1:dword;p2:dword);
@cdecl;
external("__imp__wsprintfA");

procedure InsertColumn;
static
lvc : w.LV_COLUMN;

begin InsertColumn;
mov( w.LVCF_TEXT | w.LVCF_WIDTH, lvc.imask );
mov( Heading1, lvc.pszText );
mov( 150, lvc.lx);
w.SendMessage(hList, w.LVM_INSERTCOLUMN,0,&lvc);
or( w.LVCF_FMT, lvc.imask);
mov( w.LVCFMT_RIGHT, lvc.fmt);
mov( Heading2, lvc.pszText );
mov( 100, lvc.lx);
w.SendMessage(hList, w.LVM_INSERTCOLUMN, 1 ,&lvc );
end InsertColumn;


procedure ShowFileInfo(row:DWORD; lpFind:DWORD); //uses edi
static
lvi : w.LV_ITEM;
buffer : BYTE[20];

begin ShowFileInfo;
push(edi);
mov( lpFind,edi);
mov( w.LVIF_TEXT | w.LVIF_PARAM, lvi.imask);
mov(row, lvi.iItem);
mov( 0, lvi.iSubItem);
lea( eax,(type w.WIN32_FIND_DATA [edi]).cFileName);
mov( eax, lvi.pszText);
mov(row, lvi.lParam);
w.SendMessage(hList, w.LVM_INSERTITEM,0, &lvi);
mov( w.LVIF_TEXT, lvi.imask);
inc( lvi.iSubItem);
wsprintf(&buffer, template,(type w.WIN32_FIND_DATA [edi]).nFileSizeLow);
lea( eax,buffer);
mov( eax, lvi.pszText);
w.SendMessage(hList,w.LVM_SETITEM, 0,&lvi);
pop(edi);
end ShowFileInfo;

procedure FillFileInfo; //uses edi
static
finddata: w.WIN32_FIND_DATA;
FHandle : DWORD;

begin FillFileInfo;
push(edi);
w.FindFirstFile(FileNamePattern,&finddata);
if( eax <> w.INVALID_HANDLE_VALUE) then;
mov( eax, FHandle);
xor( edi,edi);
while( eax <> 0) do;
test( w.FILE_ATTRIBUTE_DIRECTORY, finddata.dwFileAttributes );
if( @z ) then;
ShowFileInfo(edi, &finddata);
inc( edi);
endif;
w.FindNextFile(FHandle, &finddata);
endwhile;
w.FindClose( FHandle);
endif;
pop(edi);
end FillFileInfo;

procedure WndProc(hWnd:dword; uMsg:uns32; wParam:dword; lParam:dword);@nodisplay;@stdcall;

begin WndProc;

if( uMsg = w.WM_CREATE)then;
w.CreateWindowEx( NULL, ListViewClassName, NULL,
w.LVS_REPORT | w.WS_CHILD | w.WS_VISIBLE, 0,0,0,0,hWnd,
NULL, hInstance, NULL);
mov( eax, hList );
InsertColumn();
FillFileInfo();
elseif( uMsg = w.WM_SIZE) then;
mov( lParam, eax );
mov( eax, edx );
and( $ffff, eax );
shr( 16, edx );
w.MoveWindow(hList, 0, 0, eax,edx,true);
elseif( uMsg = w.WM_DESTROY) then;
w.PostQuitMessage(NULL);
else
w.DefWindowProc(hWnd,uMsg,wParam,lParam );
exit WndProc;
endif;
xor( eax,eax);
end WndProc;


procedure WinMain ( hInst : dword; hPrevInst : dword; CmdLine : dword; CmdShow : dword );
@nodisplay;

var
wc : w.WNDCLASSEX;
msg : w.MSG;
hwnd : dword;

begin WinMain;

mov ( @size( w.WNDCLASSEX ), wc.cbSize );
mov ( w.CS_HREDRAW | w.CS_VREDRAW , wc.style );
mov ( &WndProc, wc.lpfnWndProc );
mov ( NULL, wc.cbClsExtra );
mov ( NULL, wc.cbWndExtra );
mov ( hInst, wc.hInstance );
w.LoadIcon ( NULL, w.IDI_APPLICATION );
mov ( eax, wc.hIconSm );
mov ( eax, wc.hIcon );
w.LoadCursor ( NULL, w.IDC_ARROW );
mov ( eax, wc.hCursor );
mov ( w.COLOR_WINDOW + 1 , wc.hbrBackground );
mov ( ClassName, wc.lpszClassName );
mov ( NULL, wc.lpszMenuName );

w.RegisterClassEx ( wc);

w.CreateWindowEx(NULL, ClassName, AppName, w.WS_OVERLAPPEDWINDOW,
w.CW_USEDEFAULT, w.CW_USEDEFAULT,w.CW_USEDEFAULT,w.CW_USEDEFAULT,
NULL,NULL,hInstance, NULL);
mov ( eax, hwnd );
w.ShowWindow ( hwnd, CmdShow );
w.UpdateWindow ( hwnd );

while ( w.GetMessage ( msg , NULL, 0, 0 ) <> 0 ) do
w.TranslateMessage ( msg ) ;
w.DispatchMessage ( msg );
endwhile;

mov ( msg.wParam, eax );
end WinMain;

begin aListView;
InitCommonControls();
w.GetModuleHandle(NULL);
mov(eax,hInstance);
WinMain( hInstance, NULL, NULL, w.SW_SHOWDEFAULT );
w.ExitProcess(eax);
end aListView;



It is only part of original code. I stripped it from much its functionality to make it look straightfoward.
This code creates Listview Control with two columns(Filename and Size), then it populates Filename column,
well, with filenames from directory where the exe resides, then it supposed to fill Size column
with files sizes in bytes. But it shows the size for the first file in a list only.

If I use macro wrapper for wsprintf function things go worst: program just crashes on the start.

In attachment full code of tutorial.

Regards, GJ
Posted on 2003-05-14 14:36:21 by Green Joe
I'm at work and don't have time to study this carefully,
but one quick suggestion I might make, even though it
means you won't do a "straight-across" conversion of this
tutorial is to look into the use of the HLA Standard Library
str.put function rather than using wsprintf.

e.g.,



static
s:str.strvar(256);
.
.
.
str.put( s, "i's value is", i:4, " j's value is ", j );

Now the HLA string "s" contains something like
"i's value is 5 j's value is 2"

Because HLA strings are zero terminated (and the string
variable contains the first character of the string) they are
generally upwards compatible to the zero-terminated strings
that Windows uses, so you can pass them to most Win32 API
functions.

Cheers,
Randy Hyde
Posted on 2003-05-20 12:37:54 by rhyde
One more deadlock...
This time tutorial #29 "Win32 Debug API part 2" (Example 1).



// Iczelion's tutorial #29: "Win32 Debug API Part II" (Example 1)
program aDebugAPI2_1;

#include("w.hhf")

readonly
AppName : string := "Win32 Debug Example no.2";
ClassName : string := "SimpleWinClass";
SearchFail : string := "Cannot find the target process";
TargetPatched : string := "Target patched!";

static
buffer : word := $9090;
DBEvent : w.DEBUG_EVENT;
ProcessId : dword;
ThreadId : dword;
context : w.CONTEXT;

begin aDebugAPI2_1;
w.FindWindow( ClassName, NULL);
if( eax!= NULL) then;
w.GetWindowThreadProcessId( eax, ProcessId);
mov( eax, ThreadId );
w.DebugActiveProcess( ProcessId);

forever
w.WaitForDebugEvent(&DBEvent, w.INFINITE);
breakif( DBEvent.dwDebugEventCode = w.EXIT_PROCESS_DEBUG_EVENT);
if( DBEvent.dwDebugEventCode = w.CREATE_PROCESS_DEBUG_EVENT) then;
mov( w.CONTEXT_CONTROL, context.ContextFlags );
w.GetThreadContext(DBEvent.u.CreateProcessInfo.hThread, &context);
[COLOR=red] w.WriteProcessMemory( DBEvent.u.CreateProcessInfo.hProcess, context.regEip , &buffer, 2, NULL );[/color]
w.MessageBox(0, TargetPatched, AppName, w.MB_OK | w.MB_ICONINFORMATION);
elseif( DBEvent.dwDebugEventCode = w.EXCEPTION_DEBUG_EVENT) then;
if( DBEvent.u.theException.pExceptionRecord.ExceptionCode = w.EXCEPTION_BREAKPOINT) then;
w.ContinueDebugEvent( DBEvent.dwProcessId,DBEvent.dwThreadId,w.DBG_CONTINUE );
continue;
endif;
endif;
w.ContinueDebugEvent( DBEvent.dwProcessId,DBEvent.dwThreadId,w.DBG_EXCEPTION_NOT_HANDLED );
endfor;
else
w.MessageBox( 0, SearchFail, AppName,w.MB_OK | w.MB_ICONERROR);
endif;
w.ExitProcess(0);
end aDebugAPI2_1;


This code practically identical with Example 2 except hilighted line. That is why I have strong feelling the promblem lies in this line.
Posted on 2003-05-20 18:08:48 by Green Joe
Hi Randy,
quick suggestion I might make, even though it
means you won't do a "straight-across" conversion of this
tutorial is to look into the use of the HLA Standard Library
str.put function rather than using wsprintf.


str.put works fine. It helped me localize an error. Problem was in macro wsprintf.
It popped too much bytes from stack.

Regards,GJ
Posted on 2003-05-21 15:58:01 by Green Joe