Ballon Tipps bei TNA Icon

Ich hab folgenden Code aus der DP...http://www.delphipraxis.net/post3004.html
Ich bin genau nach Anleitung vorgegangen, um da nix zu verhunzen, doch leider erkennt der Compiler am Ende diese 3 Zeilen nicht...
Code:
    IconData.szInfo     := 'Ein Beispiel für einen neuen Balloon-Tipp,' +
      #13#10 + 'der auch mehrzeilig sein kann.';
    IconData.szInfoTitle := 'Taskbar-Demo';
    IconData.dwInfoFlags := NIIF_INFO;

"Undefinierter Bezeichner: szInfo, szInfoTitle, dwInfoFlags"
Allerdings sind diese Konstanten in der ShellAPI eingetragen und die ShellAPI steht bei den Uses dabei, trotzdem kennt er die Variablen nicht...

Auszug aus meiner ShellAPI:
Code:
  _NOTIFYICONDATAW = record  
    cbSize: DWORD;  
    Wnd: HWND;  
    uID: UINT;  
    uFlags: UINT;  
    uCallbackMessage: UINT;  
    hIcon: HICON;  
    szTip: array [0..127] of WideChar;  
    dwState: DWORD;  
    dwStateMask: DWORD;  
    szInfo: array[0..255]of WideChar;  
    case integer of  
      0: (uTimeout: UINT);  
      1: (uVersion: UINT;  
          szInfoTitle: array[0..63]of WideChar;  
          dwInfoFlags: DWORD;  
          guidItem : TGuid;  
         )  
  end;

Wenn ich mit Strg + Klick auf die Deklaration meines IconData gehe, springt er in die ShellAPI zu obigem Auszug.Wo liegt der Fehler? Ich hab keine Ahnung...
 
Zuletzt bearbeitet:

CSANecromancer

Erfahrenes Mitglied
Ist ein bißchen wenig Code, den du da gepostet hast. Gibt es vielleicht irgendwelche Konflikte mit einer with-Klausel? Sind die Sichtbarkeiten gegeben? Alle Konstruktoren aufgerufen?
 
Also with-Klausel hab ich gar keine und mit den anderen 2 Tipps von dir kann ich leider nix anfangen, weil ich sie nicht verstehe :D

Ich schmeiß mal den ganzen Source in die Runde,dazu häng ich noch meine ShellAPI an, vielleicht sieht jemand etwas ;)

Code:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls,
  imGauge,QDialogs,ShlObj,ShellAPI,ActiveX, SsBase, StAbout, StShlCtl,
  Menus, XPMan,ddlversion;
type
  TMainForm = class(TForm)
    GroupBox1: TGroupBox;
    Label1: TLabel;
    Edit1: TEdit;
    Button1: TButton;
    GroupBox2: TGroupBox;
    Log: TMemo;
    Progress1: TimGauge;
    ProgressTimer: TTimer;
    Status: TStatusBar;
    Notfier: TStShellNotification;
    MainMenu1: TMainMenu;
    Programm1: TMenuItem;
    Info1: TMenuItem;
    berSpitzel1: TMenuItem;
    spyon: TMenuItem;
    N1: TMenuItem;
    Programmbeenden1: TMenuItem;
    ZumTrayiconminimieren1: TMenuItem;
    PopupMenu1: TPopupMenu;
    Hauptfensteranzeigen1: TMenuItem;
    spychecker: TMenuItem;
    N2: TMenuItem;
    Programmbeenden2: TMenuItem;
    XPManifest1: TXPManifest;
    procedure ProgressTimerTimer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure NotfierFileCreate(Sender: TObject; ShellItem: TStShellItem);
    procedure NotfierFileDelete(Sender: TObject; OldShellItem,
      NewShellItem: TStShellItem);
    procedure NotfierFileRename(Sender: TObject; OldShellItem,
      NewShellItem: TStShellItem);
    procedure NotfierFolderCreate(Sender: TObject;
      ShellItem: TStShellItem);
    procedure NotfierFolderDelete(Sender: TObject;
      ShellItem: TStShellItem);
    procedure NotfierFolderRename(Sender: TObject; OldShellItem,
      NewShellItem: TStShellItem);
    procedure berSpitzel1Click(Sender: TObject);
    procedure Programm1Click(Sender: TObject);
    procedure Programmbeenden1Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure spyonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Programmbeenden2Click(Sender: TObject);
    procedure ZumTrayiconminimieren1Click(Sender: TObject);
    procedure Hauptfensteranzeigen1Click(Sender: TObject);
    procedure spycheckerClick(Sender: TObject);
  private
    { Private-Deklarationen }
    // für MessageID von RegisterWindowsMessage 
    TaskBarNewReg : DWORD;
    IconData: TNotifyIconData;
  public
    { Public-Deklarationen }
    procedure WndProc(var Msg: TMessage); override; 
    procedure WMSysCommand(var Message: TWMSysCommand); message WM_SYSCOMMAND;
  end;
