2009-12-28 1 views
2

여러 가지 이유로 시스템 트레이 아이콘을 사용하여 필자가 작성한 (Delphi에서) 몇 가지 오래된 응용 프로그램이 있습니다. 대부분 AppControls TacTrayIcon 또는 다른 유사한 구성 요소를 사용하고 있습니다.Windows 시스템 트레이 아이콘 - 위치 제어

여기 내 질문이 있습니다. 트레이 아이콘은 어떻게 제어하나요? (즉, 시스템 시간과 관련하여 - 제 1 위치/"슬롯", 제 2 위치/"슬롯"등). 사용자가 "왼쪽으로 아이콘을 이동"하고 "오른쪽으로 아이콘을 이동"할 수있는 데모 (C#, 메모리가 작동하는 경우)를 보았지만 어떻게 수행되었는지는 기억하지 못합니다.

사용자가 Windows 2000 - Windows 7에서 아이콘을 표시 할 위치를 선택할 수있게하고 싶습니다. (Windows 7은 시스템 트레이 관련 정보를 조금 다르게 처리하지만 그 것을 테스트하지는 않았습니다. 밖으로 아직).

도움 주셔서 감사합니다.

+15

Windows API에서 해결책을 찾을 수 없을 때마다 그럴만 한 이유가 있는지 여부를 묻는 것이 좋습니다. 정확한 일치는 아니지만 일반적인 아이디어는 http://blogs.msdn.com/oldnewthing/archive/2006/11/01/922449.aspx를 참조하십시오.어쩌면 트레이 아이콘이있는 여러 가지 이유를 다시 생각해 봐야 할 것입니다. 그리고 그 이유가 참으로 좋다면 좋은 아이콘을 제시하고 그 위치를 혼자 두십시오. – mghie

+0

@mghie - 귀하가 제공 한 링크와 의견의 톤을 모두 유추하는 것이 아니라 사용자가 제어하는 ​​설정을 도용하거나 침입하려고한다는 것을 암시하는 것입니다. 그건 사실이 아니야. * 사용자가 아이콘 위치를 제어 할 수 있도록하기 위해 노력하고 있는데, Windows (XP)가 직접 요청하지 않았기 때문에 아이콘 위치를 쉽게 제어 할 수있다. 다른 곳에서. – Jamo

+0

@ Jamo : 미안 해요, 아무 것도 함축하지 않았습니다. Windows API는 거대하며 같은 목적을 달성하는 데 여러 가지 방법이 있습니다. 뭔가를 성취 할 준비가 된 방법이 없다면, 목적을 달성하지 못하는 것보다 더 자주 있습니다. 물론 사용자가 제어하는 ​​설정에 개입하지 않아도됩니다. 고객이 제어 할 의도가없는 것을 제어하도록 요청할 수 있습니다. – mghie

답변

10

프로그램이 셸 알림 아이콘의 위치를 ​​제어하는 ​​방법에 대해 문서화되거나 지원되지 않습니다. 그들이 전혀 나타나지 않거나, 나타나면 시계 근처의 아무 곳에 나 나타나서 포지셔닝 지시가 의미가 있다는 것을 보장하지 않습니다.

(전 아이콘 일부 또는 전부를 가로 채고 시계가 아닌 자신의 창에 선택적으로 표시 한 프로그램을 사용했습니다.) Mike Lin의 TraySaver입니다. 그의 해킹이 어떻게 작동하는지보고 싶다.)

아이콘의 위치는 사용자 제어에 의해 결정되지 않습니다. 내 충고는 프로그램의 책임이 아니라, 특히 처음부터 프로그램에서 그러한 기능을 실제로 요구 한 사람이 없다면 말이다. 사람들이 프로그램의 아이콘 위치를 제어하고 싶다면 다른 프로그램의 아이콘 위치를 제어하고 싶을 수도 있습니다.이 경우 문제는 여러분보다 큽니다.

+2

정당한 답변을 주셔서 감사합니다. 단지 판단/판단의 비난보다는 바람직합니다. 이것은 실제로 사용자가 요청하는 기능입니다. 그러나 내 앱이 문제는 아니라는 점에 동의합니다. TraySaver 코드를 살펴 보겠습니다. 다시 한번 감사드립니다. – Jamo

6

셸 알림 영역에 액세스하고 수정하는 것은 어렵지만 가능합니다. 먼저 최상위 창을 찾을 필요가 :

var 
    Wnd: HWND; 
begin 
    Wnd := FindWindow('Shell_TrayWnd', nil); 
    if IsWindow(Wnd) then 
    EnumChildWindows(Wnd, @FindTrayWnd, 0); 
end; 

