在NT/2000中怎么禁用Ctrl+Alt+Delete?(注意不能用gina,键盘驱动) ?誰能把這段代碼改成delphi的!(50分)

  • 主题发起人 主题发起人 ljy_17
  • 开始时间 开始时间
贴子太长,delete这代码,代码可以在下面找到:
http://www.playicq.com/databack/trapkeys.zip
 
TO:copy_paste
非常感謝!…
程個程序,請到這裡下載……
src: http://freehost19.websamba.com/skyflier/caq0209.rar
bin: http://freehost19.websamba.com/skyflier/disablectrlaltdelete.zip
 
太多太长,:(

快过年了,先过年吧。。。:),不然你先译,然后调不通的,拿出来看看吧。。。
 
TO:copy_paste
那裡邊包含很多的代碼,但其他的都不是有用的!
主要的代碼就剛才那些!還有一些是沒有必要,我昨天安裝了一下BCB,TMD安裝不成功!
害得我的Delphi也壞了!
其實隻要在BCB中打開,看一下主要屏蔽ctrl+del+alt的代碼就夠了,如果N的話,不要發
一個小時就可以搞定的!我對BCB實在是不那個………

還請copy_paste多幫忙了…………
 
不然你下这个BCB6试试:
http://www.playicq.com/ocx/cb6.0.rar
http://www.playicq.com/ocx/cb6.0disk2.rar

还有它里面的代码是VC的。。。我先试试吧。呵呵,不要抱太大希望。。。:)
 
TO:copy_paste
哈哈,謝了,我靜候你的佳音…………
搞定後500分都是你的………………………
 
译的文件在:
http://www.playicq.com/dispdoc.php?id=2898
http://www.playicq.com/databack/trapkeys.zip

还没译完,太多了,太累了,先过年再。。。
还没写实现的代码,有兴趣的继续。。。其它的应该不难了。。。

没进行调试。。。有错是很正常的。。。

睡觉,回家,过年,
明年见。。。

春节愉快。。。
 
TO:copy_paste
新年好…
謝謝你的熱心幫助!
我密切關注中……
 
//Main.pas
unit Main;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button2: TButton;
cbTaskList: TCheckBox;
cbCAD: TCheckBox;
cbTaskMgr: TCheckBox;
cbTaskKey: TCheckBox;
cbTaskBar: TCheckBox;
procedure cbTaskListClick(Sender: TObject);
private
FRemoteDLL: string;
FTaskList: Boolean;
FTaskKey: Boolean;
FCtrlAltDel: Boolean;
FTaskBar: Boolean;
FTaskMgr: Boolean;
procedure Disable(dwFlags: DWORD; Disabled, Beep: Boolean);
procedure SetTaskBar(const Value: Boolean);
procedure SetTaskKey(const Value: Boolean);
procedure SetTaskList(const Value: Boolean);
procedure SetTaskMgr(const Value: Boolean);
procedure SetCtrlAltDel(const Value: Boolean);
protected
property TaskBar: Boolean read FTaskBar write SetTaskBar;
property TaskMgr: Boolean read FTaskMgr write SetTaskMgr;
property TaskKey: Boolean read FTaskKey write SetTaskKey;
property TaskList: Boolean read FTaskList write SetTaskList;
property CtrlAltDel: Boolean read FCtrlAltDel write SetCtrlAltDel;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
end;

var
Form1: TForm1;

implementation

uses PSAPI, ImageHlp, TlHelp32, CommonFunc, Registry;
{$R *.dfm}

const
TASK_MGR = $01; // disable task manager (Ctrl+Alt+Del)
TASK_KEYS = $02; // disable task keys (Alt-TAB, etc)
TASK_BAR = $04; // disable task bar
TASK_LIST = $08; // disable listing process list
CTRL_ALT_DEL = $10; // disable Ctrl+Alt+Del
TASK_ALL = TASK_MGR or TASK_KEYS or TASK_BAR or TASK_LIST or CTRL_ALT_DEL;

function IsWin2k: Boolean;
begin
Result := (Win32MajorVersion >= 5) and (Win32Platform =
VER_PLATFORM_WIN32_NT);
end;

{ Finally, the following example tests whether Terminal Services is installed. }
function IsTerminalServices: Boolean;
var
OS: TOSVersionInfoEx;
dwlConditionMask: Int64;
begin
FillChar(OS, SizeOf(OS), 0);
OS.dwOSVersionInfoSize := SizeOf(OS);
OS.wSuiteMask := VER_SUITE_TERMINAL;
dwlConditionMask := 0;
dwlConditionMask := VerSetConditionMask(dwlConditionMask, VER_SUITENAME, VER_AND);
Result := VerifyVersionInfo(@OS, VER_SUITENAME, dwlConditionMask);
end;

function ThreadFuncAttach(pInfo: PInjectLibInfo): DWORD; stdcall;
begin
pInfo^.dwReturnValue := 0;
Result := pInfo^.pfnLoadLibrary(pInfo^.szDllName);
if Result = 0 then
pInfo^.dwReturnValue := pInfo^.pfnGetLastError;
end;

procedure AfterThreadFuncAttach;
begin
end;

{ 远程线程,用来卸载DLL }
function ThreadFuncDetach(pInfo: PDeinjectLibInfo): DWORD; stdcall;
var
Handle: THandle;
FoundModule: Boolean;
begin
Result := 1;
pInfo^.dwReturnValue := 0; { 意味成功,如果这个值不是0,则是一个错误代码。}
Handle := pInfo^.pfnGetModuleHandle(pInfo^.szDllName);
FoundModule := Handle <> 0;
if FoundModule and not pInfo^.pfnFreeLibrary(Handle) then
pInfo^.dwReturnValue := pInfo^.pfnGetLastError;
if (pInfo^.dwReturnValue = 0) and not FoundModule then
pInfo^.dwReturnValue := pInfo^.pfnGetLastError;
end;

procedure AfterThreadFuncDetach;
begin
end;

function EnablePrivilege(lpszPrivilegeName: PChar; Enabled: Boolean): Boolean;
var
luid: Int64;
Token: THandle;
RetLen: Cardinal;
Privileges: TTokenPrivileges;
begin
Result := False;
if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or
TOKEN_QUERY or TOKEN_READ, Token) then Exit;
try
Result := not LookupPrivilegeValue(nil, lpszPrivilegeName, luid);
if Result then Exit;
FillChar(Privileges, SizeOf(Privileges), 0);
Privileges.PrivilegeCount := 1;
Privileges.Privileges[0].Luid := luid;
if Enabled then
Privileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(Token, False, Privileges, 0, nil, RetLen);
Result := GetLastError = ERROR_SUCCESS
finally
CloseHandle(Token);
end;
end;

{ 通过进程名称得到进程的ID(这里使用方法Toolhelp函数,因此在NT上无法使用,当然也
可以PSAPI函数,这样就可以在NT上使用了)}
function GetPIDFromName(lpszProcName: PChar): DWORD;

function QueryWithWTS(const ProcName: string): THandle;
var
pSessionInfo: PChar;
dwCurSessionID, dwBytes: DWORD;
I, ProcessCount: DWORD;
ProcessInfo: PWTSProcessInfo;
S: string;
begin
Result := PROCESS_ERROR;
pSessionInfo := nil;
if WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION,
WTSSessionId, pSessionInfo, dwBytes) then
begin
dwCurSessionID := PDWORD(pSessionInfo)^;
if WTSEnumerateProcesses(WTS_CURRENT_SERVER_HANDLE, 0, 1, @ProcessInfo, ProcessCount) then
for I := 0 to ProcessCount - 1 do
begin
S := LowerCase(ProcessInfo^.pProcessName);
if (Pos(ProcName, S) > 0) and (dwCurSessionID = ProcessInfo^.SessionId) then
begin
Result := ProcessInfo^.ProcessId;
break;
end;
Inc(ProcessInfo);
end;
WTSFreeMemory(pSessionInfo);
end;
end;

{ added by jiangsheng 2002-11-8 }
function QueryWithTool(const ProcName: string): THandle;
var
S: string;
Next: Boolean;
SnapShot: THandle;
ProcessEntry: TProcessEntry32;
begin
Result := PROCESS_ERROR;
SnapShot := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
FillChar(ProcessEntry, SizeOf(ProcessEntry), 0);
ProcessEntry.dwSize := SizeOf(ProcessEntry);
Next := Process32First(SnapShot, ProcessEntry);
while Next do
begin
S := LowerCase(ProcessEntry.szExeFile);
if Pos(ProcName, S) > 0 then
begin
Result := ProcessEntry.th32ProcessID;
break;
end;
Next := Process32Next(SnapShot, ProcessEntry);
end;
CloseHandle(SnapShot);
end;