var
  MainForm: TMainForm;
  SpyFolder:Widestring;
  time:string;
  // Für Ballon Tipps
  shell32_ver : dword = 400; // Standardversion 4.0 der "shell32.dll"  
  dll         : DWORD = 0;  
  ver         : TDllVersionInfo;

implementation
uses Unit2;
{$R *.dfm}
// Für Ballon Tipps
const
  {$EXTERNALSYM NIN_SELECT}
  NIN_SELECT     = WM_USER + 0;
  {$EXTERNALSYM NINF_KEY} 
  NINF_KEY       = $01; 
  {$EXTERNALSYM NIN_KEYSELECT} 
  NIN_KEYSELECT  = NIN_SELECT or NINF_KEY; 
  {$EXTERNALSYM NIN_BALLOONSHOW} 
  NIN_BALLOONSHOW      = WM_USER + 2; 
  {$EXTERNALSYM NIN_BALLOONHIDE} 
  NIN_BALLOONHIDE      = WM_USER + 3; 
  {$EXTERNALSYM NIN_BALLOONTIMEOUT} 
  NIN_BALLOONTIMEOUT   = WM_USER + 4; 
  {$EXTERNALSYM NIN_BALLOONUSERCLICK} 
  NIN_BALLOONUSERCLICK = WM_USER + 5; 
  {$EXTERNALSYM NIM_SETFOCUS} 
  NIM_SETFOCUS    = $00000003; 
  {$EXTERNALSYM NIM_SETVERSION} 
  NIM_SETVERSION  = $00000004; 
  {$EXTERNALSYM NOTIFYICON_VERSION} 
  NOTIFYICON_VERSION = 3; 
  {$EXTERNALSYM NIF_STATE} 
  NIF_STATE       = $00000008; 
  {$EXTERNALSYM NIF_INFO} 
  NIF_INFO        = $00000010; 
  {$EXTERNALSYM NIF_GUID} 
  NIF_GUID        = $00000020; 
  {$EXTERNALSYM NIS_HIDDEN} 
  NIS_HIDDEN       = $00000001; 
  {$EXTERNALSYM NIS_SHAREDICON} 
  NIS_SHAREDICON   = $00000002; 
// says this is the source of a shared icon 
// Notify Icon Infotip flags 
  {$EXTERNALSYM NIIF_NONE} 
  NIIF_NONE        = $00000000; 
// icon flags are mutualy exclusive 
// and take only the lowest 2 bits 
  {$EXTERNALSYM NIIF_INFO} 
  NIIF_INFO        = $00000001; 
  {$EXTERNALSYM NIIF_WARNING} 
  NIIF_WARNING     = $00000002; 
  {$EXTERNALSYM NIIF_ERROR} 
  NIIF_ERROR       = $00000003; 
  {$EXTERNALSYM NIIF_ICON_MASK} 
  NIIF_ICON_MASK   = $0000000F; 
  {$EXTERNALSYM NIIF_NOSOUND} 
  NIIF_NOSOUND     = $00000010; 
const 
  {$EXTERNALSYM NOTIFYICONDATAA_V1_SIZE} 
  NOTIFYICONDATAA_V1_SIZE = 88; 
  {$EXTERNALSYM NOTIFYICONDATAW_V1_SIZE} 
  NOTIFYICONDATAW_V1_SIZE = 152; 
  {$EXTERNALSYM NOTIFYICONDATA_V1_SIZE} 
  NOTIFYICONDATA_V1_SIZE  = NOTIFYICONDATAA_V1_SIZE; 
  {$EXTERNALSYM NOTIFYICONDATAA_V2_SIZE} 
  NOTIFYICONDATAA_V2_SIZE = sizeof(NOTIFYICONDATAA) - (sizeof(TGUID)); 
  {$EXTERNALSYM NOTIFYICONDATAW_V2_SIZE} 
  NOTIFYICONDATAW_V2_SIZE = sizeof(NOTIFYICONDATAW) - (sizeof(TGUID)); 
  {$EXTERNALSYM NOTIFYICONDATA_V2_SIZE} 
  NOTIFYICONDATA_V2_SIZE  = NOTIFYICONDATAA_V2_SIZE;
