Balloon tip met Shell_NotifyIcon

Door Hmail op woensdag 29 februari 2012 13:27 - Reacties (9)
Categorie: -, Views: 3.288

Voor mijn stage moet ik in-, en uitklokken via een web interface. Dat betekent dus: Binnenkomen, laptop aanzetten, koffie pakken, aanmelden, slok koffie, mail lezen, beginnen met werken en na 3 uur realiseren dat ik vergeten ben in te klokken en die uren dus overnieuw moet doen :(

Dus, C++ to the rescue :D

Ik had al met .NET een simpel tooltje gemaakt om een melding te tonen die uitgevoerd wordt als ik me aanmeld, maar omdat ik meer met Win32 wil leren werken, en ik door Raymond Chen's blog geÔnspireerd werd, leek het me wel een leuk idee om door een balloon getipt te worden.
Met daarbij o.a. het idee om later nog functionaliteit toe te voegen die het mogelijk maakt om erop te klikken, en automatisch geforward te worden, of zelfs een schermpje die voor mij de GET/POST opdrachten uitvoert zodat ik helemaal niets meer hoef te doen :D
Maar dat is allemaal later. Nu eerst eens een icon maken die een berichtje toont.

http://geensite.nl/tmp/goedemorgen.png


Op het moment van schrijven heb ik nog maar net het eerste deel van Petzold's Programming Windows uit en een klein beetje ervaring met het schrijven van Windows-programma's. Op en aanmerkingen zijn zeker welkom, maar be kind, het is m'n eerste blog entry ;)

Shell_NotifyIcon heeft twee parameters, DWORD dwMessage en PNOTIFYICONDATA lpdata. Voor dwMessage kunnen we kort zijn, in dit geval hebben we twee flags nodig: NIM_ADD en NIM_DELETE. Vergeet die laatste niet, anders blijft het icon staan, ook na het sluiten.

De NOTIFYICONDATA struct is iets uitgebreider.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// Voor enkel het tonen van een balloon kan NULL als handle gebruikt 
// worden. Als je een applicatie hebt met window procedures heb je 
// uiteraard een window handle.
HWND hwnd = NULL;

NOTIFYICONDATA nid = {};

// Dit lijkt simpelweg de grootte in te stellen, maar dit bepaalt ook een 
// groot deel van de functionaliteit. VÚÚr Windows Vista moet je een andere
// grootte instellen, anders wordt bijvoorbeeld de tip niet getoond. Zie 
// hiervoor het kopje 'Remarks' bij 
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773352(v=vs.85).aspx
nid.cbSize = sizeof(NOTIFYICONDATA);

nid.hWnd = hwnd;

// Na Windows Vista kun je van een guid gebruik maken. Deze kan er echter ook
// regelmatig voor zorgen dat de icon niet getoond wordt. Voor het gemak heb 
// ik daarom maar voor een uID gekozen. 
nid.uID = 0;

// Hoewel de Express-versie van Visual Studio geen resource editor heeft, 
// kun je de resource files met de hand aanmaken. Een voorbeeld hiervan 
//is met de post meegeleverd.
nid.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
    
// Dit toont een icon en een omschrijving. "Echte" applicaties gebruiken
// uiteraard ook NIF_TIP om een tooltip te tonen die een korte omschrijving
// van de applicatie geeft. 
nid.uFlags = NIF_ICON | NIF_INFO | NIF_SHOWTIP;
    
// Stel de titel en de omschrijving in.
StringCchCopy(nid.szInfoTitle, ARRAYSIZE(nid.szInfoTitle), 
    L"Goedemorgen \\o/");
StringCchCopy(nid.szInfo, ARRAYSIZE(nid.szInfo), 
    L"Geniet van de koffie! Vergeet niet in te klokken!");

// Voeg de icon toe aan de system tray.
Shell_NotifyIcon(NIM_ADD, &nid);

// In dit geval laat ik de icon een tijdlang staan. Op zich is dit 
// niet zo'n groot probleem, het sluit vanzelf, en onder Windows 7
// wordt het icoon netjes verborgen. 
// Het icoon verdwijnt niet als ik niet achter de computer zit, het 
// blijft getoond worden tot ik met de muis beweeg. Dan zit er een 2 sec
// timeout op. Daarna fade het icoon weg. Tenzij ik er op klik, dan verdwijnt
// het meteen.
// Een betere oplossing zou natuurlijk zijn om NIN_BALLOONTIMEOUT en
// NIN_BALLOONUSERCLICK af te vangen en dan het icon te verwijderen. 
// Hier kom ik echter in een latere versie op terug.
Sleep(600000); // Na 10m zou de koffie wel op moeten zijn
Shell_NotifyIcon(NIM_DELETE, &nid);



Natuurlijk is bovenstaande code weinig spannend. Maar het heeft me best even tijd gekost om dit goed werkend te krijgen, en er zijn maar weinig sites waar simpelweg dit te vinden is. Met hulp van deze code kan iemand anders misschien weer verder.

In een volgende post: Context menu die getoond wordt als er met de rechtermuisknop op het icon geklikt wordt en een fatsoenlijke manier om af te sluiten.

Code: http://geensite.nl/tmp/Shell_NotifyIcon1.zip

Reacties


Door Tweakers user Jarrean, woensdag 29 februari 2012 14:44

Ik gebruik voor dit soort reminders altijd de taskscheduler van windows, die laat ik meteen betreffende pagina of prog opstarten samen met een melding.

Door Tweakers user Ethernal Five, woensdag 29 februari 2012 15:10

Sleep werkt met miliseconden, 100000ms is geen 10 minuten, maar 100 seconden ;)
10 minuten is dus 600000ms

