怎样实现程序后台执行(100分)

  • 主题发起人 主题发起人 zkkzjj
  • 开始时间 开始时间
Z

zkkzjj

Unregistered / Unconfirmed
GUEST, unregistred user!
就是说,想超级解霸一样,
在后台,就是WIN98右手边出现小图标
的地方,这样可以让,计算机一开机就
执行他,并且可以随时等待执行?
 
开机执行:
修改注册表:HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Run
加入要运行的程序.
在WIN98右手边出现小图标:
用api函数 *shell* (忘了,待查)
 
看了标题还以为是HOOK:)
<--
 
》用api函数 *shell* (忘了,待查)
Shell_NotifyIcon
 
不知道下面我写的是否真确!
User Registry;
Var
RegF:TRegistry;
begin
RegF:=TRegistry.Create;
RegF.RootKey:=HKEY_LOCAL_MACHINE;
try
RegF.OpenKey('SOFTWARE/Microsoft/Windows/CurrentVersion/Run',True);
RegF.WriteString('名字', '"添加文件的具体路径和名字"');

except
End;
RegF.Close;
RegF.Free;
end;
 
给应用程序做个连接,把连接放在启动组里
 
还可以放在win.ini下的load 和run ,还有winstart.bat
你可以用控件的
 
; //找到托盘所在父窗口
hparent := Findwindow(Pchar('Shell_TrayWnd'),nil);
//找到托盘窗口
h := FindWindowEx(hp,0,Pchar('TrayNotifyWnd'),nil);
//在上面加窗口
hbutton:=CreateWindow('Button','test',WS_VISIBLE or
WS_CHILD,0,0,100,100,h,0,0,nil);
这只是个例子,你可以加一个正常点的窗口,然后setwindowlong
为他设定处理程序入口,ok?
 
zkkzjj写的挺对的呀,另外trayicon可以用控件,一些书也有,以前也讨论过吧
 
写个小程序让它隐藏起来,把它注册到
HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Run
注册如下代码
procedure Tform1.FormCreate(Sender: TObject);
var
RegF:TRegistry;
begin
RegF:=TRegistry.Create;
RegF.RootKey:=HKEY_LOCAL_MACHINE;
try
RegF.OpenKey('SOFTWARE/Microsoft/Windows/CurrentVersion/Run',True);
RegF.WriteString(application.Title,
application.ExeName);

except
// ...
End;
RegF.CloseKey;
RegF.Free;
end;

让它检测光趋,并通知你的主程序(用winexec)启动。
关于隐藏已多次介绍可以:
Client.Left := Screen.Width + 100; //窗体不可见
Client.Top := Screen.Height + 100;
试一下,相信一定可以实现!!!
hamburger@sina.com与我联系,共同解决。
 
开机自动运行的方法,前人已经说过了。
一个任务栏应用程序非常象普通的应用程序,它有一个消息循环,
相应Windows的消息来完成相应的功能。
Procedure RunTrayApplication;
Var Msg : TMsg;
Begin
CreateWindow;
AddTrayIcon;
While GetMessage(Msg,0,0,0) do Begin
TranslateMessage(Msg);
DispatchMessage(Msg);
End;
DeleteTrayIcon;
End;
需要做的工作只是创建一个窗口,注册一个图标到任务栏,设置它的消息循环,
最后关闭它。其他功能自便。
实际上,这个窗口是不能在任务栏上能见到的窗口。
Procedure CreateWindow;
Var
WC : TWndClass;
W : hWnd;
Begin
With WC do Begin
Style := 0;
lpfnWndProc := @WndProc;
cbClsExtra := 0;
cbWndExtra := 0;
hIcon := 0;
hCursor := 0;
hbrBackground := 0;
lpszMenuName := nil;
lpszClassName := 'MyTrayIconClass';
hInstance := System.hInstance;
end;
RegisterClass(WC);
W := Windows.CreateWindow('MyTrayIconClass','MyVeryOwnTrayIconWindow',
ws_OverlappedWindow,0,0,0,0,0,0,hInstance,nil);
ShowWindow(W,sw_Hide);
UpdateWindow(W);
MainWindow := W;
End;
这个窗口使用普通的窗口函数创建。注意这个窗口的类型是“ws_OverlappedWindow”,
但是这个尺寸是0,并且它是隐藏的,所有,它将不会显示出来。
注册我们的图标。这将需要使用Shell_NotifyIcon这个API函数,
这个函数实际上可以完成三个功能,这里只需要它的增加的特性。

Procedure AddTrayIcon;
Var IconData : TNotifyIconData;
Begin
With IconData do Begin
cbSize := SizeOf(IconData);
Wnd := MainWindow;
uID := 0;
uFlags := nif_Icon Or nif_Message Or nif_Tip;
uCallBackMessage := wm_MyCallBack;
hIcon := LoadIcon(hInstance,'MYICON');
StrCopy(szTip,PChar(TrayIconTip));
End;
Shell_NotifyIcon(nim_Add,@IconData);
End;
这个最重要的事情是TNotifyIconData的数据结构,
它是一个设置Window句柄的数据结构,是一个记录参数,
对我们来说,我们需要设置这个图标的窗口句柄(这将定义哪个窗口处理消息循环),
回调消息号,图标,工具提示等。
一旦这个数据设置了,我们就可以增加一个图标到任务栏上了。
为了完成这个工作,使用nim_Add程序。
我们已经加了我们的图标到任务栏,下面需要决定如何处理消息。
Const
wm_MyCallback = wm_User+1000;
cm_Exit = 100; { we worry about... }
cm_About = 101; { ...these later }
这个实际的窗口处理过程也是相当普通。几个窗口消息(如wm_NCCreate)必须处理。
然而,对我们来说,更重要的事情是处理wm_MyCallback和wm_Command消息:
Function WndProc(Window : hWnd; Msg,WParam,LParam : Integer): Integer; StdCall;
Begin
Result := 0;
Case Msg of
wm_NCCreate : Result := 1;
wm_Destroy : PostQuitMessage(0);
wm_Command : Begin { a command was chosen from the popup menu }
If (WParam = cm_Exit) Then
PostMessage(Window,wm_Destroy,0,0)
Else If (WParam = cm_About) Then
MessageBox(0,'Shell Test Copyright ?'+
'Jani J鋜vinen 1996.',
'About Shell Test',mb_OK)
Else OpenDesktopIcon(WParam-cm_About);
End;
wm_MyCallback : Begin { our icon was clicked }
If (LParam = wm_LButtonDown) Then
ShowIconPopupMenu
Else If (LParam = wm_RButtonDown) Then
ShowAboutPopupMenu;
End;
Else Result := DefWindowProc(Window,Msg,WParam,LParam);
End;
End;
就象你看到的一样,当用户单击图标时,Windows提示我们。
注意我们不使用通常使用的wm_LButtonDown(单击左键) 消息,
而使用wm_MyCallback message,
详细的消息信息存储在LParam参数中。
当用户单击鼠标右键,我们创建一个菜单在桌面上。
Type
TIconData = Array[1..100] of String;
Var
IconData : TIconData;
Procedure ShowIconPopupMenu;
Var
ShellFolder : IShellFolder;
EnumIDList : IEnumIDList;
Result : hResult;
Dummy : ULong;
ItemIDList : TItemIDList;
Pntr : PItemIDList;
StrRet : TStrRet;
PopupMenu : hMenu;
ItemID : Integer;
Pos : TPoint;
Procedure AddToMenu(Item : String);
Var S : String;
Begin
IconData[ItemID-cm_About] := Item;
S := ExtractFileName(Item);
If (System.Pos('.',S) <> 0) Then SetLength(S,System.Pos('.',S)-1);
AppendMenu(PopupMenu,mf_Enabled Or mf_String,ItemID,PChar(S));
Inc(ItemID);
End;
begin
PopupMenu := CreatePopupMenu;
ItemID := cm_About+1;
SHGetDesktopFolder(ShellFolder);
ShellFolder.EnumObjects(MainWindow,SHCONTF_NONFOLDERS,EnumIDList);
Pntr := @ItemIDList;
Result := EnumIDList.Next(1,Pntr,Dummy);
While (Result = NoError) do Begin
ShellFolder.GetDisplayNameOf(Pntr,SHGDN_FORPARSING,@StrRet);
With StrRet do AddToMenu(String(CStr));
Result := EnumIDList.Next(1,Pntr,Dummy);
End;
EnumIDList.Release;
ShellFolder.Release;
GetCursorPos(Pos);
AppendMenu(PopupMenu,mf_Separator,0,'');
AppendMenu(PopupMenu,mf_Enabled Or mf_String,cm_Exit,'E&xit');
SetForegroundWindow(MainWindow);
TrackPopupMenu(PopupMenu,tpm_LeftAlign Or tpm_LeftButton,
Pos.X,Pos.Y,0,MainWindow,nil);
DestroyMenu(PopupMenu);
end;
首先,我们使用SHGetDesktopForlder函数得到使用桌面的IShellFolder接口。
使用这个接口,我们能得到另一个接口的实例:IEnumIDList。
这个接口通常实现实际的列举工作。
我们简单的重复调用这个函数直到错误值返回(例如:所有的菜单被列举)。
当我们得到一个菜单,我们使用AddToMenu函数加它。
当所有的菜单被列举和创建后,现在我们需要运行这个菜单。我们将找到的菜单保存到一个全局的List变量中,每一个菜单都拥有它的菜单号。这确保我们能得到它的索引。
OpenDesktopIcon(WParam-cm_About)
当然,WParam中储存了用户单击鼠标的菜单的菜单号(ID)。
下面我们将处理运行用户选择的菜单。
Procedure OpenDesktopIcon(Number : Integer);
Var
S : String;
I : Integer;
begin
S := IconData[Number];
I := ShellExecute(0,nil,PChar(S),nil,nil,sw_ShowNormal);
If (I < 32) Then Begin
S := 'Could not open selected item "'+S+'". '+
'Result was: '+IntToStr(I)+'.';
MessageBox(0,PChar(S),'Shell Test',mb_OK);
End;
end;
上面,Win 32 API函数ShellExecute做了所有的工作。
这方面的例子很多。
 
多人接受答案了。
 
后退
顶部