var
S: string;
begin
S := LowerCase(lpszProcName);
if IsTerminalServices then
Result := QueryWithWTS(S)
else
Result := QueryWithTool(S);
end;

procedure RaiseError(const S: string);
begin
raise Exception.CreateFmt(S, [SysErrorMessage(GetLastError)]);
end;

var
RemoteParam: Pointer = nil;
pRemoteThread: Pointer = nil;
dwRemoteProcess: DWORD = PROCESS_ERROR;

procedure SetCtrlAltDel(ThreadBuffer: Pointer; ThreadSize: DWORD;
LibInfo: Pointer; LibInfoCount: Integer; Inject: Boolean);
var
hRemoteThread: THandle;
Writen, RemoteProcess: DWORD;
begin
if dwRemoteProcess = PROCESS_ERROR then
dwRemoteProcess := GetPIDFromName(RemoteProcessName);
if dwRemoteProcess = PROCESS_ERROR then
RaiseError('Failed to query process ID.');
RemoteProcess := OpenProcess(PROCESS_ALL_ACCESS, False, dwRemoteProcess);
if RemoteProcess = 0 then
RaiseError('Failed to open process: %s');

{ 在远程线程分配内存来存放参数 }
if Assigned(RemoteParam) then
VirtualFreeEx(RemoteProcess, RemoteParam, 0, MEM_RELEASE);
RemoteParam := VirtualAllocEx(RemoteProcess, nil, LibInfoCount,
MEM_COMMIT, PAGE_READWRITE);
if not Assigned(RemoteParam) then
RaiseError('Failed to allocate memory at remote process for param,Err=%s');
if not WriteProcessMemory(RemoteProcess, RemoteParam, LibInfo,
LibInfoCount, Writen) then
RaiseError('Failed to write param to remote process, msg: %s');

{ 拷贝线程体 }
if Assigned(pRemoteThread) then
VirtualFreeEx(RemoteProcess, pRemoteThread, 0, MEM_RELEASE);
pRemoteThread := VirtualAllocEx(RemoteProcess, nil, ThreadSize,
MEM_COMMIT, PAGE_READWRITE);
if not Assigned(pRemoteThread) then
RaiseError('Failed to allocate memory at remote process for thread, code.Err: %s');
if not WriteProcessMemory(RemoteProcess, pRemoteThread, ThreadBuffer,
ThreadSize, Writen) then
RaiseError('Failed to write thread code to remote process code.Err: %s');

{ 启动远程线程 }
hRemoteThread := CreateRemoteThread(RemoteProcess, nil, 0, pRemoteThread,
RemoteParam, 0, Writen);
if hRemoteThread = 0 then
RaiseError('Failed to create unload thread.Err=%s');
WaitForSingleObject(hRemoteThread, INFINITE);
CloseHandle(hRemoteThread);

{ 读卸载返回值 }
if not ReadProcessMemory(RemoteProcess, RemoteParam, LibInfo,
LibInfoCount, Writen) then
RaiseError('Unable to read load return value.Err=%s')
else
begin
if (Inject and (PInjectLibInfo(LibInfo)^.dwReturnValue <> 0)) or
(not Inject and (PDeinjectLibInfo(LibInfo)^.dwReturnValue <> 0)) then
RaiseError('Failed to load library to Winlogon.Err=%s');
end;
end;
//---------------------------------------------------------------------------
// 插入代码
//---------------------------------------------------------------------------
procedure InjectFunc(const RemoteDllName: string);

procedure InitParam(Param: Pointer; const RemoteDllName: string);
var
Info: PInjectLibInfo;
begin
Info := PInjectLibInfo(Param);
FillChar(Info^, SizeOf(Info^), 0);
Move(RemoteDLLName[1], Info.szDllName[0], Length(RemoteDllName));
Info.pfnLoadLibrary := GetProcAddress(GetModuleHandle(Kernel32),
LoadLibraryFuncStr);
Info.pfnGetLastError := GetProcAddress(GetModuleHandle(Kernel32),
GetLastErrorFuncStr);
end;