[Reactie gewijzigd op woensdag 29 februari 2012 15:13]


Door Tweakers user Hmail, woensdag 29 februari 2012 15:13

Ethernal Five schreef op woensdag 29 februari 2012 @ 15:10:
Sleep werkt met miliseconden, dus 100000ms is geen 10 minuten, maar 100 seconden ;)
10 minuten is dus 600000ms
Toen ik de blog entry schreef stond er nog 600000, maar om de code voor de zekerheid nog even te checken had ik het aangepast naar 100s, ik wist dat ik zou vergeten het terug te zetten.. Aangepast, thanks :)

Door Tweakers user SeatRider, woensdag 29 februari 2012 15:17

Wat voor bedrijf vraagt haar medewerkers nog om in te klokken? :O

Door Tweakers user Hmail, woensdag 29 februari 2012 15:46

SeatRider schreef op woensdag 29 februari 2012 @ 15:17:
Wat voor bedrijf vraagt haar medewerkers nog om in te klokken? :O
Het was voor mij ook een verrassing :P Ik heb het bij eerdere werkgevers ook niet meegemaakt. Men doet het alleen voor de stagiaires, om een overzicht bij te kunnen houden van de gemaakte stageuren.
Vandaar dus ook die reminder, anders zou ik het gewoon vergeten.

Door Tweakers user BillsGate, donderdag 1 maart 2012 10:29

SeatRider schreef op woensdag 29 februari 2012 @ 15:17:
Wat voor bedrijf vraagt haar medewerkers nog om in te klokken? :O
Bedrijven waar medewerkers, veelal uitzendkrachten of inderdaad stagiares, op onregelmatige tijden of in ploegen werken.
Bij productiebedrijven en fabricageprocessen is inklokken zo gek nog niet :)

Door Tweakers user Kecin, vrijdag 2 maart 2012 12:12

Hmail schreef op woensdag 29 februari 2012 @ 15:46:
[...]

Het was voor mij ook een verrassing :P Ik heb het bij eerdere werkgevers ook niet meegemaakt. Men doet het alleen voor de stagiaires, om een overzicht bij te kunnen houden van de gemaakte stageuren.
Vandaar dus ook die reminder, anders zou ik het gewoon vergeten.
Inklokken en nooit meer uitklokken. Win

Door Tweakers user Zerfox, donderdag 8 maart 2012 18:32

Zo meteen een POST opdracht erin, wordt de inklokwebsite geŁpdatet..
Dan werk je enkele daagjes zonder te realiseren dat je nooit bent ingeklokt |:(

[Reactie gewijzigd op donderdag 8 maart 2012 18:32]


Door Tweakers user Xesxen, dinsdag 13 maart 2012 19:27

ZaroX schreef op donderdag 08 maart 2012 @ 18:32:
Zo meteen een POST opdracht erin, wordt de inklokwebsite geŁpdatet..
Dan werk je enkele daagjes zonder te realiseren dat je nooit bent ingeklokt |:(
Dat vang je dus op door te kijken of de output van de website wel de output is die je verwachtte. Zoniet, geef je een waarschuwing. :)

Reageren is niet meer mogelijk