Zum Inhalt springen

Anwendung (mfc) minimiert starten und/oder in trayleiste anzeigen...


TinTin

Empfohlene Beiträge

hi,

noch ne frage. gibt es ne möglichkeit eine dialogbasierende anwendung (mfc)

minimiert zu starten oder sogar so aufzurufen, dass sie nur in der trayleiste, vergleichbar mit z.b einen antivieren programm, angezeigt wird?

bei MDI oder SDI anwendungen ist das kein problem, zumindest das minimiert starten funktioniert aber bei dialogbasierenden anwendungen hab ich dazu noch nix gefunden. eventuell hat ja jemand erfahrung damit.

alternativ da zu könnte man die anwendung auch als dienst starten (soll unter win2k laufen), aber damit hab ich mich noch nicht ausernandersetzen können. eventuell kann mir dazu auch jemamd einen tipp geben.

ciao TinTin

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by TinTin

hi,

oder sogar so aufzurufen, dass sie nur in der trayleiste, vergleichbar mit z.b einen antivieren programm, angezeigt wird?

Hi,

in OnInitDialog

SetTimer(1, 20, HideTimerProc);

und binde dann folgende Funktion ein:


void CALLBACK EXPORT CMyDlg::HideTimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
::KillTimer(hWnd, nIDEvent);

::ShowWindow(hWnd, SW_HIDE);

HICON hIcon= (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);

BOOL res;

NOTIFYICONDATA tnd;
memset(&tnd, 0x00, sizeof(tnd));
tnd.cbSize = sizeof(NOTIFYICONDATA);
tnd.hWnd = hWnd;
tnd.uID = ID_TRAYNOTIFY;

tnd.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
tnd.uCallbackMessage = WM_TRAYNOTIFY;
tnd.hIcon = hIcon;

CString ProductName = AfxGetAppName();
lstrcpyn(tnd.szTip, (char*)(LPCTSTR)ProductName, sizeof(tnd.szTip));

res = Shell_NotifyIcon(NIM_ADD, &tnd);

if (hIcon)
::DestroyIcon(hIcon);

}

[/PHP]

Link zu diesem Kommentar
Auf anderen Seiten teilen

hi und danke erstmal für die schnelle hilfe!

ich hab noch kleiner probleme die ganze sach zum laufen zu bekommen...

folgendes hab ich gemacht...


// trayDlg.h : Header-Datei

//


class CTrayDlg : public CDialog

{

// Konstruktion

public:

   void CALLBACK EXPORT HideTimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime);

.

.

.

// trayDlg.cpp : Implementierungsdatei

//


#include "stdafx.h"

#include "tray.h"

#include "trayDlg.h"

.

.

.

BOOL CTrayDlg::OnInitDialog()

{

	CDialog::OnInitDialog();


                SetIcon(m_hIcon, TRUE);

                SetIcon(m_hIcon, FALSE);


                SetTimer(1, 20, HideTimerProc);


                return TRUE;

}

.

.

.

void CALLBACK EXPORT CTrayDlg::HideTimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)

{

    ::KillTimer(hWnd, nIDEvent);


    ::ShowWindow(hWnd, SW_HIDE);


    HICON hIcon= (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); 


    BOOL res;


    NOTIFYICONDATA tnd;

    memset(&tnd, 0x00, sizeof(tnd));

    tnd.cbSize              = sizeof(NOTIFYICONDATA);

    tnd.hWnd                = hWnd;

    tnd.uID                 = ID_TRAYNOTIFY;


    tnd.uFlags              = NIF_MESSAGE|NIF_ICON|NIF_TIP;

    tnd.uCallbackMessage    = WM_TRAYNOTIFY;

    tnd.hIcon               = hIcon;


    CString ProductName = AfxGetAppName();

    lstrcpyn(tnd.szTip, (char*)(LPCTSTR)ProductName, sizeof(tnd.szTip));


    res = Shell_NotifyIcon(NIM_ADD, &tnd);


    if (hIcon)

	::DestroyIcon(hIcon);


}

und das sind die fehler die der kompiler bringt...

C:\projekte\tray\trayDlg.cpp(53) : error C2664: 'SetTimer' : Konvertierung des Parameters 3 von 'void (struct HWND__ *,unsigned int,unsigned int,unsigned long)' in 'void (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,unsigned long)' nicht m

oeglich

        Keine Funktion mit diesem Namen im Gueltigkeitsbereich stimmt mit dem Zieltyp ueberein

C:\projekte\tray\trayDlg.cpp(109) : error C2065: 'ID_TRAYNOTIFY' : nichtdeklarierter Bezeichner

C:\projekte\tray\trayDlg.cpp(112) : error C2065: 'WM_TRAYNOTIFY' : nichtdeklarierter Bezeichner

was mach ich falsch?

ciao TinTin

Link zu diesem Kommentar
Auf anderen Seiten teilen

"...'ID_TRAYNOTIFY' : nichtdeklarierter Bezeichner..."