var
InjectLibInfo: TInjectLibInfo;
ThreadSize: DWORD;
begin
{ 提升本进程权限然后打开目的进程 }
EnablePrivilege(SE_DEBUG_NAME, True);
try
InitParam(@InjectLibInfo, RemoteDllName);
ThreadSize := DWORD(@AfterThreadFuncAttach) - DWORD(@ThreadFuncAttach) +
1024 + SizeOf(InjectLibInfo);
SetCtrlAltDel(@ThreadFuncAttach, ThreadSize, @InjectLibInfo,
SizeOf(InjectLibInfo), True);
finally
{ 恢复权限 }
EnablePrivilege(SE_DEBUG_NAME, False);
end;
end;

//---------------------------------------------------------------------------
// 卸载线程
//---------------------------------------------------------------------------
procedure DeinjectFunc(const RemoteDllName: string);

procedure InitParam(Param: Pointer; const RemoteDllName: string);
var
Info: PDeinjectLibInfo;
begin
Info := PDeinjectLibInfo(Param);
FillChar(Info^, SizeOf(Info^), 0);
Info.pfnFreeLibrary := GetProcAddress(GetModuleHandle(Kernel32),
FreeLibraryFuncStr);
Info.pfnGetModuleHandle := GetProcAddress(GetModuleHandle(Kernel32),
GetModuleHandleFuncStr);
Info.pfnGetLastError := GetProcAddress(GetModuleHandle(Kernel32),
GetLastErrorFuncStr);
Move(RemoteDLLName[1], Info.szDllName, Length(RemoteDllName));
end;

var
DeinjectLibInfo: TDeinjectLibInfo;
ThreadSize: DWORD;
begin
{ 提升本进程权限然后打开目的进程 }
EnablePrivilege(SE_DEBUG_NAME, True);
try
InitParam(@DeinjectLibInfo, RemoteDllName);
ThreadSize := DWORD(@AfterThreadFuncDetach) - DWORD(@ThreadFuncDetach) +
1024 + SizeOf(DeinjectLibInfo);
SetCtrlAltDel(@ThreadFuncDetach, ThreadSize, @DeinjectLibInfo,
SizeOf(DeinjectLibInfo), False);
finally
{ 恢复权限 }
EnablePrivilege(SE_DEBUG_NAME, False);
end;
end;

{ TForm1 }
constructor TForm1.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
cbTaskList.Tag := TASK_LIST;
cbCAD.Tag := CTRL_ALT_DEL;
cbTaskMgr.Tag := TASK_MGR;
cbTaskKey.Tag := TASK_KEYS;
cbTaskBar.Tag := TASK_BAR;
FTaskList := False;
FTaskKey := False;
FCtrlAltDel := False;
FTaskBar := False;
FTaskMgr := False;
FRemoteDLL := ExtractFilePath(ParamStr(0)) + 'RemoteDll.Dll';
end;

destructor TForm1.Destroy;
begin
Disable(TASK_ALL, False, False);
if Assigned(RemoteParam) then
begin
VirtualFreeEx(dwRemoteProcess, RemoteParam, 0, MEM_RELEASE);
RemoteParam := nil;
end;
if Assigned(pRemoteThread) then
begin
VirtualFreeEx(dwRemoteProcess, pRemoteThread, 0, MEM_RELEASE);
pRemoteThread := nil;
end;
if dwRemoteProcess <> PROCESS_ERROR then
CloseHandle(dwRemoteProcess);
inherited Destroy;
end;

procedure TForm1.Disable(dwFlags: DWORD; Disabled, Beep: Boolean);
begin
if not IsWin2K then
raise Exception.Create('Work in W2K');
if (dwFlags and TASK_MGR) = TASK_MGR then
TaskMgr := Disabled;
if (dwFlags and TASK_KEYS) = TASK_KEYS then
TaskKey := Disabled;
if (dwFlags and TASK_BAR) = TASK_BAR then
TaskBar := Disabled;
if (dwFlags and TASK_List) = TASK_LIST then
TaskList := Disabled;
if (dwFlags and CTRL_ALT_DEL) = CTRL_ALT_DEL then
CtrlAltDel := Disabled;
end;

