¿¹Àü¿¡ ¸¶¿ì½º Æ÷ÀÎÅ͸¦ Æ®·¹ÀÌÂÊÀ¸·Î ¿Å°Ü¼ Áö¿öÁÖ´Â ¼Ò½º°¡ ÀÖ¾ú´Âµ¥
´©°¡ Àß ¾ÈµÈ´Ù°í Çؼ ´Ù½Ã ¸¸µé¾ú½À´Ï´Ù.
¼Ò½º´Â ¼ÀÇà ÄÚµå¶ó Á» ÁöÀúºÐÇÕ´Ï´Ù.
TB_BUTTONCOUNT ¸Þ½ÃÁö·Î Æ®·¹ÀÌ ¾ÆÀÌÄÜ °¹¼ö¸¦ ¾ò°í
TB_GETBUTTON À¸·Î ¹öÆ° ±¸Á¶Ã¼¸¦ ¾ò¾î¼ ProcessID¸¦ ±¸ÇÏ°í
ProcessID°¡ ºñ¾î ÀÖ´Â(¾²·¹±â) ¾ÆÀÌÄÜÀ»
Shell_NotifyIcon(NIM_DELETE, @icon); API·Î Á÷Á¢ Á¦°ÅÇÕ´Ï´Ù.
64ºñÆ®¶û 32ºñÆ®´Â ±¸Á¶Ã¼°¡ Á¶±Ý ´Þ¶ó¼
ÇÔ¼ö°¡ µÎ°³¿©¿ä.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TIsWow64Process = function (hProcess: THANDLE; Wow64Process: PBOOL): BOOL; stdcall;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
//=========================================================
// ±¸Á¶Ã¼ Á¤ÀÇ
//=========================================================
TRAYDATA = packed record
wnd: HWND;
uID: UINT;
uCallbackMessage: UINT;
Reserved: array [0..1] of DWORD;
hIcon: HICON;
end;
TBBUTTON = packed record
iBitmap: Integer;
idCommand: Integer;
fsState: BYTE;
fsStyle: BYTE;
bReserved: array [0..1] of BYTE; // padding for alignment
dwData: Pointer; //DWORD_PTR;
iString: Pointer; //INT_PTR;
end;
TBBUTTON64 = packed record
iBitmap: Integer;
idCommand: Integer;
fsState: BYTE;
fsStyle: BYTE;
bReserved: array [0..5] of BYTE; // padding for alignment 64bit
dwData: Pointer; //DWORD_PTR;
iString: Pointer; //INT_PTR;
end;
const
TB_BUTTONCOUNT = WM_USER + 24;
TB_GETBUTTON = WM_USER + 23;
var
Form1: TForm1;
IsWow64Process: TIsWow64Process;
implementation
{$R *.dfm}
uses
ShellAPI;
//=========================================================
// Tray ¾ÆÀÌÄÜÀÇ ÇÁ·Î¼¼½º À̸§À» ¾ò±â À§ÇØ À©µµ¿ì ÇÚµéÀ» ¾ò´Â ÇÔ¼ö
//=========================================================
function FindTrayToolbarWindow: HWND;
var
hWnd_ToolbarWindow32: HWND;
hWnd_ShellTrayWnd: HWND;
hWnd_TrayNotifyWnd: HWND;
hWnd_SysPager: HWND;
begin
hWnd_ToolbarWindow32 := 0;
hWnd_ShellTrayWnd := FindWindow('Shell_TrayWnd', nil);
if hWnd_ShellTrayWnd <> 0 then begin
hWnd_TrayNotifyWnd := FindWindowEx(hWnd_ShellTrayWnd, 0, 'TrayNotifyWnd', nil);
if hWnd_TrayNotifyWnd <> 0 then begin
hWnd_SysPager := FindWindowEx(hWnd_TrayNotifyWnd, 0,'SysPager', nil); // WinXP
// WinXP ¿¡¼´Â SysPager ±îÁö ÃßÀû
if hWnd_SysPager <> 0 then begin
hWnd_ToolbarWindow32 := FindWindowEx(hWnd_SysPager, 0, 'ToolbarWindow32', nil);
end else begin
// Win2000 ÀÏ °æ¿ì¿¡´Â SysPager °¡ ¾øÀÌ TrayNotifyWnd -> ToolbarWindow32 ·Î ³Ñ¾î°£´Ù
hWnd_ToolbarWindow32 := FindWindowEx(hWnd_TrayNotifyWnd, 0,'ToolbarWindow32', nil);
end;
end;
end;
Result := hWnd_ToolbarWindow32;
end;
//=========================================================
// Refresh ÀÇ ¸ÞÀÎ
//=========================================================
function ShellTrayIconRefresh32: Boolean;
var
m_hProcess: THANDLE;
m_lpData: ^TBBUTTON;
tb: TBBUTTON;
tray: TRAYDATA; //NOTIFYICONDATA; //
dwTrayPid: DWORD;
TrayCount: Integer;
m_hTrayWnd: HWND;
i: Integer;
read: Cardinal;
dwProcessId: DWORD;
icon: NOTIFYICONDATA;
aRes: Integer;
begin
try
// Tray ÀÇ À©µµ¿ì ÇÚµé ¾ò±â
m_hTrayWnd := FindTrayToolbarWindow();
if m_hTrayWnd = 0 then begin
Result := False;
Exit;
end;
// Tray ÀÇ °³¼ö¸¦ ±¸ÇÏ°í
TrayCount := SendMessage(m_hTrayWnd, TB_BUTTONCOUNT, 0, 0);
// Tray À©µµ¿ì ÇÚµéÀÇ PID ¸¦ ±¸ÇÑ´Ù
GetWindowThreadProcessId(m_hTrayWnd, dwTrayPid);
// ÇØ´ç Tray ÀÇ Process ¸¦ ¿¾î¼ ¸Þ¸ð¸®¸¦ ÇÒ´çÇÑ´Ù
m_hProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTrayPid);
if m_hProcess = 0 then begin
Result := False;
Exit;
end;
// ÇØ´ç ÇÁ·Î¼¼½º ³»¿¡ ¸Þ¸ð¸®¸¦ ÇÒ´ç
m_lpData := VirtualAllocEx(m_hProcess, nil, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);
if m_lpData = nil then begin
Result := False;
Exit;
end;
// Tray ¸¸Å »±»±ÀÌ
for i := TrayCount - 1 downto 0 do begin
aRes := SendMessage(m_hTrayWnd, TB_GETBUTTON, i, Integer(m_lpData));
if aRes = 0 then
Continue;
// TBBUTTON ÀÇ ±¸Á¶Ã¼¿Í TRAYDATA ÀÇ ³»¿ëÀ» ¾ò±â
ReadProcessMemory(m_hProcess, m_lpData, @tb, sizeof(TBBUTTON), read);
ReadProcessMemory(m_hProcess, tb.dwData, @tray, sizeof(tray), read);
// °¢°¢ Æ®·¹ÀÌÀÇ ÇÁ·Î¼¼½º ¹øÈ£¸¦ ¾ò¾î¼
dwProcessId := 0;
GetWindowThreadProcessId(tray.Wnd, dwProcessId);
// Process °¡ ¾ø´Â °æ¿ì TrayIcon À» »èÁ¦ÇÑ´Ù
if dwProcessId = 0 then begin
icon.cbSize