Frage zu Baloontips
-
danke, werde mal versuchen zu fummeln!
*schwitz*gruß gerd
-
@el clio:
habe etwas gefunden, funzt auch prima, nur müsste ich jetzt noch ein bestimmtes icon dafür haben, nicht unbedingt das application icon.
kann ich auch icons nehmen, welche in einer imagelist als bmps drin sind?
gruß gerd
ps: hier die lösung:
void __fastcall TForm1::MyNotify(TMessage& Msg) { POINT MousePos; switch(Msg.LParam) { case WM_RBUTTONUP: if (GetCursorPos(&MousePos)) { PopupMenu1->PopupComponent = Form1; SetForegroundWindow(Handle); PopupMenu1->Popup(MousePos.x, MousePos.y); } else Show(); break; case WM_LBUTTONUP: ToggleState(); break; default: break; } TForm::Dispatch(&Msg);
-
Ja genau die meinte ich. Hab ich auch in etwa so.
Welches Icon du nimmst ist egal musste halt anpassen in:
bool __fastcall TMainForm::TrayMessage(DWORD dwMessage) { [...] tnd.hIcon = Application->Icon->Handle; // oder irgend ein anderer Icon [...] } //---------------------------------------------------------------------------Die Imagelist-Bilder sollten ja auch kein Problem darstellen. Gibts da nicht ne Funktion GetIcon() oder so, die direkt ein Icon von nem Bitmap zurückgibt...
Du schaffst das!

Wenn das alles fertig ist würd ich übrigens gerne mal deine komplettlösung sehen

-
danke für den zuspruch, jetzt suche ich nur noch nach einer methode für das icon(werde dein mal versuchen), und nach der lösung, wie man die sachen im tray befördert beim minimieren.
werde wenn alles fertig alles posten!

gruß gerd
-
@el clio:
eine frage stellt sich mir, wie bekomme ich einen message handler hin, der mir beim minimze die möglichkeit gibt, darauf zu reagieren?
ps: mit dem Icon muss ich noch etwas testen.
du hattest recht, TImageList hat die möglichkeit ein icon zu liefern:
TIcon *ic = new TIcon(); ImageList1->GetIcon(0,ic);nur fehlt mir jetzt noch der handle auf ic.
vielleicht muss ich es aber dann, da mir das oberste vielleicht doch probleme bereitet auf eine ressource zurückgreifen, welche ich einlinke.
gruß gerd
-
@el clio:
ok, hatte (so dachte ich) die möglichkeit gefunden, funzt nur leider nicht so, wie gedacht:
eine eigene memberfunktion ins formular rein, und über:
Application->OnMinimize = Eigene_Memberfunktionzuweisen:
dann in dieser funktion einfach nur ein:
Hide();einbringen. Klappt anfangs sehr schön, aber nach einiger Zeit nicht mehr. Vielleicht mache ich auch nur etwas falsch. natürlich habe ich noch beim abfangen von MyNotify ein :
Show(); Application->Restore();drin, aber irgendwie ist das kein richtiger ansatz, siehe oben beschriebenes Problem.
naja, war nur zur info.
gruß gerd
*derweiteraufdersucheist*
-
ok, ich hoffe ich freu mich nicht zu früh, aber ich glaube es liegt am
Hide();wenn man nämlich statt dem einfach die API-Funktion:
ShowWindow(Application->Handle, SW_HIDE);aufruft, spinnt es nicht mehr herum.
*hoffentlich liege ich richtig*
gruß gerd
-
es ist vollbracht, und funzt alles!

vielleicht nicht die elegantesten lösungen, aber es erfüllt alles seinen zweck. Wer etwas zu verbessern hat, soll es ruhig dazu beitragen, damit ich fehler erkenne!
Danke.hier nochmal als einfachstes beispiel, damit nur code kopieren, und routinen implementieren, damit man auch sieht, was man alles braucht:
Headerdatei:
//--------------------------------------------------------------------------- #ifndef mainH #define mainH //--------------------------------------------------------------------------- #include <Classes.hpp> #include <Controls.hpp> #include <StdCtrls.hpp> #include <Forms.hpp> #include <ImgList.hpp> #include <Menus.hpp> #define MYWM_NOTIFY WM_USER #define IDC_MYICON 1006 //--------------------------------------------------------------------------- class TfrmMain : public TForm { __published: // Von der IDE verwaltete Komponenten TPopupMenu *TrayPop; TMenuItem *Wiederherstellen1; TImageList *ImageList1; void __fastcall FormCreate(TObject *Sender); void __fastcall FormClose(TObject *Sender, TCloseAction &Action); void __fastcall FormClick(TObject *Sender); private: // Anwender-Deklarationen public: // Anwender-Deklarationen __fastcall TfrmMain(TComponent* Owner); TIcon* ic; BEGIN_MESSAGE_MAP // needed for tray icon (messages) MESSAGE_HANDLER(WM_DRAWITEM, TMessage,DrawItem); MESSAGE_HANDLER(MYWM_NOTIFY,TMessage,MyNotify); END_MESSAGE_MAP(TForm) void __fastcall DrawItem(TMessage& Msg); // MySize: wenn die Anwenung minimiert wird void __fastcall MySize(TObject *Sender); void __fastcall MyNotify(TMessage& Msg); bool __fastcall TrayMessage(DWORD dwMessage); bool __fastcall BalloonTip(AnsiString title, AnsiString text,int flag); // flag bitte mit (NIIF_ERROR,NIIF_WARNING,NIIF_INFO...) füttern }; //--------------------------------------------------------------------------- extern PACKAGE TfrmMain *frmMain; //--------------------------------------------------------------------------- #endifQuelldatei:
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "main.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TfrmMain *frmMain; HINSTANCE g_hinst; LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi); ///< Callback function //--------------------------------------------------------------------------- LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi) { HICON hIcon; hIcon = (HICON)LoadImage(g_hinst, MAKEINTRESOURCE(lpdi->CtlID), IMAGE_ICON, 16, 16, 0); if (!hIcon) return(FALSE); DrawIconEx(lpdi->hDC, lpdi->rcItem.left, lpdi->rcItem.top, hIcon, 16, 16, 0, NULL, DI_NORMAL); return(TRUE); } //--------------------------------------------------------------------------- void __fastcall TfrmMain::DrawItem(TMessage& Msg) { IconDrawItem((LPDRAWITEMSTRUCT)Msg.LParam); TForm::Dispatch(&Msg); } //--------------------------------------------------------------------------- void __fastcall TfrmMain::MySize(TObject *Sender) { ShowWindow(Application->Handle, SW_HIDE); } //--------------------------------------------------------------------------- void __fastcall TfrmMain::MyNotify(TMessage& Msg) { POINT MousePos; switch(Msg.LParam) { case WM_RBUTTONUP: if (GetCursorPos(&MousePos)) { TrayPop->PopupComponent = frmMain; SetForegroundWindow(Handle); TrayPop->Popup(MousePos.x, MousePos.y); } else Show(); break; case WM_LBUTTONUP: //TrayMessage(NIM_MODIFY); break; case WM_LBUTTONDBLCLK: Application->Restore();//TrayMessage(NIM_MODIFY); Show(); frmMain->SetFocus(); break; default: break; } TForm::Dispatch(&Msg); } //--------------------------------------------------------------------------- bool __fastcall TfrmMain::BalloonTip(AnsiString title, AnsiString text,int flag) { TIcon * ic = new TIcon(); ImageList1->GetIcon(0,ic); NOTIFYICONDATA tnd; tnd.cbSize = sizeof(NOTIFYICONDATA); tnd.hWnd = Handle; tnd.uID = IDC_MYICON; tnd.uFlags = NIF_INFO; tnd.dwInfoFlags = flag; tnd.uCallbackMessage = MYWM_NOTIFY; tnd.uTimeout = 1000; // in milliseconds *10? lstrcpyn(tnd.szTip, "was auch immer", sizeof(tnd.szTip)); lstrcpyn(tnd.szInfoTitle, title.c_str(), sizeof(tnd.szInfoTitle)); tnd.hIcon = ic->Handle; lstrcpyn(tnd.szInfo, text.c_str(), sizeof(tnd.szInfo)); return (Shell_NotifyIcon(NIM_MODIFY, &tnd)); } //--------------------------------------------------------------------------- bool __fastcall TfrmMain::TrayMessage(DWORD dwMessage) { TIcon * ic = new TIcon(); ImageList1->GetIcon(0,ic); NOTIFYICONDATA tnd; tnd.cbSize = sizeof(NOTIFYICONDATA); tnd.hWnd = Handle; tnd.uID = IDC_MYICON; tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; tnd.uCallbackMessage = MYWM_NOTIFY; if (dwMessage == NIM_MODIFY) { tnd.hIcon = ic->Handle;//Application->Icon->Handle;// oder irgend ein anderer Icon lstrcpyn(tnd.szTip, "was auch immer", sizeof(tnd.szTip)); } else { tnd.hIcon = NULL; tnd.szTip[0] = '\0'; } return (Shell_NotifyIcon(dwMessage, &tnd)); } //--------------------------------------------------------------------------- __fastcall TfrmMain::TfrmMain(TComponent* Owner) : TForm(Owner) { TrayMessage(NIM_ADD); // TrayIcon hinzufügen TrayMessage(NIM_MODIFY); } //--------------------------------------------------------------------------- void __fastcall TfrmMain::FormCreate(TObject *Sender) { Application->OnMinimize = MySize; TIcon* ic=new TIcon(); ic = NULL; } //--------------------------------------------------------------------------- void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action) { Action = caFree; TrayMessage(NIM_DELETE); delete ic; } //--------------------------------------------------------------------------- void __fastcall TfrmMain::FormClick(TObject *Sender) { BalloonTip("Überschrift","Ein kleiner Text.\nAuch mit Umbruch",NIIF_INFO); } //---------------------------------------------------------------------------viel spass, gruß gerd
(dank an el clio)
-
Sieht doch gut aus!!!
Allerding denke ich, dass du dir das Hide() (oder ShowWindow()) und das Show() sparen kannst.
Das OnMinimize wird ja beim bzw. vor dem minimieren aufgerufen, somit "verschwindet" deine Anwendung ja sowieso danach, oder? Entsprechend wird die dann auch mit Restore() wieder hergestellt - ohne Show().Ach so und nochwas - wohlgemerkt völlig egal, aber ich sags trotzdem mal - die Prototypendeklaration für die CallBack-Funktion
LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi); ///< Callback functionkannste dir glaub ich sparen, weil deine Callback ja eh ganz oben steht und so ja auch in allen anderen Funktionen bekannt sein sollte...

Ansonsten: TOP!!!
Ach noch ne Ergänzung fällt mir grad ein:
Die TrayMessage() könnte man noch um einen Parameter (z.B. int index = 0) erweitern, um so den Icon dynamisch zu machen, also anhand des indexes ein anderes Bild aus der Imagelist verwenden.
(Evtl. sinnvoll für "animierte"-TrayIcons)
in der Header: public: [...] bool __fastcall TrayMessage(DWORD dwMessage, int index = 0); [...] in der cpp: bool __fastcall TfrmMain::TrayMessage(DWORD dwMessage, int index) { [...] ImageList1->GetIcon(index, ic); [...] } //---------------------------------------------------------------------------
-
mit dem prototypen haste recht, natürlich!

das mit dem index ist auch ne gute idee, werde ich noch einfügen.
zum hide(), dass kann man nicht weglassen, da sonst die anwendung nur minimiert wird.
aber das Show() kann weg, da restore ebenfalls das formular hoch bringt.

gruß gerd
ps: wen es stört, dass das fenster nach dem restore nur wiederhergestellt wird, aber nicht im vordergrund liegt ruft einfach nach dem
Application->Restore();noch diese funktion auf:
SetForegroundWindow(Handle);