procedure TForm1.cbTaskListClick(Sender: TObject);
var
CheckBox: TCheckBox;
begin
CheckBox := TCheckBox(Sender);
Disable(CheckBox.Tag, CheckBox.Checked, False);
end;

procedure TForm1.SetTaskBar(const Value: Boolean);
var
Handle: THandle;
begin
if Value = FTaskBar then Exit;
Handle := FindWindow('Shell_traywnd', nil);
EnableWindow(Handle, not Value);
FTaskBar := Value;
end;

procedure TForm1.SetTaskKey(const Value: Boolean);
begin
if FTaskKey = Value then Exit;
FTaskKey := Value;
{ TaskKeyHook.dsw }
end;

procedure TForm1.SetTaskList(const Value: Boolean);
begin
if FTaskList = Value then Exit;
FTaskList := Value;
{ HookApi.dsw }
end;

procedure TForm1.SetTaskMgr(const Value: Boolean);
const
KEY_DisableTaskMgr = 'Software/Microsoft/Windows/CurrentVersion/Policies/System';
VAL_DisableTaskMgr = 'DisableTaskMgr';
begin
if FTaskMgr = Value then Exit;
with TRegistry.Create do
try
RootKey := HKEY_CURRENT_USER;
if OpenKey(KEY_DisableTaskMgr, False) then
WriteInteger(VAL_DisableTaskMgr, Integer(Value));
CloseKey;
FTaskMgr := Value;
finally
Free;
end;
end;

procedure TForm1.SetCtrlAltDel(const Value: Boolean);
begin
if FCtrlAltDel = Value then Exit;
if not FileExists(FRemoteDll) then
raise Exception.CreateFmt('file not find: %s', [FRemoteDll]);
if Value then
InjectFunc(FRemoteDll)
else
DeinjectFunc(FRemoteDll);
FCtrlAltDel := Value;
end;

end.

//Main.dfm
object Form1: TForm1
Left = 222
Top = 171
Width = 485
Height = 278
Caption = 'Form1'
Color = clBtnFace
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = '宋体'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 12
object Button2: TButton
Left = 32
Top = 216
Width = 75
Height = 25
Caption = 'E&xit'
TabOrder = 0
end
object cbTaskList: TCheckBox
Left = 32
Top = 56
Width = 401
Height = 25
Caption = 'Disable listing in Process List'
TabOrder = 1
OnClick = cbTaskListClick
end
object cbCAD: TCheckBox
Left = 32
Top = 88
Width = 409
Height = 17
Caption = 'Disable Ctrl+Alt+Delete'
TabOrder = 2
OnClick = cbTaskListClick
end
object cbTaskMgr: TCheckBox
Left = 32
Top = 112
Width = 401
Height = 25
Caption = 'Disable Task &Manager (winnt//system32//taskmgr.exe)'
TabOrder = 3
OnClick = cbTaskListClick
end
object cbTaskKey: TCheckBox
Left = 32
Top = 144
Width = 401
Height = 17
Caption = 'Disable Task &Keys (Alt-TAB, Ctl-Esc, Alt-Esc), Start Menu'
TabOrder = 4
OnClick = cbTaskListClick
end
object cbTaskBar: TCheckBox
Left = 32
Top = 168
Width = 409
Height = 25
Caption = 'Disable Task&bar'
TabOrder = 5
OnClick = cbTaskListClick
end
end
//////////////////////////////////////////////////////////////
CommonFunc.pas应该没改。

应该可以了。
 
哦,我直接使用了原来的RemoteDll.dll(要Copy到Exe的目录下)文件,那个文件我没去译,大概和上次的差不多吧。

除了CtrlAltDel功能外,其它的没搞了,懒的去了。有兴趣的继续吧。
 
library RemoteDll;

uses
SysUtils, Messages, Windows;

{$R *.res}
var
FOldProc: TFarProc;
SASHandle: THandle;