"...'WM_TRAYNOTIFY' : nichtdeklarierter Bezeichner..."

das sollte eigentlich schon alles sagen ;)

Höchstwahrscheinlich hast du einfach vergessen, die beiden Konstanten zu deklarieren.

Und die Sache mit der Timerfunktion ist neu für mich. Ich schreibe die Initalisierungen von NOTIFYICONDATA immer direkt in 'OnInitDialog()', und den Dialog selbst "verstecke" ich in 'InitInstance()' der der Applikationsklasse (ShowWindow( SW_HIDE )).

Vielleicht hilft dir das ja weiter.

Gruß, Eight

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Wochen später...
Ich schreibe die Initalisierungen von NOTIFYICONDATA immer direkt in 'OnInitDialog()', und den Dialog selbst "verstecke" ich in 'InitInstance()' der der Applikationsklasse (ShowWindow( SW_HIDE )).

kannst du da was genaueres zu sagen, denn aus dem letzten teil werde ich nicht ganz schlau...

ciao TinTin

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

die eigentliche WinAPI Funktion ShowWindow(), benötigt 2 Parameter nämlich

das Handle zum Fenster und das Flag was damit geschehen soll.

Die Funktion ShowWindow() die du benutzen möchtest ist eine Methode

von CWnd bzw. CWindow, d.h. du mußt dein Fensterobjekt angeben und

dessen Funktion aufrufen, dann brauchst du auch nur einen Parameter.

Gruß

Guybrush

Link zu diesem Kommentar
Auf anderen Seiten teilen

ich glaube ich bin ... :confused:

ich habe jetzt ein ganz neues dialogbasierendes mfc projekt erstellt.

alles ausser die 'ok' und 'abrechen' buttons aus dem projekt entfernt.

was muss ich denn jetzt machen, damit das programm beim start zumindest

minimiert gestartet wird. lieber wäre mir natürlich das programm in die tray zu schieben...

heute sitze ich auf meinem kopf glaube ich...HILFE !!!

mit der bitte um verständnis

ciao

TinTin

Link zu diesem Kommentar
Auf anderen Seiten teilen

Innerhalb von OnInitDialog ist es nicht möglich, mit ShowWindow oder ModifyStyle das Anzeigen zu verhinden, weil die MFC selbst dafür sorgt, dass der Dialog angezeigt wird, sobald es möglich ist.

Das kann man nur verhindern, indem man CDialog::DoModal überschreibt. Dazu deklarierst du in deiner Dialogklasse die Methode

public:

INT_PTR DoModal();

Für die Implementierung übernimmst du den Code aus CDialog::DoModal (aus dlgcore.cpp, im MFC-Source-Verzeichnis), und machst die folgenden Änderungen:

Zusätzlich:

#include <afxpriv.h>

Ersetzen (jeweils einmal):

MLF_SHOWONIDLE durch 0 (das ist das Entscheidende)

DELETE_EXCEPTION(e) durch e->Delete() (sonst gibts einen Compilerfehler)

Nachtrag:

Das Visible-Flag des Dialogs musst du natürlich auf False stellen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

hab jetzt folgendes gemacht...


//trayDlg.h:


class CTrayDlg : public CDialog

{

// Konstruktion

public:


	INT_PTR DoModal();


	CTrayDlg(CWnd* pParent = NULL);	// Standard-Konstruktor


// Dialogfelddaten

	//{{AFX_DATA(CTrayDlg)

	enum { IDD = IDD_TRAY_DIALOG };


...

und

//trayDlg.cpp

INT_PTR CTrayDlg::DoModal()

//  int CDialog::DoModal()

{

	// can be constructed with a resource template or InitModalIndirect

	ASSERT(m_lpszTemplateName != NULL || m_hDialogTemplate != NULL ||

		m_lpDialogTemplate != NULL);


	// load resource as necessary

	LPCDLGTEMPLATE lpDialogTemplate = m_lpDialogTemplate;

	HGLOBAL hDialogTemplate = m_hDialogTemplate;

	HINSTANCE hInst = AfxGetResourceHandle();

	if (m_lpszTemplateName != NULL)

	{

		hInst = AfxFindResourceHandle(m_lpszTemplateName, RT_DIALOG);

		HRSRC hResource = ::FindResource(hInst, m_lpszTemplateName, RT_DIALOG);

		hDialogTemplate = LoadResource(hInst, hResource);

	}

	if (hDialogTemplate != NULL)

		lpDialogTemplate = (LPCDLGTEMPLATE)LockResource(hDialogTemplate);


	// return -1 in case of failure to load the dialog template resource

	if (lpDialogTemplate == NULL)

		return -1;


	// disable parent (before creating dialog)

	HWND hWndParent = PreModal();

	AfxUnhookWindowCreate();

	BOOL bEnableParent = FALSE;

	if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))

	{

		::EnableWindow(hWndParent, FALSE);

		bEnableParent = TRUE;

	}


	TRY

	{

		// create modeless dialog

		AfxHookWindowCreate(this);

		if (CreateDlgIndirect(lpDialogTemplate,

						CWnd::FromHandle(hWndParent), hInst))

		{

			if (m_nFlags & WF_CONTINUEMODAL)

			{

				// enter modal loop

//				geändert

//				DWORD dwFlags = MLF_SHOWONIDLE;

				[COLOR=red]DWORD dwFlags = 0;[/COLOR]

				if (GetStyle() & DS_NOIDLEMSG)

					dwFlags |= MLF_NOIDLEMSG;

				VERIFY(RunModalLoop(dwFlags) == m_nModalResult);

			}


			// hide the window before enabling the parent, etc.

			if (m_hWnd != NULL)

				SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|

					SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);

		}

	}

	CATCH_ALL(e)

	{

//		DELETE_EXCEPTION(e);

		[COLOR=red]e->Delete();[/COLOR]

		m_nModalResult = -1;

	}

	END_CATCH_ALL


	if (bEnableParent)

		::EnableWindow(hWndParent, TRUE);

	if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)

		::SetActiveWindow(hWndParent);


	// destroy modal window

	DestroyWindow();

	PostModal();


	// unlock/free resources as necessary

	if (m_lpszTemplateName != NULL || m_hDialogTemplate != NULL)

		UnlockResource(hDialogTemplate);

	if (m_lpszTemplateName != NULL)

		FreeResource(hDialogTemplate);


	return m_nModalResult;

}

