我无法编译此代码。我可以帮忙吗?感谢。
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;
在使用“WriteProcessMemory”的行中显示“实际和正式var参数的类型必须相同”。
答案 0 :(得分:6)
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. 答案 1 :(得分:2)
您的代码中有几个简化。
您正在将HWND
传递给VirtualAllocEx()
,但它希望THandle
代替已打开的流程。在打开流程句柄之前,您正在调用VirtualAllocEx()
。并且您没有请求写入已分配的内存。
在致电OpenProcess()
时,您并未要求获得PROCESS_VM_WRITE
WriteProcessMemory()
所需的WriteProcessMemory()
权限。
您对HWND
的使用与其声明不符。这就是您收到编译器错误的原因。
您正在将LPARAM
的进程ID作为DTM_SETSYSTEMTIME
的{{1}}传递,但它需要使用已分配的TSystemTime
指针。
尝试更像这样的事情:
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;