I cannot compile this code. Could I have a help? Thanks.
procedure ChangeOutsideDateTime(h: HWND; dt: TDateTime);
var
st: TSystemTime;
pst: Pointer;
hDTP: Cardinal;
hProc: THandle;
dwWrote: DWORD;
begin
DateTimeToSystemTime(dt, st);
pst:= VirtualAllocEx(h, nil, SizeOf(st), MEM_COMMIT, 0);
if pst <> nil then begin
if GetWindowThreadProcessId(h, hDTP) > 0 then begin
hProc:= OpenProcess(PROCESS_VM_OPERATION, false, hDTP);
if WriteProcessMemory(hProc, pst, @st, SizeOf(st), dwWrote) > 0 then begin
SendMessage(h, DTM_SETSYSTEMTIME, GDT_VALID, hDTP);
CloseHandle(hProc);
end;
end;
VirtualFreeEx(h, pst, 0, MEM_RELEASE);
end;
end;
It shows "Types of actual and formal var parameters must be identical" at line where is using "WriteProcessMemory".
Types of actual and formal var parameters must be identical
This is compiler error E2003. If you encounter a compiler error that you don't understand, the first thing to do is read the documentation . It says:
For a variable parameter, the actual argument must be of the exact type of the formal parameter.
The function call which leads to this error is WriteProcessMemory
. Let's look at its declaration:
function WriteProcessMemory(hProcess: THandle; const lpBaseAddress: Pointer;
lpBuffer: Pointer; nSize: SIZE_T; var lpNumberOfBytesWritten: SIZE_T): BOOL; stdcall;
There is only one var
parameter here, the final parameter. The variable that you pass must be of type SIZE_T
, but you passed a variable of type DWORD
. That is the mismatch.
Some other comments:
VirtualAllocEx
is bound to fail because you pass a window handle rather than a process handle. OpenProcess
return value. That could readily fail. PROCESS_VM_WRITE
access right which is necessary for WriteProcessMemory
. WriteProcessMemory
fails. WriteProcessMemory
is BOOL
. hDTP
is a strange name for a process ID. That name suggests you think it is the handle of the date time picker control. It's not. It's the process ID. SendMessage
call rather than the address of the system time that you just wrote. Your code has several mitakes in it.
you are passing an HWND
to VirtualAllocEx()
, but it expects a THandle
to an opened process instead. And you are calling VirtualAllocEx()
before you have opened the process handle. And you are not requesting write acess to the allocated memory.
when calling OpenProcess()
, you are not asking for PROCESS_VM_WRITE
permission, which WriteProcessMemory()
requires.
your use of WriteProcessMemory()
does not match its declaration. That is why you are getting a compiler error.
you are passing the HWND
's process ID as the LPARAM
of DTM_SETSYSTEMTIME
, but it expects the allocated TSystemTime
pointer instead.
Try something more like this:
procedure ChangeOutsideDateTime(h: HWND; dt: TDateTime);
var
st: TSystemTime;
PID: DWORD;
hProc: THandle;
pst: Pointer;
NumWrote: SIZE_T;
begin
GetWindowThreadProcessId(h, PID);
hProc := OpenProcess(PROCESS_VM_OPERATION or PROCESS_VM_WRITE, false, PID);
if hProc <> 0 then
try
pst := VirtualAllocEx(hProc, nil, SizeOf(st), MEM_COMMIT, PAGE_READWRITE);
if pst <> nil then
try
DateTimeToSystemTime(dt, st);
if WriteProcessMemory(hProc, pst, @st, SizeOf(st), NumWrote) then begin
SendMessage(h, DTM_SETSYSTEMTIME, GDT_VALID, LPARAM(pst));
end;
finally
VirtualFreeEx(hProc, pst, 0, MEM_RELEASE);
end;
finally
CloseHandle(hProc);
end;
end;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.