在Delphi中隐藏程序进程的方法
在Delphi中隐藏程序进程方法[1]
主要需要解决两个问题,即隐藏窗口和设定热键。
一. 隐藏窗口
通过API函数GETACTIVEWINDOW获取当前窗口;函数ShowWindow(HWND,nCmdShow)的参数nCmdShow取SW_HIDE时将之隐藏,取SW_SHOW时将之显示。例如:
showwindow(getactivewindow,sw_hide)。隐藏好窗体后,须记住窗体句柄以便恢复。二. 键盘监控
为了实现键盘监控须用到钩子。
以下是程序的源文件:
一、创建一个动态链接库
unit HKHide; //链接库中的Unit文件
interface
uses
Windows, Messages, sysutils;
var
hNextHookHide: HHook;
HideSaveExit: Pointer;
hbefore:longint;
function KeyboardHookHandler(iCode: Integer;wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
function EnableHideHook: BOOL; export;
function DisableHideHook: BOOL; export;
procedure HideHookExit; far;
implementation
function KeyboardHookHandler(iCode: Integer;wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall; export;
const _KeyPressMask = $80000000;
var
f:textfile;
temp:string;
begin
Result := 0;
If iCode < 0 Then
begin
Result := CallNextHookEx(hNextHookHide, iCode, wParam, lParam); Exit;
end;
//侦测 Ctrl + Alt + F12 组合键
if ((lParam and _KeyPressMask) = 0) //按下时生效
and (GetKeyState(vk_Control) < 0)
and (getkeystate(vk_menu)<0)
and (wParam = vk_F12) then
begin
Result := 1;
//文件不存在则创建
if not fileexists('c:\test.txt') then
begin
assignfile(f,'c:\test.txt');
rewrite(f);
writeln(f,0);
closefile(f);
end
else
begin
assignfile(f,'c:\test.txt');
reset(f);
readln(f,temp);
hbefore:=strtoint(temp);
begin
hbefore:=getactivewindow;
temp:=inttostr(hbefore);
rewrite(f);
writeln(f,temp);
closefile(f);
ShowWindow(hbefore, SW_HIDE);
end;
end; //end if FileExists(....)
end
else begin
showwindow(hbefore,SW_SHOW);
rewrite(f);
writeln(f,0);
closefile(f);
end;//end if Ctrl+Alt+F12按键
end;
function EnableHideHook: BOOL; export;
begin
Result := False;
if hNextHookHide <> 0 then Exit;
// 挂上 WH_KEYBOARD 这型的 HOOK, 同时, 传回值必须保留下 // 来, 免得 HOOK 呼叫链结断掉
hNextHookHide := SetWindowsHookEx(WH_KEYBOARD,
KeyboardHookHandler,HInstance,0);
Result := hNextHookHide <> 0;
end;
function DisableHideHook: BOOL; export;
begin
if hNextHookHide <> 0 then
begin
Result:=True;
UnhookWindowshookEx(hNextHookHide); // 解除 Keyboard Hook hNextHookHide:=0;
end
else
Result:=False;
end;
procedure HideHookExit;
begin
// 如果忘了解除 HOOK, 自动代理解除的动作
if hNextHookHide <> 0 then DisableHideHook;
ExitProc := HideSaveExit;
end;
end.
library HKPHide; //动态链接库工程文件
uses
HKHide in HKHide.pas;
exports
EnableHideHook,
DisableHideHook;
begin
hNextHookHide := 0;
hbefore:=0;
HideSaveExit := ExitProc;
ExitProc := @HideHookExit;
end.
//文件制作好后先Build All编译成HKPHide.dll。
二、新建一个测试工程TestPrj
unit Unit1;//这是测试工程的窗体单元
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function EnableHideHook: BOOL; external 'HKPHide.DLL'; function DisableHideHook: BOOL; external 'HKPHide.DLL';
procedure TForm1.Button1Click(Sender: TObject);
begin
if EnableHideHook then
ShowMessage('HotKey Testing...');
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
if DisableHideHook then
ShowMessage('HotKey Testing..., DONE!);
end;
end.
DELPHI中隐藏程序进程,纯DELPHI代码方式,我在XP下通过测试。下面是隐藏进程的unit HideProcess
unit HideProcess;
interface
function MyHideProcess: Boolean;
implementation
uses
Windows, SysUtils, Variants, Classes, AclAPI, accCtrl;
type
NTSTATUS = LongInt;
const
//NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
STATUS_INFO_LENGTH_MISMATCH = NTSTATUS($C0000004);
STATUS_ACCESS_DENIED = NTSTATUS($C0000022);
OBJ_INHERIT = $00000002;
OBJ_PERMANENT = $00000010;
OBJ_EXCLUSIVE = $00000020;
OBJ_CASE_INSENSITIVE = $00000040;
OBJ_OPENIF = $00000080;
OBJ_OPENLINK = $00000100;
OBJ_KERNEL_HANDLE = $00000200;
OBJ_VALID_ATTRIBUTES = $000003F2;
type
PIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
IO_STATUS_BLOCK = record
Status: NTSTATUS;
FObject: DWORD;
end;
PUNICODE_STRING = ^UNICODE_STRING;
UNICODE_STRING = record
Length: Word;
MaximumLength: Word;
Buffer: PWideChar;
end;
POBJECT_ATTRIBUTES = ^OBJECT_ATTRIBUTES;
OBJECT_ATTRIBUTES = record
Length: DWORD;
RootDirectory: Pointer;
ObjectName: PUNICODE_STRING;
Attributes: DWORD;
SecurityDescriptor: Pointer;
SecurityQualityOfService: Pointer;
end;
TZwOpenSection = function(SectionHandle: PHandle;
DesiredAccess: ACCESS_MASK;
ObjectAttributes: POBJECT_ATTRIBUTES): NTSTATUS; stdcall;
TRTLINITUNICODESTRING = procedure(DestinationString: PUNICODE_STRING; SourceString: PWideChar); stdcall;
var
RtlInitUnicodeString: TRTLINITUNICODESTRING = nil;
ZwOpenSection: TZwOpenSection = nil;
g_hNtDLL: THandle = 0;
g_pMapPhysicalMemory: Pointer = nil;
g_hMPM: THandle = 0;
g_hMPM2: THandle = 0;
g_osvi: OSVERSIONINFO;
b_hide: Boolean = false;
//---------------------------------------------------------------------------
function InitNTDLL: Boolean;
begin
g_hNtDLL := LoadLibrary('ntdll.dll');
if 0 = g_hNtDLL then
begin
Result := false;
Exit;
end;
RtlInitUnicodeString := GetProcAddress(g_hNtDLL, 'RtlInitUnicodeString'); ZwOpenSection := GetProcAddress(g_hNtDLL, 'ZwOpenSection');
Result := True;
end;
//---------------------------------------------------------------------------
procedure CloseNTDLL;
begin
if (0 <> g_hNtDLL) then
FreeLibrary(g_hNtDLL);
g_hNtDLL := 0;
end;
//---------------------------------------------------------------------------
procedure SetPhyscialMemorySectionCanBeWrited(hSection: THandle);
var
pDacl: PACL;
pSD: PPSECURITY_DESCRIPTOR;
pNewDacl: PACL;
dwRes: DWORD;
ea: EXPLICIT_ACCESS;
begin
pDacl := nil;
pSD := nil;
pNewDacl := nil;
dwRes := GetSecurityInfo(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, pDacl, nil, pSD);
if ERROR_SUCCESS <> dwRes then
begin
if Assigned(pSD) then
LocalFree(Hlocal(pSD^));
if Assigned(pNewDacl) then
LocalFree(HLocal(pNewDacl));
end;
ZeroMemory(@ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions := SECTION_MAP_WRITE;
ea.grfAccessMode := GRANT_ACCESS;
ea.grfInheritance := NO_INHERITANCE;
ea.Trustee.TrusteeForm := TRUSTEE_IS_NAME;
ea.Trustee.TrusteeType := TRUSTEE_IS_USER;
ea.Trustee.ptstrName := 'CURRENT_USER';
dwRes := SetEntriesInAcl(1, @ea, pDacl, pNewDacl);
if ERROR_SUCCESS <> dwRes then
begin
if Assigned(pSD) then
LocalFree(Hlocal(pSD^));
if Assigned(pNewDacl) then
LocalFree(HLocal(pNewDacl));
end;
dwRes := SetSecurityInfo
(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, pNewDacl, nil);
if ERROR_SUCCESS <> dwRes then
begin
if Assigned(pSD) then
LocalFree(Hlocal(pSD^));
if Assigned(pNewDacl) then
LocalFree(HLocal(pNewDacl));
end;
end;
//---------------------------------------------------------------------------
function OpenPhysicalMemory: THandle;
var
status: NTSTATUS;
physmemString: UNICODE_STRING;
attributes: OBJECT_ATTRIBUTES;
PhyDirectory: DWORD;
begin
g_osvi.dwOSVersionInfoSize := sizeof(OSVERSIONINFO);
GetVersionEx(g_osvi);
if (5 <> g_osvi.dwMajorVersion) then
begin
Result := 0;
Exit;
end;
case g_osvi.dwMinorVersion of
0: PhyDirectory := $30000;
1: PhyDirectory := $39000;
else
begin
Result := 0;
Exit;
end;
end;
RtlInitUnicodeString(@physmemString, '\Device\PhysicalMemory');
attributes.Length := SizeOf(OBJECT_ATTRIBUTES);
attributes.RootDirectory := nil;
attributes.ObjectName := @physmemString;
attributes.Attributes := 0;
attributes.SecurityDescriptor := nil;
attributes.SecurityQualityOfService := nil;
status := ZwOpenSection(@g_hMPM, SECTION_MAP_READ or SECTION_MAP_WRITE, @attributes);
if (status = STATUS_ACCESS_DENIED) then
begin
ZwOpenSection(@g_hMPM, READ_CONTROL or WRITE_DAC, @attributes); SetPhyscialMemorySectionCanBeWrited(g_hMPM);
CloseHandle(g_hMPM);
status := ZwOpenSection(@g_hMPM, SECTION_MAP_READ or SECTION_MAP_WRITE,
@attributes);
end;
if not (LongInt(status) >= 0) then
begin
Result := 0;
Exit;
end;
g_pMapPhysicalMemory := MapViewOfFile(g_hMPM,
FILE_MAP_READ or FILE_MAP_WRITE, 0, PhyDirectory, $1000);
if (g_pMapPhysicalMemory = nil) then
begin
Result := 0;
Exit;
end;
Result := g_hMPM;
end;
//--------------------------------------------------------------------------- function LinearToPhys(BaseAddress: PULONG; addr: Pointer): Pointer;
var
VAddr, PGDE, PTE, PAddr, tmp: DWORD;
begin
VAddr := DWORD(addr);
// PGDE := BaseAddress[VAddr shr 22];
PGDE := PULONG(DWORD(BaseAddress) + (VAddr shr 22) * SizeOf(ULONG))^; // Modify by dot.
if 0 = (PGDE and 1) then
begin
Result := nil;
Exit;
end;
tmp := PGDE and $00000080;
if (0 <> tmp) then
begin
PAddr := (PGDE and $FFC00000) + (VAddr and $003FFFFF);
end
else
begin
PGDE := DWORD(MapViewOfFile(g_hMPM, 4, 0, PGDE and $FFFFF000, $1000));
// PTE := (PDWORD(PGDE))[(VAddr and $003FF000) shr 12];
PTE := PDWORD(PGDE + ((VAddr and $003FF000) shr 12) * SizeOf(DWord))^; // Modify by dot.
if (0 = (PTE and 1)) then
begin
Result := nil;
Exit;
end;
PAddr := (PTE and $FFFFF000) + (VAddr and $00000FFF);
UnmapViewOfFile(Pointer(PGDE));
end;
Result := Pointer(PAddr);
end;
//---------------------------------------------------------------------------
function GetData(addr: Pointer): DWORD;
var
phys, ret: DWORD;
tmp: PDWORD;
begin
phys := ULONG(LinearToPhys(g_pMapPhysicalMemory, Pointer(addr)));
tmp := PDWORD(MapViewOfFile(g_hMPM, FILE_MAP_READ or FILE_MAP_WRITE, 0,
phys and $FFFFF000, $1000));
if (nil = tmp) then
begin
Result := 0;
Exit;
end;
// ret := tmp[(phys and $FFF) shr 2];
ret := PDWORD(DWORD(tmp) + ((phys and $FFF) shr 2) * SizeOf(DWord))^; // Modify by dot.
UnmapViewOfFile(tmp);
Result := ret;
end;
//---------------------------------------------------------------------------
function SetData(addr: Pointer; data: DWORD): Boolean;
var
phys: DWORD;
tmp: PDWORD;
begin
phys := ULONG(LinearToPhys(g_pMapPhysicalMemory, Pointer(addr)));
tmp := PDWORD(MapViewOfFile(g_hMPM, FILE_MAP_WRITE, 0, phys and $FFFFF000, $1000));
if (nil = tmp) then
begin
Result := false;
Exit;
end;
// tmp[(phys and $FFF) shr 2] := data;
PDWORD(DWORD(tmp) + ((phys and $FFF) shr 2) * SizeOf(DWord))^ := data; // Modify by dot.
UnmapViewOfFile(tmp);
Result := TRUE;
end;
//--------------------------------------------------------------------------- {long __stdcall exeception(struct _EXCEPTION_POINTERS *tmp)
begin
ExitProcess(0);
return 1 ;
end }
//---------------------------------------------------------------------------
function YHideProcess: Boolean;
var
thread, process: DWORD;
fw, bw: DWORD;
begin
// SetUnhandledExceptionFilter(exeception);
if (FALSE = InitNTDLL) then
begin
Result := FALSE;
Exit;
end;
if (0 = OpenPhysicalMemory) then
begin
Result := FALSE;
Exit;
end;
thread := GetData(Pointer($FFDFF124)); //kteb
process := GetData(Pointer(thread + $44)); //kpeb
if (0 = g_osvi.dwMinorVersion) then
begin
fw := GetData(Pointer(process + $A0));
bw := GetData(Pointer(process + $A4));
SetData(Pointer(fw + 4), bw);
SetData(Pointer(bw), fw);
Result := TRUE;
end
else if (1 = g_osvi.dwMinorVersion) then
begin
fw := GetData(Pointer(process + $88));
bw := GetData(Pointer(process + $8C));
SetData(Pointer(fw + 4), bw);
SetData(Pointer(bw), fw);
Result := TRUE;
end
else
begin
Result := False;
end;
CloseHandle(g_hMPM);
CloseNTDLL;
end;
function MyHideProcess: Boolean; begin
if not b_hide then
begin
b_hide := YHideProcess;
end;
Result := b_hide;
end;
end.
用法:
implementation
uses HideProcess;
过程调用
begin
MyHideProcess;
....
end;
异常死亡进程的自动复活
[作者: 上海三吉电子工程有限公司卓乃奇]
一、问题的产生
我们或多或少都有这样的经历,在Windows上运行的应用程序常常会异常终止,需要通过手工重新将其启动起来。若计算机无人看守,异常终止的进程不能实时启动,则可能给生产造成损失。
本人在开发GPS全球卫星定位系统控制中心程序时,就遇到过控制中心程序异常终止死亡的情况,由此,找出了一个自动复活死亡进程的方法,供参考。
二、相关知识
通常,把一个应用程序的一次运行实例叫做一个进程,在一个进程内又可包含多条可并发执行的路径,每条执行路径叫做一个线程,一个进程至少包含一个主线程。主线程负责执行运行的启动代码。另外,一个进程可以创建若干子进程。当进程被创建时,系统自动产生主线程,主线程然后可创建更多的线程。
我们可以编写一个程序,让其创建、启动子进程,并监视进程的运行情况,在其出现异常终止时,立即重新创建并启动子进程即可。
三、相关函数
1、创建一个子进程函数:
BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);
参数说明:
lpApplicationName:新进程将要使用的可执行文件的名字,必须包含扩展名。LpCommandLine:新进程的命令行。若lpApplicationName为NULL,LpCommandLine 的第一个参数是新进程将要使用的可执行文件的名字,可以不包含扩展名,系统假定是exe文件。LpProcessAttributes和lpThreadAttributes:分别是给进程对象和线程对象指定的安全属
性。
BInheritHandles:指定该进程是否继承其父进程中的句柄。
dwCreationFlags:指定新进程产生方式的标志,可用逻辑操作符or相连接。LpEnvironment:指向含有新进程将要使用的环境块字符串的一块内存,一般为NULL,使子进程继承父进程的一组环境块。
LpCurrentDirectory:设置子进程的当前驱动器和工作目录, 为NULL,子进程继承父进程的当前驱动器和工作目录。
LpStartupInfo:指向STARTUPINFO 的结构。一般让子进程使用缺省值。但要把该结构中的所有成员初始化为0,并设置cb为结构大小。
STARTUPINFO 结构如下:
typedef struct _STARTUPINFO {
DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
} STARTUPINFO, *LPSTARTUPINFO;
lpProcessInformation 参数指向LPPROCESS_INFORMATION结构,CreateProcess在返回之前,填入有关子进程的信息,父进程正是利用该信息监测子进程是否终止。该结构如下:typedef struct _PROCESS_INFORMATION {
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
} PROCESS_INFORMATION;
hProcess和hThread分别是子进程的句柄和子进程的主线程的句柄,dwProcessId和dwThreadId分别是子进程的标识号和子进程的主线程的标识号。
2、子进程终止检测函数
GetEXitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode );
Hprocess:进程句柄,lpExitCode:进程终止时的退出码。
如果一个进程没有终止,lpExitCode 的返回值是STILL_ACTIVE,否则返回其他值。
四、方法的Delphi语言实现
1、创建一个新的项目 Project1
选择File,New Application。在表单Form1上放一Memo组件,一个OK按钮组件,改变OK 按钮组件的Cation属性为 CreateProcess。再放一个timer组件。设置timer组件的Interval值为1000,每秒检查一次进程是否终止。
2、在Unit1 Use节的Type后定义一个过程
procedure EstablishProcess;
在Unit1 Use节的Var后定义一个变量:
piProcInfoGPS:PROCESS_INFORMATION;
3、在Unit1 implementation节中编写EstablishProcess过程的实现代码如下:procedure EstablishProcess;
Var
siStartupInfo:STARTUPINFO;
saProcess,saThread:SECURITY_ATTRIBUTES;
fSuccess:boolean;
begin
fSuccess:=false;
ZeroMemory(@siStartupInfo,sizeof(siStartupInfo));
siStartupInfo.cb:=sizeof(siStartupInfo);
saProcess.nLength:=sizeof(saProcess);
saProcess.lpSecurityDescriptor:=PChar(nil);
saProcess.bInheritHandle:=true;
saThread.nLength:=sizeof(saThread);
saThread.lpSecurityDescriptor:=PChar(nil);
saThread.bInheritHandle:=true;
fSuccess:=CreateProcess(PChar(nil),'c:\sr350\Sr350buff',@saProcess,@saThread ,false,
CREATE_DEFAULT_ERROR_MODE,Pchar(nil),Pchar(nil),siStartupInfo,piProcInfoGPS); if( not fSuccess)then
Form1.Memo1.Lines.Add('Create Process Sr350buff fail.')
else
Form1.Memo1.Lines.Add('Create Process Sr350buff success.')
end;
4、在CreateProcess按钮的OnClick事件中调用过程
EstablishProcess;
5、为Timer1的OnTimer事件编写代码:
Procedure TForm1.Timer1Timer(Sender: TObject);
Var
dwExitCode:DWORD;
fprocessExit:boolean;
Begin
dwExitCode:=0;
fprocessExit:=false;
fprocessExit:=GetExitCodeProcess(piProcInfoGPS.hProcess,dwExitCode);
if(fprocessExit and (dwExitCode<>STILL_ACTIVE))then
begin
Memo1.Lines.Add('SR350buff.exe进程终止');
CloseHandle(piProcInfoGPS.hThread);
CloseHandle(piProcInfoGPS.hProcess);
EstablishProcess;
end;
End;
6、程序中设可执行文件名为c:\sr350\sr350buff.exe,所以c:盘\sr350目录下需有
sr350buff.exe文件。
7、编译联接,运行project1,单击CreateProcess可见c:\sr350\sr350buff.exe启动。
关掉sr350buff.exe进程,可见sr350buff.exe自动再启动。
浅谈Delphi中进程间的数据共享
https://www.360docs.net/doc/47487146.html, 2005年08月11日09:10 天极yesky
DLL是创建Windows应用程序,实现代码重用的重要手段。那么当我们需要在进程间共享数据时,怎样做才能快捷方便地实现呢?在32位应用系统中,每个应用程序会将DLL映射到自己的地址空间,同时DLL中的数据也就随之被映射了。这样,每个应用程序都有自己
的数据实例,在一个应用程序中修改DLL中的全局变量,不会影响其它的应用程序。DLL 的使用似乎与我们的目的相背离,那么如何才能实现我们想要的东东呢?这里给大家介绍一
种特殊的技术,那就是内存映射文件。
内存映射文件提供了一种方法,就是在WIN32系统的地址空间保留一块内存区域,物理存储可以向其中提交。并且内存映射文件不只是磁盘文件,也可以是WIN32的页面文件,而且后者比前者要好,因为这意味着可以像访问一个磁盘文件那样访问内存中的一个区域,而不用创建临时文件,用完后还得删除它。WIN32有自己的管理页面调度文件,当不需要页面调度文件时,系统会自动将有关区域释放。以下是具体的实现代码:
delphi制作多文档界面
最为一个巩固之前有关窗体和对象的有关知识,下面就建立一个简单的MDI示范程序,这个程序的功能是打开和保存图形文件(包括位图、图标等),为了完成这个任务,我们有一个大概的计划,计划内容如下: (1)建立主窗体(一个MDI父窗体),包括菜单。 (2)为【File | Open…】和【File | Save…】菜单选项编写代码。 (3)为Windows菜单上的Cascade、Tile和Arrange All选项编写代码。 (4)建立MDI子窗体。 (5)建立一个About对话框。 (6)然后再回忆和欣赏一下这段工作。 时间就是金钱,即刻就做吧。 一、创建主窗口窗体 首先创建一个主窗口窗体,一个MDI应用程序的主窗口的FormStyle属性必须设置为fsMDIForm。不但要为应用程序增加File Open和File Save 对话框,还要增加一个菜单。 1、启动Delphi,并从主菜单选择【File | New | Application】; 2、把主窗体的Name属性设置为MainForm; 3、把Caption属性设置为Picture Viewer; 4、把FormStyle属性设置为fsMDIForm; 好了,下面为此窗体增加一个菜单,利用Delphi特性,引进一个预定义菜单,具体如下:1、点击组件选项板的Standard标签,并点击MainMenu按钮;
2、把MainMenu组件点击放置到窗体上,具体放到哪个地方无所谓了,因为在运行阶段,代表菜单的图标只是占地方而不显示,这是非可视化组件。 3、把MainMenu组件Name属性改为MainMenu; 4、双击MainMenu组件,就会出现Menu Designer对话框; 5、在MainMenu上点击鼠标右键,选择“Insert From Template…”,将出现Insert Template对话框;
delphi制作登陆界面
///////////////////// (一)项目文件 test.dpr ////////////////////// program SerialGet; uses Forms, UMain in UMain.pas {frmMain}, ULogin in ULogin.pas {frmLogin}, UDataModule in UDataModule.pas {DataModule1: TDataModule}, {$R *.res} begin Application.Initialize; if CreateMutex then //创建句柄,判断此应用程序是否在运行 begin //调用全局函数,创建并显示登陆界面 if doLogin then //登陆成功 begin Application.CreateForm(TfrmMain, frmMain); //数据模块文件不须在这儿创建,因为 ULogin.pas 中已创建 //Application.CreateForm(TDataModule1, DataModule1); Application.Run; end else //登陆不成功 begin try DataModule1.free; Application.terminate; except end; end; end else begin DestroyMutex; //释放句柄 end; end. //////////////// (二)登陆窗体 ULogin.pas ULogin.dfm ////////////////// unit ULogin; interface uses ...... type ... ... ...
用delphi设计图书管理系统
《数据库技术与应用》 大作业 题目:数据库应用系统的设计和实现 适用专业: 指导老师: 班级: 姓名: 学号: 中南大学信息科学与工程学院 2010 年1月
图书是人类文明的见证,随着高科技的发展各式各样图书越来越多,图书馆和书店的管理也越来越复杂。如今图书管理系统是一 个书店或一个图书馆的必备系统。一个安全可靠并且对于用户比较实用的图书管理系统来说变得尤其重要。 本次设计设计了一个在DELPHI平台基于SQL Server 2000开发出的图书管理系统。在系统的设计上面实现了该系统的交互式界面。 从系统的需求分析、系统设计、系统实现入手,详细阐述了一个 C/S 结构的图书管理信息系统主要功能的实现过程。每一阶段均给 出了相应的理论依据和实现内容,并介绍了系统实现部分的主要算法。整个系统的设计与开发严格按照软件工程思想进行,从需求分析到系统设计和实现、从原型系统设计到迭代完善,本图书管理系统涵盖了六个主要的子系统:图书资料管理、读者资料管理、借书 操作、还书操作、删除、修改和查询处理,提高了工作的准确率和效率。 本图书管理信息系统是利用计算机管理信息处理的迅速、准确、可靠且具有强大存储能力的突出特点,全面提高图书馆的管理水平 和工作效率,并以及时、完整的业务经营资料,为图书馆的及时转换提供一定的支持。
关键词:数据库,SQL server2000,Delphi 7,图书管理系统 1.1 课题研究现状分析 在现金信息化发达的社会,图书的发行量与日俱增。因此需要对书籍资源、读者资源、借书信息、还书信息进行管理,及时了解各个环节中信息的变更,有利用管理效率的提高。传统的图书馆需要制作有署名与对应编号的书卡,由读者按分类查找再交由图书管理员来处理借书工作,还书也要人工翻阅大量的记录,这样使得工作量大并及其繁琐,效率变得低下。建立网上电子图书管理系统的目的是实现无纸化图书管理,减轻管理员的工作量,方便读者查阅所需的图书,还可以利用网络实现提醒读者还书的功能。管理员还可以对各种图书进行分析统计,对过时、损坏的图书进行删除。达到降低成本提高工作效率的目标。 1.1.1本领域内已开展的研究工作 1. 理论研究基础 (1)数据库设计方法的完整化、多样化,又有多学科的综合性。 (2)数据库设计步骤的规范化和细致化。 (3)数据库技术不断的更新,并不断增加新的技术,兼容性范围也逐渐扩大。2. 技术层面的支持 SQL Server的普遍应用,并得到的用户的支持,与Windows操作系统的完全兼容性也决定了它在今天仍然有着庞大的使用群体。SQL Server2000作为后台数据库与前台开发软件Visual Basic、C#、Visual C++、Delphi等都能够无缝连接。 1.1.2已经取得的研究成果 (1)开发出了一套系统的数据库理论,安全性、完整性、并发性、恢复性都有完整的概述。 (2)随着Internet的迅猛发展,数据库在各个领域作为后台存储得到了广泛的 支持。 (3)完善的数据库管理并与前台开发软件的结合使用开发了一系列优秀的图书管理系统,在商业、经济等方面得到了广泛的应用。
delphi可视化编程讲稿
第三章D e l p h i的窗体与组件 教学要求: 掌握窗体、编辑类组件、按钮类控件、列表类控件、分组类组件、时钟组件、菜单组件、工具栏组件和工具按钮、多选项卡的的属性、方法与事件,学会使用这些组件设计应用程序的界面。 掌握ShowMessage、ShowMessageFmt、MassageDlg、MassageDlgPos、InputBox、InputQuery对话框函数与对话框过程的特点,并能熟练应用。熟悉公共对话框控件组件的属性,方法、事件及应用。 掌握创建新窗体的两种不同的方法及其应用。 掌握windows的模式与非模式窗体的概念及应用方法。 掌握焦点的含义,与焦点相关的属性,应用焦点设计程序的方法。 了解CreateMessageDialog函数的定义与用法、speedbutton和文件有关的控件的属性、方法与事件。
从本章开始,将介绍Delphi 编程的一些基本方法。通过这一部分的学习,可以了解开发Windows 环境下应用程序的一些关键技术,并可以方便、快捷地开发一般的应用程序。 为了简化编程工作,Delphi 提供了许多功能强大的函数和类。其中很重要的一部分就是组件类。本章将重点介绍常见组件及其编程应用。 现在深入普及的Windows操作系统中,方便快捷的人机交互界面主要是通过窗体和对话框实现的。在Delphi中,这些窗体和对话框就是程序设计阶段的窗体,Delphi的可视化设计工作就是在窗体中进行的。 通常,窗体中会有文字输入、滚动条、复选框、单选框、按钮等一系列组件,通过这些直观易懂的组件,可以方便的实现多种多样的功能。在Delphi中,这些运行期间出现在窗体和对话框中的组件称为可视组件。在窗体中,还可以放置一些运行期间非可视的组件,对应其它的TComponent子类。这些不可视组件集中地实现了一些特殊的功能。比如,时钟控制等功能。 ●TComponent组件类,所有的组件都是由这个类派生来的。 ●TControl子类(可视组件)可分为两类:窗体组件和图 形组件。
delphi的精美界面设计
Delphi界面设计专辑 [前言:]界面的美观和用户亲和性是应用软件成功的首要条件,因此界面往往是程序员最费心的地方。在这个专辑中,将向读者全面介绍Delphi中界面设计的原则和技巧 窗体设计 制作固定大小的Form 固定的Form像一个对话框,何不试试下面的语句 巧用Delphi制作溅射屏幕 精心编写的WINDOWS程序显示启动注意事项,称之为溅射屏幕(splash screen)。利用一点儿小小的内容,即可给程序的显示添加不少色彩 LED数码管仿真显示程序 在电子设备上广泛地使用LED数码管显示数据,在许多应用软件中也经常模拟LED数码管显示数据,使程序画面看起来很有特色 菜单设计 DELPHI中自适应表单的实现 我们知道,屏幕分辨率的设置影响着表单布局,假设你的机器上屏幕分辨率是800*600,而最终要分发应用的机器分辨率为640*480,或1024*768,这样你原先设计的表单在新机器上势必会走样 作非常规程序菜单掌握delphi高级秘籍 大家可能见过诸如金山毒霸,瑞星杀毒,以及五笔输入法等等在系统托盘(即右下角有时间和输入法图标的地方)在的控制菜单,而在正常的任务栏(即屏幕最下方的“开始”按钮的右边的各式各样)中却不出现按钮的程序,即我们常说的在后台运行的程序 用Delphi制作动态菜单 所谓动态菜单是指菜单项随着程序的操作变化而变化。现在,我们用Delphi来实现这一功能,具体步骤如下 工具栏和状态条 为Windows窗口标题栏添加新按钮 对于我们熟悉的标准windows窗口来讲,标题栏上一般包含有3个按钮,即最大化按钮,最小化按钮和关闭按钮。你想不想在Windows的窗口标题栏上添加一个新的自定义按钮用Delphi4实现风Word97格的工具栏 用过Word97的人对它的工具栏印象很深刻,因为它的风格很“酷”,同样IE4.0的工具栏也有类似的风格,Win98的出现,使这种风格的工具栏得到了推广 如何隐藏和显示Windows的任务条 如果隐藏和显示Windows的任务条?仅仅调用以下的函数就可以. 其他技巧 Delphi利用Windows GDI实现文字倾斜 在Delphi开发环境中,文字的输出效果一般都是头上脚下的"正统"字符,如何输出带有一定倾斜角度的文字以达到特殊的显示效果呢 Delphi之三十六计之界面篇 设置状态栏面板对象的Style为OwnerDraw,并在状态栏对象的DrawPanel事件中书写以下代码 利用COM技术实现外壳扩展的属性页 当用户在资源管理器中调用右键菜单时,会显示一个"属性"菜单项,点击属性菜单项会显
Delphi用BusinessSkinForm 做界面皮肤的使用说明
Delphi用BusinessSkinForm 做界面皮肤的使用说明 注意:新版的Delphi 已经用bsCompressedStoredSkin 代替了bsStoredSkin 1、先放bsBusinessSkinForm、bsSkinData、bsStoredSkin(bsCompressedStoredSkin)各一个到窗体上 2、修改bsBusinessSkinForm的SkinData属性为bsSkinData1 3、修改bsSkinData1的StoredSkin属性为bsStoredSkin1 4、修改bsStoredSkin1的filename属性,指向一个皮肤文件,例如我的55套皮肤包是放在C:\Program Files\Borland\Delphi7\BSF-Skins\Skins文件夹里,我就修改 bsStoredSkin1的filename属性为C:\Program Files\Borland\Delphi7\BSF-Skins\Skins\Animate\skin.ini 5、在delphi设计窗口中按下F9 6、爽吧!!!!! 第一步-安装: 1、双击BSFD7.dpk文件,在delphi 7.0中打开 2、单击compile按钮,你会发现原来不可用的install按钮可以使用了 3、单击install按钮,会弹出来一个对话框提示你“安装成功!” 4、将所有源文件复制到C:\Program Files\Borland\Delphi7\Lib文件夹中(如delphi安装路径不同的话,请各位老兄自行更改) 第二步-最基本的使用方法: 当你安装成功后,你会在delphi的组件面板上发现三个控件组,它们是: businessskinform vcl和businessskinform db vcl和businessskinform vcl dialogs,顾名思义,第一个是常用组件,第二个是数据库组件,第三个是对话框组件。 按照下面的步骤,不用写一行代码,你可以马上做出一个有漂亮界面的程序来 1、先放bsBusinessSkinForm、bsSkinData、bsStoredSkin(在businessskinform vcl控件组中)各一个到窗体上 2、修改bsBusinessSkinForm的SkinData属性为bsSkinData1 3、修改bsSkinData1的StoredSkin属性为bsStoredSkin1
Delphi XE FireMonkey 自带Demo体验与效果图
Delphi XE FireMonkey Demo体验与效果图 版本:Delphi XE6 FireMonkey DEMO:delphi FireMonkey自带 DEMO路径,在DELPHI XE6安装目录下:E:\Documents and Settings\All Users\Documents\Embarcadero\Studio\14.0\Samples 1●TabSlideTransition(分页可滑动翻页) 功能:每页可填写,并支持可滑动翻页 路径:Samples\Object Pascal\Mobile Samples\User Interface\TabSlideTransition 开启界面:
2●TabletMasterDetailWithSearch(查找联系人,定位,并显示明细) 功能:可以查找列表联系人,并定位,和显示明细 路径:Samples\Object Pascal\Mobile Samples\User Interface\TabletMasterDetailWithSearch 开启界面:
3●Settings Project(系统设置) 功能:打开USB调试,WIFI等设置 路径:Samples\Object Pascal\Mobile Samples\User Interface\Settings Project 开启界面:
4●ScrollableForm(滚动编辑框) 功能:滚动编辑框 路径:Samples\Object Pascal\Mobile Samples\User Interface\ScrollableForm 开启界面: