使用API如何写出稳定的系统托盘程序? ( 积分: 100 )

  • 主题发起人 主题发起人 sy0116
  • 开始时间 开始时间
S

sy0116

Unregistered / Unconfirmed
GUEST, unregistred user!
我想要写一个系统托盘程序,只需要显示一个小图标,然后如果用右键点击一下就弹出一个菜单,找到了一段这样的代码,我试验过后发现这样确实可以实现我想要的功能,但是程序运行一、两个小时后右键菜单就显示不出来了,在显示不出右键菜单时TrackPopupMenu函数虽然返回True,但是我通过GetLastError函数发现有错误ERROR_INVALID_HANDLE,而前面CreatePopupMenu却没有任何错误。代码中的MyDll.dll只需要LoadLibrary就会开启两个线程用TextOutA函数在屏幕上不断的输出文字。<br>program&nbsp;Shell;<br><br>uses<br>&nbsp;&nbsp;Windows,ShellAPI,Messages,SysUtils;<br><br>{$R&nbsp;ShellCPU.res}<br>const<br>&nbsp;&nbsp;ClassName='myownclassname';<br><br>var<br>&nbsp;&nbsp;msg:TMsg;<br>&nbsp;&nbsp;WndClass:TWndClassA;<br>&nbsp;&nbsp;hWnd,hPop:THandle;<br>&nbsp;&nbsp;hMap:THandle;<br>&nbsp;&nbsp;pBool:Pointer;<br>&nbsp;&nbsp;ShowUsage:BOOL;<br>&nbsp;&nbsp;WM_TASKBARCREATED:Cardinal;<br>&nbsp;&nbsp;PopText:PChar;<br>&nbsp;&nbsp;NotifyData:&nbsp;NOTIFYICONDATA;<br>&nbsp;&nbsp;bInit:BOOL;<br>procedure&nbsp;Shell_AddICON(Add:Boolean=True);<br>begin<br>&nbsp;&nbsp;with&nbsp;NotifyData&nbsp;do<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;cbSize:=SizeOf(NotifyData);<br>&nbsp;&nbsp;&nbsp;&nbsp;Wnd:=hWnd;<br>&nbsp;&nbsp;&nbsp;&nbsp;uID:=&nbsp;0;<br>&nbsp;&nbsp;&nbsp;&nbsp;uFlags:=NIF_MESSAGE&nbsp;or&nbsp;NIF_ICON;<br>&nbsp;&nbsp;&nbsp;&nbsp;uCallbackMessage:=WM_USER+888;<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;if&nbsp;Add&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;Shell_NotifyIcon(NIM_ADD,@NotifyData)<br>&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;Shell_NotifyIcon(NIM_DELETE,@NotifyData);<br>end;<br>procedure&nbsp;InitShare;<br>begin<br>&nbsp;&nbsp;hMap:=CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(Bool),'myinformation');<br>&nbsp;&nbsp;pBool:=MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0,0);<br>&nbsp;&nbsp;CopyMemory(pBool,@ShowUsage,SizeOf(BOOL));<br>end;<br><br>procedure&nbsp;WriteShare;<br>begin<br>&nbsp;&nbsp;CopyMemory(pBool,@ShowUsage,SizeOf(BOOL));<br>end;&nbsp;&nbsp;<br><br>function&nbsp;MainWndProc(HWin:&nbsp;THandle;&nbsp;MsgID:&nbsp;UINT;&nbsp;wParam,&nbsp;lParam:&nbsp;Integer):&nbsp;LRESULT;&nbsp;stdcall;<br>var<br>&nbsp;&nbsp;iButton:Integer;<br>&nbsp;&nbsp;hdcS:HDC;<br>&nbsp;&nbsp;dwErr:DWORD;<br>&nbsp;&nbsp;tpCurrentPoint:TPoint;<br>begin<br>&nbsp;&nbsp;case&nbsp;MsgID&nbsp;of<br>&nbsp;&nbsp;&nbsp;&nbsp;WM_CREATE:<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WM_TASKBARCREATED:=RegisterWindowMessage('TaskbarCreated');<br>&nbsp;&nbsp;&nbsp;&nbsp;end;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;WM_CLOSE:<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UnmapViewOfFile(pBool);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CloseHandle(hMap);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DestroyWindow(hWnd);<br>&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;&nbsp;&nbsp;WM_DESTROY:<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostQuitMessage(0);<br>&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;&nbsp;&nbsp;WM_USER+888:<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;((wParam=0)&nbsp;and&nbsp;(lParam=$201))&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ShowUsage:=not&nbsp;ShowUsage;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteShare;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;((wParam=0)&nbsp;and&nbsp;(lParam=$205))&nbsp;then//在图标上按了右键<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hPop:=CreatePopupMenu;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AppendMenu(hPop,MF_STRING,1,'退出');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AppendMenu(hPop,MF_SEPARATOR,9,nil);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetForegroundWindow(HWin);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetCursorPos(tpCurrentPoint);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;ShowUsage=True&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PopText:=PChar('不显示')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PopText:=PChar('显示');<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AppendMenu(hPop,MF_CHANGE&nbsp;or&nbsp;MF_STRING,2,PopText);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iButton:=Integer(TrackPopupMenu(hPop,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TPM_LEFTALIGN&nbsp;&nbsp;or&nbsp;TPM_LEFTBUTTON,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tpCurrentPoint.X,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tpCurrentPoint.y,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hWnd,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nil));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DestroyMenu(hPop);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;if&nbsp;MsgID=&nbsp;WM_COMMAND&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;iButton:=wParam;<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;iButton=1&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Shell_AddICON(False);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExitProcess(0);<br>&nbsp;&nbsp;&nbsp;&nbsp;end<br>&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;if&nbsp;iButton=2&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ShowUsage:=not&nbsp;ShowUsage;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WriteShare;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;ShowUsage&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NotifyData.hIcon:=LoadIcon(HInstance,'TRAYH')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NotifyData.hIcon:=LoadIcon(HInstance,'TRAYS');<br>&nbsp;&nbsp;&nbsp;&nbsp;end;<br>&nbsp;&nbsp;&nbsp;&nbsp;Shell_NotifyIcon(NIM_MODIFY,@NotifyData);<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;if&nbsp;MsgID=WM_TASKBARCREATED&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;Shell_AddICON;<br>&nbsp;&nbsp;end;&nbsp;&nbsp;<br>&nbsp;&nbsp;Result:=DefWindowProc(HWin,MsgID,wParam,lParam);<br>end;<br><br>begin<br>&nbsp;&nbsp;if&nbsp;ParamStr(1)='f'&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;ShowUsage:=False;<br>&nbsp;&nbsp;&nbsp;&nbsp;NotifyData.hIcon:=LoadIcon(HInstance,'TRAYS');<br>&nbsp;&nbsp;end<br><br>&nbsp;&nbsp;else<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;ShowUsage:=True;<br>&nbsp;&nbsp;&nbsp;&nbsp;NotifyData.hIcon:=LoadIcon(HInstance,'TRAYH');<br>&nbsp;&nbsp;end;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;with&nbsp;WndClass&nbsp;do<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;style:=CS_HREDRAW&nbsp;or&nbsp;CS_VREDRAW;<br>&nbsp;&nbsp;&nbsp;&nbsp;lpfnWndProc:=@MainWndProc;<br>&nbsp;&nbsp;&nbsp;&nbsp;hInstance:=&nbsp;sysinit.HInstance;<br>&nbsp;&nbsp;&nbsp;&nbsp;hIcon:=LoadIcon(0,PChar(IDI_APPLICATION));<br>&nbsp;&nbsp;&nbsp;&nbsp;hCursor:=LoadCursor(0,IDC_ARROW);<br>&nbsp;&nbsp;&nbsp;&nbsp;hbrBackground:=GetStockObject(WHITE_BRUSH);<br>&nbsp;&nbsp;&nbsp;&nbsp;lpszClassName:=ClassName;<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;if&nbsp;RegisterClass(WndClass)=0&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;ExitProcess(0);<br>&nbsp;&nbsp;hWnd:=CreateWindowEx(0,PChar(ClassName),'Shell',WS_OVERLAPPED,0,0,100,100,0,0,hInstance,nil);<br>&nbsp;&nbsp;if&nbsp;hWnd=0&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;MessageBox(0,'无法创建窗口!','错误',0);<br>&nbsp;&nbsp;&nbsp;&nbsp;ExitProcess(0);<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;InitShare;<br>&nbsp;&nbsp;Shell_AddICON;<br>&nbsp;&nbsp;LoadLibrary('MyDll.dll');<br>&nbsp;&nbsp;while&nbsp;GetMessage(msg,0,0,0)&nbsp;do<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;TranslateMessage(msg);<br>&nbsp;&nbsp;&nbsp;&nbsp;DispatchMessage(msg);<br>&nbsp;&nbsp;end;<br>end.
 
我建議先找些資料查查。
 
又发现一个最新现象,就是时间长了后虽然菜单显示不出来,但是如果在菜单所在的位置上点击鼠标却发现相应的功能是可以执行的,也就是说,菜单确实是弹出来了,但是看不见它
 
终于找出问题所在了:真正的问题竟是出在那个DLL文件上,我找到写DLL的人,看了源码后发现DLL文件中一个函数通过CreateFont获得了一个HFONT,但是函数结束时没有DeleteObject,而这个函数是循环调用的,所以一段时间后GDI句柄用光了(通过Process&nbsp;&nbsp;&nbsp;Explorer可以看到),所以菜单无法绘制出来,但是在相应的位置上点击去仍然有效
 
接受答案了.
 

Similar threads

后退
顶部