////////////////////////////////////////////////////////////////////////////////
// Überwachung starten
procedure StartSpy;
begin
If MainForm.Edit1.Text = '' then
  ShowMessage('Sie müssen als erstes einen Ordner für die Überwachung auswählen!')
else
  begin
  MainForm.Notfier.WatchFolder := SpyFolder;
  MainForm.ProgressTimer.Enabled := True;
  MainForm.Notfier.Active := True;
  MainForm.Status.Panels[0].Text := 'Überwachung aktiv...';
  end;
end;
////////////////////////////////////////////////////////////////////////////////
// Spezielle Pfade auslesen
function GetSpecialFolder(const AFolder: Integer): String;
var
  ItemIDList: PItemIDList;
  hPath: PChar;
  ShellH: IMalloc;
begin
  if SUCCEEDED(SHGetSpecialFolderLocation(Application.Handle, AFolder, ItemIDList)) then
  begin
    try
      hPath:= StrAlloc(max_path);
      try
        if SHGetPathFromIDList (ItemIDList, hPath) then
          Result:=hPath;
      finally
        StrDispose(hPath);
      end;
    finally
     if SHGetMalloc(ShellH) = NOERROR then
       ShellH.Free(ItemIDList);
    end;
  end
  else
    RaiseLastOSError;
end;
////////////////////////////////////////////////////////////////////////////////
// Timer für die Fortschrittsanzeige
procedure TMainForm.ProgressTimerTimer(Sender: TObject);
var pos:TPercent;
begin
pos := MainForm.Progress1.Percent;
if pos <> 100 then
  inc(pos)
else
  pos := 0;
MainForm.Progress1.Percent := pos;
end;
////////////////////////////////////////////////////////////////////////////////
// Ordner zur Überwachung auswählen
procedure TMainForm.Button1Click(Sender: TObject);
var dir:string;
begin
dir := GetSpecialFolder(CSIDL_Drives);
If SelectDirectory('Bitte einen Ordner zur Überwachung auswählen!',Dir,SpyFolder) = true then
  begin
  MainForm.Edit1.Text := IncludeTrailingPathDelimiter(SpyFolder);
  StartSpy;
  end;
end;
////////////////////////////////////////////////////////////////////////////////
// Datei wurde erstellt
procedure TMainForm.NotfierFileCreate(Sender: TObject;
  ShellItem: TStShellItem);
begin
time := '[' + TimeToStr(now) + '] ';
MainForm.Log.Lines.Add(time + 'Die Datei ' + ShellItem.DisplayName + ' wurde erstellt');
end;
////////////////////////////////////////////////////////////////////////////////
// Datei wurde gelöscht
procedure TMainForm.NotfierFileDelete(Sender: TObject; OldShellItem,
  NewShellItem: TStShellItem);
begin
time := '[' + TimeToStr(now) + '] ';
MainForm.Log.Lines.Add(time + 'Die Datei ' + OldShellItem.DisplayName + ' wurde gelöscht');
end;
////////////////////////////////////////////////////////////////////////////////
// Datei wurde umbenannt
procedure TMainForm.NotfierFileRename(Sender: TObject; OldShellItem,
  NewShellItem: TStShellItem);
begin
time := '[' + TimeToStr(now) + '] ';
MainForm.Log.Lines.Add(time + 'Die Datei ' + OldShellItem.DisplayName + ' wurde in ' + NewShellItem.DisplayName + ' umbenannt' );
end;
////////////////////////////////////////////////////////////////////////////////
// Ordner wurde erstellt
procedure TMainForm.NotfierFolderCreate(Sender: TObject;
  ShellItem: TStShellItem);
begin
time := '[' + TimeToStr(now) + '] ';
MainForm.Log.Lines.Add(time + 'Der Ordner ' + ShellItem.DisplayName + ' wurde erstellt');
end;
////////////////////////////////////////////////////////////////////////////////
// Ordner wurde gelöscht
procedure TMainForm.NotfierFolderDelete(Sender: TObject;
  ShellItem: TStShellItem);
begin
time := '[' + TimeToStr(now) + '] ';
MainForm.Log.Lines.Add(time + 'Der Ordner ' + ShellItem.DisplayName + ' wurde gelöscht');
end;
////////////////////////////////////////////////////////////////////////////////
// Ordner wurde umbenannt
procedure TMainForm.NotfierFolderRename(Sender: TObject; OldShellItem,
  NewShellItem: TStShellItem);