function SWSWindowProc(hwnd: THandle; uMsg: UINT;
wParam, lParam: Integer): Integer; stdcall;
var
wKey, wModifier: Word;
IsCtrlDown, IsAltDown, IsShiftDown: Boolean;
begin
{ 屏蔽Ctrl + Alt + Del }
if uMsg = WM_HOTKEY then
begin
wKey := HiWord(lParam);
wModifier := LoWord(lParam);
IsCtrlDown := (wModifier and VK_CONTROL) <> 0;
IsAltDown := (wModifier and VK_MENU) <> 0;
IsShiftDown := (wModifier and VK_SHIFT) <> 0;
{ 按下Ctrl + Alt + Del组合键 }
if IsCtrlDown and IsAltDown and (wKey = VK_DELETE) then
begin
Result := 1;
Exit;
end else
{ 按下Ctrl + Shift + Esc组合键,这个组合键将显示任务管理器,
可根据需要是否屏蔽。}
if IsCtrlDown and IsShiftDown and (wKey = VK_ESCAPE) then
begin
{ do nothing }
end;
end;
Result := CallWindowProc(FOldProc, hwnd, uMsg, wParam, lParam);
end;

{ 查找"Winlogon"桌面的窗口 }
function EnumWindowsProc(hwnd: THandle; Param: Integer): Boolean; stdcall;
var
Buffer: array [0..127] of Char;
begin
Result := True;
FillChar(Buffer, SizeOf(Buffer), 0);
if GetWindowText(hwnd, Buffer, SizeOf(Buffer)) > 0 then
begin
StrUpper(Buffer);
{ 我自己写了一个系统服务,然后在里边查询"Winlogon"桌面上的窗口,
发现桌面上存在窗口"SAS window"。 }
if Pos('SAS WINDOW', Buffer) > 0 then
begin
SASHandle := hwnd;
Result := False;
end;
end;
end;

function ThreadFunc(Param: Pointer): Integer; stdcall;
var
Desk: HDESK;
begin
Result := 1;
Desk := OpenDesktop('Winlongon', 0, False, MAXIMUM_ALLOWED);
FOldProc := nil;
SASHandle := 0;
EnumDesktopWindows(Desk, @EnumWindowsProc, 0);
if SASHandle <> 0 then
FOldProc := Pointer(SetWindowLong(SASHandle, GWL_WNDPROC, Integer(@SWSWindowProc)));
CloseHandle(Desk);
end;

var
Thread: THandle;
ThreadID: Cardinal;

procedure DLLExit(Reason: Integer);
begin
case Reason of
DLL_PROCESS_DETACH:
begin
if Assigned(FOldProc) then
SetWindowLong(SASHandle, GWL_WNDPROC, Integer(FOldProc));
CloseHandle(Thread);
end;
end;
end;

begin
Thread := CreateThread(nil, 0, @ThreadFunc, nil, 0, ThreadID);
DllProc := @DLLExit;
end.

这个是RemoteDLL。编绎后和上面的EXE组合起来就可以了

收工。
 
TO:copy_paste
謝謝你!………基本搞定!RemoteDll文件還有一點小小問題,程序關閉後有錯,會自動重啟!
沒關系!我自已看一下!你辛苦了:)
祝你在新的一年裡 三羊開泰……步步高升…請到這裡來領分……
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1615016
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1615019
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1603400

 
我那里好像没什么问题,不会重启。
不然你留MAIL给我,晚上我把我的程序和EXE,DLL发给你试试。(程序在家)
 
接受答案了……
 
TO:copy_paste
我的Email: ljy_17@163.com
我用VC的DLL是沒有錯!
用譯過來的Delphi的DLL就會有錯……
 
我昨天是都试过的,我那边都不会出错,倒是调试,重启了N次,说不清了。
晚上我发程序给你,你再看看。

哦我的机子:W2KServer + SP3, D7,D5也应该可以。
 
我的操作是Win2000P+sp3用的是D6
用VC的DLL運行成功調試狀態下沒有試過!
你用的是譯過來的DLL嗎?
 
不错,就是译过来的DLL文件,没有出错。
 
我修改了一下Main.pas,你将Main.pas部分的代码copy覆盖一下。
我加入了VirtualFreeEx释放Pointer的部分,原来的代码是没有的,所以翻译过来的也就没
有,刚加上去,没有试出错误。
 
我試過了,還是同樣的問題!
用你發過來的EXE文件運行沒有錯誤,但我重新編譯DLL文件之後,運行就會出錯!
你用D5、D7編譯DLL,難道說是編譯器的原因?我用的是D6!不解………
 
后退
顶部