ich bekomme vom kompiler immer folgende nachricht...
CTrayDlg::DoModal' : Neue Version der virtuellen Funktion unterscheidet sich

von 'CDialog::DoModal' nur hinsichtlich des Ergebnistyps oder der Aufrufkonvention

was mach ich denn beim überschreiben falsch?

und wo finde ich die visible-flag?

ciao TinTin

Link zu diesem Kommentar
Auf anderen Seiten teilen

Originally posted by TinTin

was mach ich denn beim überschreiben falsch?

Wenn CDialog::DoModal bei dir vom Typ int ist, dann musst du die Methode auch als int überschreiben. Offenbar haben wir unterschiedliche Versionen der MFC.

und wo finde ich die visible-flag?
Im Resource-Editor, wenn du dir die Eigenschaften des Dialogs anzeigen lässt.
Link zu diesem Kommentar
Auf anderen Seiten teilen

super, jetzt gehts...:uli

hab aber noch ne kleine frage:

jetzt seh ich vom progrann nichts mehr. ich kann nur den laufenden prozess

im taskmanager sehen. gibt es ne möglichkeit ein icon in der tray anzuzeigen, mit dem ich das programm wieder sichtbar machen kann? so wie bei z.b. 'antivir' oder 'winamp'...

nochmal danke für die hilfe...

ciao TinTin

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das könnte z.B. folgendermaßen aussehen:

Als erstes brauchst du eine Message-ID, die das Trayicon an dein Dialogfenster schickt:

#define UM_TRAY_ACTION (WM_USER+0x100)

Um das Fenster aus- und das TrayIcon einzublenden:

ShowWindow( SW_HIDE );
NOTIFYICONDATA nid;
memset( &nid, 0, sizeof( nid));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = GetSafeHwnd();
nid.uID = 0;
nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
nid.uCallbackMessage = UM_TRAY_ACTION;
wsprintf( nid.szTip, TEXT("TrayIcon ToolTip"));
nid.hIcon = IrgendeinHICON; // z.B. m_hIcon der Dialogklasse
Shell_NotifyIcon( NIM_ADD, &nid);[/CODE] Umgekehrt:
[CODE]NOTIFYICONDATA nid;
memset( &nid, 0, sizeof( nid));
nid.cbSize = sizeof(NOTIFYICONDATA);
nid.hWnd = hWnd;
nid.uID = 0;
Shell_NotifyIcon( NIM_DELETE, &nid);
ShowWindow( SW_SHOW );
Damit du aber von der Tray-Nachricht überhaupt etwas mitbekommst, brauchst du eine Behandlungsfunktion. Deklariere in deiner Dialogklasse: LRESULT OnTrayAction( WPARAM wParam, LPARAM lParam); (der Name ist dabei willkürlich gewählt, wenn der Compiler sich an LRESULT stört, nimm void) Die Funktion musst du in die Messagemap der Dialogklasse einfügen, am besten nach //}}AFX_MSG_MAP, damit der Wizard nicht durcheinanderkommt: ON_MESSAGE(UM_TRAY_ACTION, OnTrayAction) Die Funktion könnte so aussehen:
LRESULT CDeinDlg::OnTrayAction( WPARAM wParam, LPARAM lParam)
{
if( lParam == WM_LBUTTONDBLCLK ) {
// Hier den Code zum Entfernen des Trayicons
// und Anzeigen des Dialogs einfügen oder
// aufrufen.
}
return 0;
}[/code]

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...