begin
time := '[' + TimeToStr(now) + '] ';
MainForm.Log.Lines.Add(time + 'Der Ordner ' + OldShellItem.DisplayName + ' wurde in ' + NewShellItem.DisplayName + ' umbenannt' );
end;
////////////////////////////////////////////////////////////////////////////////
// Form2 zeigen
procedure TMainForm.berSpitzel1Click(Sender: TObject);
begin
Form2.ShowModal;
end;
////////////////////////////////////////////////////////////////////////////////
// Beschriftungscheck
procedure TMainForm.Programm1Click(Sender: TObject);
begin
If MainForm.Edit1.Text = '' then
  MainForm.spyon.Enabled := false
else
  MainForm.spyon.Enabled := true;
If MainForm.Notfier.Active = True then
  MainForm.spyon.Caption := 'Überwachung deaktivieren'
else
  MainForm.spyon.Caption := 'Überwachung aktivieren';
end;
////////////////////////////////////////////////////////////////////////////////
// Programm beenden
procedure TMainForm.Programmbeenden1Click(Sender: TObject);
begin
Close;
end;
////////////////////////////////////////////////////////////////////////////////
// Beim Aktivieren Fokus auf Button legen
procedure TMainForm.FormActivate(Sender: TObject);
begin
MainForm.Button1.SetFocus;
end;
////////////////////////////////////////////////////////////////////////////////
// Überwachung an-/abschalten
procedure TMainForm.spyonClick(Sender: TObject);
begin
If MainForm.Notfier.Active = true then
  begin
  MainForm.Notfier.Active := false;
  MainForm.Status.Panels[0].Text := 'Überwachung nicht aktiv...';
  MainForm.ProgressTimer.Enabled := false;
  MainForm.Progress1.Percent := 0;
  end
else
  begin
  MainForm.Notfier.Active := true;
  MainForm.Status.Panels[0].Text := 'Überwachung aktiv...';
  MainForm.ProgressTimer.Enabled := true;
  end;
end;
//////////////////////////////////////////////////////////////////////////////// 
// Beim Erstellen des Formulares TNotifyIconData-Struktur initialisieren
procedure TMainForm.FormCreate(Sender: TObject);
begin
  // Message ID für Message merken, die gesendet wird, wenn die Taskbar im
  // System registriert wird. 
  TaskBarNewReg := RegisterWindowMessage('TaskbarCreated'); 
  // IconData Struktur füllen 
  IconData.cbSize := SizeOf(IconData); 
  IconData.Wnd := Handle; 
  IconData.uID := 100; 
  IconData.uFlags := NIF_MESSAGE + NIF_ICON + NIF_TIP; 
  IconData.uCallBackMessage := WM_USER + 20; 
  IconData.hIcon := Application.Icon.Handle;
  IconData.szTip := 'Spitzel - (c) Delphi-n Software';
  // Icon einfügen. Bei Bedarf sofort 
  //Shell_NotifyIcon(NIM_ADD, @IconData);
  // DDL Version der Shell32.dll herausfinden
  dll := LoadLibrary('shell32.dll');  
    if(dll <> 0) then
      begin
        DllGetVersion := GetProcAddress(dll,'DllGetVersion');
        if(@DllGetVersion <> nil) then
          begin
            fillchar(ver,sizeof(TDllVersionInfo),0);
            ver.cbSize := sizeof(TDllVersionInfo);
            if(DllGetVersion(@ver) = NOERROR) then
              shell32_ver := (ver.dwMajorVersion * 100) + ver.dwMinorVersion;
          end;
        FreeLibrary(dll);
      end;
  // abhängig von der "shell32.dll" die Strukturgröße setzen!
  if(shell32_ver = 600) then IconData.cbSize := sizeof(TNotifyIconData)
    else if(shell32_ver >= 500) then IconData.cbSize := NOTIFYICONDATA_V2_SIZE
      else IconData.cbSize := NOTIFYICONDATA_V1_SIZE;
end;
////////////////////////////////////////////////////////////////////////////////
// Wenn Form weg -> dann Icon weg
procedure TMainForm.FormDestroy(Sender: TObject);
begin
  Shell_NotifyIcon(NIM_DELETE, @IconData);
end;
////////////////////////////////////////////////////////////////////////////////
// auf Mausklicks reagieren, Fensterprozedur erweitern
procedure TMainForm.WndProc(var Msg: TMessage);
var
  Point: TPoint;
begin
  // WM_USER + 20 ist unsere TNA Icon Nachricht
  if Msg.Msg = WM_USER + 20 then
  begin
    // im lParam steht die Nachricht
    case Msg.lParam of
      // rechte Taste für Menü
      WM_RBUTTONDOWN:
        begin
          SetForegroundWindow(Handle); 
          GetCursorPos(Point);
          PopUpMenu1.PopUp(Point.X, Point.Y);
          if MainForm.Edit1.Text = '' then
          MainForm.spychecker.Enabled := false;
          if MainForm.Notfier.Active = true then
            MainForm.spychecker.Checked := true else
            MainForm.spychecker.Checked := false;
        end;
      // linke Taste
      WM_LBUTTONDOWN:
        begin
          //ShowMessage('links runter');
        end; 
      // Doppelklick
      WM_LBUTTONDBLCLK:
        begin 
          // Fenster anzeigen und Fokus setzen
          MainForm.Show;
          MainForm.SetFocus;
          // Icon entfernen 
          Shell_NotifyIcon(NIM_DELETE, @IconData);
        end; 
    end; 
  end 
  // Taskbar wurde im System registriert, Icon einfügen 
  else if Msg.Msg = TaskBarNewReg then
  begin 
    Shell_NotifyIcon(NIM_ADD, @IconData); 
  end; 
  inherited; 
end; 
//////////////////////////////////////////////////////////////////////////////// 
// beim Minimieren Fomr verstecken und Icon in die TNA
procedure TMainForm.WMSysCommand(var Message: TWMSysCommand);
begin 
  // Fenster wurde minimiert 
  if Message.CmdType and $FFF0 = SC_MINIMIZE then 
  begin
    Hide;
    // Icon in der TNA anzeigen
    Shell_NotifyIcon(NIM_ADD, @IconData);
  end 
  else 
    inherited; 
end;
////////////////////////////////////////////////////////////////////////////////
// Programm beenden - Popup
procedure TMainForm.Programmbeenden2Click(Sender: TObject);
begin
Close;
end;
////////////////////////////////////////////////////////////////////////////////
// Zum TNA Icon - Menu
procedure TMainForm.ZumTrayiconminimieren1Click(Sender: TObject);
begin
  Hide;
  // Icon in der TNA anzeigen
  Shell_NotifyIcon(NIM_ADD, @IconData);
  if MainForm.Edit1.Text = '' then
    MainForm.spychecker.Enabled := false;
  if(shell32_ver >= 500) then 
  begin
    IconData.uFlags      := IconData.uFlags or NIF_INFO;
    IconData.szInfo     := 'Ein Beispiel für einen neuen Balloon-Tipp,' +
      #13#10 + 'der auch mehrzeilig sein kann.';
    IconData.szInfoTitle := 'Taskbar-Demo';
    IconData.dwInfoFlags := NIIF_INFO;
  end;
end;
////////////////////////////////////////////////////////////////////////////////
// Hauptfenster anzeigen - Popup
procedure TMainForm.Hauptfensteranzeigen1Click(Sender: TObject);
begin
MainForm.Show;
MainForm.SetFocus;
Shell_NotifyIcon(NIM_DELETE, @IconData);
end;
////////////////////////////////////////////////////////////////////////////////
// Überwachung an/aus - Popup
procedure TMainForm.spycheckerClick(Sender: TObject);
begin
If MainForm.Notfier.Active = true then
  begin
  MainForm.Notfier.Active := false;
  MainForm.spychecker.Checked := false;
  MainForm.Status.Panels[0].Text := 'Überwachung nicht aktiv...';
  MainForm.ProgressTimer.Enabled := false;
  MainForm.Progress1.Percent := 0;
  end
else
  begin
  MainForm.Notfier.Active := true;
  MainForm.spychecker.Checked := true;
  MainForm.Status.Panels[0].Text := 'Überwachung aktiv...';
  MainForm.ProgressTimer.Enabled := true;
  end;
end;
end.

PS: Ein Kompliment an alle, die sich hier zurechtfinden ;) :D
 

Anhänge

  • 26294attachment.txt
    27,3 KB · Aufrufe: 788

CSANecromancer

Erfahrenes Mitglied
Hmmm... In der Initialisierung benutzt du NIF_MESSAGE + NIF_ICON + NIF_TIP, weiter unten jedoch machst du ein IconData.uFlags or NIF_INFO. Hast du es schon mit einem IconData.uFlags + NIF_INFO versucht?
Sonst fällt mir auf Anhieb auch nichts ein.