ToMKoL Posted May 26, 2022 Posted May 26, 2022 Hi all I'm trying to convert this small c snippet to delphi 7 code but without success for now. If any delphi coder could help I'll be gratefull. HANDLE hthread; hthread = CreateThread(0, 0, &animate, hWnd, 0, 0) DWORD WINAPI animate(HWND hWnd) { unsigned char wincaption[32]; unsigned int i; SendMessageA(hWnd, WM_GETTEXT, 32, (LPARAM)wincaption); do { for(i=0;i<20;i++) { if (((wincaption[i] >= 0x41) && (wincaption[i] <= 0x5A)) || ((wincaption[i] >= 0x61) && (wincaption[i] <= 0x7A))) wincaption[i] ^= 0x20; SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)wincaption); Sleep(500); } } while (1); } And my delphi attempt: hthread : THandle; hthread := CreateThread(nil, 0, @animate, hWnd, 0, 0); procedure animate(hWnd : HWND); var wincaption: array[0..32] of char; i: integer; begin SendMessageA(hWnd, WM_GETTEXT, 32, integer(pchar(@wincaption[0]))); while true do begin for i := 1 to 23 do begin if (((wincaption[i] >= $41) and (wincaption[i] <= $5A)) or ((wincaption[i] >= $61) and (wincaption[i] <= $7A))) wincaption[i] := wincaption[i] xor $20; SendMessageA(hWnd, WM_SETTEXT, 0, LPARAM(wincaption)); Sleep(500); end; end; end;
h4sh3m Posted May 26, 2022 Posted May 26, 2022 1 hour ago, ToMKoL said: Hi all I'm trying to convert this small c snippet to delphi 7 code but without success for now. If any delphi coder could help I'll be gratefull. HANDLE hthread; hthread = CreateThread(0, 0, &animate, hWnd, 0, 0) DWORD WINAPI animate(HWND hWnd) { unsigned char wincaption[32]; unsigned int i; SendMessageA(hWnd, WM_GETTEXT, 32, (LPARAM)wincaption); do { for(i=0;i<20;i++) { if (((wincaption[i] >= 0x41) && (wincaption[i] <= 0x5A)) || ((wincaption[i] >= 0x61) && (wincaption[i] <= 0x7A))) wincaption[i] ^= 0x20; SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)wincaption); Sleep(500); } } while (1); } And my delphi attempt: hthread : THandle; hthread := CreateThread(nil, 0, @animate, hWnd, 0, 0); procedure animate(hWnd : HWND); var wincaption: array[0..32] of char; i: integer; begin SendMessageA(hWnd, WM_GETTEXT, 32, integer(pchar(@wincaption[0]))); while true do begin for i := 1 to 23 do begin if (((wincaption[i] >= $41) and (wincaption[i] <= $5A)) or ((wincaption[i] >= $61) and (wincaption[i] <= $7A))) wincaption[i] := wincaption[i] xor $20; SendMessageA(hWnd, WM_SETTEXT, 0, LPARAM(wincaption)); Sleep(500); end; end; end; Hi Following code is not exact translation but can help you : Spoiler function animate(hWnd: PDWORD): DWORD; stdcall; var TextLength: Integer; wincaption: WideString; i: integer; hndl : NativeUInt; begin hndl := hWnd^; TextLength := SendMessage(hndl, WM_GETTEXTLENGTH, 0, 0) + 1; wincaption := StringOfChar(#0, TextLength); GetWindowText(hndl, PWideChar(wincaption), 255); while true do begin for i := 1 to Length(wincaption) do begin if (((Ord(wincaption[i]) >= $41) and (Ord(wincaption[i]) <= $5A)) or ((Ord(wincaption[i]) >= $61) and (Ord(wincaption[i]) <= $7A))) then wincaption[i] := WideChar(Ord(wincaption[i]) xor $20); SetWindowText(hndl, PWideChar(wincaption)); UpdateWindow(hndl); Sleep(500); end; end; end; procedure TForm1.BitBtn1Click(Sender: TObject); var hthread : THandle; hndl : HWND; FThreadID : cardinal; begin hndl := Form1.Handle; hthread := CreateThread(nil, 0, @animate, @hndl, 0, FThreadID); end;
NOP Posted May 26, 2022 Posted May 26, 2022 I normally setup a thread something like this... FWorkerThread := TBackgroundThread.Create(true); FWorkerThread.FreeOnTerminate := true; FWorkerThread.OnTerminate := HandleOnTerminate; FWorkerThread.Resume; and then use this for your execute thread code... procedure TBackgroundThread.Execute; and this if you want to do anything after the thread is completed... procedure TfrmMain.HandleOnTerminate(Sender: TObject);
ToMKoL Posted May 26, 2022 Author Posted May 26, 2022 Thanks for reply but forgot to mention that I don't use forms and try as much as I can to stay with winapi. I'm using external resources with dialog to do my stuff. @h4sh3m Your reply helped a lot but still can't compile my project. I did this changes: var hndl : HWND; hndl := hWnd; hthread := CreateThread(nil, 0, @animate, @hndl, 0, 0); procedure animate(hWnd : PDWORD); var ... wndhndl : NativeUInt; begin hndl := hWnd^; ... But now retrive this error message - 'Types of actual and formal var parameters must be identical'. My delphi coding skills are limited so I test all solution that I can google but till now nothing worked.
kao Posted May 26, 2022 Posted May 26, 2022 It's hard to "debug" your code by seeing just a small code snippet. It would be nice if you could post the entire project so that it can be opened in Delphi and compiled right away.. Anyway, I think I see 2 problems: 1) This is how CreateThread is defined in Delphi9 (sorry, no D7 here): function CreateThread(lpThreadAttributes: Pointer; dwStackSize: DWORD; lpStartAddress: TFNThreadStartRoutine; lpParameter: Pointer; dwCreationFlags: DWORD; var lpThreadId: DWORD): THandle; stdcall; See the last parameter, lpThreadId? It's declared as "var". Therefore you may not use a constant 0, even if you don't care about the thread id. You should use a variable instead. Something like this may work: var hndl : HWND; threadId : DWORD; hndl := hWnd; hthread := CreateThread(nil, 0, @animate, @hndl, 0, threadId); 2) Thread procedure must be defined as "stdcall". Compiler might not complain but your thread will crash because by default it will expect hWnd to be passed via registers. procedure animate(hWnd : PDWORD); stdcall;
NOP Posted May 26, 2022 Posted May 26, 2022 (edited) Kao beat me to it but I think the ThreadId needs to be Cardinal not DWORD for Delphi 7 Edited May 26, 2022 by NOP
ToMKoL Posted May 27, 2022 Author Posted May 27, 2022 (edited) Thanks guys for replies. Will check them. I'm, attaching full project. Just don't blame me for shitty code. Coded this in few houres at work (have plenty free time right now) using only examples found in google. To test You'll need to uncomment code for thread. Also any optimizations to this code are more than welcome. And please be aware that I'm using archaic d7 personal version. sdfkgme15.zip Small update - almost made it work. Thanks for tips with 'ThreadID'. This was the key. Now have problem with dereferncing pointer in thread. hthread := CreateThread(nil, 0, @animate, PDWORD(hWnd), 0, tid); procedure animate(hWnd : PDWORD); stdcall; ... SendMessageA(hWnd^, WM_GETTEXT, 32, integer(pchar(@wincaption[0]))); ... and this is translated by compiler like: mov eax, hWnd push eax ... call CreateThread thread proc mov edi, dword ptr [ebp+8] -> edi holds hwnd ... mov eax,dword ptr [edi] -> here is error it should compile to mov eax,edi Small update2 - made it work partially: hthread := CreateThread(nil, 0, @animate, PDWORD(hWnd), 0, tid); procedure animate(hWnd : HWND); stdcall; var wincaption: array[0..32] of char; i: integer; begin SendMessageA(hWnd, WM_GETTEXT, 32, integer(pchar(@wincaption[0]))); while true do begin for i := 0 to 22 do begin if ((ord(wincaption[i]) >= $41) and (ord(wincaption[i]) <= $5A)) or ((ord(wincaption[i]) >= $61) and (ord(wincaption[i]) <= $7A)) then wincaption[i] := ord(wincaption[i]) xor $20; SendMessageA(hWnd, WM_SETTEXT, 0, LPARAM(@wincaption[0])); Sleep(500); end; end; end; This works except the line - 'wincaption[i] := ord(wincaption[i]) xor $20;'. It gives me error about incompatible types char and integer. Edited May 27, 2022 by ToMKoL added more information
ToMKoL Posted May 28, 2022 Author Posted May 28, 2022 Manage to make it work like I wanted. Working package included. Thanks guys for all help. sdfkgme15.zip 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now