다음 트레이 알림 영역을 찾기 위해 아이를 열거 :
function FindTrayWnd(AWnd: HWND; AParam: LPARAM): BOOL; stdcall; 
var 
    ClassName: string; 
begin 
    SetLength(ClassName, 64); 
    SetLength(ClassName, GetClassName(AWnd, PChar(ClassName), 64)); 
    Result := True; 
    if AnsiCompareText(ClassName, 'TrayNotifyWnd') = 0 then begin 
    EnumChildWindows(AWnd, @FindToolbar, 0); 
    Result := False; 
    end; 
end; 

다음 알림 아이콘 표준 Windows 도구 모음을 찾기 위해 아이를 열거합니다. Windows 메시지는 도구 모음 속성을 가져 오거나 설정하는 데 사용됩니다.

function FindToolbar(AWnd: HWND; AParam: LPARAM): BOOL; stdcall; 
const 
    VMFLAGS = PROCESS_VM_OPERATION or PROCESS_VM_READ or PROCESS_VM_WRITE; 
var 
    ClassName: string; 
    i, ButtonCount: integer; 
    ProcessId, BytesRead: Cardinal; 
    ProcessHandle: THandle; 
    ExplorerButtonInfo: PTBButton; 
    ButtonInfo: array of TTBButton; 
begin 
    SetLength(ClassName, 64); 
    SetLength(ClassName, GetClassName(AWnd, PChar(ClassName), 64)); 
    if AnsiCompareText(ClassName, 'ToolbarWindow32') = 0 then begin 
    GetWindowThreadProcessId(AWnd, @ProcessId); 
    ProcessHandle := OpenProcess(VMFLAGS, FALSE, ProcessId); 
    ExplorerButtonInfo := VirtualAllocEx(ProcessHandle, nil, SizeOf(TTBButton), 
     MEM_RESERVE or MEM_COMMIT, PAGE_READWRITE); 
    if ExplorerButtonInfo <> nil then try 
     ButtonCount := SendMessage(AWnd, TB_BUTTONCOUNT, 0, 0); 
     SetLength(ButtonInfo, ButtonCount); 
     for i := 0 to ButtonCount - 1 do begin 
     SendMessage(AWnd, TB_GETBUTTON, i, LPARAM(ExplorerButtonInfo)); 
     ReadProcessMemory(ProcessHandle, ExplorerButtonInfo, @ButtonInfo[i], 
      SizeOf(TTBButton), BytesRead); 
     end; 
     // manipulate the button info, use WriteProcessMemory() and SendMessage() 
     // to repopulate the toolbar 

    finally 
     VirtualFreeEx(ProcessId, ExplorerButtonInfo, SizeOf(TTBButton), 
     MEM_RELEASE); 
    end; 
    Result := False; 
    end else 
    Result := True; 
end; 

당신은 버튼을 식별 할 수 있어야한다 : 툴바가 다른 프로세스에 살고 있기 때문에 당신은 (버튼의 텍스트 나 버튼 정보를 받고 같은) 어떤 종류의 버퍼를 포함하는 모든 메시지에 대한 ReadProcessMemory()WriteProcessMemory()를 고용 할 필요가 알림 아이콘의 이름을 클릭 한 다음 해당 버튼을 삭제하고 원하는 위치에 삽입하십시오. 모든 오류 처리가 생략되었지만 시작해야합니다.

+0

mghie,이 게시물을 게시 할 시간을 내 주셔서 감사 드리며 귀하의 종류와 명확한 위임 사항에 대해서도 감사드립니다. 정말 감사드립니다. (매우 그렇다!). "고객이 통제 할 수없는 무언가를 통제 할 것을 고객이 요구합니다." 사용자가 직접 Windows에서 "제어 할 수있는"것이 아니라는 점에서 이상하게 보입니다. 응용 프로그램에 의해 프로그래밍 방식으로 프로그래밍되지 않았더라도, Chen과 같이 연결된 문서를 참조하십시오. – Jamo

1

this article on CodeProject을 보면 도움이되기를 바랍니다.

이 솔루션은 호환성이 매우 낮으므로 권장하지 않습니다.

+0

아 ~ 고마워! 그건 내가 전에 보았던 프로젝트이지만, 찾는 데 어려움을 겪고 있었다. 포인트 지적 다시 : "전혀 권장하지 않음"; 신중히 연구 할 것입니다. ;) – Jamo

+0

Ок. 이 작업에 필요한 다른 프로세스 및 사용자 권한의 메모리를 읽는 데주의하십시오. 또 다른 한 가지는 이러한 활동을 모니터링하는 바이러스 백신 소프트웨어입니다. – ThinkJet