Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » Dialoganwendung minimiert im systray starten.

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
27.02.2004, 01:22 Uhr
mmc20
puss in boots


hallo,
ich hab neulich genau nach dieser lösung gesucht, aber kein richtiges TUT gefunden... desshalb hab ich etwas rumgebastelt und das hier ist das ergebnis, wenn die MOD's keinen fehler finden könnt ihrs ja in die FAQ's verschieben...

(das projekt heisst CTestmenue)
als erstes mal den Dialog nichtmodal machen

C++:
BOOL CTestmenueApp::InitInstance()
{
#ifdef _AFXDLL
    Enable3dControls();
#else
    Enable3dControlsStatic();
#endif

    CTestmenueDlg* dlg = new CTestmenueDlg;

    dlg->Create(IDD_MAINDLG);
    dlg->ShowWindow(SW_HIDE);
    dlg->ProcessMessages();
    return TRUE;
}


dadurch ist es erforderlich eine nachrichtenschleife zu installieren

C++:
void CTestmenueDlg::ProcessMessages()
{
    MSG m_msg;
    while(GetMessage(&m_msg, 0, 0, 0))
    {
        if (!PreTranslateMessage(&m_msg))
        {
            TranslateMessage(&m_msg);
            DispatchMessage(&m_msg);
        }
    }
}

natürlich kann man den dialog jetzt nicht mehr mit "CDialog::OnOK();" beenden...

C++:
void CTestmenueDlg::OnOK(){}
void CTestmenueDlg::OnCancel(){}
void CTestmenueDlg::OnClose()
{
    if ( IDCANCEL == MessageBox("Diese Option beendet das Programm.\n"
                        "Der Server steht dann nicht mehr zur verfügung!",
                        " Programm beenden ?", MB_ICONINFORMATION | MB_OKCANCEL) )
        return;

    Shell_NotifyIcon(NIM_DELETE, &m_nID); // systrayicon entfernen
    DestroyWindow();
}

und dies noch einfügen...

C++:
void CTestmenueDlg::PostNcDestroy()
{
    PostQuitMessage(0);
    delete this;
}

jetzt muss man nur noch das minimieren abfangen

C++:
void CTestmenueDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ( nID == SC_MINIMIZE )
    {
        ShowWindow(SW_HIDE);
        return;
    }

    CDialog::OnSysCommand(nID, lParam);
}

jetzt fügen wir das trayicon hinzu

C++:
BOOL CTestmenueDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
    //  wenn das Hauptfenster der Anwendung kein Dialogfeld ist
    SetIcon(m_hIcon, TRUE);            // Großes Symbol verwenden
    SetIcon(m_hIcon, FALSE);        // Kleines Symbol verwenden

//SystemTrayIcon////////////////////////////////////////////////////////////////////////
    m_nID.cbSize = sizeof ( NOTIFYICONDATA ) ;
    m_nID.hWnd = this->m_hWnd ;
    m_nID.uID = 1 ;
    m_nID.hIcon = (HICON)LoadImage(AfxGetApp()->m_hInstance,
                        MAKEINTRESOURCE(IDI_ICON1),
                        IMAGE_ICON,16,16,LR_SHARED|LR_DEFAULTCOLOR);
    m_nID.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
    m_nID.uCallbackMessage = WM_TRAY; // #define WM_TRAY WM_USER+1
    strcpy(m_nID.szTip, _T("SysTrayDialog mit Menu")) ;
    Shell_NotifyIcon ( NIM_ADD, &m_nID ) ;
//EndeSystemTrayIcon///////////////////////////////////////////////////////////////////

    return TRUE;  // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten
}

jetzt hat unsere anwendung ein trayicon, nur noch kein menu...

C++:
LRESULT CTestmenueDlg::OnTrayNotification(WPARAM wParam, LPARAM lParam)
{
    switch( lParam )
    {
        case WM_LBUTTONDBLCLK:// linker doppelklick zeigt dialog an
        {
            ShowWindow(SW_SHOW);
        }
        break;
        case WM_RBUTTONUP:// rechter klick öffnet menue
        {
            CPoint pos;
            GetCursorPos(&pos);

// schnell noch ein menue erstellen
            CMenu Menu;
            Menu.CreatePopupMenu();
            Menu.AppendMenu(MF_STRING|MF_GRAYED, ID_POPUP1, "Erster Eintrag");
            Menu.AppendMenu(MF_STRING|MF_GRAYED|MF_CHECKED, ID_POPUP2, "Zweiter Eintrag");
            Menu.AppendMenu(MF_STRING|MF_GRAYED, ID_POPUP3, "Dritter Eintrag");
            Menu.AppendMenu(MF_SEPARATOR);
            Menu.AppendMenu(MF_STRING, ID_POPUP4, "Programm beenden");
            Menu.TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, pos.x, pos.y, this);
            Menu.DestroyMenu();

/* oder ein vorhandenes anzeigen
            CMenu mPopup;
            CMenu *menu;
            mPopup.LoadMenu(IDR_MENU1);
            menu = mPopup.GetSubMenu(0);
            menu->TrackPopupMenu(TPM_LEFTALIGN |TPM_RIGHTBUTTON, pos.x, pos.y, this);
            menu->DestroyMenu();
*/

        }
        break;
    }
    return 0;
}

so das mit dem menu klappt schon mal, jetzt nur noch auf die menu ID's reagieren

C++:
void CTestmenueDlg::OnPopup(UINT nID)
{
    switch( nID )
    {
        case ID_POPUP1:
        {
        }
        break;
        case ID_POPUP2:
        {
        }
        break;
        case ID_POPUP3:
        {
        }
        break;
        case ID_POPUP4:// Programm beenden
        {
            OnClose();
        }
        break;
    }
}

das wars... nicht vergessen beim programmende alles aufzuräumen !
hier noch schnell die deklarationen:

C++:
// header-datei
class CTestmenueDlg : public CDialog
{
// Konstruktion
public:
    LRESULT OnTrayNotification(WPARAM wParam, LPARAM lParam);
    void ProcessMessages();
    NOTIFYICONDATA m_nID;
    CTestmenueDlg(CWnd* pParent = NULL);    // Standard-Konstruktor

//    Dialogfelddaten
    //{{AFX_DATA(CTestmenueDlg)
    enum { IDD = IDD_TESTMENUE_DIALOG };
        // HINWEIS: der Klassenassistent fügt an dieser Stelle Datenelemente (Members) ein
    //}}AFX_DATA

    // Vom Klassenassistenten generierte Überladungen virtueller Funktionen
    //{{AFX_VIRTUAL(CTestmenueDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV-Unterstützung
    virtual void PostNcDestroy();
    //}}AFX_VIRTUAL

// Implementierung
protected:
    HICON m_hIcon;

    // Generierte Message-Map-Funktionen
    //{{AFX_MSG(CTestmenueDlg)
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    afx_msg void OnClose();
    afx_msg void OnCancel();
    afx_msg void OnOK();
    afx_msg void OnPopup(UINT nID);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
private:
}
...
// cpp-datei
...
BEGIN_MESSAGE_MAP(CTestmenueDlg, CDialog)
    //{{AFX_MSG_MAP(CTestmenueDlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_CLOSE()
    ON_MESSAGE(WM_TRAY, OnTrayNotification)
    ON_COMMAND_RANGE(ID_POPUP1, ID_POPUP4, OnPopup)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
...


hoffentlich hab ich nichts vergessen... ( nen vorschau-button, wäre echt gut ! )

Dieser Post wurde am 27.02.2004 um 01:24 Uhr von mmc20 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: